Docs

Cinder UI

Component Library

Static docs for Cinder UI components. Open any component for preview, HEEx usage, generated attributes/slots docs, and a link to the original shadcn/ui reference.

Components: 101

Actions

Actions.button

Server-rendered Open docs

Renders a shadcn-style button.

  <.button type="submit">Save changes</.button>

Actions.button_group

Server-rendered Open docs

Renders a horizontal or vertical button group.

  <.button_group>
  <.button>Deploy</.button>
  <.button variant={:outline}>Rollback</.button>
</.button_group>

Actions.toggle

Server-rendered Open docs

Renders a shadcn-style toggle button.

  <.toggle pressed={true}>Bold</.toggle>

Actions.toggle_group

Server-rendered Open docs

Groups toggles in either single-select or multi-select mode.

  <.toggle_group type={:single}>
  <.toggle>Left</.toggle>
  <.toggle pressed={true}>Center</.toggle>
  <.toggle>Right</.toggle>
</.toggle_group>

Forms

Forms.autocomplete

Progressive Open docs

Renders a filterable autocomplete input backed by a hidden form value.

  <.autocomplete id="team-owner" name="owner" value="levi">
  <:option value="levi" label="Levi Buzolic" description="Engineering" />
  <:option value="mira" label="Mira Chen" description="Design" />
  <:option value="sam" label="Sam Hall" description="Operations" />
</.autocomplete>

Forms.checkbox

Server-rendered Open docs

Renders a checkbox control with optional inline label content.

  <.checkbox id="terms" name="terms">Accept terms</.checkbox>

Forms.field

Server-rendered Open docs

Field wrapper for label, control, description, and errors.

Shown in your profile.

  <.field>
  <:label><.label for="name">Name</.label></:label>
  <.input id="name" name="name" />
  <:description>Shown in your profile.</:description>
</.field>

Forms.field_control

Server-rendered Open docs

Wraps the main interactive control inside a field.

  <.field_control>
  <.input id="workspace_slug" value="cinder-ui" />
</.field_control>

Forms.field_description

Server-rendered Open docs

Helper text shown beneath a field control.

Used in your public workspace URL.

  <.field_description>Used in your public workspace URL.</.field_description>

Forms.field_error

Server-rendered Open docs

Error or validation message shown beneath a field control.

Please use your company domain.

  <.field_error>Please use your company domain.</.field_error>

Forms.field_label

Server-rendered Open docs

Wraps field labels so shared spacing and invalid-state styling remain consistent across controls. Inside field/1, provide it via the :label slot when you need richer label content than a single label/1.

Used across the dashboard.
  <.field_label>
  <.label for="workspace_name">Workspace name</.label>
  <span class="text-muted-foreground text-xs">Used across the dashboard.</span>
</.field_label>

Forms.field_message

Server-rendered Open docs

Neutral status or informational message shown beneath a field control.

Visible immediately after save.

  <.field_message>Visible immediately after save.</.field_message>

Forms.input

Server-rendered Open docs

Renders an input with shadcn classes.

  <.input id="email" type="email" placeholder="name@example.com" />

Forms.input_group

Server-rendered Open docs

Wraps an input and sibling controls (buttons/icons) in a single inline group.

  <.input_group>
  <.input placeholder="Search" />
  <.button variant={:secondary} size={:xs}>Go</.button>
</.input_group>

Forms.input_group_addon

Server-rendered Open docs

Non-interactive text/icon/status segment used inside input_group/1.

  <.input_group>
  <.input_group_addon>
    <.icon name="mail" class="size-4" />
  </.input_group_addon>
  <.input type="email" placeholder="team@example.com" />
</.input_group>

Forms.input_otp

Progressive Open docs

Renders an OTP-style segmented input layout.

  <.input_otp name="verification_code[]" length={6} />

Forms.label

Server-rendered Open docs

Renders a form label.

  <.label for="email">Email</.label>

Forms.native_select

Server-rendered Open docs

Renders a native <select> element with shadcn styles.

  <.native_select name="framework" value="phoenix">
  <:option value="phoenix" label="Phoenix" />
  <:option value="rails" label="Rails" />
  <:option value="laravel" label="Laravel" />
