import type { KeyboardEvent, ReactNode } from 'react'; export interface TabItem { value: T; label: string; icon?: ReactNode; content: ReactNode; disabled?: boolean; } export function Tabs({ items, value, onValueChange, label, className = '', keepMounted = true, }: { items: TabItem[]; value: T; onValueChange: (value: T) => void; label: string; className?: string; keepMounted?: boolean; }) { const active = items.find((item) => item.value === value) ?? items.find((item) => !item.disabled) ?? items[0]; const navigate = (event: KeyboardEvent) => { if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) return; const enabled = items.filter((item) => !item.disabled); if (!enabled.length) return; const current = enabled.findIndex((item) => item.value === active.value); const next = event.key === 'Home' ? 0 : event.key === 'End' ? enabled.length - 1 : event.key === 'ArrowRight' ? (current + 1) % enabled.length : (current - 1 + enabled.length) % enabled.length; event.preventDefault(); const item = enabled[next]; onValueChange(item.value); requestAnimationFrame(() => document.getElementById(`${label}-tab-${item.value}`)?.focus()); }; return (
{items.map((item) => ( ))}
{(keepMounted ? items : [active]).map((item) => ( ))}
); }