weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
407 lines (353 loc) • 13.7 kB
JavaScript
/** @jsx createElement */
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _rax = require('rax');
var _nukeView = require('../../View/index.js');
var _nukeView2 = _interopRequireDefault(_nukeView);
var _nukeEpUtils = require('../../EpUtils/index.js');
var _nukeThemeProvider = require('../../ThemeProvider/index.js');
var _emitter = require('../util/emitter.js');
var _emitter2 = _interopRequireDefault(_emitter);
var _transform = require('./transform.js');
var _transform2 = _interopRequireDefault(_transform);
var _index = require('../styles/index.js');
var _index2 = _interopRequireDefault(_index);
var _finger = require('./finger.js');
var _finger2 = _interopRequireDefault(_finger);
var _nav = require('./nav.js');
var _nav2 = _interopRequireDefault(_nav);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
// 在weex及非android4.4以下的机器中才使用ep绑定
var expressionBinding = {};
try {
expressionBinding = require('@weex-module/expressionBinding');
} catch (e) {}
var formatRem = function formatRem(num) {
return (parseInt(num, 10) * document.documentElement.clientWidth / 750).toString() + 'px';
};
var Tabbar = function (_Component) {
_inherits(Tabbar, _Component);
function Tabbar(props) {
_classCallCheck(this, Tabbar);
var _this = _possibleConstructorReturn(this, (Tabbar.__proto__ || Object.getPrototypeOf(Tabbar)).call(this, props));
_this.panEnd = function (e) {
if (newIndex < 0) {
newIndex = 0;
} else if (newIndex > _this.maxIndex) {
newIndex = _this.maxIndex;
}
if (_nukeEpUtils.Detection.iOS) {
setTimeout(function () {
_this.slideTo(newIndex, 'pan');
}, 50);
} else {
_this.slideTo(newIndex, 'pan');
}
};
_this.slideTo = function (index, type) {
var time = 300;
if (_this.isMoving === true) return;
_this.isMoving = true;
var _this$props = _this.props,
onChange = _this$props.onChange,
beforeSlide = _this$props.beforeSlide,
forbidNavScroll = _this$props.forbidNavScroll;
var prevIndex = _this.state.curIndex;
var moveEndCallback = function moveEndCallback() {
if (typeof onChange === 'function') {
onChange(index, prevIndex, type);
}
_this.setState({
curIndex: index,
prevIndex: prevIndex
});
_this.isMoving = false;
};
var navRef = _this.refs.nav && _this.refs.nav.wrappedInstance;
if (typeof beforeSlide === 'function') {
if (!beforeSlide(index, type)) return;
}
// 选中状态滚动,当只有两个item,无需scroll的时候需要禁止滚动
if (!forbidNavScroll) {
navRef.scrollTo(index);
}
navRef.focusMove(index);
navRef.setState({
curIndex: index
});
// if (Detection.epEnable) {
// // 高版本系统的手机才使用transform动画
// const animation = require('@weex-module/animation');
// const sliderElement = this.refs.listSlider;
// const dist = 750 * index;
// animation.transition(
// findDOMNode(sliderElement),
// {
// styles: {
// transform: `translateX(-${dist}px)`,
// },
// delay: 0,
// duration: time,
// timingFunction: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', // ['cubic-bezier(0.25, 0.46, 0.45, 0.94)', 'cubic-bezier(0,0,0.25,1)']
// },
// () => {}
// );
// }
_this.list.style.webkitTransition = '300ms ease';
_this.translateX = -index * (750 + _this.props.gap);
_this.list.style.transform = 'translateX(' + formatRem(-index * 750) + ')';
moveEndCallback();
};
_this.childrenElements = []; // 存放tab主体element
_this.tabMap = {}; // 用于记录哪个tab是被激活过的状态
_this.tabPage = []; // 存放tab节点
_this.ob = null;
_this.scrolling = false;
_this.maxIndex = props.children && props.children.length - 1 || 0; // tab的子节点只能是tab.item
_this.state = {
curIndex: props.activeKey && props.activeKey >= 0 && props.activeKey <= _this.maxIndex ? props.active : 0,
transform: 0,
prevIndex: null
};
if (typeof props.activeKey === 'number' && props.activeKey >= 0 && props.activeKey <= _this.maxIndex) {
_this.tabMap[props.activeKey] = true;
}
return _this;
}
_createClass(Tabbar, [{
key: 'componentWillMount',
value: function componentWillMount() {}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var curIndex = this.state.curIndex;
this.ob = (0, _rax.findDOMNode)('view' + curIndex);
}
/**
* 横向滑动停止
*/
}, {
key: 'onSwipe',
value: function onSwipe(evt) {
var direction = evt.direction;
var curIndex = this.state.curIndex;
if (this.focused) {
return false;
}
switch (direction) {
case 'Left':
curIndex < this.maxIndex && ++curIndex && this.bindStyle(curIndex);
break;
case 'Right':
curIndex > 0 && curIndex-- && this.bindStyle(curIndex);
break;
}
this.slideTo(curIndex);
}
}, {
key: 'endAnimation',
value: function endAnimation() {
this.list.style.webkitTransition = '0';
// this.ob && this.ob.style && (this.ob.style.webkitTransition = '0');
}
}, {
key: 'bindStyle',
value: function bindStyle(current) {
// this.ob && this.restore();
// this.ob = findDOMNode(`view${current}`);
// if (this.ob && !this.ob.scaleX) {
// Transform(this.ob);
// }
}
}, {
key: 'restore',
value: function restore() {
// this.ob.translateX = this.ob.translateY = 0;
// !!rotate && (this.ob.rotateZ = 0);
// this.ob.scaleX = this.ob.scaleY = 1;
// this.ob.originX = this.ob.originY = 0;
var rotate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
}
}, {
key: 'onPressMove',
value: function onPressMove(evt) {
var curIndex = this.state.curIndex;
this.endAnimation();
if (!this.focused) {
if (curIndex === 0 && evt.deltaX > 0 || curIndex === this.maxIndex && evt.deltaX < 0) {
this.translateX += evt.deltaX / 3;
this.list.style.transform = 'translateX(' + formatRem(this.translateX) + ')';
} else {
this.translateX += evt.deltaX;
}
}
evt.preventDefault();
}
/**
* tab切换前的回调函数
* @param index 即将滚动去的位置
* @param type 触发滚动的事件类型
*/
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _state = this.state,
curIndex = _state.curIndex,
prevIndex = _state.prevIndex;
var _props = this.props,
themeStyle = _props.themeStyle,
children = _props.children,
style = _props.style,
navTop = _props.navTop,
dataSource = _props.dataSource,
renderNavItem = _props.renderNavItem,
navStyle = _props.navStyle,
renderLoading = _props.renderLoading,
navFocusStyle = _props.navFocusStyle,
forceRender = _props.forceRender,
navContentStyle = _props.navContentStyle;
var slider = themeStyle.slider;
if (!children.length) {
return null;
}
if (navTop) {
slider.top = navStyle && navStyle.height;
navStyle.top = 0;
delete navStyle.bottom;
} else {
slider.bottom = navStyle && navStyle.height;
navStyle.bottom = 0;
delete navStyle.top;
}
// 根据子节点计算tab偏移
var sliderStyle = [slider];
sliderStyle.push({
width: 750 * children.length
});
this.translateX = -750 * this.state.curIndex;
sliderStyle.push({
transform: 'translateX(' + formatRem(-750 * this.state.curIndex) + ')'
});
if (this.tabMap[curIndex]) {
this.tabMap[curIndex]++;
} else {
this.tabMap[curIndex] = 1;
}
var formatChildren = [];
formatChildren = children.map(function (child, index) {
var length = children.length;
var next = circleIndex(_this2.state.curIndex + 1, length);
var prev = circleIndex(_this2.state.curIndex - 1, length);
var shouldRender = _this2.tabMap[index] === 1;
var eachTabStyle = [themeStyle.eachTab, { left: 750 * index }];
if (_this2.tabMap[index] && curIndex === index) {
_this2.tabPage[curIndex] = (0, _rax.createElement)(
_nukeView2.default,
{ style: eachTabStyle, key: index, shouldRender: shouldRender },
child
);
}
if (_this2.tabMap[index]) {
return _this2.tabPage[index];
}
if (typeof renderLoading === 'function' && (index === next || index === prev)) {
return (0, _rax.createElement)(
_nukeView2.default,
{ style: eachTabStyle, key: index },
renderLoading(index)
);
}
return null;
});
// } else {
// formatChildren = children.map((child, index) => {
// child.props.id = `view${index}`;
// if (index === curIndex) {
// return child;
// }
// return null;
// });
// }
// const childrenElements = [
// <Finger
// onPressMove={this.onPressMove.bind(this)}
// onSwipe={this.onSwipe.bind(this)}
// >
// <View
// style={sliderStyle}
// id="listWrapper"
// ref={node => {
// this.list = findDOMNode(node);
// }}
// onHorizontalPan={
// Detection.epEnable && this.props.epEnable
// ? this.onHorizontalPan
// : null
// }
// >
// {formatChildren}
// </View>
// </Finger>,
// ];
var childrenElements = [(0, _rax.createElement)(
_nukeView2.default,
{
style: sliderStyle,
id: 'listWrapper',
ref: function ref(node) {
_this2.list = (0, _rax.findDOMNode)(node);
},
onHorizontalPan: _nukeEpUtils.Detection.epEnable && this.props.epEnable ? this.onHorizontalPan : null
},
formatChildren
)];
var headerStyle = navTop ? _extends({}, navStyle, {
top: 0,
positon: 'relative'
}) : navStyle;
var NavWithProps = (0, _rax.createElement)(
_nukeView2.default,
{ style: [themeStyle.header, headerStyle] },
(0, _rax.createElement)(_nav2.default, {
ref: 'nav',
dataSource: dataSource,
renderNavItem: renderNavItem,
slideTo: function slideTo() {
return _this2.slideTo.apply(_this2, arguments);
},
style: navStyle,
contentStyle: navContentStyle,
navFocusStyle: navFocusStyle,
forceRender: forceRender
})
);
navTop ? childrenElements.unshift(NavWithProps) : childrenElements.push(NavWithProps);
return (0, _rax.createElement)(
_nukeView2.default,
{ style: [themeStyle.wrapContainer, style] },
childrenElements
);
}
}]);
return Tabbar;
}(_rax.Component);
function circleIndex(i, len) {
return (len + i % len) % len;
}
// Tabbar.propTypes = {
// };
Tabbar.defaultProps = {
epEnable: false,
navTop: true
};
Tabbar.displayName = 'Ep-Tabbar';
exports.default = (0, _nukeThemeProvider.connectStyle)(_index2.default)(Tabbar);
module.exports = exports['default'];