PUI.Tabs
(pui v1.0.0-alpha.32)
Copy Markdown
Accessible tabs for switching between related panels of content.
PUI tabs follow the shadcn/ui visual language while keeping a Phoenix-friendly,
server-renderable API. The component renders correct WAI-ARIA roles and states
on the server, then enhances the experience with the PUI.Tabs hook for arrow
key navigation, roving focus, and optional client-side activation.
Use tabs/1 with :trigger and :content slots. Triggers and panels are
matched by their shared value.
Basic Usage
<.tabs id="account-tabs" default_value="account">
<:trigger value="account">Account</:trigger>
<:trigger value="password">Password</:trigger>
<:content value="account">
Make changes to your account here.
</:content>
<:content value="password">
Change your password here.
</:content>
</.tabs>Server-Controlled Tabs
Set value from your assigns and push a LiveView event from each trigger when
you want the server to be the source of truth:
<.tabs id="settings-tabs" value={@active_tab} client_controlled={false}>
<:trigger value="profile" phx-click="select_tab" phx-value-tab="profile">
Profile
</:trigger>
<:trigger value="billing" phx-click="select_tab" phx-value-tab="billing">
Billing
</:trigger>
<:content value="profile">Profile settings...</:content>
<:content value="billing">Billing settings...</:content>
</.tabs>Vertical Tabs
<.tabs id="preferences-tabs" default_value="notifications" orientation="vertical">
<:trigger value="notifications">Notifications</:trigger>
<:trigger value="security">Security</:trigger>
<:content value="notifications">Notification preferences...</:content>
<:content value="security">Security preferences...</:content>
</.tabs>Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
id | string | auto-generated | Unique id used to link tabs and panels |
value | string | nil | Active value when the server controls selection |
default_value | string | first enabled trigger | Initial active value for client-controlled tabs |
orientation | string | "horizontal" | "horizontal" or "vertical" |
activation_mode | string | "manual" | "automatic" or "manual" keyboard activation |
client_controlled | boolean | true | Whether the hook updates active state in the browser |
variant | string | "default" | "default", "line", or "unstyled" |
class | string | "" | Additional root classes |
list_class | string | "" | Additional classes for the tab list |
panels_class | string | "" | Additional classes for the panels wrapper |
Trigger Slot Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
value | string | required | Tab value used to match a panel |
id | string | generated | Custom trigger id |
class | string | "" | Additional trigger classes |
disabled | boolean | false | Disables pointer and keyboard activation |
phx-click | any | nil | LiveView event or JS command for server-controlled tabs |
phx-target | any | nil | Optional event target |
phx-value-tab | string | nil | Tab value sent with phx-click |
Content Slot Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
value | string | required | Panel value matched with a trigger |
id | string | generated | Custom panel id |
class | string | "" | Additional panel classes |
Accessibility
- Uses
role="tablist",role="tab", androle="tabpanel" - Supports roving focus with arrow keys,
Home, andEnd - Defaults to manual activation so arrow keys move focus and
Space/Enteractivate - Supports automatic and manual activation modes
- Keeps inactive panels hidden from assistive technology and visual layout
Summary
Functions
Renders an accessible tabs interface with server and client control modes.
Functions
Renders an accessible tabs interface with server and client control modes.
The server renders the active tab state for the initial response, while the
PUI.Tabs hook adds keyboard support and optional browser-managed activation.
Examples
<.tabs id="team-tabs" default_value="members">
<:trigger value="members">Members</:trigger>
<:trigger value="billing">Billing</:trigger>
<:content value="members">Manage team members.</:content>
<:content value="billing">Manage billing details.</:content>
</.tabs>
<.tabs id="live-tabs" value={@active_tab} client_controlled={false}>
<:trigger value="overview" phx-click="select_tab" phx-value-tab="overview">
Overview
</:trigger>
<:trigger value="activity" phx-click="select_tab" phx-value-tab="activity">
Activity
</:trigger>
<:content value="overview">Overview panel.</:content>
<:content value="activity">Activity panel.</:content>
</.tabs>Attributes
id(:string) - Defaults tonil.value(:string) - Defaults tonil.default_value(:string) - Defaults tonil.orientation(:string) - Defaults to"horizontal". Must be one of"horizontal", or"vertical".activation_mode(:string) - Defaults to"manual". Must be one of"automatic", or"manual".client_controlled(:boolean) - Defaults totrue.variant(:string) - Defaults to"default". Must be one of"default","line", or"unstyled".class(:string) - Defaults to"".list_class(:string) - Defaults to"".panels_class(:string) - Defaults to"".- Global attributes are accepted.
Slots
trigger(required) - Accepts attributes:value(:string) (required)id(:string)class(:string)disabled(:boolean)phx-click(:any)phx-target(:any)phx-value-tab(:string)
content(required) - Accepts attributes:value(:string) (required)id(:string)class(:string)