</.native_select>

Forms.number_field

Server-rendered Open docs

Renders a number input with increment and decrement controls.

  <.number_field id="seat-count" name="seats" value={3} min={1} max={10} />

Forms.radio_group

Server-rendered Open docs

Renders a radio group with native radio inputs.

  <.radio_group name="plan" value="pro">
  <:option value="free" label="Free" />
  <:option value="pro" label="Pro" />
</.radio_group>

Forms.select

Progressive Open docs

Renders a custom select with a button trigger and listbox content.

  <.select id="team-plan" name="plan" value="pro">
  <:option value="free" label="Free" />
  <:option value="pro" label="Pro" />
  <:option value="enterprise" label="Enterprise" />
</.select>

Forms.slider

Server-rendered Open docs

Renders a slider using native range input(s).

  <.slider id="volume" name="volume" value={45} min={0} max={100} step={1} />

Forms.switch

Server-rendered Open docs

Renders a switch control with optional label content.

  <.switch id="marketing" checked={true}>Email updates</.switch>

Forms.textarea

Server-rendered Open docs

Renders a textarea with shadcn classes.

  <.textarea id="bio" name="bio" rows={4} />

Layout

Layout.aspect_ratio

Server-rendered Open docs

Maintains a fixed aspect ratio for content.

  <.aspect_ratio ratio="16 / 9">
  <img src="https://picsum.photos/id/191/800/800" class="h-full w-full object-cover" />
</.aspect_ratio>

Layout.card

Server-rendered Open docs

Card container.

Project status
Active deployments across environments.

Production healthy, staging pending one migration.

  <.card>
  <.card_header>
    <.card_title>Project status</.card_title>
    <.card_description>Active deployments across environments.</.card_description>
  </.card_header>
  <.card_content>
    <p class="text-sm">Production healthy, staging pending one migration.</p>
  </.card_content>
</.card>

Layout.card_action

Server-rendered Open docs

Right-aligned card action region for buttons/chips.

Project details
Manage metadata and ownership.
  <.card class="max-w-sm">
  <.card_header>
    <.card_title>Project details</.card_title>
    <.card_action>
      <.button size={:sm} variant={:ghost}>Edit</.button>
    </.card_action>
    <.card_description>Manage metadata and ownership.</.card_description>
  </.card_header>
</.card>

Layout.card_content

Server-rendered Open docs

Card content section.

API key
Use this key for network requests.

Your API key was generated successfully.

  <.card class="max-w-md">
  <.card_header>
    <.card_title>API key</.card_title>
    <.card_description>Use this key for network requests.</.card_description>
  </.card_header>
  <.card_content class="space-y-3">
    <p class="text-sm">Your API key was generated successfully.</p>
    <.input_group>
      <.input value="ck_live_************************" readonly />
      <.button variant={:outline} size={:sm}>Copy</.button>
    </.input_group>
  </.card_content>
</.card>

Layout.card_description

Server-rendered Open docs

Card description text.

Billing setup
Connect your billing details to unlock premium features.
  <.card class="max-w-sm">
  <.card_header>
    <.card_title>Billing setup</.card_title>
    <.card_description>
      Connect your billing details to unlock premium features.
    </.card_description>
  </.card_header>
</.card>

Layout.card_header

Server-rendered Open docs

Card header section.

Billing
Usage and invoices for this workspace.

Current cycle usage: 72%.

  <.card class="max-w-md">
  <.card_header class="border-b">
    <.card_title>Billing</.card_title>
    <.card_action>
      <.button size={:sm} variant={:outline}>Manage</.button>
    </.card_action>
    <.card_description>Usage and invoices for this workspace.</.card_description>
  </.card_header>
  <.card_content>
    <p class="text-sm">Current cycle usage: 72%.</p>
  </.card_content>
</.card>

Layout.card_title

Server-rendered Open docs

Card title text.

Payment method

Visa ending in 4242.

  <.card class="max-w-sm">
  <.card_header>
    <.card_title>Payment method</.card_title>
  </.card_header>
  <.card_content>
    <p class="text-sm">Visa ending in 4242.</p>
  </.card_content>
