diff --git a/site/docs/en-US/anchor-smooth.md b/site/docs/en-US/anchor-smooth.md
new file mode 100644
index 000000000..842eca806
--- /dev/null
+++ b/site/docs/en-US/anchor-smooth.md
@@ -0,0 +1,86 @@
+## AnchorSmooth
+
+A label slide to anchor point.
+
+### Basic usage
+
+Similar to the use of a tag, the attribute targetId is used to indicate the anchor that you want to reach.
+
+::: demo The AnchorSmooth component provides `targetId` attributes to point to ID elements that exist in the page and must have values. If the child element does not exist, `targetId` is used as the child element.
+```js
+render() {
+ return (
+
+
Here is the anchor#anchor0
+
+
+
+ Slide to anchor#anchor1
+
+
+
+ )
+}
+```
+:::
+
+### callback
+
+The attribute `onFinish` can bind a callback function and execute the callback function after reaching the anchor point.
+
+::: demo In the AnchorSmooth component, you can set the `onFinish` callback function that completes the sliding, and then call the `onFinish` function when it reaches the anchor.
+```js
+render() {
+ return (
+
+
+ Here is the anchor#anchor1
+
+
console.log("Arrive at anchor2")}>
+ Go to the anchor with ID anchor2 and execute the callback function
+
+
+ )
+}
+```
+:::
+
+### set title
+
+The` title` property tells the user the anchor to go when the mouse moves in.
+
+::: demo Use the `title` attribute to describe an anchor.
+```js
+render() {
+ return (
+
+
+ Here is the anchor#anchor2
+
+
console.log("Arrive at anchor0")}>
+ To the anchor with ID anchor0, containing title
+
+
+ )
+}
+```
+:::
+
+### Attributes
+
+| Attribute | Description | Type | Accepted Values | Default |
+|---------- |-------------- |---------- |-------------------------------- |-------- |
+| **targetId** | Anchor target **REQUIRED** | string | — | — |
+| title | title | string | — | — |
+
+### Events
+
+| Event Name | Description | Parameters |
+|---------- |-------- |---------- |
+| onFinish | fires when anchor is arrived | — |
+
diff --git a/site/docs/en-US/go-top.md b/site/docs/en-US/go-top.md
new file mode 100644
index 000000000..ccc7b5b02
--- /dev/null
+++ b/site/docs/en-US/go-top.md
@@ -0,0 +1,120 @@
+## GoTop
+
+In a long page, you can go back to the top of the page by clicking on the button from the bottom to the top.
+
+### Basic usage
+
+Usually the top-back button appears in the lower right corner of the page, so it is recommended to modify the `right`, `bottom` attributes for positioning; if there are special needs, you can also modify the `left`, `top` attributes.
+
+::: demo In the GoTop component, you can modify the `right` and `bottom` attributes with the default values of right: 50px and bottom: 50px.
+```js
+render() {
+ return (
+
+
Basic usage: The first button in the lower right corner
+
+
+ )
+}
+```
+:::
+
+### Property `showheight`
+
+Usually the top button will not appear when the rolling distance is 0. We can define the height of the scrollbar when the button appears by the attribute `showheight`, with the default value of 300, per unit px. If the scroll distance is greater than 300, the display button will fade in; if the scroll distance is less than 300, the hidden button will fade out.
+
+::: demo In the GoTop component, you can modify the showheight property to specify the scroll distance of the scrollbar, default value: 300; type: number.
+
+```js
+render() {
+ return (
+
+
+ A button appears when the scroll distance is 200 px:
+ the second button in the lower right corner
+
+
+
+ )
+}
+```
+
+:::
+
+### With icon
+
+By default, the `el-icon-caret-top` in elementUI can be used to replace the default icon by setting sub-elements.
+
+::: demo By setting the` children` attribute to display GoTop's icon, you can more effectively show the user your display intentions.
+```js
+render() {
+ return (
+
+
With icon:The third button in the lower right corner
+
+
+
+
+ )
+}
+```
+:::
+
+### Sliding time and callback function
+
+Customize the time used to complete the sliding, attribute: `time`, default value: 300, unit: Ms.
+
+::: demo In the GoTop component, you can set the `time` needed to complete the sliding and call an `onFinish` callback function when you reach the anchor.
+
+```js
+render() {
+ return (
+
+
+ Custom sliding time and callback function:
+ The fourth button in the lower right corner
+
+ console.log("go to top")}/>
+
+ )
+}
+```
+
+:::
+
+### Set title
+
+The` title` property tells the user the anchor to go when the mouse moves in.
+
+::: demo Use the `title` attribute to describe an anchor.
+
+```js
+render() {
+ return (
+
+
Title: the fifth button in the lower right corner
+
+
+ )
+}
+```
+
+:::
+
+### Attributes
+| Attribute | Description | Type | Accepted Values | Default |
+|---------- |-------------- |---------- |-------------------------------- |-------- |
+| showheight | Scrollbar Scroll Distance Threshold, Unit PX | number | — | 300 |
+| time | The time required to reach the top, unit MS | number | — | 300 |
+| title | title | string | — | — |
+| right | Distance to the rightof the page | string | — | 50px |
+| bottom | Distance to the bottom of the page | string | — | 50px |
+| top | Distance to the top of the page | string | — | — |
+| left | Distance to the left of the page | string | — | — |
+
+### Events
+
+| Event Name | Description | Parameters |
+| ---------- | ---------------------------- | ---------- |
+| onFinish | fires when anchor is arrived | — |
\ No newline at end of file
diff --git a/site/docs/zh-CN/anchor-smooth.md b/site/docs/zh-CN/anchor-smooth.md
new file mode 100644
index 000000000..c4494b998
--- /dev/null
+++ b/site/docs/zh-CN/anchor-smooth.md
@@ -0,0 +1,85 @@
+## AnchorSmooth 滑向锚点
+
+用于a标签滑向锚点。
+
+### 基本用法
+
+和a标签用法类似,使用属性`targetId`表明想到达的锚点。
+
+::: demo AnchorSmooth 组件提供`targetId`属性指向页面中**存在id元素**,必须值。若子元素不存在,则使用`targetId`当作子元素。
+```js
+render() {
+ return (
+
+ )
+}
+```
+:::
+
+### 回调函数
+
+属性`onFinish`可在绑定一个回调函数,在到达锚点后执行回调函数。
+
+::: demo 在 AnchorSmooth 组件中,你可以设置完成滑动完成的回调函数`onFinish`,到达锚点之后会调用`onFinish`函数。
+```js
+render() {
+ return (
+
+
+ 这里是锚点#anchor1
+
+
console.log("Arrive at anchor2")}>
+ 到id为anchor2的锚点,并执行回调函数
+
+
+ )
+}
+```
+:::
+
+### 设置标题
+
+`title`属性,鼠标移入时告诉用户即将去的锚点。
+
+::: demo 使用`title`属性来描述一个锚点。
+```js
+render() {
+ return (
+
+
+ 这里是锚点#anchor2
+
+
console.log("Arrive at anchor0")}>
+ 到id为anchor0的锚点,包含title
+
+
+ )
+}
+```
+:::
+
+### Attributes
+
+| 参数 | 说明 | 类型 | 可选值 | 默认值 |
+|---------- |-------------- |---------- |-------------------------------- |-------- |
+| **targetId** | 锚点目标,页面中需要有对应id,**必选参数** | string | — | — |
+| title | 辅助性文字 | string | — | — |
+
+### Events
+
+| 事件名称 | 说明 | 回调参数 |
+|---------- |-------- |---------- |
+| onFinish | 锚点到达时的回调函数 | — |
diff --git a/site/docs/zh-CN/go-top.md b/site/docs/zh-CN/go-top.md
new file mode 100644
index 000000000..22e2d94ae
--- /dev/null
+++ b/site/docs/zh-CN/go-top.md
@@ -0,0 +1,114 @@
+## GoTop 回顶部
+
+长页面中从底部回到顶部的按钮,点击可以回到页面顶部。
+
+### 基本用法
+
+通常回顶部按钮出现在页面的右下角,因此建议修改`right`,`bottom`属性进行定位;若有特殊需求,也可以修改`left` ,`top`属性。
+
+::: demo 在 GoTop组件中,你可以修改`right`,`bottom`属性,默认值为right:50px;bottom:50px;。
+```js
+render() {
+ return (
+
+
基本用法:右下角按钮第一个
+
+
+ )
+}
+```
+:::
+
+### 出现时机
+
+一般回顶部按钮,不会在滚动距离为0时出现。我们可以通过属性`showheight` 来定义按钮出现时滚动条的高度,默认值为300,单位px。滚动距离大于300,会淡入显示按钮;小于300,会淡出隐藏按钮。
+
+::: demo 在 GoTop组件中,你可以修改`showheight`属性,指定滚动条的滚动距离,默认值:300;类型:number。
+
+```js
+render() {
+ return (
+
+
在滚动距离为200px时出现按钮:右下角按钮第二个
+
+
+ )
+}
+```
+
+:::
+
+### 替换 icon
+
+GoTop 组件中,默认使用elementUI中的el-icon-caret-top,可以通过设置子元素的方式,替换默认icon图标。
+
+::: demo 通过设置`children`属性来显示 GoTop 的 icon,这能更有效地向用户展示你的显示意图。
+```js
+render() {
+ return (
+
+
替换 icon:右下角按钮第三个
+
+
+
+
+ )
+}
+```
+:::
+
+### 滑动时间和回调函数
+
+自定义完成滑动所用的时间,属性:` time`,默认值: 300,单位: ms。
+
+::: demo 在 GoTop 组件中,你可以设置完成滑动所用的时间`time`,到达锚点之后会调用一个的`onFinish`的回调函数。`time`属性决定完成滑动所用的时间,接受`number`,默认为300。
+
+```js
+render() {
+ return (
+
+
自定义滑动时间和回调函数:右下角按钮第四个
+ console.log("go to top")}/>
+
+ )
+}
+```
+
+:::
+
+### title
+
+包含标题,鼠标移入时告诉用户即将去的锚点。
+
+::: demo 使用`title`属性来描述一个锚点。
+
+```js
+render() {
+ return (
+
+
title:右下角按钮第五个
+
+
+ )
+}
+```
+
+:::
+
+### Attributes
+| 参数 | 说明 | 类型 | 可选值 | 默认值 |
+|---------- |-------------- |---------- |-------------------------------- |-------- |
+| showheight | 滚动条滚动距离阈值,单位px | number | — | 300 |
+| time | 到达描点所需要的时间,单位ms | number | — | 300 |
+| title | title | string | — | — |
+| right | 到页面右边的距离 | string | — | 50px |
+| bottom | 到页面底端的距离 | string | — | 50px |
+| top | 到页面顶端的距离 | string | — | — |
+| left | 到页面左边的距离 | string | — | — |
+
+### Events
+
+| 事件名称 | 说明 | 回调参数 |
+| -------- | -------------------------- | -------- |
+| onFinish | 滚动条到达顶部时的回调函数 | — |
\ No newline at end of file
diff --git a/site/locales/en-US.js b/site/locales/en-US.js
index 37bfc3dd0..9bfa7a186 100644
--- a/site/locales/en-US.js
+++ b/site/locales/en-US.js
@@ -45,7 +45,9 @@ module.exports = {
'popover': 'Popover',
'card': 'Card',
'carousel': 'Carousel',
- 'collapse': 'Collapse'
+ 'collapse': 'Collapse',
+ 'anchor-smooth':'AnchorSmooth',
+ 'go-top':'GoTop'
},
misc: {
'guide': 'Guide',
diff --git a/site/locales/zh-CN.js b/site/locales/zh-CN.js
index 4bc9b2b32..4feac10dc 100644
--- a/site/locales/zh-CN.js
+++ b/site/locales/zh-CN.js
@@ -45,7 +45,9 @@ module.exports = {
'popover': 'Popover 弹出框',
'card': 'Card 卡片',
'carousel': 'Carousel 走马灯',
- 'collapse': 'Collapse 折叠面板'
+ 'collapse': 'Collapse 折叠面板',
+ 'anchor-smooth':'AnchorSmooth 滑向锚点',
+ 'go-top':'GoTop 回顶部'
},
misc: {
'guide': '指南',
diff --git a/site/pages/anchor-smooth/index.jsx b/site/pages/anchor-smooth/index.jsx
new file mode 100644
index 000000000..5794c1b1f
--- /dev/null
+++ b/site/pages/anchor-smooth/index.jsx
@@ -0,0 +1,9 @@
+import Markdown from '../../../libs/markdown';
+
+import './style.scss';
+
+export default class AnchorSmooth extends Markdown {
+ document(locale) {
+ return require(`../../docs/${locale}/anchor-smooth.md`);
+ }
+}
diff --git a/site/pages/anchor-smooth/style.scss b/site/pages/anchor-smooth/style.scss
new file mode 100644
index 000000000..9a9c0b820
--- /dev/null
+++ b/site/pages/anchor-smooth/style.scss
@@ -0,0 +1,13 @@
+.demo-anchorsmooth{
+
+ .anchor-point{
+ color: #20a0ff;
+ height: 50px;
+ line-height: 50px;
+ }
+
+ .anchor-group a{
+ margin-right: 100px;
+ }
+
+}
diff --git a/site/pages/go-top/index.jsx b/site/pages/go-top/index.jsx
new file mode 100644
index 000000000..8e0c27a03
--- /dev/null
+++ b/site/pages/go-top/index.jsx
@@ -0,0 +1,9 @@
+import Markdown from '../../../libs/markdown';
+
+import './style.scss';
+
+export default class GoTop extends Markdown {
+ document(locale) {
+ return require(`../../docs/${locale}/go-top.md`);
+ }
+}
diff --git a/site/pages/go-top/style.scss b/site/pages/go-top/style.scss
new file mode 100644
index 000000000..ea3b29b46
--- /dev/null
+++ b/site/pages/go-top/style.scss
@@ -0,0 +1,5 @@
+.demo-gotop {
+ h3{
+ color: #20a0ff;
+ }
+}
diff --git a/site/pages/index.jsx b/site/pages/index.jsx
index 5bfb46530..7768dc7b6 100644
--- a/site/pages/index.jsx
+++ b/site/pages/index.jsx
@@ -58,7 +58,9 @@ export default {
'popover': require('./popover'),
'card': require('./card'),
'carousel': require('./carousel'),
- 'collapse': require('./collapse')
+ 'collapse': require('./collapse'),
+ 'anchor-smooth':require('./anchor-smooth'),
+ 'go-top':require('./go-top')
}
}
}
diff --git a/site/pages/input/custom-item.jsx b/site/pages/input/custom-item.jsx
index 436752e58..b2967a42b 100644
--- a/site/pages/input/custom-item.jsx
+++ b/site/pages/input/custom-item.jsx
@@ -16,4 +16,4 @@ CustomItem.propTypes = {
item: PropTypes.object
};
-module.exports = CustomItem;
+export default CustomItem;
diff --git a/src/anchor/AnchorSmooth.jsx b/src/anchor/AnchorSmooth.jsx
new file mode 100644
index 000000000..32c482627
--- /dev/null
+++ b/src/anchor/AnchorSmooth.jsx
@@ -0,0 +1,93 @@
+/* @flow */
+
+import React from 'react';
+import {Component, PropTypes} from '../../libs';
+
+export function getScrollTop() {
+ let html = document.documentElement || {scrollTop : 0};
+ let body = document.body || {scrollTop : 0};
+ return window.pageYOffset ||
+ html ? html.scrollTop :
+ body ? body.scrollTop : 0;
+}
+
+function goTarget(targetTop, time = 300, callback) {
+ let interval = 10;
+ time = Math.max(time, 100);
+ let initTop = getScrollTop();
+ let total = Math.ceil(time / interval);
+ let speed = (targetTop - initTop) / total;
+
+ if (speed === 0) {
+ return;
+ }
+
+ let count = 1;
+ let timer = setInterval(goMove, interval);
+
+ function goMove() {
+ if (count >= total) {
+ window.scrollTo(0, targetTop);
+ clearInterval(timer);
+ callback && callback();
+ return;
+ }
+ window.scrollTo(0, speed * count + initTop);
+ count++;
+ }
+
+}
+
+export default class AnchorSmooth extends Component {
+
+ onClick(e: SyntheticEvent): void{
+ e.preventDefault();
+ let targetDom = document.getElementById(this.props.targetId);
+ if (targetDom && targetDom.scrollIntoView) {
+ targetDom.scrollIntoView({
+ behavior: 'smooth',
+ block: 'start',
+ inline: 'nearest'
+ });
+ this.props.onFinish && this.props.onFinish();
+ } else {
+ let targetTop = targetDom ? targetDom.offsetTop : 0;
+ goTarget(targetTop, this.props.time, this.props.onFinish);
+ }
+ }
+
+
+ // shouldComponentUpdate(nextProps) {
+ // const propsKeys = Object.keys(this.props);
+ // const nextPropsKeys = Object.keys(nextProps);
+ //
+ // if (propsKeys.length !== nextPropsKeys.length) {
+ // return true;
+ // }
+ // for (const key of propsKeys) {
+ // if (this.props[key] !== nextProps[key]) {
+ // return true;
+ // }
+ // }
+ // return false;
+ // }
+
+ render() {
+ const {targetId, children, ...other} = this.props;
+ return (
+ {children || targetId}
+ )
+ }
+}
+
+AnchorSmooth.propTypes = {
+ targetId: PropTypes.string,
+ time: PropTypes.number,
+ onFinish: PropTypes.func
+};
+
+AnchorSmooth.defaultProps = {
+ time: 300
+};
+
diff --git a/src/anchor/GoTop.jsx b/src/anchor/GoTop.jsx
new file mode 100644
index 000000000..4bf6d5f84
--- /dev/null
+++ b/src/anchor/GoTop.jsx
@@ -0,0 +1,65 @@
+/* @flow */
+
+import React from 'react';
+import {Component, PropTypes} from '../../libs';
+import AnchorSmooth, {getScrollTop} from './AnchorSmooth';
+// import './style.css';
+
+export default class GoTop extends Component {
+
+ constructor() {
+ super(...arguments);
+ this.state = {show: false};
+ this.$showAnchor = this.showAnchor.bind(this);
+ }
+
+ showAnchor() {
+ let scrollY = getScrollTop();
+ let show = scrollY >= this.props.showheight;
+ if (this.state.show !== show) {
+ this.setState({
+ show
+ });
+ }
+ }
+
+ componentDidMount() {
+ this.$showAnchor();
+ window.addEventListener("scroll", this.$showAnchor)
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener("scroll", this.$showAnchor);
+ }
+
+ render() {
+ const {children, bottom, right, top, left, ...other} = this.props;
+ return (
+
+ )
+ }
+}
+
+GoTop.propTypes = {
+ showheight: PropTypes.number,
+ bottom: PropTypes.string,
+ top: PropTypes.string,
+ left: PropTypes.string,
+ right: PropTypes.string
+};
+
+GoTop.defaultProps = {
+ showheight: 300
+};
diff --git a/src/anchor/index.js b/src/anchor/index.js
new file mode 100644
index 000000000..44ce0f1fa
--- /dev/null
+++ b/src/anchor/index.js
@@ -0,0 +1,4 @@
+import AnchorSmooth from './AnchorSmooth';
+import GoTop from './GoTop';
+
+export {AnchorSmooth,GoTop};
\ No newline at end of file
diff --git a/src/anchor/style.css b/src/anchor/style.css
new file mode 100644
index 000000000..d10558340
--- /dev/null
+++ b/src/anchor/style.css
@@ -0,0 +1,28 @@
+.el-anchor__top-wrapper {
+ position: fixed;
+ bottom: 50px;
+ right: 50px;
+ z-index: 99;
+ transition: opacity 0.2s linear 0s, visibility 0s linear 0.2s;
+}
+
+.el-anchor__top {
+ border-radius: 50%;
+ width: 50px;
+ height: 50px;
+ background-color: #58b7ff;
+ display: block;
+ text-align: center;
+ line-height: 50px;
+ opacity: 0.4;
+ transition: opacity 0.3s linear 0s;
+}
+
+.el-anchor__top:hover {
+ opacity: 1;
+}
+
+.el-anchor__top i {
+ color: #ffffff;
+ font-size: 22px;
+}
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index fdbac9308..a1b0a46f5 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,7 @@
export { default as i18n } from './locale';
export { default as Alert } from './alert';
+export { AnchorSmooth, GoTop} from './anchor';
export { default as Button } from './button';
export { default as Card } from './card';
export { default as Layout } from './layout';