Headless Core — Tabs
Powers Tabs internally.
import { createTabs } from '@andersseen/headless-components/tabs';
const tabs = createTabs({ defaultValue: 'tab-1', orientation: 'horizontal', onValueChange: tabId => console.log('Selected:', tabId),});
tabs.actions.selectTab('tab-2');Config
Section titled “Config”| Option | Type | Default | Notes |
|---|---|---|---|
defaultValue | string | — | Initially selected tab id. |
onValueChange | (tabId: string) => void | — | |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Swaps which arrow keys move focus. |
activationMode | 'automatic' | 'manual' | 'automatic' | Automatic: arrow-focusing a tab selects it immediately. |
disabled | boolean | false |
selectedTab: string | null, orientation, activationMode, disabled.
Actions & queries
Section titled “Actions & queries”| Member | Signature |
|---|---|
actions.selectTab(id) | (tabId: string) => void |
actions.setDisabled(v) | (disabled: boolean) => void |
actions.setOrientation(v) | (orientation: 'horizontal' | 'vertical') => void |
actions.setActivationMode(v) | (mode: 'automatic' | 'manual') => void |
queries.isSelected(id) | (tabId: string) => boolean |
queries.getSelectedTab() | () => string | null |
Prop-getters & handler
Section titled “Prop-getters & handler”| Getter | Returns |
|---|---|
getContainerProps() | data-orientation |
getListProps() | role: 'tablist', aria-orientation |
getTriggerProps(id) | role: 'tab', aria-selected, aria-controls, aria-disabled, tabindex (roving — 0 only for the selected tab), id, data-state, data-disabled, data-orientation |
getContentProps(id) | role: 'tabpanel', aria-labelledby, tabindex: 0, id, hidden, data-state |
handleTriggerKeyDown(event, currentTabId, allTabIds) — needs the full id list
every call, since the headless core doesn’t track registration order itself.
ArrowRight/ArrowLeft (or ArrowDown/ArrowUp when
orientation: 'vertical') move focus with wraparound; Home/End jump to the
first/last. In automatic mode, moving focus also calls selectTab — actually
focusing the resulting element is left to the consuming component (no DOM access
here).
Live example
Section titled “Live example”Next steps
Section titled “Next steps”Sidebar and Navbar implement a similar roving-focus keyboard pattern over a registered item list.