import classNames from 'classnames'; import type { ReactNode } from 'react'; import { memo, useCallback, useEffect, useRef } from 'react'; import { Icon } from '../Icon'; import type { RadioDropdownProps } from '../RadioDropdown'; import { RadioDropdown } from '../RadioDropdown'; import { HStack } from '../Stacks'; export type TabItem = | { value: string; label: ReactNode; } | { value: string; options: Omit; }; interface Props { label: string; value?: string; onChangeValue: (value: string) => void; tabs: TabItem[]; tabListClassName?: string; className?: string; children: ReactNode; addBorders?: boolean; } export function Tabs({ value, onChangeValue, label, children, tabs, className, tabListClassName, addBorders, }: Props) { const ref = useRef(null); const handleTabChange = useCallback( (value: string) => { const tabs = ref.current?.querySelectorAll(`[data-tab]`); for (const tab of tabs ?? []) { const v = tab.getAttribute('data-tab'); if (v === value) { tab.setAttribute('tabindex', '-1'); tab.setAttribute('data-state', 'active'); tab.setAttribute('aria-hidden', 'false'); tab.style.display = 'block'; } else { tab.setAttribute('data-state', 'inactive'); tab.setAttribute('aria-hidden', 'true'); tab.style.display = 'none'; } } onChangeValue(value); }, [onChangeValue], ); useEffect(() => { if (value === undefined) return; handleTabChange(value); }, [handleTabChange, value]); return (
{tabs.map((t) => { const isActive = t.value === value; const btnClassName = classNames( 'h-full flex items-center rounded', '!px-2 ml-[1px]', addBorders && 'border', isActive ? 'text-text' : 'text-text-subtle hover:text-text', isActive && addBorders ? 'border-border-subtle' : 'border-transparent', ); if ('options' in t) { const option = t.options.items.find( (i) => 'value' in i && i.value === t.options?.value, ); return ( ); } else { return ( ); } })}
{children}
); } interface TabContentProps { value: string; children: ReactNode; className?: string; } export const TabContent = memo(function TabContent({ value, children, className, }: TabContentProps) { return (
{children}
); });