UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

298 lines (265 loc) 9.66 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import classnames from 'classnames'; import { isTransformSupported, setTransform } from './utils'; import React from 'react'; import addEventListener from '../../_util/addEventListener'; import debounce from 'lodash/debounce'; export default { getDefaultProps: function getDefaultProps() { return { scrollAnimated: true, onPrevClick: function onPrevClick() {}, onNextClick: function onNextClick() {} }; }, getInitialState: function getInitialState() { this.offset = 0; return { next: false, prev: false }; }, componentDidMount: function componentDidMount() { var _this = this; this.componentDidUpdate(); this.debouncedResize = debounce(function () { _this.setNextPrev(); _this.scrollToActiveTab(); }, 200); this.resizeEvent = addEventListener(window, 'resize', this.debouncedResize); }, componentDidUpdate: function componentDidUpdate(prevProps) { var props = this.props; if (prevProps && prevProps.tabBarPosition !== props.tabBarPosition) { this.setOffset(0); return; } var nextPrev = this.setNextPrev(); // wait next, prev show hide /* eslint react/no-did-update-set-state:0 */ if (this.isNextPrevShown(this.state) !== this.isNextPrevShown(nextPrev)) { this.setState({}, this.scrollToActiveTab); } else if (!prevProps || props.activeKey !== prevProps.activeKey) { // can not use props.activeKey this.scrollToActiveTab(); } }, componentWillUnmount: function componentWillUnmount() { if (this.resizeEvent) { this.resizeEvent.remove(); } if (this.debouncedResize && this.debouncedResize.cancel) { this.debouncedResize.cancel(); } }, setNextPrev: function setNextPrev() { var navNode = this.nav; var navNodeWH = this.getScrollWH(navNode); var containerWH = this.getOffsetWH(this.container); var navWrapNodeWH = this.getOffsetWH(this.navWrap); var offset = this.offset; // 当容器小于tab的时候使用最小值才可以防止回弹问题。 var navNodeWHValue = Math.min(containerWH, navWrapNodeWH); var minOffset = navNodeWHValue - navNodeWH; // -165 var _this$state = this.state, next = _this$state.next, prev = _this$state.prev; if (minOffset >= 0) { next = false; this.setOffset(0, false); offset = 0; } else if (minOffset < offset) { next = true; } else { next = false; // Test with container offset which is stable // and set the offset of the nav wrap node var realOffset = navWrapNodeWH - navNodeWH; this.setOffset(realOffset, false); offset = realOffset; } if (offset < 0) { prev = true; } else { prev = false; } this.setNext(next); this.setPrev(prev); return { next: next, prev: prev }; }, getOffsetWH: function getOffsetWH(node) { var tabBarPosition = this.props.tabBarPosition; var prop = 'offsetWidth'; if (tabBarPosition === 'left' || tabBarPosition === 'right') { prop = 'offsetHeight'; } return node[prop]; }, getScrollWH: function getScrollWH(node) { var tabBarPosition = this.props.tabBarPosition; var prop = 'scrollWidth'; if (tabBarPosition === 'left' || tabBarPosition === 'right') { prop = 'scrollHeight'; } return node[prop]; }, getOffsetLT: function getOffsetLT(node) { var tabBarPosition = this.props.tabBarPosition; var prop = 'left'; if (tabBarPosition === 'left' || tabBarPosition === 'right') { prop = 'top'; } return node.getBoundingClientRect()[prop]; }, setOffset: function setOffset(offset) { var checkNextPrev = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; var target = Math.min(0, offset); if (this.offset !== target) { this.offset = target; var navOffset = {}; var tabBarPosition = this.props.tabBarPosition; var navStyle = this.nav.style; var transformSupported = isTransformSupported(navStyle); if (tabBarPosition === 'left' || tabBarPosition === 'right') { if (transformSupported) { navOffset = { value: "translate3d(0,".concat(target, "px,0)") }; } else { navOffset = { name: 'top', value: "".concat(target, "px") }; } } else { if (transformSupported) { navOffset = { value: "translate3d(".concat(target, "px,0,0)") }; } else { navOffset = { name: 'left', value: "".concat(target, "px") }; } } if (transformSupported) { setTransform(navStyle, navOffset.value); } else { navStyle[navOffset.name] = navOffset.value; } if (checkNextPrev) { this.setNextPrev(); } } }, setPrev: function setPrev(v) { if (this.state.prev !== v) { this.setState({ prev: v }); } }, setNext: function setNext(v) { if (this.state.next !== v) { this.setState({ next: v }); } }, isNextPrevShown: function isNextPrevShown(state) { if (state) { return state.next || state.prev; } return this.state.next || this.state.prev; }, prevTransitionEnd: function prevTransitionEnd(e) { if (e.propertyName !== 'opacity') { return; } var container = this.container; this.scrollToActiveTab({ target: container, currentTarget: container }); }, scrollToActiveTab: function scrollToActiveTab(e) { var activeTab = this.activeTab, navWrap = this.navWrap; if (e && e.target !== e.currentTarget || !activeTab) { return; } // when not scrollable or enter scrollable first time, don't emit scrolling var needToSroll = this.isNextPrevShown() && this.lastNextPrevShown; this.lastNextPrevShown = this.isNextPrevShown(); if (!needToSroll) { return; } var activeTabWH = this.getScrollWH(activeTab); var navWrapNodeWH = this.getOffsetWH(navWrap); var offset = this.offset; var wrapOffset = this.getOffsetLT(navWrap); var activeTabOffset = this.getOffsetLT(activeTab); if (wrapOffset > activeTabOffset) { offset += wrapOffset - activeTabOffset; this.setOffset(offset); } else if (wrapOffset + navWrapNodeWH < activeTabOffset + activeTabWH) { offset -= activeTabOffset + activeTabWH - (wrapOffset + navWrapNodeWH); this.setOffset(offset); } }, prev: function prev(e) { this.props.onPrevClick(e); var navWrapNode = this.navWrap; var navWrapNodeWH = this.getOffsetWH(navWrapNode); var offset = this.offset; this.setOffset(offset + navWrapNodeWH); }, next: function next(e) { this.props.onNextClick(e); var navWrapNode = this.navWrap; var navWrapNodeWH = this.getOffsetWH(navWrapNode); var offset = this.offset; this.setOffset(offset - navWrapNodeWH); }, getScrollBarNode: function getScrollBarNode(content) { var _classnames, _classnames2, _classnames3, _classnames4; var _this$state2 = this.state, next = _this$state2.next, prev = _this$state2.prev; var _this$props = this.props, prefixCls = _this$props.prefixCls, scrollAnimated = _this$props.scrollAnimated; var showNextPrev = prev || next; var prevButton = React.createElement("span", { onClick: prev ? this.prev : null, unselectable: "unselectable", className: classnames((_classnames = {}, _defineProperty(_classnames, "".concat(prefixCls, "-tab-prev"), 1), _defineProperty(_classnames, "".concat(prefixCls, "-tab-btn-disabled"), !prev), _defineProperty(_classnames, "".concat(prefixCls, "-tab-arrow-show"), showNextPrev), _classnames)), onTransitionEnd: this.prevTransitionEnd }, React.createElement("span", { className: "".concat(prefixCls, "-tab-prev-icon") })); var nextButton = React.createElement("span", { onClick: next ? this.next : null, unselectable: "unselectable", className: classnames((_classnames2 = {}, _defineProperty(_classnames2, "".concat(prefixCls, "-tab-next"), 1), _defineProperty(_classnames2, "".concat(prefixCls, "-tab-btn-disabled"), !next), _defineProperty(_classnames2, "".concat(prefixCls, "-tab-arrow-show"), showNextPrev), _classnames2)) }, React.createElement("span", { className: "".concat(prefixCls, "-tab-next-icon") })); var navClassName = "".concat(prefixCls, "-nav"); var navClasses = classnames((_classnames3 = {}, _defineProperty(_classnames3, navClassName, true), _defineProperty(_classnames3, scrollAnimated ? "".concat(navClassName, "-animated") : "".concat(navClassName, "-no-animated"), true), _classnames3)); return React.createElement("div", { className: classnames((_classnames4 = {}, _defineProperty(_classnames4, "".concat(prefixCls, "-nav-container"), 1), _defineProperty(_classnames4, "".concat(prefixCls, "-nav-container-scrolling"), showNextPrev), _classnames4)), key: "container", ref: this.saveRef('container') }, prevButton, nextButton, React.createElement("div", { className: "".concat(prefixCls, "-nav-wrap"), ref: this.saveRef('navWrap') }, React.createElement("div", { className: "".concat(prefixCls, "-nav-scroll") }, React.createElement("div", { className: navClasses, ref: this.saveRef('nav') }, content)))); } }; //# sourceMappingURL=ScrollableTabBarMixin.js.map