Switching views of the same record: controlled value/onChange, the tablist role and arrow keys between tabs.
value is controlled from outside, so the caller keeps it in the URL. The pattern:const [params, setParams] = useSearchParams();
const view = params.get("view") ?? "overview";
<IngotTabs
items={ITEMS}
value={view}
onChange={(key) => setParams({ view: key }, { replace: true })}
>items: IngotTabItem[] — The views: a key, a translated label and an optional record count.value: string — Key of the active view. Controlled from outside — typically the caller's URL.onChange: (key: string) => void — Switches the view. Does not change the page's scroll position.children: ReactNode — Content of the active view — rendered as a tabpanel tied to the active tab.label: string — Translated aria-label of the tab list.testId: string — data-testid of the tablist; a tab gets `${testId}-tab-${key}`.