import { useCallback, useEffect, useRef, useState } from "react"; import classes from "./classes.module.scss"; import HorizontalTab, { ITab } from "./HorizontalTab"; import VerticalTabs from "./VerticalTabs"; import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; import { useDebounce, useWindowSize } from "@uidotdev/usehooks"; import useOpenable from "@Front/Hooks/useOpenable"; export type ITabValue = T & { id: unknown; }; type ITabInternal = ITab & { key?: string; value: ITabValue; }; type IProps = { tabs: ITabInternal[]; onSelect: (value: T) => void; }; export default function Tabs(props: IProps) { const { onSelect } = props; const rootRef = useRef(null); const [visibleElements, setVisibleElements] = useState[]>([]); const [overflowedElements, setOverflowedElements] = useState[]>([]); const [selectedTab, setSelectedTab] = useState>(props.tabs[0]!.value); const { close, isOpen, toggle } = useOpenable(); const windowSize = useWindowSize(); const windowSizeDebounced = useDebounce(windowSize, 100); const calculateVisibleElements = useCallback(() => { const container = rootRef.current; if (!container) return; const containerWidth = container.offsetWidth; let totalWidth = 115; let visibleCount = 0; const children = Array.from(container.children) as HTMLDivElement[]; for (let i = 0; i < children.length; i++) { totalWidth += children[i]!.offsetWidth; if (totalWidth > containerWidth) { break; } visibleCount++; } setVisibleElements(props.tabs.slice(0, visibleCount)); setOverflowedElements(props.tabs.slice(visibleCount)); }, [props.tabs]); useEffect(() => { calculateVisibleElements(); }, [calculateVisibleElements, windowSizeDebounced]); const handleSelect = useCallback( (value: ITabValue) => { setSelectedTab(value); onSelect(value); close(); }, [close, onSelect], ); return (
{props.tabs.map((element, index) => ( label={element.label} key={element.key ?? index} value={element.value} onSelect={handleSelect} isSelected={element.value.id === selectedTab.id} /> ))}
{visibleElements.map((element, index) => ( label={element.label} key={element.key ?? index} value={element.value} onSelect={handleSelect} isSelected={element.value.id === selectedTab.id} /> ))}
{overflowedElements.length > 0 && (
{overflowedElements.length} de plus...
{overflowedElements.length > 0 && overflowedElements.map((element, index) => ( label={element.label} key={element.key ?? index} value={element.value} onSelect={handleSelect} isSelected={selectedTab === element.value} /> ))}
)}
); }