Tabs
Organize content into separate views where only one is visible at a time.
Import
Section titled “Import”import { Tabs } from 'asterui'Examples
Section titled “Examples”Basic Usage
Simple tabs with content switching handled automatically.
Content of Tab 1
import { Tabs, Typography } from 'asterui'
function App() {
return (
<Tabs>
<Tabs.Panel tab="Tab 1" key="1">
<Typography.Text>Content of Tab 1</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Tab 2" key="2">
<Typography.Text>Content of Tab 2</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Tab 3" key="3">
<Typography.Text>Content of Tab 3</Typography.Text>
</Tabs.Panel>
</Tabs>
)
}
export default App Settings Page
Complete settings page with forms using floating label inputs.
import { Tabs, Space, Input, Button } from 'asterui'
function App() {
return (
<Tabs defaultActiveKey="account" variant="border">
<Tabs.Panel tab="Account" key="account">
<Space direction="vertical" size="md">
<Input floatingLabel="Username" placeholder="john_doe" />
<Input floatingLabel="Email" type="email" placeholder="john@example.com" />
<Button color="primary">Save</Button>
</Space>
</Tabs.Panel>
<Tabs.Panel tab="Security" key="security">
<Space direction="vertical" size="md">
<Input floatingLabel="Current Password" type="password" />
<Input floatingLabel="New Password" type="password" />
<Button color="primary">Update</Button>
</Space>
</Tabs.Panel>
</Tabs>
)
}
export default App Boxed Variant
Tabs with enclosed box styling.
Home content
import { Tabs, Typography } from 'asterui'
function App() {
return (
<Tabs variant="box">
<Tabs.Panel tab="Home" key="home">
<Typography.Text>Home content</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Profile" key="profile">
<Typography.Text>Profile content</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Settings" key="settings">
<Typography.Text>Settings content</Typography.Text>
</Tabs.Panel>
</Tabs>
)
}
export default App Lifted Variant
Tabs with 3D lifted appearance.
Overview content
import { Tabs, Typography } from 'asterui'
function App() {
return (
<Tabs variant="lift">
<Tabs.Panel tab="Overview" key="1">
<Typography.Text>Overview content</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Reports" key="2">
<Typography.Text>Reports content</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Analytics" key="3">
<Typography.Text>Analytics content</Typography.Text>
</Tabs.Panel>
</Tabs>
)
}
export default App Different Sizes
Tabs in various sizes using Space and Typography components.
Small
Small tabs content
Large
Large tabs content
import { Tabs, Space, Typography } from 'asterui'
function App() {
return (
<Space direction="vertical" size="md">
<div>
<Typography.Text strong>Small</Typography.Text>
<Tabs size="sm">
<Tabs.Panel tab="Tab 1" key="1"><Typography.Text>Small tabs content</Typography.Text></Tabs.Panel>
<Tabs.Panel tab="Tab 2" key="2"><Typography.Text>Content 2</Typography.Text></Tabs.Panel>
</Tabs>
</div>
<div>
<Typography.Text strong>Large</Typography.Text>
<Tabs size="lg">
<Tabs.Panel tab="Tab 1" key="1"><Typography.Text>Large tabs content</Typography.Text></Tabs.Panel>
<Tabs.Panel tab="Tab 2" key="2"><Typography.Text>Content 2</Typography.Text></Tabs.Panel>
</Tabs>
</div>
</Space>
)
}
export default App Disabled Tab
Disable specific tabs.
Active content
import { Tabs, Typography } from 'asterui'
function App() {
return (
<Tabs>
<Tabs.Panel tab="Active" key="1">
<Typography.Text>Active content</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Disabled" key="2" disabled>
<Typography.Text>Cannot see this</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Also Active" key="3">
<Typography.Text>Active content</Typography.Text>
</Tabs.Panel>
</Tabs>
)
}
export default App Data-Driven Pattern
Use items prop for data-driven tabs with icons.
Home content
import { Tabs, notification, Typography } from 'asterui'
import { HomeIcon, UserIcon, Cog6ToothIcon } from '@aster-ui/icons'
import { useState } from 'react'
function App() {
const [activeKey, setActiveKey] = useState('home')
const items = [
{ key: 'home', label: 'Home', icon: <HomeIcon size="sm" />, children: <Typography.Text>Home content</Typography.Text> },
{ key: 'profile', label: 'Profile', icon: <UserIcon size="sm" />, children: <Typography.Text>Profile content</Typography.Text> },
{ key: 'settings', label: 'Settings', icon: <Cog6ToothIcon size="sm" />, children: <Typography.Text>Settings content</Typography.Text> },
]
return (
<Tabs
items={items}
activeKey={activeKey}
onChange={(key) => {
setActiveKey(key)
notification.info({ message: `Switched to ${key}` })
}}
variant="border"
/>
)
}
export default App Bottom Position
Tabs positioned below the content.
Content appears above the tabs
import { Tabs, Typography } from 'asterui'
function App() {
return (
<Tabs position="bottom" variant="border">
<Tabs.Panel tab="Tab 1" key="1">
<Typography.Text>Content appears above the tabs</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Tab 2" key="2">
<Typography.Text>Second tab content</Typography.Text>
</Tabs.Panel>
<Tabs.Panel tab="Tab 3" key="3">
<Typography.Text>Third tab content</Typography.Text>
</Tabs.Panel>
</Tabs>
)
}
export default App | Property | Description | Type | Default |
|---|---|---|---|
children | Tab panels (compound pattern) | React.ReactNode | - |
items | Tab items (data-driven pattern) | TabItem[] | - |
activeKey | Current active tab key (controlled) | string | - |
defaultActiveKey | Default active tab key (uncontrolled) | string | - |
onChange | Callback when tab changes | (key: string) => void | - |
variant | Visual style variant | 'box' | 'border' | 'lift' | - |
size | Tab size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | - |
position | Tab position relative to content | 'top' | 'bottom' | 'top' |
data-testid | Test ID prefix for child elements | string | - |
className | Additional CSS classes | string | - |
TabItem (for items prop)
Section titled “TabItem (for items prop)”| Property | Description | Type | Default |
|---|---|---|---|
key | Unique identifier | string | - |
label | Tab button label | React.ReactNode | - |
children | Tab panel content | React.ReactNode | - |
disabled | Disable the tab | boolean | false |
icon | Tab icon | React.ReactNode | - |
Tabs.Panel (compound pattern)
Section titled “Tabs.Panel (compound pattern)”| Property | Description | Type | Default |
|---|---|---|---|
key | Unique identifier for the tab (React key prop) | string | - |
tab | Tab button label | React.ReactNode | - |
disabled | Disable the tab | boolean | false |
icon | Tab icon | React.ReactNode | - |
children | Tab panel content | React.ReactNode | - |
Accessibility
Section titled “Accessibility”- Uses proper ARIA roles:
tablist,tab, andtabpanel - Keyboard navigation: Arrow keys move between tabs, Tab key moves focus into the panel
- Active tab is indicated with
aria-selected="true" - Disabled tabs use
aria-disabledfor proper communication - Tab panels use
aria-labelledbyto associate with their tab
Usage Tips
Section titled “Usage Tips”- Use
activeKeyfor controlled tabs,defaultActiveKeyfor uncontrolled - Use
itemsprop for data-driven tabs,Tabs.Panelfor compound pattern - Use
position="bottom"to place tabs below content