</.card>

Layout.kbd

Server-rendered Open docs

Keyboard key badge.

⌘K
  <.kbd>⌘K</.kbd>

Layout.kbd_group

Server-rendered Open docs

Groups multiple kbd/1 entries.

P
  <.kbd_group>
  <.kbd></.kbd>
  <.kbd></.kbd>
  <.kbd>P</.kbd>
</.kbd_group>

Layout.panel

Server-rendered Open docs

A bordered surface with card-like styling but no inner padding or gap, for flexible layouts where the caller controls spacing.

Notifications

  • New deployment completed
  • Invite accepted by teammate
  <.panel class="max-w-md">
  <div class="p-4 border-b">
    <h3 class="text-sm font-medium">Notifications</h3>
  </div>
  <ul class="divide-y">
    <li class="px-4 py-3 text-sm">New deployment completed</li>
    <li class="px-4 py-3 text-sm">Invite accepted by teammate</li>
  </ul>
</.panel>

Layout.resizable

Progressive Open docs

Resizable split layout container with optional client-side persistence.

Panel A
Panel B
  <.resizable id="resizable-1">
  <:panel size={35}>
    <div class="rounded-md bg-muted p-2 text-xs">Panel A</div>
  </:panel>
  <:panel size={65}>
    <div class="rounded-md bg-muted/60 p-2 text-xs">Panel B</div>
  </:panel>
</.resizable>

Layout.scroll_area

Server-rendered Open docs

Overflow container that mirrors shadcn scroll-area structure.

Scrollable content
Scrollable content
Scrollable content
Scrollable content
Scrollable content
  <.scroll_area class="h-24 rounded-md border">
  <div class="space-y-2 text-sm p-4">
    <div>Scrollable content</div>
    <div>Scrollable content</div>
    <div>Scrollable content</div>
    <div>Scrollable content</div>
    <div>Scrollable content</div>
  </div>
</.scroll_area>

Layout.separator

Server-rendered Open docs

Horizontal or vertical separator.

Overview

Details

  <div class="space-y-3">
  <p class="text-sm">Overview</p>
  <.separator />
  <p class="text-sm">Details</p>
</div>

Layout.skeleton

Server-rendered Open docs

Animated skeleton placeholder.

  <.skeleton class="h-4 w-[220px]" />

Icons

Icons.icon

Server-rendered Open docs

Renders a Lucide icon by name.

  <.icon name="chevron-down" class="size-4 text-muted-foreground" aria-hidden="true" />

Feedback

Feedback.alert

Server-rendered Open docs

Renders an alert container.

Default

Destructive

Success

Warning

Info

  <div class="space-y-4">
  <div>
    <h4 class="text-sm font-medium mb-2">Default</h4>
    <.alert>
      <.icon name="circle-alert" />
      <:title>Heads up!</:title>
      <:description>
        You can add components to your app using the install task.
      </:description>
    </.alert>
  </div>

  <div>
    <h4 class="text-sm font-medium mb-2">Destructive</h4>
    <.alert variant={:destructive}>
      <.icon name="triangle-alert" />
      <:title>Unable to deploy</:title>
      <:description>
        Your build failed. Check logs and try again.
      </:description>
    </.alert>
  </div>

  <div>
    <h4 class="text-sm font-medium mb-2">Success</h4>
    <.alert variant={:success}>
      <.icon name="circle-check-big" />
      <:title>Changes saved</:title>
      <:description>
        Your updates have been successfully saved to the server.
      </:description>
    </.alert>
  </div>

  <div>
    <h4 class="text-sm font-medium mb-2">Warning</h4>
    <.alert variant={:warning}>
      <.icon name="triangle-alert" />
      <:title>Deprecated API</:title>
      <:description>
        This endpoint will be removed in the next major version.
      </:description>
    </.alert>
  </div>

  <div>
    <h4 class="text-sm font-medium mb-2">Info</h4>
    <.alert variant={:info}>
      <.icon name="info" />
      <:title>FYI</:title>
      <:description>
        Additional information to help you understand the current situation.
      </:description>
    </.alert>
  </div>
</div>

Feedback.badge

