{"version":3,"file":"use-carousel.mjs","names":[],"sources":["../../../../../../packages/components/carousel/src/use-carousel.ts"],"sourcesContent":["import {\n  computed,\n  getCurrentInstance,\n  isVNode,\n  onBeforeUnmount,\n  onMounted,\n  provide,\n  ref,\n  shallowRef,\n  unref,\n  useSlots,\n  watch,\n} from 'vue'\nimport { throttle } from 'lodash-unified'\nimport { useResizeObserver } from '@vueuse/core'\nimport { debugWarn, flattedChildren, isString } from '@element-plus/utils'\nimport { useOrderedChildren } from '@element-plus/hooks'\nimport { CHANGE_EVENT } from '@element-plus/constants'\nimport { CAROUSEL_ITEM_NAME, carouselContextKey } from './constants'\n\nimport type { SetupContext } from 'vue'\nimport type { DebouncedFunc } from 'lodash-unified'\nimport type { CarouselItemContext } from './constants'\nimport type { CarouselEmits, CarouselProps } from './carousel'\n\nconst THROTTLE_TIME = 300\n\nexport const useCarousel = (\n  props: Required<CarouselProps>,\n  emit: SetupContext<CarouselEmits>['emit'],\n  componentName: string\n) => {\n  const {\n    children: items,\n    addChild: addItem,\n    removeChild: removeItem,\n    ChildrenSorter: ItemsSorter,\n  } = useOrderedChildren<CarouselItemContext>(\n    getCurrentInstance()!,\n    CAROUSEL_ITEM_NAME\n  )\n\n  const slots = useSlots()\n\n  // refs\n  const activeIndex = ref(-1)\n  const timer = ref<ReturnType<typeof setInterval> | null>(null)\n  const hover = ref(false)\n  const root = ref<HTMLDivElement>()\n  const containerHeight = ref<number>(0)\n  const isItemsTwoLength = ref(true)\n\n  // computed\n  const arrowDisplay = computed(\n    () => props.arrow !== 'never' && !unref(isVertical)\n  )\n\n  const hasLabel = computed(() => {\n    return items.value.some((item) => item.props.label.toString().length > 0)\n  })\n\n  const isCardType = computed(() => props.type === 'card')\n  const isVertical = computed(() => props.direction === 'vertical')\n\n  const containerStyle = computed(() => {\n    if (props.height !== 'auto') {\n      return {\n        height: props.height,\n      }\n    }\n    return {\n      height: `${containerHeight.value}px`,\n      overflow: 'hidden',\n    }\n  })\n\n  // methods\n  const throttledArrowClick: DebouncedFunc<(index: number) => void> = throttle(\n    (index: number) => {\n      setActiveItem(index)\n    },\n    THROTTLE_TIME,\n    { trailing: true }\n  )\n\n  const throttledIndicatorHover: DebouncedFunc<(index: number) => void> =\n    throttle((index: number) => {\n      handleIndicatorHover(index)\n    }, THROTTLE_TIME)\n\n  const isTwoLengthShow = (index: number) => {\n    if (!isItemsTwoLength.value) return true\n    return activeIndex.value <= 1 ? index <= 1 : index > 1\n  }\n\n  function pauseTimer() {\n    if (timer.value) {\n      clearInterval(timer.value)\n      timer.value = null\n    }\n  }\n\n  function startTimer() {\n    if (props.interval <= 0 || !props.autoplay || timer.value) return\n    timer.value = setInterval(() => playSlides(), props.interval)\n  }\n\n  const playSlides = () => {\n    if (activeIndex.value < items.value.length - 1) {\n      activeIndex.value = activeIndex.value + 1\n    } else if (props.loop) {\n      activeIndex.value = 0\n    }\n  }\n\n  function setActiveItem(index: number | string) {\n    if (isString(index)) {\n      const filteredItems = items.value.filter(\n        (item) => item.props.name === index\n      )\n      if (filteredItems.length > 0) {\n        index = items.value.indexOf(filteredItems[0])\n      }\n    }\n    index = Number(index)\n    if (Number.isNaN(index) || index !== Math.floor(index)) {\n      debugWarn(componentName, 'index must be integer.')\n      return\n    }\n    const itemCount = items.value.length\n    const oldIndex = activeIndex.value\n    if (index < 0) {\n      activeIndex.value = props.loop ? itemCount - 1 : 0\n    } else if (index >= itemCount) {\n      activeIndex.value = props.loop ? 0 : itemCount - 1\n    } else {\n      activeIndex.value = index\n    }\n    if (oldIndex === activeIndex.value) {\n      resetItemPosition(oldIndex)\n    }\n    resetTimer()\n  }\n\n  function resetItemPosition(oldIndex?: number) {\n    items.value.forEach((item, index) => {\n      item.translateItem(index, activeIndex.value, oldIndex)\n    })\n  }\n\n  function itemInStage(item: CarouselItemContext, index: number) {\n    const _items = unref(items)\n    const itemCount = _items.length\n    if (itemCount === 0 || !item.states.inStage) return false\n    const nextItemIndex = index + 1\n    const prevItemIndex = index - 1\n    const lastItemIndex = itemCount - 1\n    const isLastItemActive = _items[lastItemIndex].states.active\n    const isFirstItemActive = _items[0].states.active\n    const isNextItemActive = _items[nextItemIndex]?.states?.active\n    const isPrevItemActive = _items[prevItemIndex]?.states?.active\n\n    if ((index === lastItemIndex && isFirstItemActive) || isNextItemActive) {\n      return 'left'\n    } else if ((index === 0 && isLastItemActive) || isPrevItemActive) {\n      return 'right'\n    }\n    return false\n  }\n\n  function handleMouseEnter() {\n    hover.value = true\n    if (props.pauseOnHover) {\n      pauseTimer()\n    }\n  }\n\n  function handleMouseLeave() {\n    hover.value = false\n    startTimer()\n  }\n\n  function handleButtonEnter(arrow: 'left' | 'right') {\n    if (unref(isVertical)) return\n    items.value.forEach((item, index) => {\n      if (arrow === itemInStage(item, index)) {\n        item.states.hover = true\n      }\n    })\n  }\n\n  function handleButtonLeave() {\n    if (unref(isVertical)) return\n    items.value.forEach((item) => {\n      item.states.hover = false\n    })\n  }\n\n  function handleIndicatorClick(index: number) {\n    activeIndex.value = index\n  }\n\n  function handleIndicatorHover(index: number) {\n    if (props.trigger === 'hover' && index !== activeIndex.value) {\n      activeIndex.value = index\n    }\n  }\n\n  function prev() {\n    setActiveItem(activeIndex.value - 1)\n  }\n\n  function next() {\n    setActiveItem(activeIndex.value + 1)\n  }\n\n  function resetTimer() {\n    pauseTimer()\n    if (!props.pauseOnHover || !hover.value) startTimer()\n  }\n\n  function setContainerHeight(height: number) {\n    if (props.height !== 'auto') return\n    containerHeight.value = height\n  }\n\n  function PlaceholderItem() {\n    // fix: https://github.com/element-plus/element-plus/issues/12139\n    const defaultSlots = slots.default?.()\n    if (!defaultSlots) return null\n\n    const flatSlots = flattedChildren(defaultSlots)\n\n    const normalizeSlots = flatSlots.filter((slot) => {\n      return isVNode(slot) && (slot.type as any).name === CAROUSEL_ITEM_NAME\n    })\n\n    if (normalizeSlots?.length === 2 && props.loop && !isCardType.value) {\n      isItemsTwoLength.value = true\n      return normalizeSlots\n    }\n    isItemsTwoLength.value = false\n    return null\n  }\n\n  // watch\n  watch(\n    () => activeIndex.value,\n    (current, prev) => {\n      resetItemPosition(prev)\n      if (isItemsTwoLength.value) {\n        current = current % 2\n        prev = prev % 2\n      }\n      if (prev > -1) {\n        emit(CHANGE_EVENT, current, prev)\n      }\n    }\n  )\n\n  const exposeActiveIndex = computed({\n    get: () => {\n      return isItemsTwoLength.value ? activeIndex.value % 2 : activeIndex.value\n    },\n    set: (value) => (activeIndex.value = value),\n  })\n\n  watch(\n    () => props.autoplay,\n    (autoplay) => {\n      autoplay ? startTimer() : pauseTimer()\n    }\n  )\n  watch(\n    () => props.loop,\n    () => {\n      setActiveItem(activeIndex.value)\n    }\n  )\n\n  watch(\n    () => props.interval,\n    () => {\n      resetTimer()\n    }\n  )\n\n  const resizeObserver = shallowRef<ReturnType<typeof useResizeObserver>>()\n  // lifecycle\n  onMounted(() => {\n    watch(\n      () => items.value,\n      () => {\n        if (items.value.length > 0) setActiveItem(props.initialIndex)\n      },\n      {\n        immediate: true,\n      }\n    )\n\n    resizeObserver.value = useResizeObserver(root.value, () => {\n      resetItemPosition()\n    })\n    startTimer()\n  })\n\n  onBeforeUnmount(() => {\n    pauseTimer()\n    if (root.value && resizeObserver.value) resizeObserver.value.stop()\n  })\n\n  // provide\n  provide(carouselContextKey, {\n    root,\n    isCardType,\n    isVertical,\n    items,\n    loop: props.loop,\n    cardScale: props.cardScale,\n    addItem,\n    removeItem,\n    setActiveItem,\n    setContainerHeight,\n  })\n\n  return {\n    root,\n    activeIndex,\n    exposeActiveIndex,\n    arrowDisplay,\n    hasLabel,\n    hover,\n    isCardType,\n    items,\n    isVertical,\n    containerStyle,\n    isItemsTwoLength,\n    handleButtonEnter,\n    handleButtonLeave,\n    handleIndicatorClick,\n    handleMouseEnter,\n    handleMouseLeave,\n    setActiveItem,\n    prev,\n    next,\n    PlaceholderItem,\n    isTwoLengthShow,\n    ItemsSorter,\n    throttledArrowClick,\n    throttledIndicatorHover,\n  }\n}\n"],"mappings":"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"}