npm install @emmgfx/activity-tabsHeadless tabs that keep panel state alive when switching.
Panel content stays mounted and alive when switching tabs — no state reset, no re-render.
Pass className and activeClassName to every component. Zero bundled styles.
No opinions on markup or layout. Compose tabs however your design needs.
Fully typed components and a useActiveTab hook for programmatic control.
Switch tabs and increment the counter — switch back and the count is still there.
Wrap the primitives with your own styles once, reuse everywhere.
useActiveTabUse the hook in any component inside Tabs to read or set the active tab, like these Prev / Next controls.
Pass activeTab and onActiveTabChange to keep the active tab in your own state. Here it is synced with the URL hash, so every tab has its own link.
state outside Tabs: #overview<Tabs />| Prop | Type | Default | Description |
|---|---|---|---|
initialActiveTab | string | number | undefined | Tab ID to activate on first render. |
activeTab | string | number | undefined | Active tab ID when you hold the state yourself (controlled). |
onActiveTabChange | (tabId) => void | undefined | Called with the new tab ID whenever the active tab changes. |
className | string | undefined | Class applied to the wrapper div. |
children | ReactNode | — | Should contain TabsList and TabsPanels. |
...props | div attributes | — | id, ref, style, data-*, aria-*… passed to the wrapper div. |
<TabsTab />| Prop | Type | Default | Description |
|---|---|---|---|
tabId | string | number | — | Unique ID matching the TabsPanel to activate. |
className | string | undefined | Class applied when the tab is inactive. |
activeClassName | string | undefined | Class applied when the tab is active. |
onClick | MouseEventHandler | undefined | Runs before the tab is activated. Call event.preventDefault() to keep the current tab. |
children | ReactNode | — | Tab label content. |
...props | button attributes | — | id, ref, style, data-*, aria-*… passed to the button. |
<TabsPanel />| Prop | Type | Default | Description |
|---|---|---|---|
tabId | string | number | — | ID of the tab that reveals this panel. |
className | string | undefined | Class applied to the panel wrapper. |
children | ReactNode | — | Panel content — stays mounted when inactive. |
...props | div attributes | — | id, ref, style, data-*, aria-*… passed to the panel div. |