Tabs
A set of layered panels of content, each associated with a tab trigger that displays one panel at a time.
The Tabs component organizes content into multiple panels, each associated with a tab trigger. It supports a context-based API for automatic state management, controlled/uncontrolled state, and is styled with NativeWind for consistent cross-platform appearance.
Preview
Installation
npx novaui-cli add tabsImport
import { Tabs, TabsList, TabsTrigger, TabsContent } from 'novaui-components'Basic Usage
The Tabs component is a compound component with four parts:
Tabs- Root container with tab state management (context-based)TabsList- Container for the tab triggersTabsTrigger- Individual tab button with avaluepropTabsContent- Panel that shows when itsvaluematches the active tab
import { Tabs, TabsList, TabsTrigger, TabsContent } from 'novaui-components'
import { Text } from 'react-native'
export function BasicTabs() {
return (
<Tabs defaultValue="account">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
<Text>Make changes to your account here. Update your display name and email address.</Text>
</TabsContent>
<TabsContent value="password">
<Text>Change your password here. Use a strong, unique password.</Text>
</TabsContent>
</Tabs>
)
}Three Tabs
Tabs with three panels:
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="settings">Settings</TabsTrigger>
</TabsList>
<TabsContent value="overview">
<Text>Overview of your project with key metrics and recent activity.</Text>
</TabsContent>
<TabsContent value="analytics">
<Text>Analytics data showing trends, charts, and performance metrics.</Text>
</TabsContent>
<TabsContent value="settings">
<Text>Configure your project settings and preferences.</Text>
</TabsContent>
</Tabs>With Cards
Combine tabs with cards for richer content panels:
import { Tabs, TabsList, TabsTrigger, TabsContent } from 'novaui-components'
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from 'novaui-components'
import { View, Text, TextInput } from 'react-native'
import { Button } from 'novaui-components'
export function TabsWithCards() {
return (
<Tabs defaultValue="account">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
<Card>
<CardHeader>
<CardTitle>Account</CardTitle>
<CardDescription>
Make changes to your account here. Click save when you're done.
</CardDescription>
</CardHeader>
<CardContent className="gap-4">
<View className="gap-2">
<Text className="text-sm font-medium">Name</Text>
<TextInput
className="h-10 rounded-md border border-input bg-background px-3"
defaultValue="Pedro Duarte"
/>
</View>
<Button label="Save changes" />
</CardContent>
</Card>
</TabsContent>
<TabsContent value="password">
<Card>
<CardHeader>
<CardTitle>Password</CardTitle>
<CardDescription>
Change your password here. Use a strong, unique password.
</CardDescription>
</CardHeader>
<CardContent className="gap-4">
<View className="gap-2">
<Text className="text-sm font-medium">Current password</Text>
<TextInput
className="h-10 rounded-md border border-input bg-background px-3"
secureTextEntry
/>
</View>
<Button label="Save password" />
</CardContent>
</Card>
</TabsContent>
</Tabs>
)
}Props API
Tabs Props
Extends React.ComponentPropsWithoutRef<typeof View> and includes:
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | string | required | The initially active tab value |
onValueChange | (value: string) => void | - | Callback when the active tab changes |
className | string | - | Additional CSS classes |
TabsList Props
Extends React.ComponentPropsWithoutRef<typeof View>:
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
TabsTrigger Props
Extends React.ComponentPropsWithoutRef<typeof Pressable>:
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | required | The value that identifies this tab |
className | string | - | Additional CSS classes |
TabsContent Props
Extends React.ComponentPropsWithoutRef<typeof View>:
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | required | The value that identifies this content panel |
className | string | - | Additional CSS classes |
Best Practices
-
Meaningful labels: Tab labels should be short and descriptive — one or two words maximum
-
Default selection: Always provide a
defaultValueso one tab is active on mount -
Consistent content depth: Keep content panels at similar depth/complexity to avoid jarring switches
-
Don't overload: If you have more than 5 tabs, consider a different navigation pattern
-
Pair with cards: Wrap
TabsContentchildren inCardfor a polished look
Related Components
- Use
CardinsideTabsContentfor structured tab panels - Use
Accordionfor vertically stacked collapsible content - Use
Collapsiblefor a single expand/collapse section