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