Tabs
A set of layered sections of content—known as tab panels—that are displayed one at a time.
Account
Make changes to your account here. Click save when you're done.
Password
Change your password here. After saving, you'll be logged out.
<Tabs defaultValue="account" className="w-[400px]">
<TabsList className="grid w-full grid-cols-2">
<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="space-y-2">
<div class="space-y-1">
<Label for="name">Name</Label>
<Input id="name" className="w-full" defaultValue="Pedro Duarte" />
</div>
<div class="space-y-1">
<Label for="username">Username</Label>
<Input id="username" className="w-full" defaultValue="@peduarte" />
</div>
</CardContent>
<CardFooter>
<Button>Save changes</Button>
</CardFooter>
</Card>
</TabsContent>
<TabsContent value="password">
<Card>
<CardHeader>
<CardTitle>Password</CardTitle>
<CardDescription>
Change your password here. After saving, you'll be logged out.
</CardDescription>
</CardHeader>
<CardContent className="space-y-2">
<div class="space-y-1">
<Label for="current">Current password</Label>
<Input id="current" className="w-full" type="password" />
</div>
<div class="space-y-1">
<Label for="new">New password</Label>
<Input id="new" className="w-full" type="password" />
</div>
</CardContent>
<CardFooter>
<Button>Save password</Button>
</CardFooter>
</Card>
</TabsContent>
</Tabs>
Installation
uvx --from basic-components components add tabs
pipx run --spec basic-components components add tabs
pip install basic-components && components add tabs
- Copy Tabs components below to your local environment
- Place them in the components/ui/tabs directory in your project
- Configure your jinja environment for JinjaX
- Add the cn() helper function to your global jinja environment
Usage
<Tabs defaultValue="account" className="w-[400px]">
<TabsList className="grid w-full grid-cols-2">
<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="space-y-2">
<div class="space-y-1">
<Label for="name">Name</Label>
<Input id="name" className="w-full" defaultValue="Pedro Duarte" />
</div>
<div class="space-y-1">
<Label for="username">Username</Label>
<Input id="username" className="w-full" defaultValue="@peduarte" />
</div>
</CardContent>
<CardFooter>
<Button>Save changes</Button>
</CardFooter>
</Card>
</TabsContent>
<TabsContent value="password">
<Card>
<CardHeader>
<CardTitle>Password</CardTitle>
<CardDescription>
Change your password here. After saving, you'll be logged out.
</CardDescription>
</CardHeader>
<CardContent className="space-y-2">
<div class="space-y-1">
<Label for="current">Current password</Label>
<Input id="current" className="w-full" type="password" />
</div>
<div class="space-y-1">
<Label for="new">New password</Label>
<Input id="new" className="w-full" type="password" />
</div>
</CardContent>
<CardFooter>
<Button>Save password</Button>
</CardFooter>
</Card>
</TabsContent>
</Tabs>
Attributes
Component | Prop | Type | Default | Description |
---|---|---|---|---|
Tabs | defaultValue |
String | `` | The default tab to display. |
TableHead | id |
String | `` | Id of the tab panel. |
TableHead | value |
String | `` | Name of the tab panel. |
TableHead | id |
String | `` | Id of the tab panel to select. |
TableHead | value |
String | `` | Name of the tab panel to select. |
Code
{# Tabs.jinja #}
{#def
defaultValue: str = "",
className: str = ""
#}
<div
x-data="{ activeTab: '{{ defaultValue }}' }"
class="{{ className }}"
{{ attrs.render() }}
>
{{ content }}
</div>
{# TabsContent.jinja #}
{#def
value: str = "",
className: str = "",
id: str = ""
#}
{% set id = id or 'tabpanel-' + value %}
<div
id="{{ id }}"
role="tabpanel"
x-show="activeTab === '{{ value }}'"
x-cloak
aria-labelledby="tab-{{ value }}"
class="{{ cn(
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
className
) }}"
{{ attrs.render() }}
>
{{ content }}
</div>
{# TabsList.jinja #}
{#def
className: str = ""
#}
<div
role="tablist"
class="{{ cn(
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
className
) }}"
{{ attrs.render() }}
>
{{ content }}
</div>
{# TabsTrigger.jinja #}
{#def
value: str = "",
className: str = "",
id: str = ""
#}
{% set id = id or 'tab-' + value %}
<button
type="button"
id="{{ id }}"
role="tab"
x-on:click="activeTab = '{{ value }}'"
:class="activeTab === '{{ value }}' ? '{{ cn('bg-background text-foreground shadow-sm') }}' : ''"
:aria-selected="(activeTab === '{{ value }}').toString()"
aria-controls="tabpanel-{{ value }}"
class="{{ cn(
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
className
) }}"
{{ attrs.render() }}
>
{{ content }}
</button>