Tabs
Tabs organize content into multiple sections and allow users to navigate between them.
Built on React Aria Components for full accessibility. Supports multiple variants, colors, sizes, and seamless Next.js router integration.
Installation
import { Tabs } from '@neo/test-components'Usage
HeroUI Tabs use a compound component pattern. Each Tab contains its own Indicator for the sliding animation effect.
Account Settings
Manage your account information and preferences here.
Dynamic
You can render tabs dynamically from an array of items.
Your photo collection
Disabled
Use isDisabled on the Tabs component to disable all tabs, or on individual Tab items.
Individual tab disabled:
This tab is active and can be selected.
All tabs disabled:
Sizes
Three size options: sm,md (default), and lg.
Size: sm
Size: md (default)
Size: lg
Radius
Customize the border radius: none,sm,md,lg, or full.
Radius: none
Radius: sm
Radius: md
Radius: lg
Radius: full
Colors
Six color options that style the indicator and selected tab text.
default
primary
secondary
success
warning
danger
Variants
Four visual variants: solid (default),bordered,light, andunderlined.
solid
bordered
light
underlined
Underlined with Colors
The underlined variant works great with color options for navigation-style tabs.
default
primary
success
warning
danger
With Icons
Add icons alongside tab labels for better visual context.
Your photo gallery
Controlled
Use selectedKey andonSelectionChange for controlled tab selection.
photosPhotos panel content
Vertical
Set orientation="vertical" for sidebar-style navigation.
Vertical Solid:
Profile Settings
Update your profile information and avatar.
Vertical Underlined:
Overview content
Full Width
Use fullWidth to make tabs expand to fill the container.
First panel
Links (Next.js Router)
Tabs can be rendered as links with the href prop. Sync with Next.js router using selectedKey.
'use client'
import { useRouter, usePathname } from 'next/navigation'
import { Tabs } from '@neo/test-components'
export function NavigationTabs() {
const router = useRouter()
const pathname = usePathname()
return (
<Tabs
variant="underlined"
selectedKey={pathname}
onSelectionChange={(key) => router.push(key as string)}
>
<Tabs.ListContainer>
<Tabs.List aria-label="Navigation">
<Tabs.Tab id="/dashboard" href="/dashboard">
Dashboard
<Tabs.Indicator />
</Tabs.Tab>
<Tabs.Tab id="/settings" href="/settings">
Settings
<Tabs.Indicator />
</Tabs.Tab>
</Tabs.List>
</Tabs.ListContainer>
</Tabs>
)
}Custom Styles
Customize tabs with Tailwind CSS classes via the className andclassNames props.
Custom photos panel
Disable Animation
Use disableAnimation ordisableCursorAnimation to turn off the indicator animation.
Slots
Customize specific parts of the Tabs component using CSS classes targeting these slots:
.tabs- Root container.tabs__list-container- Tab list wrapper.tabs__list- Tab list (contains tabs).tabs__tab- Individual tab button.tabs__indicator- Animated selection indicator.tabs__panel- Tab panel content
Data Attributes
Tab elements expose these data attributes for styling:
[data-selected]- When tab is selected[data-disabled]- When tab is disabled[data-hovered]- When tab is hovered[data-focus-visible]- When tab has keyboard focus[data-pressed]- When tab is being pressed[data-orientation]- "horizontal" or "vertical"
Accessibility
- ✓ Mouse, touch, and keyboard interactions supported
- ✓ Arrow key navigation between tabs
- ✓ Disabled tabs properly announced
- ✓ Follows ARIA tabs pattern with proper roles
- ✓ Tab panels associated with their triggers
- ✓ Focus management for panels without focusable children
API Reference
Tabs Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children* | ReactNode | - | Tab content |
| variant | "solid" | "bordered" | "light" | "underlined" | "solid" | Visual style variant |
| color | "default" | "primary" | "secondary" | "success" | "warning" | "danger" | "default" | Color theme |
| size | "sm" | "md" | "lg" | "md" | Tab size |
| radius | "none" | "sm" | "md" | "lg" | "full" | varies | Border radius style |
| orientation | "horizontal" | "vertical" | "horizontal" | Tab layout direction |
| fullWidth | boolean | false | Tabs expand to fill container |
| selectedKey | Key | - | Controlled selected tab |
| defaultSelectedKey | Key | - | Default selected tab |
| isDisabled | boolean | false | Disable all tabs |
| disableAnimation | boolean | false | Disable indicator animation |
| showSeparators | boolean | true | Show dividers (solid variant) |
Tabs Events
| Event | Type | Description |
|---|---|---|
| onSelectionChange | (key: Key) => void | Called when selected tab changes |
Tabs.Tab Props
| Prop | Type | Default | Description |
|---|---|---|---|
| id* | string | - | Unique tab identifier |
| children | ReactNode | - | Tab content (label + indicator) |
| isDisabled | boolean | false | Disable this tab |
| href | string | - | URL for tab as link |
Tabs.Panel Props
| Prop | Type | Default | Description |
|---|---|---|---|
| id* | string | - | Matching tab id |
| children | ReactNode | - | Panel content |