Server-rendered Open docs

Renders a status badge.

New
  <.badge>New</.badge>

Feedback.empty_state

Server-rendered Open docs

Empty-state block for no-data screens.

No projects

Create your first project to get started.

  <.empty_state>
  <:title>No projects</:title>
  <:description>Create your first project to get started.</:description>
</.empty_state>

Feedback.flash

Server-rendered Open docs

Renders a flash notice.

  <.flash kind={:info}>Settings saved.</.flash>

Feedback.flash_group

Server-rendered Open docs

Shows the flash group with standard titles and content.

  <.flash_group flash={%{"info" =>> "Saved", "error" => "Unable to complete request"}} />

Feedback.progress

Server-rendered Open docs

Progress bar.

Deploy progress 72%
  <div class="space-y-2">
  <div class="flex items-center justify-between text-sm">
    <span>Deploy progress</span>
    <span>72%</span>
  </div>
  <.progress value={72} />
</div>

Feedback.spinner

Server-rendered Open docs

Generic loading spinner.

Syncing changes
  <div class="inline-flex items-center gap-2 text-sm text-muted-foreground">
  <.spinner />
  Syncing changes
</div>

Data Display

DataDisplay.accordion

Server-rendered Open docs

Accordion with multiple items.

What is CinderUI?
A Phoenix-first component library modeled after shadcn/ui patterns.
Does it require JavaScript?
Core interactions use semantic HTML first, with optional hooks for enhancement.
  <.accordion>
  <:item title="What is CinderUI?" open={true}>
    A Phoenix-first component library modeled after shadcn/ui patterns.
  </:item>
  <:item title="Does it require JavaScript?">
    Core interactions use semantic HTML first, with optional hooks for enhancement.
  </:item>
</.accordion>

DataDisplay.avatar

Server-rendered Open docs

Renders a circular avatar with optional image and fallback.

Levi
  <.avatar src="example.png" alt="Levi" fallback="LV" />

DataDisplay.avatar_group

Server-rendered Open docs

Groups avatars with overlap.

Levi
Mira
Shadcn
+2
  <.avatar_group>
  <.avatar src="example.png" alt="Levi" />
  <.avatar src="example.png" alt="Mira" />
  <.avatar src="example.png" alt="Shadcn" />
  <.avatar_group_count>+2</.avatar_group_count>
</.avatar_group>

DataDisplay.avatar_group_count

Server-rendered Open docs

Counter item for avatar groups (e.g. +3).

LB
MJ
+3
  <.avatar_group>
  <.avatar alt="Levi Buzolic" />
  <.avatar alt="Mira Jones" />
  <.avatar_group_count size={:sm}>+3</.avatar_group_count>
</.avatar_group>

DataDisplay.code_block

Progressive Open docs

Monospaced code block wrapper.


    mix cinder_ui.docs.build
  
  <.code_block>
  mix cinder_ui.docs.build
</.code_block>

DataDisplay.collapsible

Server-rendered Open docs

Generic collapsible section with trigger/content slots.

Release notes
Added generated attr tables and improved examples.
  <.collapsible open={true}>
  <:trigger>
    Release notes
  </:trigger>
  Added generated attr tables and improved examples.
</.collapsible>

DataDisplay.table

Server-rendered Open docs

Table wrapper with overflow container.

Active deployments across environments.
Service Status Latency
API Healthy 82ms
Worker Degraded 164ms
  <.table>
  <.table_caption>Active deployments across environments.</.table_caption>
  <.table_header>
    <.table_row>
      <.table_head>Service</.table_head>
      <.table_head>Status</.table_head>
      <.table_head class="text-right">Latency</.table_head>
    </.table_row>
  </.table_header>
  <.table_body>
    <.table_row>
      <.table_cell>API</.table_cell>
      <.table_cell>Healthy</.table_cell>
      <.table_cell class="text-right">82ms</.table_cell>
    </.table_row>
    <.table_row>
      <.table_cell>Worker</.table_cell>
      <.table_cell>Degraded</.table_cell>
      <.table_cell class="text-right">164ms</.table_cell>
    </.table_row>
  </.table_body>
</.table>

