Tabs
Introduction
The Tabs component provides a flexible, accessible, and highly customizable tabbed navigation interface for organizing content into separate views. It supports multiple visual variants, sizes, icons, controlled and uncontrolled usage, vertical orientation, event triggers (click/hover), and can be composed with either an items array or children panels. Common use cases include dashboards, user profiles, product details, analytics, and more.
Import
ts
import { Tabs } from '@odyssee/components';
// Tabs.Panel is available as a static property for flexible composition1
2
2
LiveCodeEditor examples
Basic Tabs
Code Éditable
Résultat
Variants
Code Éditable
Résultat
Sizes
Code Éditable
Résultat
Tabs with Icons
Code Éditable
Résultat
Controlled Tabs
Code Éditable
Résultat
Event Types (Click & Hover)
Code Éditable
Résultat
Use Case: User Profile Sections
Code Éditable
Résultat
Props
Tabs
| Prop | Type | Default | Description |
|---|---|---|---|
items | Tabs.Item[] | — | Array of tab items (see below for structure). |
children | HTMLElement | HTMLElement[] | — | Custom children panels (alternative to items). |
activeTab | string | Signal<string> | — | Controlled active tab ID (or Pulse signal). |
variant | "underline" | "pills" | "enclosed" | "vertical" | "underline" | Visual style of the tabs. |
eventType | "click" | "hover" | "click" | Event trigger for tab activation. |
bordered | boolean | true | Show border under tabs (underline/enclosed variants). |
fullWidth | boolean | false | Tabs take full width of container. |
size | "sm" | "md" | "lg" | "md" | Size of tab labels. |
tablistClassName | string | — | Custom class for the tablist container. |
contentClassName | string | — | Custom class for the content panel container. |
onChange | (tabId: string, prevTabId: string) => void | — | Callback fired when the active tab changes. |
className | string | — | Additional CSS classes for the root element. |
id | string | auto-generated | ID for the tabs component. |
| ...rest | BaseComponentProps | — | Any other base props supported by Odyssee components. |
Tabs.Item
| Prop | Type | Description |
|---|---|---|
id | string | Unique identifier for the tab. |
label | string | HTMLElement | Tab label (text or custom element). |
content | string | HTMLElement | HTMLElement[] | Content for the tab panel. |
icon | string | HTMLElement | Icon displayed next to the label. |
disabled | boolean | Disables the tab. |
badge | string | number | Badge displayed next to the label. |
Tabs.Panel
| Prop | Type | Description |
|---|---|---|
id | string | Unique identifier for the panel. |
label | string | HTMLElement | Tab label for the panel. |
children | string | HTMLElement | HTMLElement[] | Content for the panel. |
icon | string | HTMLElement | Icon displayed next to the label. |
disabled | boolean | Disables the tab. |
badge | string | number | Badge displayed next to the label. |
Implementation notes
- The component supports both array-based (
items) and children-based (Tabs.Panel) composition. - Controlled usage is supported via the
activeTabprop (string or Pulse signal). - Four visual variants:
underline,pills,enclosed, andvertical. - Tabs can be activated by click or hover (
eventType). - Icons and badges are supported for tab labels.
- Disabled tabs are skipped in navigation and visually indicated.
- Designed for both light and dark themes.
- All tab panels are rendered, but only the active panel is visible.
Accessibility
- All tab buttons use proper ARIA roles (
role="tab",aria-selected,aria-controls). - Tab panels use
role="tabpanel"and are linked to their tab viaaria-labelledby. - Keyboard navigation is supported (Tab, Arrow keys).
- Disabled tabs are not focusable.
- Focus and active states are clearly styled for usability.
- Supports vertical orientation with correct ARIA attributes.
Best practices
- Use controlled mode (
activeTabas signal +onChange) for full synchronization with your app state. - Choose the appropriate variant and size for your layout and design system.
- Use icons and badges to enhance tab clarity and highlight important sections.
- Prefer vertical tabs for sidebar navigation or dense layouts.
- Ensure all tab labels are clear and concise for accessibility.
- Avoid excessive numbers of tabs; group related content when possible.