Comparing version
# History | ||
---- | ||
## 5.2.0 / 2015-07-06 | ||
support tabPosition | ||
## 5.1.0 / 2015-06-10 | ||
@@ -4,0 +8,0 @@ |
@@ -11,17 +11,22 @@ 'use strict'; | ||
var inkBarNode = React.findDOMNode(refs.inkBar); | ||
var active; | ||
for (var ref in refs) { | ||
if (ref.slice(0, 3) === 'tab') { | ||
var tab = refs[ref]; | ||
if (tab.props['data-active']) { | ||
active = 1; | ||
var tabNode = React.findDOMNode(tab); | ||
var tabOffset = offset(tabNode); | ||
var left = tabOffset.left - containerOffset.left; | ||
inkBarNode.style.left = left + 'px'; | ||
inkBarNode.style.right = containerNode.offsetWidth - left - tabNode.offsetWidth + 'px'; | ||
} | ||
var activeTab = refs.activeTab; | ||
var tabPosition = component.props.tabPosition; | ||
if (activeTab) { | ||
var tabNode = React.findDOMNode(activeTab); | ||
var tabOffset = offset(tabNode); | ||
if (tabPosition === 'top' || tabPosition === 'bottom') { | ||
var left = tabOffset.left - containerOffset.left; | ||
inkBarNode.style.left = left + 'px'; | ||
inkBarNode.style.top = ''; | ||
inkBarNode.style.bottom = ''; | ||
inkBarNode.style.right = containerNode.offsetWidth - left - tabNode.offsetWidth + 'px'; | ||
} else { | ||
var top = tabOffset.top - containerOffset.top; | ||
inkBarNode.style.left = ''; | ||
inkBarNode.style.right = ''; | ||
inkBarNode.style.top = top + 'px'; | ||
inkBarNode.style.bottom = containerNode.offsetHeight - top - tabNode.offsetHeight + 'px'; | ||
} | ||
} | ||
inkBarNode.style.display = active ? 'block' : 'none'; | ||
inkBarNode.style.display = activeTab ? 'block' : 'none'; | ||
} | ||
@@ -28,0 +33,0 @@ |
@@ -5,5 +5,9 @@ 'use strict'; | ||
function _defineProperty(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } | ||
var React = require('react'); | ||
var prefixClsFn = require('./utils').prefixClsFn; | ||
var cx = require('./utils').cx; | ||
function noop() {} | ||
var Nav = React.createClass({ | ||
@@ -33,7 +37,7 @@ displayName: 'Nav', | ||
var key = child.key; | ||
var cls = activeKey === key ? prefixClsFn(prefixCls, 'tab-active') : ''; | ||
cls += ' ' + prefixClsFn(prefixCls, 'tab'); | ||
var cls = activeKey === key ? '' + prefixCls + '-tab-active' : ''; | ||
cls += ' ' + prefixCls + '-tab'; | ||
var events = {}; | ||
if (child.props.disabled) { | ||
cls += ' ' + prefixClsFn(prefixCls, 'tab-disabled'); | ||
cls += ' ' + prefixCls + '-tab-disabled'; | ||
} else { | ||
@@ -44,6 +48,12 @@ events = { | ||
} | ||
var ref = {}; | ||
if (activeKey === key) { | ||
ref.ref = 'activeTab'; | ||
} | ||
rst.push(React.createElement( | ||
'div', | ||
_extends({}, events, { className: cls, key: key, | ||
ref: 'tab' + key, 'data-active': activeKey === key }), | ||
_extends({}, events, { | ||
className: cls, | ||
key: key | ||
}, ref), | ||
React.createElement( | ||
@@ -68,10 +78,14 @@ 'a', | ||
componentDidUpdate: function componentDidUpdate() { | ||
componentDidUpdate: function componentDidUpdate(prevProps) { | ||
if (prevProps && prevProps.tabPosition !== this.props.tabPosition) { | ||
this.setOffset(0); | ||
return; | ||
} | ||
var navNode = React.findDOMNode(this.refs.nav); | ||
var navNodeWidth = navNode.offsetWidth; | ||
var navNodeWH = this.getOffsetWH(navNode); | ||
var navWrapNode = React.findDOMNode(this.refs.navWrap); | ||
var navWrapNodeWidth = navWrapNode.offsetWidth; | ||
var navWrapNodeWH = this.getOffsetWH(navWrapNode); | ||
var state = this.state; | ||
var offset = state.offset; | ||
if (navWrapNodeWidth - offset < navNodeWidth) { | ||
if (navWrapNodeWH - offset < navNodeWH) { | ||
if (!state.next) { | ||
@@ -83,3 +97,3 @@ this.setState({ | ||
} else { | ||
var minOffset = navWrapNodeWidth - navNodeWidth; | ||
var minOffset = navWrapNodeWH - navNodeWH; | ||
if (minOffset < 0 && minOffset > offset) { | ||
@@ -115,8 +129,17 @@ if (state.next) { | ||
getOffsetWH: function getOffsetWH(node) { | ||
var tabPosition = this.props.tabPosition; | ||
var prop = 'offsetWidth'; | ||
if (tabPosition === 'left' || tabPosition === 'right') { | ||
prop = 'offsetHeight'; | ||
} | ||
return node[prop]; | ||
}, | ||
prev: function prev() { | ||
var navWrapNode = React.findDOMNode(this.refs.navWrap); | ||
var navWrapNodeWidth = navWrapNode.offsetWidth; | ||
var navWrapNodeWH = this.getOffsetWH(navWrapNode); | ||
var state = this.state; | ||
var offset = state.offset; | ||
this.setOffset(offset + navWrapNodeWidth); | ||
this.setOffset(offset + navWrapNodeWH); | ||
}, | ||
@@ -126,6 +149,6 @@ | ||
var navWrapNode = React.findDOMNode(this.refs.navWrap); | ||
var navWrapNodeWidth = navWrapNode.offsetWidth; | ||
var navWrapNodeWH = this.getOffsetWH(navWrapNode); | ||
var state = this.state; | ||
var offset = state.offset; | ||
this.setOffset(offset - navWrapNodeWidth); | ||
this.setOffset(offset - navWrapNodeWH); | ||
}, | ||
@@ -139,33 +162,49 @@ | ||
var tabMovingDirection = props.tabMovingDirection; | ||
var inkBarClass = prefixClsFn(prefixCls, 'ink-bar'); | ||
var tabPosition = props.tabPosition; | ||
var inkBarClass = '' + prefixCls + '-ink-bar'; | ||
if (tabMovingDirection) { | ||
inkBarClass += ' ' + prefixClsFn(prefixCls, 'ink-bar-transition-' + tabMovingDirection); | ||
inkBarClass += ' ' + prefixCls + '-ink-bar-transition-' + tabMovingDirection; | ||
} | ||
var nextButton, prevButton; | ||
if (state.prev) { | ||
var showNextPrev = state.prev || state.next; | ||
if (showNextPrev) { | ||
var _cx, _cx2; | ||
prevButton = React.createElement( | ||
'span', | ||
{ | ||
onClick: this.prev, | ||
onClick: state.prev ? this.prev : noop, | ||
unselectable: 'unselectable', | ||
className: prefixClsFn(prefixCls, 'tab-prev') }, | ||
React.createElement('span', { className: prefixClsFn(prefixCls, 'tab-prev-icon') }) | ||
className: cx((_cx = {}, _defineProperty(_cx, '' + prefixCls + '-tab-prev', 1), _defineProperty(_cx, '' + prefixCls + '-tab-btn-disabled', !state.prev), _cx)) }, | ||
React.createElement('span', { className: '' + prefixCls + '-tab-prev-icon' }) | ||
); | ||
} | ||
if (state.next) { | ||
nextButton = React.createElement( | ||
'span', | ||
{ | ||
onClick: this.next, | ||
onClick: state.next ? this.next : noop, | ||
unselectable: 'unselectable', | ||
className: prefixClsFn(prefixCls, 'tab-next') }, | ||
React.createElement('span', { className: prefixClsFn(prefixCls, 'tab-next-icon') }) | ||
className: cx((_cx2 = {}, _defineProperty(_cx2, '' + prefixCls + '-tab-next', 1), _defineProperty(_cx2, '' + prefixCls + '-tab-btn-disabled', !state.next), _cx2)) }, | ||
React.createElement('span', { className: '' + prefixCls + '-tab-next-icon' }) | ||
); | ||
} | ||
var navOffset = {}; | ||
if (tabPosition === 'left' || tabPosition === 'right') { | ||
navOffset = { | ||
top: state.offset | ||
}; | ||
} else { | ||
navOffset = { | ||
left: state.offset | ||
}; | ||
} | ||
return React.createElement( | ||
'div', | ||
{ className: prefixClsFn(prefixCls, 'nav-container'), ref: 'container' }, | ||
{ className: '' + prefixCls + '-nav-container', | ||
style: props.style, | ||
ref: 'container' }, | ||
prevButton, | ||
@@ -175,9 +214,9 @@ nextButton, | ||
'div', | ||
{ className: prefixClsFn(prefixCls, 'nav-wrap'), ref: 'navWrap' }, | ||
{ className: '' + prefixCls + '-nav-wrap', ref: 'navWrap' }, | ||
React.createElement( | ||
'div', | ||
{ className: prefixClsFn(prefixCls, 'nav-scroll') }, | ||
{ className: '' + prefixCls + '-nav-scroll' }, | ||
React.createElement( | ||
'div', | ||
{ className: prefixClsFn(prefixCls, 'nav'), ref: 'nav', style: { left: state.offset } }, | ||
{ className: '' + prefixCls + '-nav', ref: 'nav', style: navOffset }, | ||
React.createElement('div', { className: inkBarClass, ref: 'inkBar' }), | ||
@@ -184,0 +223,0 @@ tabs |
@@ -10,3 +10,2 @@ 'use strict'; | ||
var React = require('react'); | ||
var prefixClsFn = require('./utils').prefixClsFn; | ||
@@ -28,4 +27,4 @@ var TabPane = (function (_React$Component) { | ||
var props = this.props; | ||
var prefixCls = props.rootPrefixCls + '-tabpane'; | ||
var cls = props.active ? '' : prefixClsFn(prefixCls, 'hidden'); | ||
var prefixCls = '' + props.rootPrefixCls + '-tabpane'; | ||
var cls = props.active ? '' : '' + prefixCls + '-hidden'; | ||
cls += ' ' + prefixCls; | ||
@@ -35,3 +34,3 @@ return React.createElement( | ||
{ className: cls }, | ||
this.props.children | ||
props.children | ||
); | ||
@@ -38,0 +37,0 @@ } |
142
lib/Tabs.js
@@ -8,5 +8,4 @@ 'use strict'; | ||
var CSSTransitionGroup = require('rc-css-transition-group'); | ||
function noop() {} | ||
var utils = require('./utils'); | ||
var prefixClsFn = utils.prefixClsFn; | ||
@@ -25,3 +24,3 @@ var Tabs = React.createClass({ | ||
React.Children.forEach(props.children, function (child) { | ||
if (!activeKey) { | ||
if (!activeKey && !child.props.disabled) { | ||
activeKey = child.key; | ||
@@ -31,4 +30,2 @@ } | ||
} | ||
//this.handleKeyDown = this.handleKeyDown.bind(this); | ||
//this.handleTabDestroy = this.handleTabDestroy.bind(this); | ||
// cache panels | ||
@@ -39,2 +36,14 @@ this.renderPanels = {}; | ||
getDefaultProps: function getDefaultProps() { | ||
return { | ||
prefixCls: 'rc-tabs', | ||
onChange: noop, | ||
tabPosition: 'top', | ||
style: {}, | ||
contentStyle: {}, | ||
navStyle: {}, | ||
onTabClick: noop | ||
}; | ||
}, | ||
setActiveKey: function setActiveKey(activeKey) { | ||
@@ -47,15 +56,7 @@ var currentActiveKey = this.state.activeKey; | ||
} else { | ||
var backward; | ||
var keys = []; | ||
React.Children.forEach(this.props.children, function (c) { | ||
if (backward !== undefined) { | ||
return; | ||
} | ||
var key = c.key; | ||
if (currentActiveKey === key) { | ||
backward = false; | ||
} else if (activeKey === key) { | ||
backward = true; | ||
} | ||
keys.push(c.key); | ||
}); | ||
var tabMovingDirection = backward === true ? 'backward' : backward === false ? 'forward' : ''; | ||
var tabMovingDirection = keys.indexOf(currentActiveKey) > keys.indexOf(activeKey) ? 'backward' : 'forward'; | ||
this.setState({ | ||
@@ -78,3 +79,3 @@ activeKey: activeKey, | ||
_getNextActiveKey: function _getNextActiveKey() { | ||
_getNextActiveKey: function _getNextActiveKey(next) { | ||
var activeKey = this.state.activeKey; | ||
@@ -84,29 +85,11 @@ var children = []; | ||
if (!c.props.disabled) { | ||
children.push(c); | ||
} | ||
}); | ||
var length = children.length; | ||
var ret = length && children[0].key; | ||
children.forEach(function (child, i) { | ||
if (child.key === activeKey) { | ||
if (i === length - 1) { | ||
ret = children[0].key; | ||
if (next) { | ||
children.push(c); | ||
} else { | ||
ret = children[i + 1].key; | ||
children.unshift(c); | ||
} | ||
} | ||
}); | ||
return ret; | ||
}, | ||
_getPreviousActiveKey: function _getPreviousActiveKey() { | ||
var activeKey = this.state.activeKey; | ||
var children = []; | ||
React.Children.forEach(this.props.children, function (c) { | ||
if (!c.props.disabled) { | ||
children.unshift(c); | ||
} | ||
}); | ||
var length = children.length; | ||
var ret = length && children[length - 1].key; | ||
var ret = length && children[0].key; | ||
children.forEach(function (child, i) { | ||
@@ -127,4 +110,6 @@ if (child.key === activeKey) { | ||
var activeKey = this.state.activeKey; | ||
var children = this.props.children; | ||
var state = this.state; | ||
var props = this.props; | ||
var activeKey = state.activeKey; | ||
var children = props.children; | ||
var newChildren = []; | ||
@@ -141,10 +126,20 @@ var renderPanels = this.renderPanels; | ||
onDestroy: _this.handleTabDestroy.bind(_this, key), | ||
rootPrefixCls: _this.props.prefixCls | ||
//eventKey: key, | ||
rootPrefixCls: props.prefixCls | ||
}); | ||
newChildren.push(renderPanels[key]); | ||
} else { | ||
// do not change owner ... | ||
// or else will destroy and reinit | ||
//newChildren.push(<TabPane active={false} | ||
// key={key} | ||
// eventKey={key} | ||
// rootPrefixCls={this.props.prefixCls}></TabPane>); | ||
// return | ||
// lazy load | ||
newChildren.push(React.createElement(TabPane, { active: false, | ||
key: key, | ||
rootPrefixCls: _this.props.prefixCls })); | ||
newChildren.push(React.cloneElement(child, { | ||
active: false, | ||
//eventKey: key, | ||
rootPrefixCls: props.prefixCls | ||
}, [])); | ||
} | ||
@@ -173,3 +168,3 @@ }); | ||
e.preventDefault(); | ||
var nextKey = this._getNextActiveKey(); | ||
var nextKey = this._getNextActiveKey(true); | ||
this.handleTabClick(nextKey); | ||
@@ -180,3 +175,3 @@ break; | ||
e.preventDefault(); | ||
var previousKey = this._getPreviousActiveKey(); | ||
var previousKey = this._getNextActiveKey(false); | ||
this.handleTabClick(previousKey); | ||
@@ -190,5 +185,5 @@ break; | ||
var props = this.props; | ||
var animation = this.props.animation; | ||
var prefixCls = props.prefixCls; | ||
var cls = prefixCls; | ||
var tabPosition = props.tabPosition; | ||
var cls = '' + prefixCls + ' ' + prefixCls + '-' + tabPosition; | ||
var tabMovingDirection = this.state.tabMovingDirection; | ||
@@ -198,4 +193,10 @@ if (props.className) { | ||
} | ||
var animation = this.props.animation; | ||
var tabPanes = this._getTabPanes(); | ||
if (animation) { | ||
var transitionName; | ||
transitionName = props.transitionName && props.transitionName[tabMovingDirection || 'backward']; | ||
if (!transitionName && animation) { | ||
transitionName = '' + prefixCls + '-' + animation + '-' + (tabMovingDirection || 'backward'); | ||
} | ||
if (transitionName) { | ||
tabPanes = React.createElement( | ||
@@ -205,19 +206,30 @@ CSSTransitionGroup, | ||
exclusive: true, | ||
transitionName: prefixClsFn(prefixCls, animation + '-' + (tabMovingDirection || 'backward')) }, | ||
transitionName: transitionName }, | ||
tabPanes | ||
); | ||
} | ||
var contents = [React.createElement(Nav, { prefixCls: prefixCls, | ||
key: 'nav', | ||
tabPosition: tabPosition, | ||
style: props.navStyle, | ||
handleTabClick: this.handleTabClick, | ||
tabMovingDirection: tabMovingDirection, | ||
panels: this.props.children, | ||
activeKey: this.state.activeKey }), React.createElement( | ||
'div', | ||
{ className: '' + prefixCls + '-content', | ||
style: props.contentStyle, | ||
key: 'content' }, | ||
tabPanes | ||
)]; | ||
if (tabPosition === 'bottom') { | ||
contents.reverse(); | ||
} | ||
return React.createElement( | ||
'div', | ||
{ className: cls, tabIndex: '0', onKeyDown: this.handleKeyDown }, | ||
React.createElement(Nav, { prefixCls: prefixCls, | ||
handleTabClick: this.handleTabClick, | ||
tabMovingDirection: tabMovingDirection, | ||
panels: this.props.children, | ||
activeKey: this.state.activeKey }), | ||
React.createElement( | ||
'div', | ||
{ className: prefixClsFn(prefixCls, 'content') }, | ||
tabPanes | ||
) | ||
{ className: cls, | ||
tabIndex: '0', | ||
style: props.style, | ||
onKeyDown: this.handleKeyDown }, | ||
contents | ||
); | ||
@@ -227,10 +239,4 @@ } | ||
Tabs.defaultProps = { | ||
prefixCls: 'rc-tabs', | ||
onChange: noop, | ||
onTabClick: noop | ||
}; | ||
Tabs.TabPane = TabPane; | ||
module.exports = Tabs; |
'use strict'; | ||
function prefixClsFn(prefixCls) { | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
return args.map(function (s) { | ||
return prefixCls + '-' + s; | ||
}).join(' '); | ||
} | ||
function getScroll(w, top) { | ||
@@ -44,5 +37,13 @@ var ret = w['page' + (top ? 'Y' : 'X') + 'Offset']; | ||
module.exports = { | ||
prefixClsFn: prefixClsFn, | ||
getScroll: getScroll, | ||
offset: offset | ||
offset: offset, | ||
cx: function cx(v) { | ||
var ret = []; | ||
for (var k in v) { | ||
if (v[k]) { | ||
ret.push(k); | ||
} | ||
} | ||
return ret.join(' '); | ||
} | ||
}; |
{ | ||
"name": "rc-tabs", | ||
"version": "5.1.0", | ||
"version": "5.2.0", | ||
"description": "tabs ui component for react", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -88,2 +88,8 @@ # rc-tabs | ||
<tr> | ||
<td>tabPosition</td> | ||
<td>String</td> | ||
<th></th> | ||
<td>tab nav 's position. one of ['left','right','top','bottom']</td> | ||
</tr> | ||
<tr> | ||
<td>animation</td> | ||
@@ -95,2 +101,15 @@ <td>String</td> | ||
<tr> | ||
<td>transitionName</td> | ||
<td>Object</td> | ||
<th></th> | ||
<td>specify backward and forward transitionName. such as | ||
```js | ||
{ | ||
backward:'rc-tabs-slide-horizontal-backward', | ||
forward:'rc-tabs-slide-horizontal-forward' | ||
} | ||
``` | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>defaultActiveKey</td> | ||
@@ -97,0 +116,0 @@ <td>String</td> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
40554
37.56%1166
46.3%186
11.38%