DataDisplay.table_body

Server-rendered Open docs

Table body (tbody).

API Healthy
  <.table>
  <.table_body>
    <.table_row>
      <.table_cell>API</.table_cell>
      <.table_cell>Healthy</.table_cell>
    </.table_row>
  </.table_body>
</.table>

DataDisplay.table_caption

Server-rendered Open docs

Table caption (caption).

Recent invoices
  <.table>
  <.table_caption>Recent invoices</.table_caption>
</.table>

DataDisplay.table_cell

Server-rendered Open docs

Table data cell (td).

$48.00
  <.table>
  <.table_body>
    <.table_row>
      <.table_cell>$48.00</.table_cell>
    </.table_row>
  </.table_body>
</.table>

DataDisplay.table_head

Server-rendered Open docs

Table heading cell (th).

Amount
  <.table>
  <.table_header>
    <.table_row>
      <.table_head class="text-right">Amount</.table_head>
    </.table_row>
  </.table_header>
</.table>

DataDisplay.table_header

Server-rendered Open docs

Table header (thead).

Name Status
  <.table>
  <.table_header>
    <.table_row>
      <.table_head>Name</.table_head>
      <.table_head>Status</.table_head>
    </.table_row>
  </.table_header>
</.table>

DataDisplay.table_row

Server-rendered Open docs

Table row (tr).

INV-002 Pending
  <.table>
  <.table_body>
    <.table_row state="selected">
      <.table_cell>INV-002</.table_cell>
      <.table_cell>Pending</.table_cell>
    </.table_row>
  </.table_body>
</.table>

Overlay

Overlay.alert_dialog

Progressive Open docs

Destructive-style dialog variant used for irreversible confirmation actions.

  <.alert_dialog id="delete-dialog">
  <:trigger><.button variant={:destructive}>Delete project</.button></:trigger>
  <:title>Delete project?</:title>
  <:description>This action is irreversible.</:description>
  All deployments and analytics will be removed.
  <:footer>
    <.button variant={:outline} type="button">Cancel</.button>
    <.button variant={:destructive} type="button">Delete</.button>
  </:footer>
</.alert_dialog>

Overlay.dialog

Progressive Open docs

Modal dialog with trigger/content slots.

  <.dialog id="delete-project-dialog">
  <:trigger>
    <.button variant={:destructive}>Delete project</.button>
  </:trigger>
  <:title>Delete project?</:title>
  <:description>This action cannot be undone.</:description>
  Are you sure you want to permanently remove this project?
  <:footer>
    <.button variant={:outline} type="button">Cancel</.button>
    <.button variant={:destructive} type="button">Delete</.button>
  </:footer>
</.dialog>

Overlay.drawer

Progressive Open docs

Drawer panel component.

  <.drawer id="mobile-filters">
  <:trigger><.button variant={:outline}>Filters</.button></:trigger>
  <:title>Filter results</:title>
  <:description>Refine issues by status and owner.</:description>
  <div class="space-y-2 text-sm">
    <p>Status: Open</p>
    <p>Owner: Platform</p>
  </div>
</.drawer>

Overlay.dropdown_menu

Progressive Open docs

Dropdown menu structure.

  <.dropdown_menu id="project-actions">
  <:trigger><.button variant={:outline}>Actions</.button></:trigger>
  <:item href="/projects/1">Open project</:item>
  <:item>Rename</:item>
  <:item disabled={true}>Archive</:item>
</.dropdown_menu>

Overlay.hover_card

Server-rendered Open docs

Hover card with trigger and content slots.

Levi Buzolic
  <.hover_card>
  <:trigger><span class="text-sm underline">Levi Buzolic</span></:trigger>
  <:content>
    <div class="space-y-1 text-sm">
      <p class="font-medium">Levi Buzolic</p>
      <p class="text-muted-foreground">Maintains docs and releases.</p>
    </div>
  </:content>
</.hover_card>

Overlay.menubar

Progressive Open docs

