UNPKG

vue-devui

Version:

DevUI components based on Vite and Vue3

486 lines (485 loc) 13.5 kB
import { defineComponent, toRefs, computed, createVNode, resolveDynamicComponent, mergeProps, 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 } }; const DEFAULT_PREFIX = "icon"; const iconProps = { name: { type: String, default: "", required: true }, size: { type: [Number, String], default: "inherit" }, color: { type: String, default: "inherit" }, component: { type: Object, default: null }, classPrefix: { type: String, default: DEFAULT_PREFIX }, operable: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, rotate: { type: [Number, String] } }; const svgIconProps = { name: { type: String, default: "", required: true }, color: { type: String, default: "inherit" }, size: { type: [Number, String], default: "inherit" } }; function createBem$1(namespace, element, modifier) { let cls = namespace; if (element) { cls += `__${element}`; } if (modifier) { cls += `--${modifier}`; } return cls; } function useNamespace$1(block, needDot = false) { const namespace = needDot ? `.devui-${block}` : `devui-${block}`; const b = () => createBem$1(namespace); const e = (element) => element ? createBem$1(namespace, element) : ""; const m = (modifier) => modifier ? createBem$1(namespace, "", modifier) : ""; const em = (element, modifier) => element && modifier ? createBem$1(namespace, element, modifier) : ""; return { b, e, m, em }; } var icon = ""; var svgIcon = defineComponent({ name: "DSvgIcon", props: svgIconProps, setup(props) { const { name, color, size } = toRefs(props); const ns = useNamespace$1("svg-icon"); const iconName = computed(() => `#icon-${name.value}`); const iconSize = computed(() => { return typeof size.value === "number" ? `${size.value}px` : size.value; }); const styles = { width: iconSize.value, height: iconSize.value }; return () => { return createVNode("svg", { "class": ns.b(), "style": styles }, [createVNode("use", { "xlink:href": iconName.value, "fill": color.value }, null)]); }; } }); function isUrl(value) { return /^((http|https):)?\/\//.test(value); } function useIconDom(props, ctx) { const { component, name, size, color, classPrefix, rotate } = toRefs(props); const ns = useNamespace$1("icon"); const iconSize = computed(() => { return typeof size.value === "number" ? `${size.value}px` : size.value; }); const IconComponent = component.value ? resolveDynamicComponent(component.value) : resolveDynamicComponent(svgIcon); const imgIconDom = () => { return createVNode("img", mergeProps({ "src": name.value, "alt": name.value.split("/")[name.value.split("/").length - 1], "class": [(rotate == null ? void 0 : rotate.value) === "infinite" && ns.m("spin")], "style": { width: iconSize.value || "", transform: `rotate(${rotate == null ? void 0 : rotate.value}deg)`, verticalAlign: "middle" } }, ctx.attrs), null); }; const svgIconDom = () => { return createVNode(IconComponent, mergeProps({ "name": name.value, "color": color.value, "size": iconSize.value, "class": [(rotate == null ? void 0 : rotate.value) === "infinite" && ns.m("spin")], "style": { transform: `rotate(${rotate == null ? void 0 : rotate.value}deg)` } }, ctx.attrs), null); }; const fontIconDom = () => { const fontIconClass = /^icon-/.test(name.value) ? name.value : `${classPrefix.value}-${name.value}`; return createVNode("i", mergeProps({ "class": [classPrefix.value, fontIconClass, (rotate == null ? void 0 : rotate.value) === "infinite" && ns.m("spin")], "style": { fontSize: iconSize.value, color: color.value, transform: `rotate(${rotate == null ? void 0 : rotate.value}deg)` } }, ctx.attrs), null); }; const iconDom = () => { return component.value ? svgIconDom() : isUrl(name.value) ? imgIconDom() : fontIconDom(); }; return { iconDom }; } var Icon = defineComponent({ name: "DIcon", props: iconProps, emits: ["click"], setup(props, ctx) { const { disabled, operable } = toRefs(props); const { iconDom } = useIconDom(props, ctx); const ns = useNamespace$1("icon"); const wrapClassed = computed(() => ({ [ns.e("container")]: true, [ns.m("disabled")]: disabled.value, [ns.m("operable")]: operable.value, [ns.m("no-slots")]: !Object.keys(ctx.slots).length })); const onClick = (e) => { if (disabled.value) { return; } ctx.emit("click", e); }; return () => { var _a, _b, _c, _d; return createVNode("div", { "class": wrapClassed.value, "onClick": onClick }, [(_b = (_a = ctx.slots).prefix) == null ? void 0 : _b.call(_a), iconDom(), (_d = (_c = ctx.slots).suffix) == null ? void 0 : _d.call(_c)]); }; } }); var iconGroup = ""; defineComponent({ name: "DIconGroup", setup(_, ctx) { const ns = useNamespace$1("icon-group"); return () => { var _a, _b; return createVNode("div", { "class": ns.b() }, [(_b = (_a = ctx.slots).default) == null ? void 0 : _b.call(_a)]); }; } }); 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(Icon, { "name": "arrow-left" }, null)]), createVNode("button", { "class": "arrow-right", "onClick": () => next() }, [createVNode(Icon, { "name": "arrow-right" }, 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 };