/** * Tabs - Horizontal tab navigation component. * * Renders a row of tab buttons and the content panel for * the active tab. Supports controlled and uncontrolled modes. * Keyboard accessible (arrow keys navigate between tabs). */ import { useState, useRef, useCallback } from "react"; import PropTypes from "prop-types"; function Tabs({ tabs, activeTab: controlledActive, onChange, className = "", }) { const [internalActive, setInternalActive] = useState( tabs.length > 0 ? tabs[0].id : null, ); const tabListRef = useRef(null); const isControlled = controlledActive !== undefined; const activeId = isControlled ? controlledActive : internalActive; const handleTabClick = useCallback( (tabId) => { if (!isControlled) { setInternalActive(tabId); } if (onChange) { onChange(tabId); } }, [isControlled, onChange], ); const handleKeyDown = useCallback( (event) => { const enabledTabs = tabs.filter((t) => !t.disabled); const currentIndex = enabledTabs.findIndex((t) => t.id === activeId); let nextIndex = currentIndex; if (event.key === "ArrowRight") { nextIndex = (currentIndex + 1) % enabledTabs.length; } else if (event.key === "ArrowLeft") { nextIndex = (currentIndex - 1 + enabledTabs.length) % enabledTabs.length; } else if (event.key === "Home") { nextIndex = 0; } else if (event.key === "End") { nextIndex = enabledTabs.length - 1; } else { return; } event.preventDefault(); const nextTab = enabledTabs[nextIndex]; handleTabClick(nextTab.id); // Focus the next tab button const buttons = tabListRef.current?.querySelectorAll('[role="tab"]'); const targetIndex = tabs.findIndex((t) => t.id === nextTab.id); buttons?.[targetIndex]?.focus(); }, [tabs, activeId, handleTabClick], ); const activeTabData = tabs.find((t) => t.id === activeId); return (