{"version":3,"file":"index.cjs","names":["IconButton"],"sources":["../../../src/components/Carousel/Carousel.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport {\n  createContext,\n  forwardRef,\n  useCallback,\n  useContext,\n  useEffect,\n  useImperativeHandle,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport { IconButton } from \"../IconButton\";\n\ninterface CarouselContextType {\n  scrollDivRef: React.RefObject<HTMLDivElement | null>;\n  scroll: (direction: \"left\" | \"right\") => void;\n  itemsToScroll: number;\n  noSnap?: boolean;\n  showButtons?: boolean;\n  variant?: \"card\" | \"sunk\";\n  isPrevVisible: boolean;\n  isNextVisible: boolean;\n}\n\nconst CarouselContext = createContext<CarouselContextType | null>(null);\n\nconst useCarousel = () => {\n  const context = useContext(CarouselContext);\n  if (!context) throw new Error(\"useCarousel must be used within a Carousel\");\n  return context;\n};\n\nexport interface CarouselProps extends React.HTMLAttributes<HTMLDivElement> {\n  itemsToScroll?: number;\n  noSnap?: boolean;\n  showButtons?: boolean;\n  variant?: \"card\" | \"sunk\";\n  onScrollLeftEnabled?: (enabled: boolean) => void;\n  onScrollRightEnabled?: (enabled: boolean) => void;\n}\n\nexport interface CarouselRef {\n  scroll: (direction: \"left\" | \"right\") => void;\n  scrollDivRef: React.RefObject<HTMLDivElement | null>;\n}\n\nexport const Carousel = forwardRef<CarouselRef, CarouselProps>(\n  (\n    {\n      itemsToScroll = 1,\n      noSnap,\n      showButtons = true,\n      variant = \"card\",\n      className,\n      children,\n      onScrollLeftEnabled,\n      onScrollRightEnabled,\n      ...props\n    },\n    ref,\n  ) => {\n    const scrollDivRef = useRef<HTMLDivElement>(null);\n    const [isPrevVisible, setIsPrevVisible] = useState(false);\n    const [isNextVisible, setIsNextVisible] = useState(false);\n\n    const scroll = useCallback(\n      (direction: \"left\" | \"right\") => {\n        if (!scrollDivRef.current) {\n          return;\n        }\n\n        const container = scrollDivRef.current;\n        const items = noSnap\n          ? Array.from(container.children[0]?.children ?? [])\n          : Array.from(container.children);\n\n        if (items.length === 0) {\n          return;\n        }\n\n        const containerRect = container.getBoundingClientRect();\n        const visibleIndex = items.findIndex((child) => {\n          const rect = child.getBoundingClientRect();\n          return rect.left >= containerRect.left;\n        });\n\n        let currentIndex = visibleIndex;\n        if (visibleIndex === -1) {\n          // Scrolled to the far right, so the last item is the current one\n          currentIndex = items.length - 1;\n        }\n\n        const targetIndex =\n          direction === \"left\"\n            ? Math.max(0, currentIndex - itemsToScroll)\n            : Math.min(items.length - 1, currentIndex + itemsToScroll);\n\n        const targetElement = items[targetIndex] as HTMLElement;\n\n        if (targetElement) {\n          container.scrollTo({\n            left: targetElement.offsetLeft,\n            behavior: \"smooth\",\n          });\n        }\n      },\n      [noSnap, itemsToScroll],\n    );\n\n    useEffect(() => {\n      if (!scrollDivRef.current) return;\n\n      const container = scrollDivRef.current;\n      const handleScroll = () => {\n        const canScrollLeft = container.scrollLeft > 0;\n        const canScrollRight =\n          Math.ceil(container.scrollLeft) + container.offsetWidth < container.scrollWidth;\n        setIsPrevVisible(canScrollLeft);\n        setIsNextVisible(canScrollRight);\n      };\n\n      handleScroll();\n\n      const resizeObserver = new ResizeObserver(handleScroll);\n      resizeObserver.observe(container);\n      const mutationObserver = new MutationObserver(handleScroll);\n      mutationObserver.observe(container, { childList: true, subtree: true });\n\n      container.addEventListener(\"scroll\", handleScroll);\n\n      return () => {\n        container.removeEventListener(\"scroll\", handleScroll);\n        resizeObserver.disconnect();\n        mutationObserver.disconnect();\n      };\n    }, []);\n\n    useEffect(() => {\n      onScrollLeftEnabled?.(isPrevVisible);\n    }, [isPrevVisible, onScrollLeftEnabled]);\n\n    useEffect(() => {\n      onScrollRightEnabled?.(isNextVisible);\n    }, [isNextVisible, onScrollRightEnabled]);\n\n    useImperativeHandle(ref, () => {\n      return {\n        scroll,\n        scrollDivRef,\n      };\n    }, [scroll]);\n\n    const contextValue = useMemo(\n      () => ({\n        scrollDivRef,\n        scroll,\n        itemsToScroll,\n        noSnap,\n        showButtons,\n        variant,\n        isPrevVisible,\n        isNextVisible,\n      }),\n      [\n        scrollDivRef,\n        scroll,\n        itemsToScroll,\n        noSnap,\n        showButtons,\n        variant,\n        isPrevVisible,\n        isNextVisible,\n      ],\n    );\n\n    return (\n      <CarouselContext.Provider value={contextValue}>\n        <div\n          className={clsx(\"openui-carousel\", `openui-carousel--${variant}`, className)}\n          {...props}\n        >\n          {children}\n        </div>\n      </CarouselContext.Provider>\n    );\n  },\n);\n\nexport const CarouselContent = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, children, ...props }, _ref) => {\n    const { scrollDivRef, noSnap, isPrevVisible, isNextVisible } = useCarousel();\n\n    const content = noSnap ? (\n      <div className=\"openui-carousel-content-wrapper\">{children}</div>\n    ) : (\n      children\n    );\n\n    return (\n      <div\n        ref={scrollDivRef}\n        className={clsx(\n          \"openui-carousel-content\",\n          {\n            \"openui-carousel-content--mask-left\": isPrevVisible,\n            \"openui-carousel-content--mask-right\": isNextVisible,\n          },\n          className,\n        )}\n        {...props}\n      >\n        {content}\n      </div>\n    );\n  },\n);\n\nexport const CarouselItem = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, children, ...props }, ref) => (\n    <div ref={ref} className={clsx(\"openui-carousel-item\", className)} {...props}>\n      {children}\n    </div>\n  ),\n);\n\nexport const CarouselPrevious = forwardRef<\n  HTMLButtonElement,\n  React.ComponentProps<typeof IconButton>\n>(({ className, style, ...props }, ref) => {\n  const { scroll, showButtons, isPrevVisible } = useCarousel();\n\n  if (!isPrevVisible || !showButtons) return null;\n\n  return (\n    <div className={clsx(\"openui-carousel-button openui-carousel-button-left\", className)}>\n      <IconButton\n        ref={ref}\n        shape=\"square\"\n        variant=\"secondary\"\n        size=\"small\"\n        onClick={() => scroll(\"left\")}\n        style={style}\n        {...props}\n      />\n    </div>\n  );\n});\n\nexport const CarouselNext = forwardRef<HTMLButtonElement, React.ComponentProps<typeof IconButton>>(\n  ({ className, style, ...props }, ref) => {\n    const { scroll, showButtons, isNextVisible } = useCarousel();\n\n    if (!isNextVisible || !showButtons) return null;\n\n    return (\n      <div className={clsx(\"openui-carousel-button openui-carousel-button-right\", className)}>\n        <IconButton\n          ref={ref}\n          shape=\"square\"\n          variant=\"secondary\"\n          size=\"small\"\n          onClick={() => scroll(\"right\")}\n          style={style}\n          {...props}\n        />\n      </div>\n    );\n  },\n);\n"],"mappings":"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"}