var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var stdin_exports = {}; __export(stdin_exports, { SWIPE_KEY: () => SWIPE_KEY, default: () => stdin_default, swipeProps: () => swipeProps }); module.exports = __toCommonJS(stdin_exports); var import_vue = require("vue"); var import_utils = require("../utils"); var import_use = require("@vant/use"); var import_use_touch = require("../composables/use-touch"); var import_use_expose = require("../composables/use-expose"); var import_on_popup_reopen = require("../composables/on-popup-reopen"); const [name, bem] = (0, import_utils.createNamespace)("swipe"); const swipeProps = { loop: import_utils.truthProp, width: import_utils.numericProp, height: import_utils.numericProp, vertical: Boolean, autoplay: (0, import_utils.makeNumericProp)(0), duration: (0, import_utils.makeNumericProp)(500), touchable: import_utils.truthProp, lazyRender: Boolean, initialSwipe: (0, import_utils.makeNumericProp)(0), indicatorColor: String, showIndicators: import_utils.truthProp, stopPropagation: import_utils.truthProp }; const SWIPE_KEY = Symbol(name); var stdin_default = (0, import_vue.defineComponent)({ name, props: swipeProps, emits: ["change", "dragStart", "dragEnd"], setup(props, { emit, slots }) { const root = (0, import_vue.ref)(); const track = (0, import_vue.ref)(); const state = (0, import_vue.reactive)({ rect: null, width: 0, height: 0, offset: 0, active: 0, swiping: false }); let dragging = false; const touch = (0, import_use_touch.useTouch)(); const { children, linkChildren } = (0, import_use.useChildren)(SWIPE_KEY); const count = (0, import_vue.computed)(() => children.length); const size = (0, import_vue.computed)(() => state[props.vertical ? "height" : "width"]); const delta = (0, import_vue.computed)(() => props.vertical ? touch.deltaY.value : touch.deltaX.value); const minOffset = (0, import_vue.computed)(() => { if (state.rect) { const base = props.vertical ? state.rect.height : state.rect.width; return base - size.value * count.value; } return 0; }); const maxCount = (0, import_vue.computed)(() => size.value ? Math.ceil(Math.abs(minOffset.value) / size.value) : count.value); const trackSize = (0, import_vue.computed)(() => count.value * size.value); const activeIndicator = (0, import_vue.computed)(() => (state.active + count.value) % count.value); const isCorrectDirection = (0, import_vue.computed)(() => { const expect = props.vertical ? "vertical" : "horizontal"; return touch.direction.value === expect; }); const trackStyle = (0, import_vue.computed)(() => { const style = { transitionDuration: `${state.swiping ? 0 : props.duration}ms`, transform: `translate${props.vertical ? "Y" : "X"}(${+state.offset.toFixed(2)}px)` }; if (size.value) { const mainAxis = props.vertical ? "height" : "width"; const crossAxis = props.vertical ? "width" : "height"; style[mainAxis] = `${trackSize.value}px`; style[crossAxis] = props[crossAxis] ? `${props[crossAxis]}px` : ""; } return style; }); const getTargetActive = (pace) => { const { active } = state; if (pace) { if (props.loop) { return (0, import_utils.clamp)(active + pace, -1, count.value); } return (0, import_utils.clamp)(active + pace, 0, maxCount.value); } return active; }; const getTargetOffset = (targetActive, offset = 0) => { let currentPosition = targetActive * size.value; if (!props.loop) { currentPosition = Math.min(currentPosition, -minOffset.value); } let targetOffset = offset - currentPosition; if (!props.loop) { targetOffset = (0, import_utils.clamp)(targetOffset, minOffset.value, 0); } return targetOffset; }; const move = ({ pace = 0, offset = 0, emitChange }) => { if (count.value <= 1) { return; } const { active } = state; const targetActive = getTargetActive(pace); const targetOffset = getTargetOffset(targetActive, offset); if (props.loop) { if (children[0] && targetOffset !== minOffset.value) { const outRightBound = targetOffset < minOffset.value; children[0].setOffset(outRightBound ? trackSize.value : 0); } if (children[count.value - 1] && targetOffset !== 0) { const outLeftBound = targetOffset > 0; children[count.value - 1].setOffset(outLeftBound ? -trackSize.value : 0); } } state.active = targetActive; state.offset = targetOffset; if (emitChange && targetActive !== active) { emit("change", activeIndicator.value); } }; const correctPosition = () => { state.swiping = true; if (state.active <= -1) { move({ pace: count.value }); } else if (state.active >= count.value) { move({ pace: -count.value }); } }; const prev = () => { correctPosition(); touch.reset(); (0, import_use.doubleRaf)(() => { state.swiping = false; move({ pace: -1, emitChange: true }); }); }; const next = () => { correctPosition(); touch.reset(); (0, import_use.doubleRaf)(() => { state.swiping = false; move({ pace: 1, emitChange: true }); }); }; let autoplayTimer; const stopAutoplay = () => clearTimeout(autoplayTimer); const autoplay = () => { stopAutoplay(); if (+props.autoplay > 0 && count.value > 1) { autoplayTimer = setTimeout(() => { next(); autoplay(); }, +props.autoplay); } }; const initialize = (active = +props.initialSwipe) => { if (!root.value) { return; } const cb = () => { var _a, _b; if (!(0, import_utils.isHidden)(root)) { const rect = { width: root.value.offsetWidth, height: root.value.offsetHeight }; state.rect = rect; state.width = +((_a = props.width) != null ? _a : rect.width); state.height = +((_b = props.height) != null ? _b : rect.height); } if (count.value) { active = Math.min(count.value - 1, active); if (active === -1) { active = count.value - 1; } } state.active = active; state.swiping = true; state.offset = getTargetOffset(active); children.forEach((swipe) => { swipe.setOffset(0); }); autoplay(); }; if ((0, import_utils.isHidden)(root)) { (0, import_vue.nextTick)().then(cb); } else { cb(); } }; const resize = () => initialize(state.active); let touchStartTime; const onTouchStart = (event) => { if (!props.touchable || // avoid resetting position on multi-finger touch event.touches.length > 1) return; touch.start(event); dragging = false; touchStartTime = Date.now(); stopAutoplay(); correctPosition(); }; const onTouchMove = (event) => { if (props.touchable && state.swiping) { touch.move(event); if (isCorrectDirection.value) { const isEdgeTouch = !props.loop && (state.active === 0 && delta.value > 0 || state.active === count.value - 1 && delta.value < 0); if (!isEdgeTouch) { (0, import_utils.preventDefault)(event, props.stopPropagation); move({ offset: delta.value }); if (!dragging) { emit("dragStart", { index: activeIndicator.value }); dragging = true; } } } } }; const onTouchEnd = () => { if (!props.touchable || !state.swiping) { return; } const duration = Date.now() - touchStartTime; const speed = delta.value / duration; const shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(delta.value) > size.value / 2; if (shouldSwipe && isCorrectDirection.value) { const offset = props.vertical ? touch.offsetY.value : touch.offsetX.value; let pace = 0; if (props.loop) { pace = offset > 0 ? delta.value > 0 ? -1 : 1 : 0; } else { pace = -Math[delta.value > 0 ? "ceil" : "floor"](delta.value / size.value); } move({ pace, emitChange: true }); } else if (delta.value) { move({ pace: 0 }); } dragging = false; state.swiping = false; emit("dragEnd", { index: activeIndicator.value }); autoplay(); }; const swipeTo = (index, options = {}) => { correctPosition(); touch.reset(); (0, import_use.doubleRaf)(() => { let targetIndex; if (props.loop && index === count.value) { targetIndex = state.active === 0 ? 0 : index; } else { targetIndex = index % count.value; } if (options.immediate) { (0, import_use.doubleRaf)(() => { state.swiping = false; }); } else { state.swiping = false; } move({ pace: targetIndex - state.active, emitChange: true }); }); }; const renderDot = (_, index) => { const active = index === activeIndicator.value; const style = active ? { backgroundColor: props.indicatorColor } : void 0; return (0, import_vue.createVNode)("i", { "style": style, "class": bem("indicator", { active }) }, null); }; const renderIndicator = () => { if (slots.indicator) { return slots.indicator({ active: activeIndicator.value, total: count.value }); } if (props.showIndicators && count.value > 1) { return (0, import_vue.createVNode)("div", { "class": bem("indicators", { vertical: props.vertical }) }, [Array(count.value).fill("").map(renderDot)]); } }; (0, import_use_expose.useExpose)({ prev, next, state, resize, swipeTo }); linkChildren({ size, props, count, activeIndicator }); (0, import_vue.watch)(() => props.initialSwipe, (value) => initialize(+value)); (0, import_vue.watch)(count, () => initialize(state.active)); (0, import_vue.watch)(() => props.autoplay, autoplay); (0, import_vue.watch)([import_utils.windowWidth, import_utils.windowHeight, () => props.width, () => props.height], resize); (0, import_vue.watch)((0, import_use.usePageVisibility)(), (visible) => { if (visible === "visible") { autoplay(); } else { stopAutoplay(); } }); (0, import_vue.onMounted)(initialize); (0, import_vue.onActivated)(() => initialize(state.active)); (0, import_on_popup_reopen.onPopupReopen)(() => initialize(state.active)); (0, import_vue.onDeactivated)(stopAutoplay); (0, import_vue.onBeforeUnmount)(stopAutoplay); (0, import_use.useEventListener)("touchmove", onTouchMove, { target: track }); return () => { var _a; return (0, import_vue.createVNode)("div", { "ref": root, "class": bem() }, [(0, import_vue.createVNode)("div", { "ref": track, "style": trackStyle.value, "class": bem("track", { vertical: props.vertical }), "onTouchstartPassive": onTouchStart, "onTouchend": onTouchEnd, "onTouchcancel": onTouchEnd }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), renderIndicator()]); }; } });