import { useRef, useState, type PropsWithChildren, type ReactElement, } from "react"; import type { BaseProps, HTMLProps } from "../../shared/types"; import { cn } from "../../shared/utils/cn"; import React from "react"; import { TabItem, type TabItemProps, type TabItemPropsPublic, } from "./components/TabItem"; import { useElementOverflow } from "./hooks/use-element-overflow"; import { useElementScroll } from "./hooks/use-element-scroll"; import { TabScroller } from "./components/TabScroller"; export type TabsProps = HTMLProps<"div"> & BaseProps; type TabsType = React.FC> & { Item: React.FC>; }; const Tabs: TabsType = ({ children, className, testId, ...props }) => { const [activeIndex, setActiveIndex] = useState(0); const containerRef = useRef(null); const tabListRef = useRef(null); const isOverflowing = useElementOverflow({ contentRef: tabListRef, containerRef, }); const { canScrollLeft, canScrollRight, scrollLeft, scrollRight } = useElementScroll({ containerRef, scrollRef: tabListRef, }); const childrenArray = React.Children.toArray(children); const tabs = React.Children.map(children, (child, index: number) => { const isFirst = index === 0; const isLast = childrenArray.length - 1 === index; return React.cloneElement( child as ReactElement, { index, isFirst, isLast, isActive: index === activeIndex, onSelect: () => setActiveIndex(index), } as TabItemProps ); }) ?? []; return (
{canScrollLeft && isOverflowing && ( )}
{tabs}
{canScrollRight && isOverflowing && ( )}
{tabs.map((child, index) => { if (index !== activeIndex) { return null; } const tabContent = (child.props as PropsWithChildren).children; return (
{tabContent}
); })}
); }; Tabs.Item = TabItem as React.FC>; export { Tabs };