UNPKG

@opensig/opendesign

Version:

<p align="center"><img src="../docs/public/opendesign-logo-light.png"/></p> <h1 align="center">opendesign</h1> <p align="center">一个 Vue 3 组件库</p> <p align="center"><b>皮肤可定制,使用 TypeScript</b></p>

354 lines (353 loc) 10.8 kB
"use strict"; const vue = require("vue"); const icons = require("../_utils/icons.js"); const gallery = require("./effects/gallery.js"); const toggle = require("./effects/toggle.js"); const provide = require("./provide.js"); const types = require("./types.js"); const _hoisted_1 = { class: "o-carousel-wrap" }; const _hoisted_2 = ["onClick"]; const _hoisted_3 = { class: "o-carousel-arrow-prev" }; const _hoisted_4 = { class: "o-carousel-arrow-icon" }; const _hoisted_5 = { class: "o-carousel-arrow-next" }; const _hoisted_6 = { class: "o-carousel-arrow-icon" }; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ __name: "OCarousel", props: types.carouselProps, emits: ["before-change", "change", "update:activeIndex", "pause"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const containerRef = vue.ref(null); const total = vue.computed(() => { var _a; return (_a = containerRef.value) == null ? void 0 : _a.children.length; }); const isAutoPlay = vue.ref(props.autoPlay); vue.watch( () => props.autoPlay, (a) => { isAutoPlay.value = a; } ); const fixIndex = (idx) => { if (!total.value) { return idx; } const i = idx % total.value; return i >= 0 ? i : i + total.value; }; const activeIndex = vue.ref(props.activeIndex ? fixIndex(props.activeIndex) : 0); vue.watch( () => props.activeIndex, (v) => { activeIndex.value = v ?? 0; } ); const initialized = vue.ref(false); const slidesRef = vue.ref(null); const slideElList = vue.computed(() => { var _a; const c = (_a = containerRef.value) == null ? void 0 : _a.children; return c ? Array.from(c).map((el) => el) : null; }); let slidesInstance = null; let isChanging = false; const activeSlideByIndex = (index) => { return new Promise((resolve) => { const to = fixIndex(index); const from = activeIndex.value; if (isChanging || !slideElList.value) { resolve(false); return; } if (to === from) { resolve(true); return; } isChanging = true; if (slidesInstance) { activeIndex.value = to; emits("update:activeIndex", to); slidesInstance.active(to).then(() => { isChanging = false; resolve(true); }); } else { isChanging = false; resolve(false); } }); }; let timer = null; const isPlaying = vue.ref(isAutoPlay.value); const pausePlay = () => { if (timer) { clearInterval(timer); timer = null; isPlaying.value = false; emits("pause", activeIndex.value); } }; const resumePlay = () => { if (isAutoPlay.value) { setTimeout(() => { startPlay(); }, 0); } }; const startPlay = () => { pausePlay(); isPlaying.value = true; timer = window.setInterval(() => { activeSlideByIndex(activeIndex.value + 1); }, props.interval); }; const activeSlide = (index, resumeAutoPlay = true) => { pausePlay(); return activeSlideByIndex(index).then((success) => { if (!success) { return; } if (!props.pauseOnHover || resumeAutoPlay) { resumePlay(); } }); }; const initSlides = () => { if (!slideElList.value || !containerRef.value || initialized.value) { return; } const options = { activeClass: props.activeClass, onTouchstart: () => { pausePlay(); }, onTouchend: () => { resumePlay(); }, onBeforeChange: (to, from) => { emits("before-change", to, from); }, onChanged: (to, from) => { activeIndex.value = to; emits("update:activeIndex", to); emits("change", to, from); } }; let EffectType = null; switch (props.effect) { case "gallery": { EffectType = gallery; break; } case "toggle": { EffectType = toggle; break; } default: { EffectType = gallery; break; } } if (EffectType) { slidesInstance = new EffectType(slideElList.value, containerRef.value, activeIndex.value, options); } if (props.clickToSwitch) { slideElList.value.forEach((el, idx) => { el.addEventListener("click", () => { if (idx !== activeIndex.value) { activeSlide(idx); } }); }); } initialized.value = true; }; vue.watch( () => props.autoPlay, (v) => { if (v) { startPlay(); } else { pausePlay(); } } ); const init = () => { initSlides(); if (isAutoPlay.value) { startPlay(); } }; vue.onMounted(() => { if (!props.manualInit) { init(); } }); vue.onUnmounted(() => { if (timer) { clearInterval(timer); timer = null; } slidesInstance == null ? void 0 : slidesInstance.destroyed(); }); vue.provide(provide.carouselInjectKey, { effect: props.effect }); const play = () => { isAutoPlay.value = true; startPlay(); }; const pause = () => { isAutoPlay.value = false; pausePlay(); }; const onHoverIn = () => { if (props.pauseOnHover) { pausePlay(); } }; const onHoverOut = () => { if (props.pauseOnHover) { resumePlay(); } }; __expose({ init, play, pause, active: activeSlide }); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock( "div", { ref_key: "slidesRef", ref: slidesRef, class: vue.normalizeClass(["o-carousel", [ { "o-carousel-visible": initialized.value, "o-carousel-click-to-switch": props.clickToSwitch, "o-carousel-hover-arrow": props.arrow === "hover", "o-carousel-autoplay": isAutoPlay.value, "is-playing": isPlaying.value }, `o-carousel-effect-${props.effect}` ]]), style: vue.normalizeStyle({ "--carousel-interval": props.interval + "ms" }), onMouseenter: onHoverIn, onMouseleave: onHoverOut }, [ vue.createElementVNode("div", _hoisted_1, [ vue.createElementVNode( "div", { ref_key: "containerRef", ref: containerRef, class: vue.normalizeClass([`o-carousel-container-${props.effect}`]) }, [ vue.renderSlot(_ctx.$slots, "default") ], 2 /* CLASS */ ) ]), !props.hideIndicator ? (vue.openBlock(), vue.createElementBlock( "div", { key: 0, class: vue.normalizeClass(["o-carousel-indicator-wrap", props.indicatorWrapClass]) }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(total.value, (item, idx) => { return vue.openBlock(), vue.createElementBlock("div", { key: item, class: "o-carousel-indicator-item", onClick: ($event) => props.indicatorClick && activeSlide(idx) }, [ vue.renderSlot(_ctx.$slots, "indicator", { active: item - 1 === activeIndex.value, index: idx }, () => [ vue.createElementVNode( "div", { class: vue.normalizeClass(["o-carousel-indicator-bar", { "o-carousel-indicator-bar-selected": item - 1 === activeIndex.value }]) }, _cache[2] || (_cache[2] = [ vue.createElementVNode( "div", { class: "o-carousel-indicator-line" }, null, -1 /* HOISTED */ ) ]), 2 /* CLASS */ ) ]) ], 8, _hoisted_2); }), 128 /* KEYED_FRAGMENT */ )) ], 2 /* CLASS */ )) : vue.createCommentVNode("v-if", true), props.arrow !== "never" ? (vue.openBlock(), vue.createElementBlock( "div", { key: 1, class: vue.normalizeClass(["o-carousel-arrow-wrap", props.arrowWrapClass]) }, [ vue.createElementVNode("div", { onClick: _cache[0] || (_cache[0] = ($event) => activeSlide(activeIndex.value - 1, false)) }, [ vue.renderSlot(_ctx.$slots, "arrow-prev", {}, () => [ vue.createElementVNode("div", _hoisted_3, [ vue.createElementVNode("div", _hoisted_4, [ vue.renderSlot(_ctx.$slots, "arrow-prev-icon", {}, () => [ vue.createVNode(vue.unref(icons.IconChevronLeft)) ]) ]) ]) ]) ]), vue.createElementVNode("div", { onClick: _cache[1] || (_cache[1] = ($event) => activeSlide(activeIndex.value + 1, false)) }, [ vue.renderSlot(_ctx.$slots, "arrow-next", {}, () => [ vue.createElementVNode("div", _hoisted_5, [ vue.createElementVNode("div", _hoisted_6, [ vue.renderSlot(_ctx.$slots, "arrow-next-icon", {}, () => [ vue.createVNode(vue.unref(icons.IconChevronRight)) ]) ]) ]) ]) ]) ], 2 /* CLASS */ )) : vue.createCommentVNode("v-if", true) ], 38 /* CLASS, STYLE, NEED_HYDRATION */ ); }; } }); module.exports = _sfc_main;