fix(ui): Tabs is an ARIA tab list with roving focus and a wired panel
The rail was a row of aria-pressed toggles: every tab a Tab stop, no arrows, nothing tying a tab to its content. tablist/tab/aria-selected, one Tab stop, arrows on either axis, Home/End, and useTabPanel for aria-controls/labelledby.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { useId } from "react";
|
||||
|
||||
// The id half of ui/Tabs (its own file so Tabs.tsx exports only components — Fast Refresh).
|
||||
|
||||
export const tabId = (base: string, id: string) => `${base}tab-${id}`;
|
||||
export const panelId = (base: string) => `${base}panel`;
|
||||
|
||||
/** The ids that tie a `Tabs` to the panel it switches: pass `idBase` to the `Tabs` and spread
|
||||
* `panelProps(active)` on the element that shows the selected tab's content. Takes no argument, so
|
||||
* it can sit above a page's loading / error returns while the active tab is only known below. */
|
||||
export function useTabPanel() {
|
||||
const base = useId();
|
||||
return {
|
||||
idBase: base,
|
||||
panelProps: (active: string) => ({
|
||||
id: panelId(base),
|
||||
role: "tabpanel" as const,
|
||||
"aria-labelledby": tabId(base, active),
|
||||
}),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user