import { setTransform, isTransformSupported } from './utils' import addDOMEventListener from 'add-dom-event-listener' import debounce from 'lodash.debounce' function noop () { } export default { props: { scrollAnimated: { type: Boolean, default: true }, onPrevClick: { type: Function, default: noop }, onNextClick: { type: Function, default: noop }, }, data () { return { next: false, prev: false, offset: 0, } }, mounted () { this.updatedCal() const debouncedResize = debounce(() => { this.setNextPrev() this.scrollToActiveTab() }, 200) this.resizeEvent = addDOMEventListener(window, 'resize', debouncedResize) }, updated () { this.updatedCal() }, beforeDestroy () { if (this.resizeEvent) { this.resizeEvent.remove() } }, watch: { tabBarPosition (val) { this.setOffset(0) }, }, methods: { updatedCal () { this.setNextPrev() this.$nextTick(() => { this.scrollToActiveTab() }) }, setNextPrev () { const navNode = this.$refs.nav const navNodeWH = this.getOffsetWH(navNode) const navWrapNode = this.$refs.navWrap const navWrapNodeWH = this.getOffsetWH(navWrapNode) let { offset } = this const minOffset = navWrapNodeWH - navNodeWH let { next, prev } = this if (minOffset >= 0) { next = false this.setOffset(0, false) offset = 0 } else if (minOffset < offset) { next = (true) } else { next = (false) this.setOffset(minOffset, false) offset = minOffset } if (offset < 0) { prev = (true) } else { prev = (false) } this.setNext(next) this.setPrev(prev) return { next, prev, } }, getOffsetWH (node) { const tabBarPosition = this.$props.tabBarPosition let prop = 'offsetWidth' if (tabBarPosition === 'left' || tabBarPosition === 'right') { prop = 'offsetHeight' } return node[prop] }, getOffsetLT (node) { const tabBarPosition = this.$props.tabBarPosition let prop = 'left' if (tabBarPosition === 'left' || tabBarPosition === 'right') { prop = 'top' } return node.getBoundingClientRect()[prop] }, setOffset (offset, checkNextPrev = true) { const target = Math.min(0, offset) if (this.offset !== target) { this.offset = target let navOffset = {} const tabBarPosition = this.$props.tabBarPosition const navStyle = this.$refs.nav.style const transformSupported = isTransformSupported(navStyle) if (tabBarPosition === 'left' || tabBarPosition === 'right') { if (transformSupported) { navOffset = { value: `translate3d(0,${target}px,0)`, } } else { navOffset = { name: 'top', value: `${target}px`, } } } else { if (transformSupported) { navOffset = { value: `translate3d(${target}px,0,0)`, } } else { navOffset = { name: 'left', value: `${target}px`, } } } if (transformSupported) { setTransform(navStyle, navOffset.value) } else { navStyle[navOffset.name] = navOffset.value } if (checkNextPrev) { this.setNextPrev() } } }, setPrev (v) { if (this.prev !== v) { this.prev = v } }, setNext (v) { if (this.next !== v) { this.next = v } }, isNextPrevShown (state) { if (state) { return state.next || state.prev } return this.next || this.prev }, prevTransitionEnd (e) { if (e.propertyName !== 'opacity') { return } const { container } = this this.scrollToActiveTab({ target: container, currentTarget: container, }) }, scrollToActiveTab (e) { const { activeTab } = this const navWrap = this.$refs.navWrap if (e && e.target !== e.currentTarget || !activeTab) { return } // when not scrollable or enter scrollable first time, don't emit scrolling const needToSroll = this.isNextPrevShown() && this.lastNextPrevShown this.lastNextPrevShown = this.isNextPrevShown() if (!needToSroll) { return } const activeTabWH = this.getOffsetWH(activeTab) const navWrapNodeWH = this.getOffsetWH(navWrap) let { offset } = this const wrapOffset = this.getOffsetLT(navWrap) const 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) } }, prevClick (e) { this.$props.onPrevClick(e) const navWrapNode = this.$refs.navWrap const navWrapNodeWH = this.getOffsetWH(navWrapNode) const { offset } = this this.setOffset(offset + navWrapNodeWH) }, nextClick (e) { this.$props.onNextClick(e) const navWrapNode = this.$refs.navWrap const navWrapNodeWH = this.getOffsetWH(navWrapNode) const { offset } = this this.setOffset(offset - navWrapNodeWH) }, getScrollBarNode (content) { const { next, prev } = this const { prefixCls, scrollAnimated } = this.$props const showNextPrev = prev || next const prevButton = ( ) const nextButton = ( ) const navClassName = `${prefixCls}-nav` const navClasses = { [navClassName]: true, [ scrollAnimated ? `${navClassName}-animated` : `${navClassName}-no-animated` ]: true, } return (
{prevButton} {nextButton}
{content}
) }, }, }