winbox-ui-next
Version:
We Design Vue 2.0: A Vue.js 3 UI Library
312 lines (311 loc) • 10.1 kB
JavaScript
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 };