UNPKG

hongluan-ui

Version:
394 lines (389 loc) 14.7 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var lodashUnified = require('lodash-unified'); var core = require('@vueuse/core'); require('../../../hooks/index.js'); var error = require('../../../utils/error.js'); var index = require('../../icon/index.js'); require('../../system-icon/index.js'); require('../../../tokens/index.js'); var carousel = require('./carousel2.js'); var pluginVue_exportHelper = require('../../../_virtual/plugin-vue_export-helper.js'); var arrowLeft = require('../../system-icon/src/arrow-left.js'); var arrowRight = require('../../system-icon/src/arrow-right.js'); var index$1 = require('../../../hooks/use-locale/index.js'); var index$2 = require('../../../hooks/use-namespace/index.js'); var index$3 = require('../../../hooks/use-ordered-children/index.js'); var carousel$1 = require('../../../tokens/carousel.js'); const _sfc_main = vue.defineComponent({ name: "Carousel", components: { HlIcon: index.HlIcon, SystemArrowLeft: arrowLeft["default"], SystemArrowRight: arrowRight["default"] }, props: carousel.carouselProps, emits: ["change"], setup(props, { emit }) { const { t } = index$1.useLocale(); const { namespace } = index$2.useNamespace("carousel"); const { children: items, addChild, removeChild: removeItem } = index$3.useOrderedChildren(vue.getCurrentInstance(), "CarouselItem"); const data = vue.reactive({ activeIndex: -1, containerWidth: 0, timer: null, hover: false, itemsIndexArray: [], throttledArrowDirection: "", itemsWidthUnit: Number.isNaN(+props.itemsWidth) ? String(props.itemsWidth).replace(/[^a-zA-Z]/g, "") : "px" }); const root = vue.ref(null); const arrowDisplay = vue.computed(() => props.arrow !== "never" && props.direction !== "vertical"); const showMultiple = vue.computed(() => { let state = props.itemsNumber !== 1 && props.direction === "horizontal" && props.type !== "card" && items.value.length - 2 >= props.itemsNumber ? true : false; return state; }); const containerWidth = vue.computed(() => { return props.itemsNumber * Number.parseFloat(String(props.itemsWidth)) + data.itemsWidthUnit; }); const hasLabel = vue.computed(() => { return items.value.some((item) => item.props.label.toString().length > 0); }); const carouselClasses = vue.computed(() => { const classes = [namespace.value, "carousel-" + props.direction]; if (props.type === "card") { classes.push("carousel-card"); } return classes; }); const indicatorsClasses = vue.computed(() => { const classes = [ "carousel-indicators", "carousel-indicators-" + props.direction, "carousel-indicators-" + props.indicatorType ]; if (hasLabel.value) { classes.push("carousel-indicators-labels"); } if (props.indicatorPosition === "outside" || props.type === "card") { classes.push("carousel-indicators-outside"); } return classes; }); const indicatorsButtonClasses = vue.computed(() => { const classes = props.indicatorType === "line" ? "carousel-button" : "carousel-dot"; return classes; }); function getitemsIndexArray() { let array = []; for (let i = 0; i < Number(items.value.length - 1); i++) { array.push(i); } array.push(-1); return showMultiple.value ? array : []; } const throttledArrowClick = lodashUnified.throttle((index, direction) => { data.throttledArrowDirection = direction; if (showMultiple.value) { data.itemsIndexArray = data.itemsIndexArray.map((itx) => { if (itx === items.value.length - 2 && direction === "previous") itx = -2; if (itx === -1 && direction === "next") itx = items.value.length - 1; direction === "previous" ? itx += 1 : itx -= 1; return itx; }); } setActiveItem(index); }, 300, { trailing: true }); const throttledIndicatorHover = lodashUnified.throttle((index) => { handleIndicatorHover(index); }, 300); function pauseTimer() { if (data.timer) { clearInterval(data.timer); data.timer = null; } } function startTimer() { if (props.interval <= 0 || !props.autoplay || data.timer) return; data.timer = setInterval(() => playSlides(), props.interval); } const playSlides = () => { if (data.activeIndex < items.value.length - 1) { data.activeIndex = data.activeIndex + 1; } else if (props.loop) { data.activeIndex = 0; } showMultiple.value && throttledArrowClick(data.activeIndex + 1, "next"); }; function setActiveItem(index) { if (typeof index === "string") { const filteredItems = items.value.filter((item) => item.props.name === index); if (filteredItems.length > 0) { index = items.value.indexOf(filteredItems[0]); } } index = Number(index); if (Number.isNaN(index) || index !== Math.floor(index)) { error.debugWarn("Carousel", "index must be an integer."); return; } let length = items.value.length; const oldIndex = data.activeIndex; if (index < 0) { data.activeIndex = props.loop ? length - 1 : 0; } else if (index >= length) { data.activeIndex = props.loop ? 0 : length - 1; } else { data.activeIndex = index; } if (oldIndex === data.activeIndex) { resetItemPosition(oldIndex); } resetTimer(); } function resetItemPosition(oldIndex) { const itemWidth = Number.parseFloat(String(props.itemsWidth)); items.value.forEach((item, index) => { let itemsDistance = showMultiple.value ? itemWidth * data.itemsIndexArray[index] : 0; let isAnimating = data.throttledArrowDirection === "next" ? data.itemsIndexArray[index] === props.itemsNumber + 1 ? false : true : itemWidth * data.itemsIndexArray[index] === -itemWidth ? false : true; item.translateItem(index, data.activeIndex, oldIndex, itemsDistance, isAnimating); }); } function addItem(item) { addChild(item); data.itemsIndexArray = getitemsIndexArray(); } function itemInStage(item, index) { const length = items.value.length; if (index === length - 1 && item.states.inStage && items.value[0].states.active || item.states.inStage && items.value[index + 1] && items.value[index + 1].states.active) { return "left"; } else if (index === 0 && item.states.inStage && items.value[length - 1].states.active || item.states.inStage && items.value[index - 1] && items.value[index - 1].states.active) { return "right"; } return false; } function handleMouseEnter() { data.hover = true; if (props.pauseOnHover) { pauseTimer(); } } function handleMouseLeave() { data.hover = false; startTimer(); } function handleButtonEnter(arrow) { if (props.direction === "vertical") return; items.value.forEach((item, index) => { if (arrow === itemInStage(item, index)) { item.states.hover = true; } }); } function handleButtonLeave() { if (props.direction === "vertical") return; items.value.forEach((item) => { item.states.hover = false; }); } function handleIndicatorClick(index) { data.activeIndex = index; } function handleIndicatorHover(index) { if (props.trigger === "hover" && index !== data.activeIndex) { data.activeIndex = index; } } function prev() { setActiveItem(data.activeIndex - 1); } function next() { setActiveItem(data.activeIndex + 1); } function resetTimer() { pauseTimer(); startTimer(); } vue.watch(() => data.activeIndex, (current, prev2) => { resetItemPosition(prev2); if (prev2 > -1) { emit("change", current, prev2); } }); vue.watch(() => props.autoplay, (current) => { current ? startTimer() : pauseTimer(); }); vue.watch(() => props.loop, () => { setActiveItem(data.activeIndex); }); vue.watch(() => props.interval, () => { resetTimer(); }); vue.watch(() => items.value, () => { if (items.value.length > 0) setActiveItem(props.initialIndex); }, { immediate: true }); const resizeObserver = vue.shallowRef(); vue.onMounted(() => { resizeObserver.value = core.useResizeObserver(root.value, () => { resetItemPosition(); }); startTimer(); }); vue.onBeforeUnmount(() => { pauseTimer(); if (root.value && resizeObserver.value) resizeObserver.value.stop(); }); vue.provide(carousel$1.carouselContextKey, { root, direction: props.direction, type: props.type, items, loop: props.loop, addItem, removeItem, setActiveItem, showMultiple: vue.toRef(showMultiple, "value"), itemsWidth: props.itemsWidth, itemsWidthUnit: data.itemsWidthUnit }); vue.provide(carousel$1.carouselIndicatorContextKey, { activeIndex: vue.toRef(data, "activeIndex"), handleIndicatorClick, throttledIndicatorHover }); return { t, data, props, items, arrowDisplay, carouselClasses, indicatorsClasses, indicatorsButtonClasses, hasLabel, containerWidth, showMultiple, handleMouseEnter, handleMouseLeave, handleIndicatorClick, throttledArrowClick, throttledIndicatorHover, handleButtonEnter, handleButtonLeave, prev, next, setActiveItem, root }; } }); function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_system_arrow_left = vue.resolveComponent("system-arrow-left"); const _component_hl_icon = vue.resolveComponent("hl-icon"); const _component_system_arrow_right = vue.resolveComponent("system-arrow-right"); return vue.openBlock(), vue.createElementBlock("div", { ref: "root", class: vue.normalizeClass(_ctx.carouselClasses), onMouseenter: vue.withModifiers(_ctx.handleMouseEnter, ["stop"]), onMouseleave: vue.withModifiers(_ctx.handleMouseLeave, ["stop"]) }, [ vue.createElementVNode("div", { class: "carousel-container", style: vue.normalizeStyle({ height: _ctx.height, width: _ctx.showMultiple ? _ctx.containerWidth : "" }) }, [ _ctx.arrowDisplay ? (vue.openBlock(), vue.createBlock(vue.Transition, { key: 0, name: "carousel-arrow-left" }, { default: vue.withCtx(() => [ vue.withDirectives(vue.createElementVNode("button", { type: "button", class: "carousel-arrow left", "aria-label": _ctx.t("hl.carousel.leftArrow"), onMouseenter: ($event) => _ctx.handleButtonEnter("left"), onMouseleave: _ctx.handleButtonLeave, onClick: vue.withModifiers(($event) => _ctx.throttledArrowClick(_ctx.data.activeIndex - 1, "previous"), ["stop"]) }, [ vue.createVNode(_component_hl_icon, null, { default: vue.withCtx(() => [ vue.createVNode(_component_system_arrow_left) ]), _: 1 }) ], 40, ["aria-label", "onMouseenter", "onMouseleave", "onClick"]), [ [vue.vShow, (_ctx.arrow === "always" || _ctx.data.hover) && (_ctx.props.loop || _ctx.data.activeIndex > 0)] ]) ]), _: 1 })) : vue.createCommentVNode("v-if", true), _ctx.arrowDisplay ? (vue.openBlock(), vue.createBlock(vue.Transition, { key: 1, name: "carousel-arrow-right" }, { default: vue.withCtx(() => [ vue.withDirectives(vue.createElementVNode("button", { type: "button", class: "carousel-arrow right", "aria-label": _ctx.t("hl.carousel.rightArrow"), onMouseenter: ($event) => _ctx.handleButtonEnter("right"), onMouseleave: _ctx.handleButtonLeave, onClick: vue.withModifiers(($event) => _ctx.throttledArrowClick(_ctx.data.activeIndex + 1, "next"), ["stop"]) }, [ vue.createVNode(_component_hl_icon, null, { default: vue.withCtx(() => [ vue.createVNode(_component_system_arrow_right) ]), _: 1 }) ], 40, ["aria-label", "onMouseenter", "onMouseleave", "onClick"]), [ [vue.vShow, (_ctx.arrow === "always" || _ctx.data.hover) && (_ctx.props.loop || _ctx.data.activeIndex < _ctx.items.length - 1)] ]) ]), _: 1 })) : vue.createCommentVNode("v-if", true), vue.renderSlot(_ctx.$slots, "default") ], 4), _ctx.indicatorPosition !== "none" && !_ctx.showMultiple ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, class: vue.normalizeClass(_ctx.indicatorsClasses) }, [ _ctx.indicatorType !== "custom" ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(_ctx.items, (item, index) => { return vue.openBlock(), vue.createElementBlock("div", { key: index, class: vue.normalizeClass([ "carousel-indicator", "carousel-indicator-" + _ctx.direction, { "is-active": index === _ctx.data.activeIndex } ]), onMouseenter: ($event) => _ctx.throttledIndicatorHover(index), onClick: vue.withModifiers(($event) => _ctx.handleIndicatorClick(index), ["stop"]) }, [ vue.createElementVNode("button", { class: vue.normalizeClass(_ctx.indicatorsButtonClasses), "aria-label": _ctx.t("hl.carousel.indicator", { index: index + 1 }) }, [ _ctx.hasLabel ? (vue.openBlock(), vue.createElementBlock("span", { key: 0 }, vue.toDisplayString(item.props.label), 1)) : vue.createCommentVNode("v-if", true) ], 10, ["aria-label"]) ], 42, ["onMouseenter", "onClick"]); }), 128)) : vue.createCommentVNode("v-if", true), vue.renderSlot(_ctx.$slots, "indicator") ], 2)) : vue.createCommentVNode("v-if", true) ], 42, ["onMouseenter", "onMouseleave"]); } var Carousel = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["render", _sfc_render]]); exports["default"] = Carousel; //# sourceMappingURL=carousel.js.map