Skip to content

Commit

Permalink
feat: add swipeableTabBar. ref react-component/tabs#56
Browse files Browse the repository at this point in the history
  • Loading branch information
paranoidjk committed Mar 2, 2017
1 parent 9e63495 commit dc5d2ef
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 114 deletions.
2 changes: 1 addition & 1 deletion components/tabs/demo/mutlitabs.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const makeMultiTabPane = (count) => {

const TabExample = () => (
<div>
<Tabs defaultActiveKey="8" onChange={callback}>
<Tabs defaultActiveKey="8" onChange={callback} pageSize={5}>
{makeMultiTabPane(11)}
</Tabs>
<WhiteSpace />
Expand Down
90 changes: 18 additions & 72 deletions components/tabs/index.web.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import RcTabs, { TabPane } from 'rc-tabs';
import className from 'classnames';
import TabsProps from './PropsType';
import SwipeableTabContent from 'rc-tabs/lib/SwipeableTabContent';
import TabContent from 'rc-tabs/lib/TabContent';
import InkTabBar from 'rc-tabs/lib/InkTabBar';
import SwipeableInkTabBar from 'rc-tabs/lib/SwipeableInkTabBar';

const Tabs = React.createClass<TabsProps, any>({
statics: {
Expand All @@ -18,98 +18,44 @@ const Tabs = React.createClass<TabsProps, any>({
swipeable: true,
tabBarPosition: 'top',
hammerOptions: {},
tabBarhammerOptions: {},
pageSize: 5,
speed: 8,
onChange() {},
onTabClick() {},
};
},

getInitialState() {
const { activeKey, defaultActiveKey, children } = this.props;
const activeTabKey = activeKey || defaultActiveKey || children[0].props.key;
const activeTabIndex = children.findIndex(tabPane => tabPane.key === activeTabKey);
return {
// 超过5个的情况下,保证初始时 activeTab 显示在屏幕中间,便于向两侧翻页
viewportStartTabIndex: children.length > 5 && activeTabIndex >= 3 ? activeTabIndex - 2 : 0,
};
},

renderTabBar() {
const {props} = this;
return <InkTabBar onTabClick={this.handleTabClick} inkBarAnimated={props.animated}/>;
const { children, animated, speed, pageSize, tabBarhammerOptions } = this.props;
if (children.length > pageSize) {
return (
<SwipeableInkTabBar
onTabClick={this.handleSwipeTabClick}
speed={speed}
pageSize={pageSize}
hammerOptions={tabBarhammerOptions}
/>
);
}
return <InkTabBar inkBarAnimated={animated} />;
},

renderTabContent() {
const { animated, swipeable, hammerOptions } = this.props;
return swipeable ? (
<SwipeableTabContent animated={animated} hammerOptions={hammerOptions}/>
<SwipeableTabContent animated={animated} hammerOptions={hammerOptions} />
) : (
<TabContent animated={animated} />
);
},

getChildren() {
const { children } = this.props;
const { viewportStartTabIndex } = this.state;
return children.slice(viewportStartTabIndex, viewportStartTabIndex + 5);
},

handleTabClick(key) {
this.setState({
viewportStartTabIndex: this.getStartTabIndex(key),
});
this.props.onTabClick(key);
},

handleTabChange(key) {
this.setState({
viewportStartTabIndex: this.getStartTabIndex(key),
});
this.props.onChange(key);
},

getStartTabIndex(activeTabKey) {
const { children } = this.props;
const { viewportStartTabIndex } = this.state;
const activeTabIndex = children.findIndex(tabPane => tabPane.key === activeTabKey);
// 只有一页,则起始tabIndex为0,永远不需要变
if (children.length < 5) {
return 0;
}
// 滚到了可视区最左侧且还可以向左翻页
if (activeTabIndex === viewportStartTabIndex && viewportStartTabIndex > 0) {
return viewportStartTabIndex - 1;
}
// 滚到了可视区最右侧且还可以向右翻页
if (activeTabIndex === viewportStartTabIndex + 4 && viewportStartTabIndex + 4 < children.length - 1) {
return viewportStartTabIndex + 1;
}
// 未到两侧,不翻页
return viewportStartTabIndex;
},

getClassName() {
const { viewportStartTabIndex } = this.state;
const totalTabsCount = this.props.children.length;
const cls = className({
[`${this.props.prefixCls}-leftpage`]: totalTabsCount > 5 && viewportStartTabIndex > 0,
[`${this.props.prefixCls}-rightpage`]: totalTabsCount > 5 && viewportStartTabIndex + 4 < totalTabsCount - 1,
[this.props.className]: this.props.className,
});
return cls;
},

render() {
const newProps = {
...this.props,
onChange: this.handleTabChange,
children: this.getChildren(),
className: this.getClassName(),
};
return (
<RcTabs
renderTabBar={this.renderTabBar}
renderTabContent={this.renderTabContent}
{...newProps}
{...this.props}
/>
);
},
Expand Down
3 changes: 3 additions & 0 deletions components/tabs/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ title: 标签页
| activeTextColor(`react-native only`) | 选中文字颜色 | string | `#108ee9` |
| prefixCls(`web only`) | className 前缀 | string | `am-tabs` |
| className(`web only`) | 额外的 className | string ||
| pageSize(`web only`) | 可视区显示的 tab 数量,可以看做一页 | number | 5 |
| speed(`web only`) | 多页模式下,TabBar 滑动的速度 | Number: 1 ~ 10 | 8 |
| tabBarhammerOptions(`web only`) | 同hammerOptions,对 TabBar 的滑动手势进行配置 | Obejct | {} |

### Tabs.TabPane

Expand Down
86 changes: 46 additions & 40 deletions components/tabs/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,60 @@
.@{tabs-prefix-cls} {
overflow: hidden;

&.@{tabs-prefix-cls}-rightpage {
.@{tabs-prefix-cls}-bar {
.@{tabs-prefix-cls}-tab {
&:last-of-type:after {
position: absolute;
top: 0;
right: 0;
display: block;
width: 118px;
height: 100%;
content: ' ';
z-index: 1000;
background: #FFF;
background: -moz-linear-gradient(left, @page-hide-color, @page-show-color);
background: -webkit-gradient(linear,0% 0%, 100% 0%, from(@page-hide-color), to(@page-show-color));
background: -o-linear-gradient(left, @page-hide-color, @page-show-color);
}
}
&-bar {
display: flex;
position: relative;

.@{tabs-prefix-cls}-prevpage:before {
position: absolute;
top: 0;
left: 0;
display: block;
width: 118px;
height: 100%;
content: ' ';
z-index: 1000;
background: #FFF;
background: -moz-linear-gradient(left, @page-show-color, @page-hide-color);
background: -webkit-gradient(linear,0% 0%, 100% 0%, from(@page-show-color), to(@page-hide-color));
background: -o-linear-gradient(left, @page-show-color, @page-hide-color);
}
}

&.@{tabs-prefix-cls}-leftpage {
.@{tabs-prefix-cls}-bar {
.@{tabs-prefix-cls}-tab {
&:nth-child(2)::before {
position: absolute;
top: 0;
left: 0;
display: block;
width: 118px;
height: 100%;
content: ' ';
z-index: 1000;
background: #FFF;
background: -moz-linear-gradient(left, @page-show-color, @page-hide-color);
background: -webkit-gradient(linear,0% 0%, 100% 0%, from(@page-show-color), to(@page-hide-color));
background: -o-linear-gradient(left, @page-show-color, @page-hide-color);
.@{tabs-prefix-cls}-nextpage:after {
position: absolute;
top: 0;
right: 0;
display: block;
width: 118px;
height: 100%;
content: ' ';
z-index: 1000;
background: #FFF;
background: -moz-linear-gradient(left, @page-hide-color, @page-show-color);
background: -webkit-gradient(linear,0% 0%, 100% 0%, from(@page-hide-color), to(@page-show-color));
background: -o-linear-gradient(left, @page-hide-color, @page-show-color);
}

.@{tabs-prefix-cls}-nav-swipe {
position: relative;
left: 0;

.@{tabs-prefix-cls}-nav {
width: 100%;
display: flex;
flex: 1;

.@{tabs-prefix-cls}-tab {
justify-content: center;
flex: 0 0 20%;
}
}
}
}

&-bar {
display: flex;
position: relative;
.@{tabs-prefix-cls}-tab {
display: flex;
flex: 1;
text-align: center;
justify-content: center;
border-bottom: @border-width-sm solid @border-color-base;
font-size: @tabs-font-size-heading;
height: @tabs-height;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"watch-tsc": "antd-tools run watch-tsc",
"clean": "antd-tools run clean",
"start": "concurrently \"bisheng start -c ./site/bisheng.desktop.config.js --no-livereload\" \"bisheng start -c ./site/bisheng.kitchen.config.js --no-livereload\"",
"demo": "bisheng start -c ./site/bisheng.kitchen.config.js",
"site": "concurrently \"bisheng build -c ./site/bisheng.desktop.config.js\" \"bisheng build -c ./site/bisheng.kitchen.config.js\" && node scripts/copy-app-res",
"pc": "bisheng start -c ./site/bisheng.desktop.config.js",
"mobile": "bisheng start -c ./site/bisheng.kitchen.config.js",
Expand Down
4 changes: 3 additions & 1 deletion site/bisheng.common.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ module.exports = {
'antd-mobile/lib': path.join(process.cwd(), 'components'),
'antd-mobile': process.cwd(),
site: path.join(process.cwd(), 'site'),
// in case you want to develop with local rc-component
'rc-tabs': '/Users/jiangkai/github/tabs',
};

config.babel.plugins.push([
Expand All @@ -26,7 +28,7 @@ module.exports = {
regenerator: true,
},
], [
'import',
require.resolve('babel-plugin-import'),
{
libraryName: 'antd-mobile',
libraryDirectory: 'components',
Expand Down

0 comments on commit dc5d2ef

Please sign in to comment.