Menubar scaffold with dropdown-like triggers.

  <.menubar>
  <:menu label="File">
    <button type="button" class="flex w-full rounded-sm px-2 py-1.5 text-sm hover:bg-accent">
      New project
    </button>
  </:menu>
  <:menu label="View">
    <button type="button" class="flex w-full rounded-sm px-2 py-1.5 text-sm hover:bg-accent">
      Toggle sidebar
    </button>
  </:menu>
</.menubar>

Overlay.popover

Progressive Open docs

Popover with trigger and content slots.

  <.popover id="share-popover">
  <:trigger><.button variant={:outline}>Share</.button></:trigger>
  <:content>
    <div class="space-y-2 text-sm">
      <p>Invite collaborators to this workspace.</p>
      <.button size={:sm}>Copy link</.button>
    </div>
  </:content>
</.popover>

Overlay.sheet

Progressive Open docs

Sheet panel component for side or edge-mounted overlays.

  <.sheet id="settings-sheet">
  <:trigger><.button variant={:outline}>Open settings</.button></:trigger>
  <:title>Workspace settings</:title>
  <:description>Manage defaults for the current workspace.</:description>
  <div class="space-y-2 text-sm">
    <p>Theme: System</p>
    <p>Notifications: Enabled</p>
  </div>
</.sheet>

Overlay.tooltip

Server-rendered Open docs

Tooltip helper with hover/focus behavior.

  <.tooltip text="Copy API key">
  <.button size={:icon} variant={:outline} aria-label="Copy">C</.button>
</.tooltip>

Advanced

Advanced.chart

Scaffold Open docs

Chart frame component for wrapping chart libraries with shadcn tokens.

Traffic

Requests over the last 7 days.

  <.chart>
  <:title>Traffic</:title>
  <:description>Requests over the last 7 days.</:description>
  <div class="h-40 rounded-md bg-muted/60"></div>
</.chart>

Advanced.combobox

Progressive Open docs

Combobox scaffold using an input and option list.

  <.combobox id="plan" value="Pro">
  <:option value="Free" label="Free" />
  <:option value="Pro" label="Pro" />
</.combobox>

Advanced.command

Server-rendered Open docs

Command palette layout.

General
Profile
Billing
Workspace
Settings
  <.command placeholder="Search commands...">
  <:group heading="General">
    <.item value="profile">Profile</.item>
    <.item value="billing">Billing</.item>
  </:group>

  <:group heading="Workspace">
    <.item value="settings">Settings</.item>
  </:group>
</.command>

Advanced.item

Server-rendered Open docs

Command/list item.

General
Profile
  <.command>
  <:group heading="General">
    <.item value="profile">Profile</.item>
  </:group>
</.command>

Advanced.sidebar

Progressive Open docs

Sidebar panel region.

  <div class="h-64 overflow-hidden rounded-xl border">
  <.sidebar class="h-full">
    <:header>
      <.sidebar_header>
        <span data-sidebar-label class="text-sm font-semibold">Workspace</span>
      </.sidebar_header>
    </:header>

    <.sidebar_group label="Navigation">
      <.sidebar_item icon="home" current={true}>Home</.sidebar_item>
      <.sidebar_item icon="folder">Projects</.sidebar_item>
    </.sidebar_group>

    <:footer>
      <.sidebar_footer>
        <span class="text-sidebar-foreground/70 text-xs">Low-level panel helper</span>
      </.sidebar_footer>
    </:footer>
  </.sidebar>
</div>

Advanced.sidebar_group

Server-rendered Open docs

Sidebar group wrapper.

  <.sidebar_layout id="sidebar-group-example" full_screen={false}>
  <:header>
    <.sidebar_header>
      <span data-sidebar-label class="text-sm font-semibold">Product nav</span>
    </.sidebar_header>
  </:header>
  <:sidebar>
    <.sidebar_group label="Workspace">
      <.sidebar_item icon="folder-kanban" current={true} collapsible={true} default_open={true}>
        Projects
        <:children>
          <.sidebar_item>Roadmap</.sidebar_item>
          <.sidebar_item>Releases</.sidebar_item>
        </:children>
      </.sidebar_item>
      <.sidebar_item icon="ship-wheel" badge="2">Deployments</.sidebar_item>
      <.sidebar_item icon="message-square">Feedback</.sidebar_item>
    </.sidebar_group>

    <.sidebar_group label="Insights">
      <.sidebar_item icon="chart-column">Analytics</.sidebar_item>
      <.sidebar_item icon="bell-ring" badge="4">Alerts</.sidebar_item>
    </.sidebar_group>
  </:sidebar>
  <:main>
    <div class="rounded border bg-card p-4 text-sm">
      A sidebar can stack multiple labeled groups while keeping each section
      visually separate.
    </div>
  </:main>
