SutraUI.Tabs (Sutra UI v0.2.0)

View Source

A tabbed interface component for organizing content into separate views.

Tabs allow users to switch between different views where only one panel is visible at a time. Useful for settings pages, dashboards, or any UI that needs to organize related content without navigation.

Examples

# Basic tabs
<.tabs id="settings-tabs" default_value="account">
  <:tab value="account">Account</:tab>
  <:tab value="password">Password</:tab>
  <:tab value="notifications">Notifications</:tab>
  <:panel value="account">
    <h3>Account Settings</h3>
    <p>Manage your account details here.</p>
  </:panel>
  <:panel value="password">
    <h3>Change Password</h3>
    <.input type="password" name="current" label="Current Password" />
  </:panel>
  <:panel value="notifications">
    <h3>Notification Preferences</h3>
    <.switch name="email_notifications" label="Email notifications" />
  </:panel>
</.tabs>

# With disabled tab
<.tabs id="feature-tabs" default_value="overview">
  <:tab value="overview">Overview</:tab>
  <:tab value="analytics">Analytics</:tab>
  <:tab value="reports" disabled>Reports (Coming Soon)</:tab>
  <:panel value="overview">Overview content...</:panel>
  <:panel value="analytics">Analytics content...</:panel>
  <:panel value="reports">Reports content...</:panel>
</.tabs>

# With icons in tabs
<.tabs id="nav-tabs" default_value="home">
  <:tab value="home">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4 mr-2"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg> Home
  </:tab>
  <:tab value="settings">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4 mr-2"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg> Settings
  </:tab>
  <:panel value="home">Home content</:panel>
  <:panel value="settings">Settings content</:panel>
</.tabs>

Slots

SlotRequiredDescription
tabYesTab trigger buttons
panelYesContent panels (matched by value)

Tab Slot Attributes

AttributeTypeDescription
valuestringRequired. Unique identifier, matches panel
disabledbooleanPrevents tab from being selected

Panel Slot Attributes

AttributeTypeDescription
valuestringRequired. Matches corresponding tab

Keyboard Navigation

KeyAction
ArrowLeftMove to previous tab
ArrowRightMove to next tab
HomeMove to first tab
EndMove to last tab

How It Works

Tab switching is handled entirely client-side using Phoenix.LiveView.JS:

  • No server round-trip for tab changes
  • Instant panel switching
  • Keyboard navigation via colocated hook

The default_value determines which tab is active on initial render. Subsequent tab changes update the DOM directly without re-rendering.

Colocated Hook

The .Tabs hook provides keyboard navigation. Tab click handling uses phx-click with JS commands for immediate feedback.

See JavaScript Hooks for more details.

Accessibility

  • Uses role="tablist" for the tab container
  • Uses role="tab" for each tab trigger
  • Uses role="tabpanel" for each content panel
  • aria-selected indicates active tab
  • aria-controls links tab to its panel
  • aria-labelledby links panel to its tab
  • tabindex management for roving focus
  • Disabled tabs use disabled attribute

Panel Focus

Tab panels have tabindex="0" allowing keyboard users to tab into panel content after selecting a tab.

Summary

Functions

Renders a tabs component.

Functions

tabs(assigns)

Renders a tabs component.

Attributes

  • default_value (:string) (required) - The value of the initially active tab.
  • class (:string) - Additional CSS classes. Defaults to nil.
  • id (:string) (required) - Unique identifier for the tabs component.
  • Global attributes are accepted. Additional HTML attributes.

Slots

  • tab (required) - Tab triggers. Accepts attributes:
    • value (:string) (required) - Unique identifier for the tab.
    • disabled (:boolean) - Whether the tab is disabled.
  • panel (required) - Tab panels. Accepts attributes:
    • value (:string) (required) - Value matching the corresponding tab.