UNPKG

ant-design-vue

Version:

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

710 lines 24.7 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { createVNode as _createVNode } from "vue"; var __rest = this && this.__rest || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import debounce from 'lodash-es/debounce'; import ResizeObserver from 'resize-observer-polyfill'; import classnames from '../_util/classNames'; import BaseMixin from '../_util/BaseMixin'; import defaultProps from './default-props'; import initialState from './initial-state'; import { getOnDemandLazySlides, extractObject, initializedState, getHeight, canGoNext, slideHandler, changeSlide, keyHandler, swipeStart, swipeMove, swipeEnd, getPreClones, getPostClones, getTrackLeft, getTrackCSS } from './utils/innerSliderUtils'; import Track from './track'; import Dots from './dots'; import { PrevArrow, NextArrow } from './arrows'; import supportsPassive from '../_util/supportsPassive'; function noop() {} export default { name: 'InnerSlider', mixins: [BaseMixin], inheritAttrs: false, props: _extends({}, defaultProps), data() { this.preProps = _extends({}, this.$props); this.list = null; this.track = null; this.callbackTimers = []; this.clickable = true; this.debouncedResize = null; const ssrState = this.ssrInit(); return _extends(_extends(_extends({}, initialState), { currentSlide: this.initialSlide, slideCount: this.children.length }), ssrState); }, watch: { autoplay(newValue, oldValue) { if (!oldValue && newValue) { this.handleAutoPlay('playing'); } else if (newValue) { this.handleAutoPlay('update'); } else { this.pause('paused'); } }, __propsSymbol__() { const nextProps = this.$props; const spec = _extends(_extends({ listRef: this.list, trackRef: this.track }, nextProps), this.$data); let setTrackStyle = false; for (const key of Object.keys(this.preProps)) { if (!nextProps.hasOwnProperty(key)) { setTrackStyle = true; break; } if (typeof nextProps[key] === 'object' || typeof nextProps[key] === 'function' || typeof nextProps[key] === 'symbol') { continue; } if (nextProps[key] !== this.preProps[key]) { setTrackStyle = true; break; } } this.updateState(spec, setTrackStyle, () => { if (this.currentSlide >= nextProps.children.length) { this.changeSlide({ message: 'index', index: nextProps.children.length - nextProps.slidesToShow, currentSlide: this.currentSlide }); } if (!this.preProps.autoplay && nextProps.autoplay) { this.handleAutoPlay('playing'); } else if (nextProps.autoplay) { this.handleAutoPlay('update'); } else { this.pause('paused'); } }); this.preProps = _extends({}, nextProps); } }, mounted() { this.__emit('init'); if (this.lazyLoad) { const slidesToLoad = getOnDemandLazySlides(_extends(_extends({}, this.$props), this.$data)); if (slidesToLoad.length > 0) { this.setState(prevState => ({ lazyLoadedList: prevState.lazyLoadedList.concat(slidesToLoad) })); this.__emit('lazyLoad', slidesToLoad); } } this.$nextTick(() => { const spec = _extends({ listRef: this.list, trackRef: this.track, children: this.children }, this.$props); this.updateState(spec, true, () => { this.adaptHeight(); this.autoplay && this.handleAutoPlay('playing'); }); if (this.lazyLoad === 'progressive') { this.lazyLoadTimer = setInterval(this.progressiveLazyLoad, 1000); } this.ro = new ResizeObserver(() => { if (this.animating) { this.onWindowResized(false); // don't set trackStyle hence don't break animation this.callbackTimers.push(setTimeout(() => this.onWindowResized(), this.speed)); } else { this.onWindowResized(); } }); this.ro.observe(this.list); document.querySelectorAll && Array.prototype.forEach.call(document.querySelectorAll('.slick-slide'), slide => { slide.onfocus = this.$props.pauseOnFocus ? this.onSlideFocus : null; slide.onblur = this.$props.pauseOnFocus ? this.onSlideBlur : null; }); if (window.addEventListener) { window.addEventListener('resize', this.onWindowResized); } else { window.attachEvent('onresize', this.onWindowResized); } }); }, beforeUnmount() { var _a; if (this.animationEndCallback) { clearTimeout(this.animationEndCallback); } if (this.lazyLoadTimer) { clearInterval(this.lazyLoadTimer); } if (this.callbackTimers.length) { this.callbackTimers.forEach(timer => clearTimeout(timer)); this.callbackTimers = []; } if (window.addEventListener) { window.removeEventListener('resize', this.onWindowResized); } else { window.detachEvent('onresize', this.onWindowResized); } if (this.autoplayTimer) { clearInterval(this.autoplayTimer); } (_a = this.ro) === null || _a === void 0 ? void 0 : _a.disconnect(); }, updated() { this.checkImagesLoad(); this.__emit('reInit'); if (this.lazyLoad) { const slidesToLoad = getOnDemandLazySlides(_extends(_extends({}, this.$props), this.$data)); if (slidesToLoad.length > 0) { this.setState(prevState => ({ lazyLoadedList: prevState.lazyLoadedList.concat(slidesToLoad) })); this.__emit('lazyLoad'); } } // if (this.props.onLazyLoad) { // this.props.onLazyLoad([leftMostSlide]) // } this.adaptHeight(); }, methods: { listRefHandler(ref) { this.list = ref; }, trackRefHandler(ref) { this.track = ref; }, adaptHeight() { if (this.adaptiveHeight && this.list) { const elem = this.list.querySelector(`[data-index="${this.currentSlide}"]`); this.list.style.height = getHeight(elem) + 'px'; } }, onWindowResized(setTrackStyle) { if (this.debouncedResize) this.debouncedResize.cancel(); this.debouncedResize = debounce(() => this.resizeWindow(setTrackStyle), 50); this.debouncedResize(); }, resizeWindow() { let setTrackStyle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; const isTrackMounted = Boolean(this.track); if (!isTrackMounted) return; const spec = _extends(_extends({ listRef: this.list, trackRef: this.track, children: this.children }, this.$props), this.$data); this.updateState(spec, setTrackStyle, () => { if (this.autoplay) { this.handleAutoPlay('update'); } else { this.pause('paused'); } }); // animating state should be cleared while resizing, otherwise autoplay stops working this.setState({ animating: false }); clearTimeout(this.animationEndCallback); delete this.animationEndCallback; }, updateState(spec, setTrackStyle, callback) { const updatedState = initializedState(spec); spec = _extends(_extends(_extends({}, spec), updatedState), { slideIndex: updatedState.currentSlide }); const targetLeft = getTrackLeft(spec); spec = _extends(_extends({}, spec), { left: targetLeft }); const trackStyle = getTrackCSS(spec); if (setTrackStyle || this.children.length !== spec.children.length) { updatedState['trackStyle'] = trackStyle; } this.setState(updatedState, callback); }, ssrInit() { const children = this.children; if (this.variableWidth) { let trackWidth = 0; let trackLeft = 0; const childrenWidths = []; const preClones = getPreClones(_extends(_extends(_extends({}, this.$props), this.$data), { slideCount: children.length })); const postClones = getPostClones(_extends(_extends(_extends({}, this.$props), this.$data), { slideCount: children.length })); children.forEach(child => { var _a, _b; const childWidth = ((_b = (_a = child.props.style) === null || _a === void 0 ? void 0 : _a.width) === null || _b === void 0 ? void 0 : _b.split('px')[0]) || 0; childrenWidths.push(childWidth); trackWidth += childWidth; }); for (let i = 0; i < preClones; i++) { trackLeft += childrenWidths[childrenWidths.length - 1 - i]; trackWidth += childrenWidths[childrenWidths.length - 1 - i]; } for (let i = 0; i < postClones; i++) { trackWidth += childrenWidths[i]; } for (let i = 0; i < this.currentSlide; i++) { trackLeft += childrenWidths[i]; } const trackStyle = { width: trackWidth + 'px', left: -trackLeft + 'px' }; if (this.centerMode) { const currentWidth = `${childrenWidths[this.currentSlide]}px`; trackStyle.left = `calc(${trackStyle.left} + (100% - ${currentWidth}) / 2 ) `; } return { trackStyle }; } const childrenCount = children.length; const spec = _extends(_extends(_extends({}, this.$props), this.$data), { slideCount: childrenCount }); const slideCount = getPreClones(spec) + getPostClones(spec) + childrenCount; const trackWidth = 100 / this.slidesToShow * slideCount; const slideWidth = 100 / slideCount; let trackLeft = -slideWidth * (getPreClones(spec) + this.currentSlide) * trackWidth / 100; if (this.centerMode) { trackLeft += (100 - slideWidth * trackWidth / 100) / 2; } const trackStyle = { width: trackWidth + '%', left: trackLeft + '%' }; return { slideWidth: slideWidth + '%', trackStyle }; }, checkImagesLoad() { const images = this.list && this.list.querySelectorAll && this.list.querySelectorAll('.slick-slide img') || []; const imagesCount = images.length; let loadedCount = 0; Array.prototype.forEach.call(images, image => { const handler = () => ++loadedCount && loadedCount >= imagesCount && this.onWindowResized(); if (!image.onclick) { image.onclick = () => image.parentNode.focus(); } else { const prevClickHandler = image.onclick; image.onclick = () => { prevClickHandler(); image.parentNode.focus(); }; } if (!image.onload) { if (this.$props.lazyLoad) { image.onload = () => { this.adaptHeight(); this.callbackTimers.push(setTimeout(this.onWindowResized, this.speed)); }; } else { image.onload = handler; image.onerror = () => { handler(); this.__emit('lazyLoadError'); }; } } }); }, progressiveLazyLoad() { const slidesToLoad = []; const spec = _extends(_extends({}, this.$props), this.$data); for (let index = this.currentSlide; index < this.slideCount + getPostClones(spec); index++) { if (this.lazyLoadedList.indexOf(index) < 0) { slidesToLoad.push(index); break; } } for (let index = this.currentSlide - 1; index >= -getPreClones(spec); index--) { if (this.lazyLoadedList.indexOf(index) < 0) { slidesToLoad.push(index); break; } } if (slidesToLoad.length > 0) { this.setState(state => ({ lazyLoadedList: state.lazyLoadedList.concat(slidesToLoad) })); this.__emit('lazyLoad', slidesToLoad); } else { if (this.lazyLoadTimer) { clearInterval(this.lazyLoadTimer); delete this.lazyLoadTimer; } } }, slideHandler(index) { let dontAnimate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; const { asNavFor, beforeChange, speed, afterChange } = this.$props; const { state, nextState } = slideHandler(_extends(_extends(_extends({ index }, this.$props), this.$data), { trackRef: this.track, useCSS: this.useCSS && !dontAnimate })); if (!state) return; beforeChange && beforeChange(this.currentSlide, state.currentSlide); const slidesToLoad = state.lazyLoadedList.filter(value => this.lazyLoadedList.indexOf(value) < 0); if (this.$attrs.onLazyLoad && slidesToLoad.length > 0) { this.__emit('lazyLoad', slidesToLoad); } if (!this.$props.waitForAnimate && this.animationEndCallback) { clearTimeout(this.animationEndCallback); afterChange && afterChange(this.currentSlide); delete this.animationEndCallback; } this.setState(state, () => { if (asNavFor && this.asNavForIndex !== index) { this.asNavForIndex = index; asNavFor.innerSlider.slideHandler(index); } if (!nextState) return; this.animationEndCallback = setTimeout(() => { const { animating } = nextState, firstBatch = __rest(nextState, ["animating"]); this.setState(firstBatch, () => { this.callbackTimers.push(setTimeout(() => this.setState({ animating }), 10)); afterChange && afterChange(state.currentSlide); delete this.animationEndCallback; }); }, speed); }); }, changeSlide(options) { let dontAnimate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; const spec = _extends(_extends({}, this.$props), this.$data); const targetSlide = changeSlide(spec, options); if (targetSlide !== 0 && !targetSlide) return; if (dontAnimate === true) { this.slideHandler(targetSlide, dontAnimate); } else { this.slideHandler(targetSlide); } this.$props.autoplay && this.handleAutoPlay('update'); if (this.$props.focusOnSelect) { const nodes = this.list.querySelectorAll('.slick-current'); nodes[0] && nodes[0].focus(); } }, clickHandler(e) { if (this.clickable === false) { e.stopPropagation(); e.preventDefault(); } this.clickable = true; }, keyHandler(e) { const dir = keyHandler(e, this.accessibility, this.rtl); dir !== '' && this.changeSlide({ message: dir }); }, selectHandler(options) { this.changeSlide(options); }, disableBodyScroll() { const preventDefault = e => { e = e || window.event; if (e.preventDefault) e.preventDefault(); e.returnValue = false; }; window.ontouchmove = preventDefault; }, enableBodyScroll() { window.ontouchmove = null; }, swipeStart(e) { if (this.verticalSwiping) { this.disableBodyScroll(); } const state = swipeStart(e, this.swipe, this.draggable); state !== '' && this.setState(state); }, swipeMove(e) { const state = swipeMove(e, _extends(_extends(_extends({}, this.$props), this.$data), { trackRef: this.track, listRef: this.list, slideIndex: this.currentSlide })); if (!state) return; if (state['swiping']) { this.clickable = false; } this.setState(state); }, swipeEnd(e) { const state = swipeEnd(e, _extends(_extends(_extends({}, this.$props), this.$data), { trackRef: this.track, listRef: this.list, slideIndex: this.currentSlide })); if (!state) return; const triggerSlideHandler = state['triggerSlideHandler']; delete state['triggerSlideHandler']; this.setState(state); if (triggerSlideHandler === undefined) return; this.slideHandler(triggerSlideHandler); if (this.$props.verticalSwiping) { this.enableBodyScroll(); } }, touchEnd(e) { this.swipeEnd(e); this.clickable = true; }, slickPrev() { // this and fellow methods are wrapped in setTimeout // to make sure initialize setState has happened before // any of such methods are called this.callbackTimers.push(setTimeout(() => this.changeSlide({ message: 'previous' }), 0)); }, slickNext() { this.callbackTimers.push(setTimeout(() => this.changeSlide({ message: 'next' }), 0)); }, slickGoTo(slide) { let dontAnimate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; slide = Number(slide); if (isNaN(slide)) return ''; this.callbackTimers.push(setTimeout(() => this.changeSlide({ message: 'index', index: slide, currentSlide: this.currentSlide }, dontAnimate), 0)); }, play() { let nextIndex; if (this.rtl) { nextIndex = this.currentSlide - this.slidesToScroll; } else { if (canGoNext(_extends(_extends({}, this.$props), this.$data))) { nextIndex = this.currentSlide + this.slidesToScroll; } else { return false; } } this.slideHandler(nextIndex); }, handleAutoPlay(playType) { if (this.autoplayTimer) { clearInterval(this.autoplayTimer); } const autoplaying = this.autoplaying; if (playType === 'update') { if (autoplaying === 'hovered' || autoplaying === 'focused' || autoplaying === 'paused') { return; } } else if (playType === 'leave') { if (autoplaying === 'paused' || autoplaying === 'focused') { return; } } else if (playType === 'blur') { if (autoplaying === 'paused' || autoplaying === 'hovered') { return; } } this.autoplayTimer = setInterval(this.play, this.autoplaySpeed + 50); this.setState({ autoplaying: 'playing' }); }, pause(pauseType) { if (this.autoplayTimer) { clearInterval(this.autoplayTimer); this.autoplayTimer = null; } const autoplaying = this.autoplaying; if (pauseType === 'paused') { this.setState({ autoplaying: 'paused' }); } else if (pauseType === 'focused') { if (autoplaying === 'hovered' || autoplaying === 'playing') { this.setState({ autoplaying: 'focused' }); } } else { // pauseType is 'hovered' if (autoplaying === 'playing') { this.setState({ autoplaying: 'hovered' }); } } }, onDotsOver() { this.autoplay && this.pause('hovered'); }, onDotsLeave() { this.autoplay && this.autoplaying === 'hovered' && this.handleAutoPlay('leave'); }, onTrackOver() { this.autoplay && this.pause('hovered'); }, onTrackLeave() { this.autoplay && this.autoplaying === 'hovered' && this.handleAutoPlay('leave'); }, onSlideFocus() { this.autoplay && this.pause('focused'); }, onSlideBlur() { this.autoplay && this.autoplaying === 'focused' && this.handleAutoPlay('blur'); }, customPaging(_ref) { let { i } = _ref; return _createVNode("button", null, [i + 1]); }, appendDots(_ref2) { let { dots } = _ref2; return _createVNode("ul", { "style": { display: 'block' } }, [dots]); } }, render() { const className = classnames('slick-slider', this.$attrs.class, { 'slick-vertical': this.vertical, 'slick-initialized': true }); const spec = _extends(_extends({}, this.$props), this.$data); let trackProps = extractObject(spec, ['fade', 'cssEase', 'speed', 'infinite', 'centerMode', 'focusOnSelect', 'currentSlide', 'lazyLoad', 'lazyLoadedList', 'rtl', 'slideWidth', 'slideHeight', 'listHeight', 'vertical', 'slidesToShow', 'slidesToScroll', 'slideCount', 'trackStyle', 'variableWidth', 'unslick', 'centerPadding', 'targetSlide', 'useCSS']); const { pauseOnHover } = this.$props; trackProps = _extends(_extends({}, trackProps), { focusOnSelect: this.focusOnSelect && this.clickable ? this.selectHandler : null, ref: this.trackRefHandler, onMouseleave: pauseOnHover ? this.onTrackLeave : noop, onMouseover: pauseOnHover ? this.onTrackOver : noop }); let dots; if (this.dots === true && this.slideCount >= this.slidesToShow) { let dotProps = extractObject(spec, ['dotsClass', 'slideCount', 'slidesToShow', 'currentSlide', 'slidesToScroll', 'clickHandler', 'children', 'infinite', 'appendDots']); dotProps.customPaging = this.customPaging; dotProps.appendDots = this.appendDots; const { customPaging, appendDots } = this.$slots; if (customPaging) { dotProps.customPaging = customPaging; } if (appendDots) { dotProps.appendDots = appendDots; } const { pauseOnDotsHover } = this.$props; dotProps = _extends(_extends({}, dotProps), { clickHandler: this.changeSlide, onMouseover: pauseOnDotsHover ? this.onDotsOver : noop, onMouseleave: pauseOnDotsHover ? this.onDotsLeave : noop }); dots = _createVNode(Dots, dotProps, null); } let prevArrow, nextArrow; const arrowProps = extractObject(spec, ['infinite', 'centerMode', 'currentSlide', 'slideCount', 'slidesToShow']); arrowProps.clickHandler = this.changeSlide; const { prevArrow: prevArrowCustom, nextArrow: nextArrowCustom } = this.$slots; if (prevArrowCustom) { arrowProps.prevArrow = prevArrowCustom; } if (nextArrowCustom) { arrowProps.nextArrow = nextArrowCustom; } if (this.arrows) { prevArrow = _createVNode(PrevArrow, arrowProps, null); nextArrow = _createVNode(NextArrow, arrowProps, null); } let verticalHeightStyle = null; if (this.vertical) { verticalHeightStyle = { height: typeof this.listHeight === 'number' ? `${this.listHeight}px` : this.listHeight }; } let centerPaddingStyle = null; if (this.vertical === false) { if (this.centerMode === true) { centerPaddingStyle = { padding: '0px ' + this.centerPadding }; } } else { if (this.centerMode === true) { centerPaddingStyle = { padding: this.centerPadding + ' 0px' }; } } const listStyle = _extends(_extends({}, verticalHeightStyle), centerPaddingStyle); const touchMove = this.touchMove; let listProps = { ref: this.listRefHandler, class: 'slick-list', style: listStyle, onClick: this.clickHandler, onMousedown: touchMove ? this.swipeStart : noop, onMousemove: this.dragging && touchMove ? this.swipeMove : noop, onMouseup: touchMove ? this.swipeEnd : noop, onMouseleave: this.dragging && touchMove ? this.swipeEnd : noop, [supportsPassive ? 'onTouchstartPassive' : 'onTouchstart']: touchMove ? this.swipeStart : noop, [supportsPassive ? 'onTouchmovePassive' : 'onTouchmove']: this.dragging && touchMove ? this.swipeMove : noop, onTouchend: touchMove ? this.touchEnd : noop, onTouchcancel: this.dragging && touchMove ? this.swipeEnd : noop, onKeydown: this.accessibility ? this.keyHandler : noop }; let innerSliderProps = { class: className, dir: 'ltr', style: this.$attrs.style }; if (this.unslick) { listProps = { class: 'slick-list', ref: this.listRefHandler }; innerSliderProps = { class: className }; } return _createVNode("div", innerSliderProps, [!this.unslick ? prevArrow : '', _createVNode("div", listProps, [_createVNode(Track, trackProps, { default: () => [this.children] })]), !this.unslick ? nextArrow : '', !this.unslick ? dots : '']); } };