</.sidebar_layout>

Advanced.sidebar_header

Server-rendered Open docs

Sidebar header container.

  <.sidebar_layout id="sidebar-header-example" full_screen={false}>
  <:header>
    <.sidebar_header>
      <div data-sidebar-label class="min-w-0 flex-1">
        <p class="truncate text-sm font-semibold">Workspace</p>
        <p class="text-sidebar-foreground/70 truncate text-xs">Active release branch</p>
      </div>
      <.badge variant={:outline}>3 open</.badge>
    </.sidebar_header>
  </:header>
  <:sidebar>
    <.sidebar_group label="Navigation">
      <.sidebar_item icon="home" current={true}>Overview</.sidebar_item>
    </.sidebar_group>
  </:sidebar>
  <:main><div class="rounded border bg-card p-4 text-sm">Inset</div></:main>
</.sidebar_layout>

Advanced.sidebar_item

Server-rendered Open docs

Sidebar navigation item.

  <.sidebar_group label="Navigation">
  <.sidebar_item icon="home" current={true}>Overview</.sidebar_item>
  <.sidebar_item icon="inbox">Inbox</.sidebar_item>
</.sidebar_group>

Advanced.sidebar_layout

Progressive Open docs

Phoenix-first sidebar shell for app layouts.

Release readiness

2 items need review before ship.

Current focus

Ship the refreshed component docs and tighten visual regression coverage.

This week

Sidebar primitives, docs examples, and browser-driven QA.

  <.sidebar_layout id="workspace-shell-sidebar" persist_key="docs:workspace-shell">
  <:header>
    <.sidebar_header>
      <button
        type="button"
        class="hover:bg-sidebar-accent hover:text-sidebar-accent-foreground flex w-full items-center gap-3 rounded-lg px-2 py-2 text-left transition-colors"
      >
        <div class="bg-sidebar-primary text-sidebar-primary-foreground flex size-8 items-center justify-center rounded-lg">
          <.icon name="briefcase-business" class="size-4" />
        </div>
        <div data-sidebar-label class="min-w-0 flex-1">
          <p class="truncate text-sm font-medium">Acme Inc</p>
          <p class="text-sidebar-foreground/70 truncate text-xs">Enterprise</p>
        </div>
        <div data-sidebar-label class="text-sidebar-foreground/70 flex flex-col">
          <.icon name="chevron-up" class="size-3" />
          <.icon name="chevron-down" class="size-3 -mt-1" />
        </div>
      </button>
    </.sidebar_header>
  </:header>

  <:sidebar>
    <.sidebar_group label="Platform">
      <.sidebar_item icon="square-play" current={true} collapsible={true} default_open={true}>
        Playground
        <:children>
          <.sidebar_item>History</.sidebar_item>
          <.sidebar_item>Starred</.sidebar_item>
          <.sidebar_item>Settings</.sidebar_item>
        </:children>
      </.sidebar_item>
      <.sidebar_item icon="bot">Models</.sidebar_item>
      <.sidebar_item icon="book-open">Documentation</.sidebar_item>
      <.sidebar_item icon="settings-2">Settings</.sidebar_item>
    </.sidebar_group>
  </:sidebar>

  <:footer>
    <.sidebar_footer>
      <.sidebar_profile_menu
        id="workspace-shell-profile-menu"
        name="shadcn"
        subtitle="m@example.com"
        avatar_src="example.png"
        avatar_alt="shadcn"
      >
        <:item icon="badge-check">Account</:item>
        <:item icon="credit-card">Billing</:item>
        <:item icon="bell">Notifications</:item>
        <:item icon="log-out" separator_before={true}>Log out</:item>
      </.sidebar_profile_menu>
    </.sidebar_footer>
  </:footer>

  <:main>
    <div class="space-y-4">
      <div class="flex h-7 items-center">
        <.sidebar_trigger />
      </div>
      <section class="rounded-xl border bg-card p-5">
        <div class="flex items-center justify-between gap-4">
          <div>
            <h3 class="text-sm font-semibold">Release readiness</h3>
            <p class="text-muted-foreground mt-1 text-sm">2 items need review before ship.</p>
          </div>
          <.button size={:sm}>Open queue</.button>
        </div>
      </section>
      <div class="grid gap-4 md:grid-cols-2">
        <section class="rounded-xl border bg-card p-4">
          <h3 class="text-sm font-semibold">Current focus</h3>
          <p class="text-muted-foreground mt-3 text-sm">
            Ship the refreshed component docs and tighten visual regression coverage.
          </p>
        </section>
        <section class="rounded-xl border bg-card p-4">
          <h3 class="text-sm font-semibold">This week</h3>
          <p class="text-muted-foreground mt-3 text-sm">
            Sidebar primitives, docs examples, and browser-driven QA.
          </p>
        </section>
      </div>
    </div>
  </:main>
