shadcn-vue/packages/module/playground/components/ui/carousel/useCarousel.ts
Sadegh Barati d34c620055
chore: lint and enable Volar hybrid mode (#419)
* chore: update deps

* feat: enable Volar hybrid mode

* chore: lint

* chore: build registry
2024-03-20 22:29:42 +03:30

60 lines
1.5 KiB
TypeScript

import { createInjectionState } from '@vueuse/core'
import emblaCarouselVue from 'embla-carousel-vue'
import { onMounted, ref } from 'vue'
import type {
EmblaCarouselType as CarouselApi,
} from 'embla-carousel'
import type { 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(true)
const canScrollPrev = ref(true)
function onSelect(api: CarouselApi) {
canScrollNext.value = api.canScrollNext()
canScrollPrev.value = api.canScrollPrev()
}
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 <Carousel />')
return carouselState
}
export { useCarousel, useProvideCarousel }