UNPKG

vue-devui

Version:

DevUI components based on Vite and Vue3

309 lines (308 loc) 9.16 kB
import { createVNode, defineComponent, toRefs, ref, watch, onMounted, onBeforeUnmount, Fragment, Comment } from "vue"; import "clipboard"; const carouselProps = { arrowTrigger: { type: String, default: "hover" }, autoplay: { type: Boolean, default: false }, autoplaySpeed: { type: Number, default: 3e3 }, height: { type: String, default: "100%" }, showDots: { type: Boolean, default: true }, dotTrigger: { type: String, default: "click" }, dotPosition: { type: String, default: "bottom" }, activeIndex: { type: Number, default: 0 }, transitionSpeed: { type: Number, default: 500 } }; function CarouselArrowLeft() { return createVNode("svg", { "width": "18px", "height": "18px", "viewBox": "0 0 16 16", "version": "1.1" }, [createVNode("g", { "stroke": "none", "stroke-width": "1", "fill": "none", "fill-rule": "evenodd" }, [createVNode("polygon", { "fill": "#293040", "fill-rule": "nonzero", "points": "10.7071068 12.2928932 9.29289322 13.7071068 3.58578644 8 9.29289322 2.29289322 10.7071068 3.70710678 6.41421356 8" }, null)])]); } function CarouselArrowRight() { return createVNode("svg", { "width": "18px", "height": "18px", "viewBox": "0 0 16 16", "version": "1.1" }, [createVNode("g", { "stroke": "none", "stroke-width": "1", "fill": "none", "fill-rule": "evenodd" }, [createVNode("polygon", { "fill": "#293040", "fill-rule": "nonzero", "transform": "translate(8.146447, 8.000000) scale(-1, 1) translate(-8.146447, -8.000000) ", "points": "11.7071068 12.2928932 10.2928932 13.7071068 4.58578644 8 10.2928932 2.29289322 11.7071068 3.70710678 7.41421356 8" }, null)])]); } function createBem(namespace, element, modifier) { let cls = namespace; if (element) { cls += `__${element}`; } if (modifier) { cls += `--${modifier}`; } return cls; } function useNamespace(block, needDot = false) { const namespace = needDot ? `.devui-${block}` : `devui-${block}`; const b = () => createBem(namespace); const e = (element) => element ? createBem(namespace, element) : ""; const m = (modifier) => modifier ? createBem(namespace, "", modifier) : ""; const em = (element, modifier) => element && modifier ? createBem(namespace, element, modifier) : ""; return { b, e, m, em }; } var carousel = ""; var Carousel = defineComponent({ name: "DCarousel", props: carouselProps, emits: ["update:activeIndex", "activeIndexChange"], setup(props, { emit, slots, expose }) { const ns = useNamespace("carousel"); const { height, showDots, dotPosition, arrowTrigger, autoplay, autoplaySpeed, dotTrigger, activeIndex, transitionSpeed } = toRefs(props); const itemCount = ref(0); const showArrow = ref(false); const currentIndex = ref(0); const wrapperRef = ref(null); const containerRef = ref(null); const scheduledId = ref(null); watch(() => arrowTrigger, () => { showArrow.value = arrowTrigger.value === "always"; }, { immediate: true }); watch(() => activeIndex, () => { currentIndex.value = activeIndex.value; }, { immediate: true }); const translatePosition = (size) => { if (containerRef.value) { containerRef.value.style.left = `${-size * 100}%`; } }; const adjustTransition = (targetEl) => { setTimeout(() => { if (containerRef.value) { containerRef.value.style.transition = ""; } targetEl.style.transform = ""; translatePosition(currentIndex.value); }, transitionSpeed.value); }; const adjustPosition = (targetEl, firstToLast) => { if (wrapperRef.value) { const wrapperRect = wrapperRef.value.getBoundingClientRect(); targetEl.style.transform = `translateX(${(firstToLast ? -itemCount.value : itemCount.value) * wrapperRect.width}px)`; } }; const clearScheduledTransition = () => { if (scheduledId.value) { clearTimeout(scheduledId.value); scheduledId.value = null; } }; const autoScheduleTransition = (callback) => { clearScheduledTransition(); if (autoplay.value && autoplaySpeed.value) { scheduledId.value = setTimeout(() => { callback == null ? void 0 : callback(); }, autoplaySpeed.value); } }; const goto = (index2) => { if (index2 === currentIndex.value || !wrapperRef.value || !containerRef.value) { return; } containerRef.value.style.transition = `left ${transitionSpeed.value}ms ease`; let latestIndex = currentIndex.value; if (index2 < 0 && currentIndex.value === 0) { latestIndex = itemCount.value - 1; const targetEl = containerRef.value.children[latestIndex]; adjustPosition(targetEl, true); translatePosition(-1); adjustTransition(targetEl); } else if (index2 >= itemCount.value && currentIndex.value === itemCount.value - 1) { latestIndex = 0; const targetEl = containerRef.value.children[latestIndex]; adjustPosition(targetEl, false); translatePosition(itemCount.value); adjustTransition(targetEl); } else { latestIndex = index2 < 0 ? 0 : index2 > itemCount.value - 1 ? itemCount.value - 1 : index2; translatePosition(latestIndex); } currentIndex.value = latestIndex; emit("update:activeIndex", latestIndex); emit("activeIndexChange", latestIndex); autoScheduleTransition(() => { goto(currentIndex.value + 1); }); }; const prev = () => { goto(currentIndex.value - 1); }; const next = () => { goto(currentIndex.value + 1); }; const arrowMouseEvent = (type) => { if (arrowTrigger.value !== "hover") { return; } showArrow.value = type === "enter"; }; const switchStep = (index2, type) => { if (type === dotTrigger.value) { goto(index2); } }; const changeItemCount = (val) => { itemCount.value = val; autoScheduleTransition(next); }; onMounted(() => { if (containerRef.value) { containerRef.value.style.transition = `left ${transitionSpeed.value}ms ease`; containerRef.value.style.left = "0%"; } autoScheduleTransition(next); }); onBeforeUnmount(() => { clearScheduledTransition(); }); expose({ prev, next, goto }); return () => { var _a, _b; const slot = (_b = (_a = slots.default) == null ? void 0 : _a.call(slots)) != null ? _b : []; let children = slot; if (children.length === 1 && children[0].type === Fragment) { children = (children[0].children || []).filter((item) => (item == null ? void 0 : item.type) !== Comment); } if (children.length !== itemCount.value) { changeItemCount(children.length); } return createVNode("div", { "class": ns.b(), "style": { height: height.value }, "onMouseenter": () => arrowMouseEvent("enter"), "onMouseleave": () => arrowMouseEvent("leave") }, [arrowTrigger.value !== "never" && showArrow.value ? createVNode("div", { "class": ns.e("arrow") }, [createVNode("button", { "class": "arrow-left", "onClick": () => prev() }, [createVNode(CarouselArrowLeft, null, null)]), createVNode("button", { "class": "arrow-right", "onClick": () => next() }, [createVNode(CarouselArrowRight, null, null)])]) : null, createVNode("div", { "class": ns.e("item-wrapper"), "ref": wrapperRef }, [createVNode("div", { "class": ns.e("item-container"), "style": { width: `${itemCount.value * 100}%` }, "ref": containerRef }, [slot])]), itemCount.value > 0 && showDots.value ? createVNode("ul", { "class": [ns.e("dots"), dotPosition.value] }, [children.map((_, index2) => createVNode("li", { "class": { "dot-item": true, active: currentIndex.value === index2 }, "onClick": () => switchStep(index2, "click"), "onMouseenter": () => switchStep(index2, "hover"), "style": { transition: `all ${transitionSpeed.value}ms ease` } }, null))]) : null]); }; } }); var CarouselItem = defineComponent({ name: "DCarouselItem", setup(props, { slots }) { var _a; const ns = useNamespace("carousel"); const children = (_a = slots.default) == null ? void 0 : _a.call(slots); return () => createVNode("div", { "class": ns.e("item") }, [children]); } }); var index = { title: "Carousel \u8D70\u9A6C\u706F", category: "\u6570\u636E\u5C55\u793A", status: "100%", install(app) { app.component(Carousel.name, Carousel); app.component(CarouselItem.name, CarouselItem); } }; export { Carousel, CarouselItem, index as default };