Skip to content

Commit

Permalink
Add component BackTop
Browse files Browse the repository at this point in the history
  • Loading branch information
Xing-He committed Dec 4, 2017
1 parent 0d1fbd7 commit 10a9636
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/Routers.js
Expand Up @@ -40,6 +40,7 @@ import progress from 'bundle-loader?lazy&name=progress!./pages/progress';
import breadcrumb from 'bundle-loader?lazy&name=breadcrumb!./pages/breadcrumb';
import dropdown from 'bundle-loader?lazy&name=dropdown!./pages/dropdown';
import steps from 'bundle-loader?lazy&name=steps!./pages/steps';
import backtop from 'bundle-loader?lazy&name=timestamp!./pages/backtop';
import alert from 'bundle-loader?lazy&name=alert!./pages/alert';
import modal from 'bundle-loader?lazy&name=modal!./pages/modal';
import message from 'bundle-loader?lazy&name=message!./pages/message';
Expand Down Expand Up @@ -124,6 +125,7 @@ const routes = {
{ path: "/:lang/breadcrumb", component: asyncComponent(breadcrumb) },
{ path: "/:lang/dropdown", component: asyncComponent(dropdown) },
{ path: "/:lang/steps", component: asyncComponent(steps) },
{ path: "/:lang/backtop", component: asyncComponent(backtop) },
],
'Feedback': [
{ path: "/:lang/alert", component: asyncComponent(alert) },
Expand Down
1 change: 1 addition & 0 deletions docs/locales/cn.js
Expand Up @@ -16,6 +16,7 @@ module.exports = {
'select': 'Select 选择器',
'slider': 'Slider 滑块',
'steps': 'Steps 步骤条',
'backtop': 'BackTop 返回顶部',
'alert': 'Alert 警告',
'avatar': 'Avatar 头像',
'badge': 'Badge 标记',
Expand Down
1 change: 1 addition & 0 deletions docs/locales/en.js
Expand Up @@ -16,6 +16,7 @@ module.exports = {
'select': 'Select',
'slider': 'Slider',
'steps': 'Steps',
'backtop': 'BackTop',
'alert': 'Alert',
'avatar': 'Avatar',
'badge': 'Badge',
Expand Down
90 changes: 90 additions & 0 deletions docs/md/cn/backtop.md
@@ -0,0 +1,90 @@
BackTop 返回顶部
===

返回页面顶部的操作按钮。

## 基本用法

<!--DemoStart-->
```js
class Demo extends Component {
render() { return ( <BackTop bordered={false}/> ) }
}
```
<!--End-->

## 自定义Icon

<!--DemoStart-->
```js
class Demo extends Component {
render() {
let icon = (<svg viewBox="0 0 1024 1024" width="18" height="18">
<path d="M563.2 379.757048 563.2 972.755371C563.2 1001.056998 540.219441 1024 512 1024 483.723021 1024 460.8 1001.019181 460.8 972.755371L460.8 379.740842 272.093167 568.447675C252.13208 588.408762 219.700711 588.340711 199.746554 568.386554 179.75171 548.39171 179.766716 515.958656 199.685432 496.039941L473.973319 221.752055C483.353204 211.343458 496.929524 204.8 512 204.8 527.198527 204.8 540.850334 211.438998 550.227358 221.968936L824.32552 496.0671C844.244236 515.985815 844.259243 548.418868 824.2644 568.413712 804.310241 588.367871 771.878874 588.435921 751.917786 568.474834L563.2 379.757048ZM0 51.2C0 22.923021 22.82342 0 51.130666 0L972.869334 0C1001.108021 0 1024 22.980559 1024 51.2 1024 79.476979 1001.17658 102.4 972.869334 102.4L51.130666 102.4C22.891979 102.4 0 79.419441 0 51.2Z"
p-id="2451" fill="#707070"></path>
</svg>)
return ( <BackTop showText={false} icon={icon} shape="circle"/> )
}
}
```
<!--End-->

## 自定义文字

<!--DemoStart-->
```js
class Demo extends Component {
render() {
let icon = (<svg viewBox="0 0 1024 1024" width="20" height="20">
<path d="M563.2 379.757048 563.2 972.755371C563.2 1001.056998 540.219441 1024 512 1024 483.723021 1024 460.8 1001.019181 460.8 972.755371L460.8 379.740842 272.093167 568.447675C252.13208 588.408762 219.700711 588.340711 199.746554 568.386554 179.75171 548.39171 179.766716 515.958656 199.685432 496.039941L473.973319 221.752055C483.353204 211.343458 496.929524 204.8 512 204.8 527.198527 204.8 540.850334 211.438998 550.227358 221.968936L824.32552 496.0671C844.244236 515.985815 844.259243 548.418868 824.2644 568.413712 804.310241 588.367871 771.878874 588.435921 751.917786 568.474834L563.2 379.757048ZM0 51.2C0 22.923021 22.82342 0 51.130666 0L972.869334 0C1001.108021 0 1024 22.980559 1024 51.2 1024 79.476979 1001.17658 102.4 972.869334 102.4L51.130666 102.4C22.891979 102.4 0 79.419441 0 51.2Z"
p-id="2451" fill="#707070"></path>
</svg>)
return ( <BackTop text="顶部" icon={icon} /> )
}
}
```
<!--End-->

## 始终显示

<!--DemoStart-->
```js
class Demo extends Component {
render() { return ( <BackTop text="始终显示" showAlways/> ) }
}
```
<!--End-->

## 自定义

<!--DemoStart-->
```js
class Demo extends Component {
render() { return (
<BackTop showText={false} showIcon={false}>
<div>自定义</div>
</BackTop>
) }
}
```
<!--End-->

## API

## Params

| 参数 | 说明 | 类型 | 默认值 |
|--------- |-------- |--------- |-------- |
| showAlways | 是否始终显示组件 | Bool | `false` |
| icon | 自定义Icon | ReactNode | `caret-up` |
| showIcon | 是否显示Icon | Bool | `true` |
| showBelow | 滚动距离多少时显示组件 | Number | `100` |
| shape | 指定组件的形状 `rectangle`方形或者`circle`| Enum{'`circle`', '`rectangle`' } | `rectangle` |
| text | 显示文字 | String | `TOP` |
| showText | 是否显示文字 | Bool | `true` |
| bordered | 是否显示边框 | Bool | `true` |
| radius | 是否圆角(shape为`rectangle`适用) | Bool | `true` |
| speed | 滚动速度 | Number | `300` |
| style | CSS样式 | String | - |
| className | CSS类名称 | String | - |
| onClick | 点击回调 | Function | - |
5 changes: 5 additions & 0 deletions docs/pages/backtop/index.js
@@ -0,0 +1,5 @@
import Markdown from '../../libs/markdown/';

export default class App extends Markdown {

}
108 changes: 108 additions & 0 deletions src/backtop/BackTop.js
@@ -0,0 +1,108 @@
import React from 'react';
import { Component, PropTypes } from '../utils/';
import Icon from '../icon';

export default class BackTop extends Component {
constructor(props) {
super(props);
this.state = {
show: false,
};

this.onClick = this.onClick.bind(this);
this.cancelScroll = this.cancelScroll.bind(this);
this.onScroll = this.onScroll.bind(this);
}

onClick(e) {
this.props.onClick && this.props.onClick(e);
this.rafId = window.requestAnimationFrame(this.move2Top);
}


componentDidMount() {
!this.props.showAlways && window.addEventListener('scroll', this.onScroll);
}

onScroll() {
if (window.pageYOffset > this.props.showBelow) {
if (!this.state.show) {
this.setState({ show: true });
}
} else if (this.state.show) {
this.setState({ show: false });
}
}

move2Top = () => {
if (window.pageYOffset <= 0) {
return this.cancelScroll();
}
window.scrollTo(0, window.pageYOffset - this.props.speed);
this.rafId = window.requestAnimationFrame(this.move2Top);
};

componentWillUnmount() {
!this.props.showAlways && window.removeEventListener('scroll', this.onScroll);
this.rafId && window.cancelAnimationFrame(this.rafId);
}

cancelScroll() {
this.rafId && window.cancelAnimationFrame(this.rafId);
}

render() {
const { prefixCls, showAlways, showIcon, showBelow, shape, showText, bordered, radius, style, text, speed, className, icon, onClick, ...others } = this.props;
const { show } = this.state;
const children = this.props.children;
const cls = this.classNames(prefixCls, {
[`${className}`]: className,
[`${shape}`]: shape,
bordered,
radius,
});
let defalutStyle = {};
if (!showAlways) {
defalutStyle = {
opacity: show ? 1 : 0,
visibility: show ? 1 : 0,
};
}
const styles = style ? Object.assign(style, defalutStyle) : defalutStyle;

return (
<div className={cls} style={styles} onClick={this.onClick} {...others} >
{showIcon ? icon || <Icon type="caret-up" /> : null}
{showText && <span className={`${prefixCls}-text`}>{text}</span>}
{children}
</div>
);
}
}

BackTop.propTypes = {
prefixCls: PropTypes.string,
shape: PropTypes.oneOf(['rectangle', 'circle']),
text: PropTypes.string,
showText: PropTypes.bool,
radius: PropTypes.bool,
bordered: PropTypes.bool,
showAlways: PropTypes.bool,
showBelow: PropTypes.number,
showIcon: PropTypes.bool,
speed: PropTypes.number,
onClick: PropTypes.func,
};

BackTop.defaultProps = {
prefixCls: 'w-back-top',
shape: 'rectangle',
text: 'TOP',
showText: true,
bordered: true,
radius: true,
showAlways: false,
showBelow: 100,
showIcon: true,
speed: 300,
};
4 changes: 4 additions & 0 deletions src/backtop/index.js
@@ -0,0 +1,4 @@
import BackTop from './BackTop';
import './style/index.less';

export default BackTop;
30 changes: 30 additions & 0 deletions src/backtop/style/index.less
@@ -0,0 +1,30 @@
.w-back-top {
display: inline-block;
transition: opacity 0.2s linear 0s, visibility;
line-height: 1.0;
text-align: center;
&.bordered {
border: 1px solid #dddee1;
}
&.rectangle {
padding: 2px 5px;
&.radius {
border-radius: 3px;
}
}
&.circle {
width: 38px;
height: 38px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
&:hover {
border-color: #9dbee0;
}
&-text {
display: block;
font-size: 12px;
}
}
1 change: 1 addition & 0 deletions src/index.js
Expand Up @@ -31,6 +31,7 @@ export { default as Switch } from './switch/';
export { default as Select } from './select/';
export { default as Slider } from './slider/';
export { default as Steps } from './steps';
export { default as BackTop } from './backtop';
export { default as Icon } from './icon/';
export { default as Input } from './input/';
export { default as InputNumber } from './input-number/';
Expand Down

0 comments on commit 10a9636

Please sign in to comment.