{
  "name": "carousel",
  "dependencies": [
    "embla-carousel-vue",
    "@vueuse/core"
  ],
  "registryDependencies": [],
  "files": [
    {
      "name": "Carousel.vue",
      "content": "<script setup lang=\"ts\">\nimport { useProvideCarousel } from './useCarousel';\nimport type { CarouselEmits, CarouselProps } from './interface';\n\nconst props = withDefaults(defineProps<CarouselProps>(), {\n  orientation: 'horizontal',\n});\n\nconst emits = defineEmits<CarouselEmits>();\n\nconst carouselArgs = useProvideCarousel(props, emits);\n\ndefineExpose(carouselArgs);\n\nfunction onKeyDown(event: KeyboardEvent) {\n  const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft';\n  const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight';\n\n  if (event.key === prevKey) {\n    event.preventDefault();\n    carouselArgs.scrollPrev();\n\n    return;\n  }\n\n  if (event.key === nextKey) {\n    event.preventDefault();\n    carouselArgs.scrollNext();\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"sigma-ui-carousel\"\n    :class=\"[$attrs.class]\"\n    role=\"region\"\n    aria-roledescription=\"carousel\"\n    tabindex=\"0\"\n    @keydown=\"onKeyDown\"\n  >\n    <slot v-bind=\"carouselArgs\" />\n  </div>\n</template>\n\n<style>\n.sigma-ui-carousel {\n  position: relative;\n}\n</style>\n"
    },
    {
      "name": "CarouselContent.vue",
      "content": "<script setup lang=\"ts\">\nimport { useCarousel } from './useCarousel';\n\ndefineOptions({\n  inheritAttrs: false,\n});\n\nconst { carouselRef, orientation } = useCarousel();\n</script>\n\n<template>\n  <div\n    ref=\"carouselRef\"\n    class=\"sigma-ui-carousel-content\"\n  >\n    <div\n      class=\"sigma-ui-carousel-content__wrapper\"\n      :class=\"[\n        orientation === 'horizontal' ? 'sigma-ui-carousel-content__wrapper--horizontal' : 'sigma-ui-carousel-content__wrapper--vertical',\n        $attrs.class ?? '',\n      ]\"\n      v-bind=\"$attrs\"\n    >\n      <slot />\n    </div>\n  </div>\n</template>\n\n<style>\n.sigma-ui-carousel-content {\n  overflow: hidden;\n}\n\n.sigma-ui-carousel-content__wrapper {\n  display: flex;\n}\n\n.sigma-ui-carousel-content__wrapper--horizontal {\n  margin-left: -1rem;\n}\n\n.sigma-ui-carousel-content__wrapper--vertical {\n  margin-top: -1rem;\n  flex-direction: column;\n}\n</style>\n"
    },
    {
      "name": "CarouselItem.vue",
      "content": "<script setup lang=\"ts\">\nimport { useCarousel } from './useCarousel';\n\nconst { orientation } = useCarousel();\n</script>\n\n<template>\n  <div\n    class=\"sigma-ui-carousel-item\"\n    :class=\"[\n      orientation === 'horizontal' ? 'sigma-ui-carousel-item--horizontal' : 'sigma-ui-carousel-item--vertical',\n      $attrs.class ?? '',\n    ]\"\n    role=\"group\"\n    aria-roledescription=\"slide\"\n  >\n    <slot />\n  </div>\n</template>\n\n<style>\n.sigma-ui-carousel-item {\n  min-width: 0;\n  flex-shrink: 0;\n  flex-basis: 100%;\n}\n\n.sigma-ui-carousel-item--horizontal {\n  padding-left: 1rem;\n}\n\n.sigma-ui-carousel-item--vertical {\n  padding-top: 1rem;\n}\n</style>\n"
    },
    {
      "name": "CarouselNext.vue",
      "content": "<script setup lang=\"ts\">\nimport { ArrowRightIcon } from 'lucide-vue-next';\nimport { useCarousel } from './useCarousel';\nimport { Button } from '@ui/registry/css/ui/button';\n\nconst { orientation, canScrollNext, scrollNext } = useCarousel();\n</script>\n\n<template>\n  <Button\n    :disabled=\"!canScrollNext\"\n    class=\"sigma-ui-carousel-next\"\n    :class=\"[\n      orientation === 'horizontal' ? 'sigma-ui-carousel-next--horizontal' : 'sigma-ui-carousel-next--vertical',\n      $attrs.class ?? '',\n    ]\"\n    variant=\"outline\"\n    @click=\"scrollNext\"\n  >\n    <slot>\n      <ArrowRightIcon class=\"sigma-ui-carousel-next__icon\" />\n      <span class=\"sr-only\">Next Slide</span>\n    </slot>\n  </Button>\n</template>\n\n<style>\n.sigma-ui-carousel-next {\n  touch-action: manipulation;\n  position: absolute;\n  height: 2rem;\n  width: 2rem;\n  padding: 0;\n  border-radius: var(--radius);\n}\n\n.sigma-ui-carousel-next--horizontal {\n  right: -3rem;\n  top: 50%;\n  transform: translateY(-50%);\n}\n\n.sigma-ui-carousel-next--vertical {\n  bottom: -3rem;\n  left: 50%;\n  transform: translateX(-50%) rotate(90deg);\n}\n\n.sigma-ui-carousel-next__icon {\n  height: 1rem;\n  width: 1rem;\n}\n</style>\n"
    },
    {
      "name": "CarouselPrevious.vue",
      "content": "<script setup lang=\"ts\">\nimport { ArrowLeftIcon } from 'lucide-vue-next';\nimport { useCarousel } from './useCarousel';\nimport { Button } from '@ui/registry/css/ui/button';\n\nconst { orientation, canScrollPrev, scrollPrev } = useCarousel();\n</script>\n\n<template>\n  <Button\n    :disabled=\"!canScrollPrev\"\n    class=\"sigma-ui-carousel-previous\"\n    :class=\"[\n      orientation === 'horizontal' ? 'sigma-ui-carousel-previous--horizontal' : 'sigma-ui-carousel-previous--vertical',\n      $attrs.class ?? '',\n    ]\"\n    variant=\"outline\"\n    @click=\"scrollPrev\"\n  >\n    <slot>\n      <ArrowLeftIcon class=\"sigma-ui-carousel-previous__icon\" />\n      <span class=\"sr-only\">Previous Slide</span>\n    </slot>\n  </Button>\n</template>\n\n<style>\n.sigma-ui-carousel-previous {\n  touch-action: manipulation;\n  position: absolute;\n  height: 2rem;\n  width: 2rem;\n  padding: 0;\n  border-radius: var(--radius);\n}\n\n.sigma-ui-carousel-previous--horizontal {\n  left: -3rem;\n  top: 50%;\n  transform: translateY(-50%);\n}\n\n.sigma-ui-carousel-previous--vertical {\n  top: -3rem;\n  left: 50%;\n  transform: translateX(-50%) rotate(90deg);\n}\n\n.sigma-ui-carousel-previous__icon {\n  height: 1rem;\n  width: 1rem;\n}\n</style>\n"
    },
    {
      "name": "index.ts",
      "content": "export { default as Carousel } from './Carousel.vue';\nexport { default as CarouselContent } from './CarouselContent.vue';\nexport { default as CarouselItem } from './CarouselItem.vue';\nexport { default as CarouselPrevious } from './CarouselPrevious.vue';\nexport { default as CarouselNext } from './CarouselNext.vue';\nexport { useCarousel } from './useCarousel';\n\nexport type {\n  UnwrapRefCarouselApi as CarouselApi,\n} from './interface';\n"
    },
    {
      "name": "interface.ts",
      "content": "import type { UnwrapRef } from 'vue';\nimport type useEmblaCarousel from 'embla-carousel-vue';\nimport type {\n  EmblaCarouselVueType,\n} from 'embla-carousel-vue';\n\ntype CarouselApi = EmblaCarouselVueType[1];\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\nexport type UnwrapRefCarouselApi = UnwrapRef<CarouselApi>;\n\nexport interface CarouselProps {\n  opts?: CarouselOptions;\n  plugins?: CarouselPlugin;\n  orientation?: 'horizontal' | 'vertical';\n}\n\nexport interface CarouselEmits {\n  (e: 'init-api', payload: UnwrapRefCarouselApi): void;\n}\n"
    },
    {
      "name": "useCarousel.ts",
      "content": "import { createInjectionState } from '@vueuse/core';\nimport emblaCarouselVue from 'embla-carousel-vue';\nimport { onMounted, ref } from 'vue';\nimport type { UnwrapRefCarouselApi as CarouselApi, CarouselEmits, CarouselProps } from './interface';\n\nconst [useProvideCarousel, useInjectCarousel] = createInjectionState(\n  ({\n    opts,\n    orientation,\n    plugins,\n  }: CarouselProps, emits: CarouselEmits) => {\n    const [emblaNode, emblaApi] = emblaCarouselVue({\n      ...opts,\n      axis: orientation === 'horizontal' ? 'x' : 'y',\n    }, plugins);\n\n    function scrollPrev() {\n      emblaApi.value?.scrollPrev();\n    }\n\n    function scrollNext() {\n      emblaApi.value?.scrollNext();\n    }\n\n    const canScrollNext = ref(false);\n    const canScrollPrev = ref(false);\n\n    function onSelect(api: CarouselApi) {\n      canScrollNext.value = api?.canScrollNext() || false;\n      canScrollPrev.value = api?.canScrollPrev() || false;\n    }\n\n    onMounted(() => {\n      if (!emblaApi.value) {\n        return;\n      }\n\n      emblaApi.value?.on('init', onSelect);\n      emblaApi.value?.on('reInit', onSelect);\n      emblaApi.value?.on('select', onSelect);\n\n      emits('init-api', emblaApi.value);\n    });\n\n    return { carouselRef: emblaNode, carouselApi: emblaApi, canScrollPrev, canScrollNext, scrollPrev, scrollNext, orientation };\n  },\n);\n\nfunction useCarousel() {\n  const carouselState = useInjectCarousel();\n\n  if (!carouselState) {\n    throw new Error('useCarousel must be used within a <Carousel />');\n  }\n\n  return carouselState;\n}\n\nexport { useCarousel, useProvideCarousel };\n"
    }
  ],
  "type": "components:ui"
}