UNPKG

winbox-ui-next

Version:

We Design Vue 2.0: A Vue.js 3 UI Library

312 lines (311 loc) 10.1 kB
var __defProp = Object.defineProperty; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; import { defineComponent, toRefs, ref, computed, reactive, provide, watchEffect, onBeforeUnmount, resolveComponent, openBlock, createElementBlock, mergeProps, toHandlers, createElementVNode, normalizeClass, renderSlot, createVNode, createCommentVNode, createBlock } from "vue"; import { getPrefixCls } from "../_utils/global-config.js"; import { TRIGGERS, DIRECTIONS, ARROWS, INDICATORS, INDICATORS_POSITION } from "./constants.js"; import CarouselIndicator from "./carousel-indicator.js"; import CarouselArrow from "./carousel-arrow.js"; import { carouselInjectionKey } from "./context.js"; import _export_sfc from "../_virtual/plugin-vue_export-helper"; const DEFAULT_AUTO_PLAY_INTERVAL = 3e3; const DEFAULT_AUTO_PLAY = { interval: DEFAULT_AUTO_PLAY_INTERVAL, hoverToPause: true }; function getValidIndex(i, length) { const indexNumber = +i; return typeof indexNumber === "number" && !Number.isNaN(indexNumber) ? (indexNumber + length) % length : i; } const _sfc_main = defineComponent({ name: "Carousel", components: { CarouselIndicator, CarouselArrow }, props: { current: { type: Number }, defaultCurrent: { type: Number, default: 1 }, autoPlay: { type: [Boolean, Object], default: false }, moveSpeed: { type: Number, default: 500 }, animationName: { type: String, default: "slide" }, trigger: { type: String, validator: (value) => { return TRIGGERS.includes(value); }, default: "click" }, direction: { type: String, validator: (value) => { return DIRECTIONS.includes(value); }, default: "horizontal" }, showArrow: { type: String, validator: (value) => { return ARROWS.includes(value); }, default: "always" }, arrowClass: { type: String, default: "" }, indicatorType: { type: String, validator: (value) => { return INDICATORS.includes(value); }, default: "dot" }, indicatorPosition: { type: String, validator: (value) => { return INDICATORS_POSITION.includes(value); }, default: "bottom" }, indicatorClass: { type: String, default: "" }, transitionTimingFunction: { type: String, default: "cubic-bezier(0.34, 0.69, 0.1, 1)" } }, emits: [ "update:current", "change" ], setup(props, { emit }) { const { current: currentRef, indicatorType: indicatorTypeRef, animationName, moveSpeed, transitionTimingFunction, autoPlay, showArrow: showArrowRef } = toRefs(props); const prefixCls = getPrefixCls("carousel"); const animationTimerRef = ref(null); const intervalRef = ref(null); const isPauseRef = ref(false); const previousIndexRef = ref(null); const slideDirectionRef = ref(null); const itemsRef = ref([]); const itemsLegnthRef = computed(() => itemsRef.value.length); const computedAutoPlayRef = useAutoPlay(autoPlay); const indexRef = ref(props.defaultCurrent - 1); const mergedIndexesRef = computed(() => { const childrenLength = itemsRef.value.length; const current = currentRef == null ? void 0 : currentRef.value; const index = indexRef.value; const mergedIndex = typeof current === "number" ? getValidIndex(current - 1, itemsLegnthRef.value) : index; const prevIndex = getValidIndex(mergedIndex - 1, childrenLength); const nextIndex = getValidIndex(mergedIndex + 1, childrenLength); return { mergedIndex, mergedPrevIndex: prevIndex, mergedNextIndex: nextIndex }; }); function addItem(item) { itemsRef.value.push(item); } function removeItem(uid) { const index = itemsRef.value.findIndex((item) => item.uid === uid); if (index !== -1) { itemsRef.value.splice(index, 1); } } const carouselContext = reactive({ addItem, removeItem, slideTo, mergedIndexes: mergedIndexesRef, previousIndex: previousIndexRef, animationName, slideDirection: slideDirectionRef, items: itemsRef, transitionTimingFunction, moveSpeed }); provide(carouselInjectionKey, carouselContext); const clearTimer = () => { if (intervalRef.value) { window.clearInterval(intervalRef.value); } }; watchEffect(() => { var _a; const { interval } = computedAutoPlayRef.value || {}; const { mergedNextIndex } = mergedIndexesRef.value; const _interval = ((_a = itemsRef.value) == null ? void 0 : _a.length) > 1 && !isPauseRef.value && interval; clearTimer(); if (_interval) { intervalRef.value = window.setInterval(() => { slideTo({ targetIndex: mergedNextIndex }); }, interval); } }); onBeforeUnmount(() => { clearTimer(); }); function slideTo({ targetIndex, isNegative = false, isManual = false }) { if (!animationTimerRef.value && targetIndex !== mergedIndexesRef.value.mergedIndex) { emit("update:current", targetIndex + 1); emit("change", targetIndex + 1, indexRef.value + 1, isManual); previousIndexRef.value = indexRef.value; indexRef.value = targetIndex; slideDirectionRef.value = isNegative ? "negative" : "positive"; animationTimerRef.value = window.setTimeout(() => { animationTimerRef.value = null; }, moveSpeed.value); } } const eventHandlers = useEventHandlers(computedAutoPlayRef, isPauseRef); const hasIndicator = computed(() => { return indicatorTypeRef.value !== "never" && itemsLegnthRef.value > 1; }); const hasArrow = computed(() => { return showArrowRef.value !== "never" && itemsLegnthRef.value > 1; }); const cls = computed(() => { return [ prefixCls, `${prefixCls}-indicator-position-${props.indicatorPosition}` ]; }); const contentCls = computed(() => { return [ `${prefixCls}-${props.animationName}`, `${prefixCls}-${props.direction}`, { [`${prefixCls}-negative`]: slideDirectionRef.value === "negative" } ]; }); const indicatorCls = computed(() => { return [ `${prefixCls}-indicator-wrapper`, `${prefixCls}-indicator-wrapper-${props.indicatorPosition}` ]; }); return { prefixCls, eventHandlers, length: itemsLegnthRef, mergedIndexes: mergedIndexesRef, slideTo, hasIndicator, hasArrow, slideDirection: slideDirectionRef, cls, contentCls, indicatorCls }; } }); const useAutoPlay = (autoPlayRef) => { return computed(() => { const { value: autoPlay } = autoPlayRef; if (autoPlay === false) { return {}; } if (autoPlay === true) { return DEFAULT_AUTO_PLAY; } return __spreadValues(__spreadValues({}, DEFAULT_AUTO_PLAY), autoPlay); }); }; const useEventHandlers = (computedAutoPlayRef, isPauseRef) => { return computed(() => { const { value: autoPlayConfig } = computedAutoPlayRef; return autoPlayConfig.hoverToPause ? { mouseEnter: () => isPauseRef.value = true, mouseLeave: () => isPauseRef.value = false } : {}; }); }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_CarouselIndicator = resolveComponent("CarouselIndicator"); const _component_CarouselArrow = resolveComponent("CarouselArrow"); return openBlock(), createElementBlock("div", mergeProps({ class: _ctx.cls }, toHandlers(_ctx.eventHandlers)), [ createElementVNode("div", { class: normalizeClass(_ctx.contentCls) }, [ renderSlot(_ctx.$slots, "default") ], 2), _ctx.hasIndicator ? (openBlock(), createElementBlock("div", { key: 0, class: normalizeClass(_ctx.indicatorCls) }, [ createVNode(_component_CarouselIndicator, { class: normalizeClass(_ctx.indicatorClass), type: _ctx.indicatorType, count: _ctx.length, "active-index": _ctx.mergedIndexes.mergedIndex, position: _ctx.indicatorPosition, trigger: _ctx.trigger, "on-select-index": (index) => _ctx.slideTo({ targetIndex: index, isNegative: index < _ctx.mergedIndexes.mergedIndex, isManual: true }) }, null, 8, ["class", "type", "count", "active-index", "position", "trigger", "on-select-index"]) ], 2)) : createCommentVNode("v-if", true), _ctx.hasArrow ? (openBlock(), createBlock(_component_CarouselArrow, { key: 1, class: normalizeClass(_ctx.arrowClass), direction: _ctx.direction, "show-arrow": _ctx.showArrow, prev: () => _ctx.slideTo({ targetIndex: _ctx.mergedIndexes.mergedPrevIndex, isNegative: true, isManual: true }), next: () => _ctx.slideTo({ targetIndex: _ctx.mergedIndexes.mergedNextIndex, isManual: true }) }, null, 8, ["class", "direction", "show-arrow", "prev", "next"])) : createCommentVNode("v-if", true) ], 16); } var _Carousel = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { _Carousel as default };