import { createInjectionState } from "@vueuse/core"; import emblaCarouselVue from "embla-carousel-vue"; import { onMounted, ref } from "vue"; import type { UnwrapRefCarouselApi as CarouselApi, CarouselEmits, CarouselProps, } from "./interface"; const [useProvideCarousel, useInjectCarousel] = createInjectionState( ({ opts, orientation, plugins }: CarouselProps, emits: CarouselEmits) => { const [emblaNode, emblaApi] = emblaCarouselVue( { ...opts, axis: orientation === "horizontal" ? "x" : "y", }, plugins, ); function scrollPrev() { emblaApi.value?.scrollPrev(); } function scrollNext() { emblaApi.value?.scrollNext(); } const canScrollNext = ref(false); const canScrollPrev = ref(false); function onSelect(api: CarouselApi) { canScrollNext.value = api?.canScrollNext() || false; canScrollPrev.value = api?.canScrollPrev() || false; } onMounted(() => { if (!emblaApi.value) return; emblaApi.value?.on("init", onSelect); emblaApi.value?.on("reInit", onSelect); emblaApi.value?.on("select", onSelect); emits("init-api", emblaApi.value); }); return { carouselRef: emblaNode, carouselApi: emblaApi, canScrollPrev, canScrollNext, scrollPrev, scrollNext, orientation, }; }, ); function useCarousel() { const carouselState = useInjectCarousel(); if (!carouselState) throw new Error("useCarousel must be used within a "); return carouselState; } export { useCarousel, useProvideCarousel };