</.sidebar_layout>

Advanced.sidebar_main

Server-rendered Open docs

Sidebar sibling content region.

Content area
Use the lower-level helper when you want manual control over the main region wrapper.
  <div class="overflow-hidden rounded-xl border">
  <.sidebar_main class="space-y-4">
    <div class="rounded border bg-card p-4 text-sm">Content area</div>
    <div class="rounded border border-dashed p-4 text-sm text-muted-foreground">
      Use the lower-level helper when you want manual control over the main region wrapper.
    </div>
  </.sidebar_main>
</div>

Advanced.sidebar_profile_menu

Server-rendered Open docs

Profile/account menu pattern for sidebar footers.

  <.sidebar_layout id="sidebar-profile-menu-shell" full_screen={false}>
  <:header>
    <.sidebar_header>
      <span data-sidebar-label class="text-sm font-semibold">Workspace tools</span>
    </.sidebar_header>
  </:header>
  <:sidebar>
    <.sidebar_group label="Navigation">
      <.sidebar_item icon="settings">Settings</.sidebar_item>
      <.sidebar_item icon="circle-help">Get help</.sidebar_item>
      <.sidebar_item icon="search">Search</.sidebar_item>
    </.sidebar_group>
    <.sidebar_group label="Shortcuts">
      <.sidebar_item icon="command">Command palette</.sidebar_item>
      <.sidebar_item icon="bell">Notifications</.sidebar_item>
    </.sidebar_group>
  </:sidebar>
  <:footer>
    <.sidebar_footer>
      <.sidebar_profile_menu
        id="sidebar-profile-menu-example"
        name="shadcn"
        subtitle="m@example.com"
        avatar_src="example.png"
        avatar_alt="shadcn"
      >
        <:item icon="badge-check">Account</:item>
        <:item icon="credit-card">Billing</:item>
        <:item icon="bell">Notifications</:item>
        <:item icon="log-out" separator_before={true}>Log out</:item>
      </.sidebar_profile_menu>
    </.sidebar_footer>
  </:footer>
  <:main><div class="rounded border bg-card p-4 text-sm">Inset</div></:main>
</.sidebar_layout>

Advanced.sidebar_trigger

Server-rendered Open docs

Button that toggles the surrounding sidebar_layout/1 between expanded and collapsed.

  <.sidebar_layout id="sidebar-trigger-example" full_screen={false}>
  <:header>
    <.sidebar_header>
      <span data-sidebar-label class="text-sm font-semibold">Navigation</span>
      <.sidebar_trigger />
    </.sidebar_header>
  </:header>
  <:sidebar>
    <.sidebar_group label="Navigation">
      <.sidebar_item icon="home" current={true}>Overview</.sidebar_item>
      <.sidebar_item icon="box">Releases</.sidebar_item>
    </.sidebar_group>
  </:sidebar>
  <:main><div class="rounded border bg-card p-4 text-sm">Inset</div></:main>
</.sidebar_layout>