import { cn } from "@/utils/helpers"; import { useState, useMemo, useCallback } from "react"; import { TabContext, useTabContext } from "./TabContext"; type TabsProps = { value?: string; defaultValue?: string; onChange?: (value: string) => void; children: | React.ReactNode | ((context: { value: string; onChange: (value: string) => void }) => React.ReactNode); }; function SegmentedTabs({ value, defaultValue, onChange, children }: Readonly) { const [internalValue, setInternalValue] = useState(defaultValue ?? ""); const currentValue = value ?? internalValue; const handleChange = useCallback((newValue: string) => { if (value === undefined) { setInternalValue(newValue); } onChange?.(newValue); }, [value, onChange]); const contextValue = useMemo( () => ({ value: currentValue, onChange: handleChange }), [currentValue, handleChange], ); return (
{typeof children === "function" ? children({ value: currentValue, onChange: handleChange }) : children}
); } function List({ children, className, }: Readonly<{ children: React.ReactNode; className?: string; }>) { return (
{children}
); } function Trigger({ children, value, disabled = false, className, selected, onClick, }: Readonly<{ children: React.ReactNode; value: string; disabled?: boolean; className?: string; selected?: boolean; onClick?: () => void; }>) { const context = useTabContext(); const isSelected = selected ?? value === context.value; let stateClassName = ""; if (isSelected) { stateClassName = "bg-nb-gray-900 text-white"; } else if (!disabled) { stateClassName = "text-nb-gray-400 hover:bg-nb-gray-900/50"; } const handleClick = () => { context.onChange(value); onClick?.(); }; return ( ); } function Content({ children, value, className, visible, }: Readonly<{ children: React.ReactNode; value: string; className?: string; visible?: boolean; }>) { const context = useTabContext(); const isVisible = visible ?? value === context.value; if (!isVisible) return null; return (
{children}
); } SegmentedTabs.List = List; SegmentedTabs.Trigger = Trigger; SegmentedTabs.Content = Content; export { SegmentedTabs };