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>