{
  "name": "carousel",
  "type": "registry:ui",
  "dependencies": [
    "embla-carousel-vue",
    "@vueuse/core"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "ui/carousel/Carousel.vue",
      "content": "<script setup lang=\"ts\">\nimport type { CarouselEmits, CarouselProps, WithClassAsProps } from \"./interface\"\nimport { cn } from \"@/lib/utils\"\nimport { useProvideCarousel } from \"./useCarousel\"\n\nconst props = withDefaults(defineProps<CarouselProps & WithClassAsProps>(), {\n  orientation: \"horizontal\",\n})\n\nconst emits = defineEmits<CarouselEmits>()\n\nconst { canScrollNext, canScrollPrev, carouselApi, carouselRef, orientation, scrollNext, scrollPrev } = useProvideCarousel(props, emits)\n\ndefineExpose({\n  canScrollNext,\n  canScrollPrev,\n  carouselApi,\n  carouselRef,\n  orientation,\n  scrollNext,\n  scrollPrev,\n})\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    scrollPrev()\n\n    return\n  }\n\n  if (event.key === nextKey) {\n    event.preventDefault()\n    scrollNext()\n  }\n}\n</script>\n\n<template>\n  <div\n    :class=\"cn('relative', props.class)\"\n    role=\"region\"\n    aria-roledescription=\"carousel\"\n    tabindex=\"0\"\n    @keydown=\"onKeyDown\"\n  >\n    <slot :can-scroll-next :can-scroll-prev :carousel-api :carousel-ref :orientation :scroll-next :scroll-prev />\n  </div>\n</template>\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/carousel/CarouselContent.vue",
      "content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from \"./interface\"\nimport { cn } from \"@/lib/utils\"\nimport { useCarousel } from \"./useCarousel\"\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { carouselRef, orientation } = useCarousel()\n</script>\n\n<template>\n  <div ref=\"carouselRef\" class=\"overflow-hidden\">\n    <div\n      :class=\"\n        cn(\n          'flex',\n          orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',\n          props.class,\n        )\"\n      v-bind=\"$attrs\"\n    >\n      <slot />\n    </div>\n  </div>\n</template>\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/carousel/CarouselItem.vue",
      "content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from \"./interface\"\nimport { cn } from \"@/lib/utils\"\nimport { useCarousel } from \"./useCarousel\"\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation } = useCarousel()\n</script>\n\n<template>\n  <div\n    role=\"group\"\n    aria-roledescription=\"slide\"\n    :class=\"cn(\n      'min-w-0 shrink-0 grow-0 basis-full',\n      orientation === 'horizontal' ? 'pl-4' : 'pt-4',\n      props.class,\n    )\"\n  >\n    <slot />\n  </div>\n</template>\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/carousel/CarouselNext.vue",
      "content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from \"./interface\"\nimport { ArrowRight } from \"lucide-vue-next\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { useCarousel } from \"./useCarousel\"\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollNext, scrollNext } = useCarousel()\n</script>\n\n<template>\n  <Button\n    :disabled=\"!canScrollNext\"\n    :class=\"cn(\n      'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n      orientation === 'horizontal'\n        ? '-right-12 top-1/2 -translate-y-1/2'\n        : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',\n      props.class,\n    )\"\n    variant=\"outline\"\n    @click=\"scrollNext\"\n  >\n    <slot>\n      <ArrowRight class=\"h-4 w-4 text-current\" />\n      <span class=\"sr-only\">Next Slide</span>\n    </slot>\n  </Button>\n</template>\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/carousel/CarouselPrevious.vue",
      "content": "<script setup lang=\"ts\">\nimport type { WithClassAsProps } from \"./interface\"\nimport { ArrowLeft } from \"lucide-vue-next\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { useCarousel } from \"./useCarousel\"\n\nconst props = defineProps<WithClassAsProps>()\n\nconst { orientation, canScrollPrev, scrollPrev } = useCarousel()\n</script>\n\n<template>\n  <Button\n    :disabled=\"!canScrollPrev\"\n    :class=\"cn(\n      'touch-manipulation absolute h-8 w-8 rounded-full p-0',\n      orientation === 'horizontal'\n        ? '-left-12 top-1/2 -translate-y-1/2'\n        : '-top-12 left-1/2 -translate-x-1/2 rotate-90',\n      props.class,\n    )\"\n    variant=\"outline\"\n    @click=\"scrollPrev\"\n  >\n    <slot>\n      <ArrowLeft class=\"h-4 w-4 text-current\" />\n      <span class=\"sr-only\">Previous Slide</span>\n    </slot>\n  </Button>\n</template>\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/carousel/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 CarouselNext } from \"./CarouselNext.vue\"\nexport { default as CarouselPrevious } from \"./CarouselPrevious.vue\"\nexport type {\n  UnwrapRefCarouselApi as CarouselApi,\n} from \"./interface\"\n\nexport { useCarousel } from \"./useCarousel\"\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/carousel/interface.ts",
      "content": "import type useEmblaCarousel from \"embla-carousel-vue\"\nimport type {\n  EmblaCarouselVueType,\n} from \"embla-carousel-vue\"\nimport type { HTMLAttributes, UnwrapRef } from \"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\nexport interface WithClassAsProps {\n  class?: HTMLAttributes[\"class\"]\n}\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/carousel/useCarousel.ts",
      "content": "import type { UnwrapRefCarouselApi as CarouselApi, CarouselEmits, CarouselProps } from \"./interface\"\nimport { createInjectionState } from \"@vueuse/core\"\nimport emblaCarouselVue from \"embla-carousel-vue\"\nimport { onMounted, ref } from \"vue\"\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    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      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  return carouselState\n}\n\nexport { useCarousel, useProvideCarousel }\n",
      "type": "registry:ui",
      "target": ""
    }
  ]
}
