Tablist
RequiredNamed container coordinating arrow-key navigation.
[role=tablist]Fields & selection
A controlled, keyboard-navigable tablist for switching between peer panels in place.
TabsTabsPropsTabuseTabPanelPropsConfigure the production component, inspect it at responsive widths, copy synchronized JSX, and share the exact state from one workspace.
This JSX stays synchronized with the controls and uses only public package APIs.
'use client';
import { useState } from 'react';
import { Tabs, useTabPanelProps } from '@ai-created/ui';
const tabs = [
{ key: 'overview', label: 'Overview' },
{ key: 'activity', label: 'Activity' },
{ key: 'settings', label: 'Settings' },
];
export function Example() {
const [active, setActive] = useState("overview");
const panelProps = useTabPanelProps(active, active, 'project-tabs');
return (
<>
<Tabs
id="project-tabs"
tabs={tabs}
active={active}
onChange={setActive}
label="Project sections"
/>
<div {...panelProps}>Content for {active}</div>
</>
);
}
import { Tabs, useTabPanelProps, type Tab } from '@ai-created/ui';Client boundary
'use client' to the file that owns this interactive state.Replace the version placeholder with the release tag your product has reviewed.
npm install --install-links "git+https://github.com/TheMarco/ai-created-ui.git#vX.Y.Z"@import '@ai-created/ui/styles/tokens.css';
@tailwind base;
@tailwind components;
@tailwind utilities;module.exports = {
presets: [require('@ai-created/ui/tailwind-preset')],
content: [
'./src/**/*.{js,ts,jsx,tsx,mdx}',
'./node_modules/@ai-created/ui/src/**/*.{js,ts,jsx,tsx}',
],
};Named regions define what belongs to the component, what remains optional, and where semantic responsibility lives.
Named container coordinating arrow-key navigation.
[role=tablist]Roving-focus button with label and optional icon.
button[role=tab]2px accent line along the active tab.
Consumer-rendered view associated through useTabPanelProps.
[role=tabpanel]The Figma-equivalent asset model, auto-layout, resizing, properties, slots, content bounds, localization, and governance contract.
Asset kind
component
Design library name
Components/Navigation/Tabs
Maturity
stable
Last reviewed
2026-08-29
Canvas applicability
Publish a component set with active-tab variants and nested tab instances.
| Property | Type | Default | Code mapping | Options or notes |
|---|---|---|---|---|
| Active previewRequired | variant | overview | Finite starter keys; custom tabs edit each nested Selected state | overview, activity, settings |
| State preview | variant | default | Keyboard focus on the active starter tab | default, focus-visible |
| TabsRequired | slot | None | tabs; attached Tab instances | No additional constraint |
| Label (nested Tab) | text | Overview | Tab.label | No additional constraint |
| Show icon (nested Tab) | boolean | false | Boolean(Tab.icon) | No additional constraint |
| Icon (nested Tab) | instance-swap | None | Tab.icon; source icon example is 24px, while consumer code owns dimensions | No additional constraint |
Keyboard navigation container.
<div role="tablist">Repeatable label, optional icon, and indicator.
Tab data itemConsumer-owned related content panel.
useTabPanelPropsOverflow: Use page navigation or another information architecture for larger sets.
All labels should remain visible without horizontal ambiguity.
Overflow: Do not truncate.
Short labels improve comparison and keyboard predictability.
Translatable: Tab list label, Tab labels
Intrinsic single row owned by its container.
Parent-selected narrow breakpoint
Accountable owner
Design systems navigation primitive owner
Canonical source: src/components/Tabs.tsx
These measurements and semantic tokens define the supported visual contract. Local overrides should preserve the same hierarchy and interaction cues.
Tab padding
20px horizontal / 10px vertical
Tab gap
2.5px
Icon/label gap
10px
Active indicator
2px high
Top radius
6px
--color-highlightActive tab background.
--color-accentActive indicator.
--color-text / --color-text2 / --color-text3Active, hover, and inactive hierarchy.
--motion-fastColor transition.
A component is not complete until its passive, interactive, disabled, and exceptional states remain understandable in both themes.
Semantics, accessible naming, keyboard behavior, focus and announcements are implementation requirements, not optional documentation.
Use the public package API and preserve the controlled-state, native-attribute, and ref contracts described below.
import { Tabs, useTabPanelProps, type Tab } from '@ai-created/ui';Client Component required
const panel = useTabPanelProps("overview", active, tabsId);
<Tabs id={tabsId} tabs={tabs} active={active} onChange={setActive} label="Project views" />
<div {...panel}>Overview content</div>These props and helpers are compatibility contracts. Changes require migration guidance and release notes.
| Prop | Type | Default | Contract |
|---|---|---|---|
| tabs | Tab<T>[] | required | Keys, labels, and optional icons. |
| active | T | required | Active tab key. |
| onChange | (key: T) => void | required | Called when tab changes. |
| label | string | required | Tablist accessible label. |
| id | string | generated id | Stable group id for panels. |
These rules keep the component recognizable across products without preventing deliberate composition.
The component should be verified as rendered UI, an interaction model, an accessibility surface, and a theme-aware visual artifact.