UNPKG

weex-nuke

Version:

基于 Rax 、Weex 的高性能组件体系 ~~

407 lines (353 loc) 13.7 kB
/** @jsx createElement */ 'use strict'; 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'];