vue-devui
Version:
DevUI components based on Vite and Vue3
486 lines (485 loc) • 13.5 kB
JavaScript
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 };