# `PUI.Layout`

Reusable application shell primitives for documentation sites, dashboards, and
other two-pane LiveView layouts.

The layout API is split into small components so applications can compose
their own shell without inheriting opinionated navigation data structures.

## Basic Usage

    <.app_layout id="docs-shell">
      <:sidebar>
        <.sidebar>
          <:header>
            <div class="px-4 py-3 font-semibold">PUI</div>
          </:header>

          <nav class="p-3">
            <.sidebar_menu_item title="Getting Started" icon="hero-rocket-launch" href="/docs" />
          </nav>
        </.sidebar>
      </:sidebar>

      <:header>
        <.content_header shell_id="docs-shell" breadcrumb_current="Getting Started" />
      </:header>

      Content goes here.
    </.app_layout>

## Collapsible Navigation

Use `collapsible={true}` on `sidebar_menu_item/1` when an item owns nested
links. The submenu state is handled by the bundled `PUI.Sidebar` hook.

    <.sidebar_menu_item
      title="Components"
      icon="hero-squares-2x2"
      collapsible
      expanded
    >
      <:subitem>
        <.link href="/docs/button" class="block rounded-md px-2 py-1.5 text-sm">Button</.link>
      </:subitem>
    </.sidebar_menu_item>

## Components

| Component | Description |
|-----------|-------------|
| `app_layout/1` | Root shell with collapsible sidebar state |
| `sidebar/1` | Sidebar surface with header and footer slots |
| `sidebar_menu_item/1` | Sidebar link row with optional collapsible submenu |
| `content_header/1` | Sticky content header with sidebar toggle and breadcrumbs |

# `app_layout`

Renders a two-pane application shell.

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `string` | `"app-layout"` | Shell DOM id, used by `content_header/1` toggle |
| `class` | `string` | `""` | Additional classes for the root shell |
| `content_class` | `string` | `"w-full px-4 py-4"` | Classes for the scrollable main content element |
| `collapsed` | `boolean` | `false` | Initial sidebar collapsed state rendered by the server |

## Slots

| Name | Required | Description |
|------|----------|-------------|
| `sidebar` | Yes | Sidebar content, usually `sidebar/1` |
| `header` | No | Sticky header content, usually `content_header/1` |
| `inner_block` | Yes | Main page content |

## Attributes

* `id` (`:string`) - Defaults to `"app-layout"`.
* `class` (`:string`) - Defaults to `""`.
* `content_class` (`:string`) - Defaults to `"w-full px-4 py-4"`.
* `collapsed` (`:boolean`) - Defaults to `false`.
## Slots

* `sidebar` (required)
* `header`
* `inner_block` (required)

# `content_header`

Renders a sticky shell header with a sidebar toggle and breadcrumb.

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `shell_id` | `string` | `"app-layout"` | Target shell id for collapse toggling |
| `class` | `string` | `""` | Additional classes for the header |
| `toggle_class` | `string` | `""` | Additional classes for the toggle button |
| `title` | `string` | `nil` | Small eyebrow text above the breadcrumb |
| `breadcrumb_parent` | `string` | `nil` | Optional parent breadcrumb |
| `breadcrumb_current` | `string` | required | Current page breadcrumb |

## Slots

| Name | Required | Description |
|------|----------|-------------|
| `right_actions` | No | Right-aligned buttons, menus, or theme controls |

## Attributes

* `shell_id` (`:string`) - Defaults to `"app-layout"`.
* `class` (`:string`) - Defaults to `""`.
* `toggle_class` (`:string`) - Defaults to `""`.
* `title` (`:string`) - Defaults to `nil`.
* `breadcrumb_parent` (`:string`) - Defaults to `nil`.
* `breadcrumb_current` (`:string`) (required)
## Slots

* `right_actions`

# `sidebar`

Renders a collapsible sidebar surface.

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `string` | `"app-sidebar"` | Sidebar DOM id |
| `class` | `string` | `""` | Additional classes for the sidebar |
| `expanded_width_class` | `string` | `"w-72"` | Width class when the shell is expanded |
| `collapsed_width_class` | `string` | `"group-data-[collapsed=true]/pui-layout:w-12"` | Width class when collapsed |

## Slots

| Name | Required | Description |
|------|----------|-------------|
| `header` | No | Logo, workspace switcher, or sidebar title |
| `inner_block` | Yes | Sidebar navigation/content |
| `footer` | No | Account controls or secondary actions |

## Attributes

* `id` (`:string`) - Defaults to `"app-sidebar"`.
* `class` (`:string`) - Defaults to `""`.
* `expanded_width_class` (`:string`) - Defaults to `"w-72"`.
* `collapsed_width_class` (`:string`) - Defaults to `"group-data-[collapsed=true]/pui-layout:w-12"`.
## Slots

* `header`
* `inner_block` (required)
* `footer`

# `sidebar_menu_item`

Renders a sidebar item as a link or as a collapsible submenu trigger.

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `string` | derived from `title` | Stable DOM id |
| `title` | `string` | required | Visible item label and link title |
| `icon` | `string` | required | Heroicon class, such as `"hero-home"` |
| `navigate` | `string` | `nil` | LiveView navigation target |
| `href` | `string` | `nil` | Link href |
| `patch` | `string` | `nil` | LiveView patch target |
| `collapsible` | `boolean` | `false` | Render a submenu trigger instead of a link |
| `expanded` | `boolean` | `false` | Initial submenu state |
| `current` | `boolean` | `false` | Applies active item styling |
| `class` | `string` | `""` | Additional classes for the row |

## Slots

| Name | Required | Description |
|------|----------|-------------|
| `trailing` | No | Badge, count, or secondary row content |
| `subitem` | No | Repeated submenu rows for collapsible items |

## Attributes

* `id` (`:string`) - Defaults to `nil`.
* `title` (`:string`) (required)
* `icon` (`:string`) (required)
* `navigate` (`:string`) - Defaults to `nil`.
* `href` (`:string`) - Defaults to `nil`.
* `patch` (`:string`) - Defaults to `nil`.
* `collapsible` (`:boolean`) - Defaults to `false`.
* `expanded` (`:boolean`) - Defaults to `false`.
* `class` (`:string`) - Defaults to `""`.
* `current` (`:boolean`) - Defaults to `false`.
## Slots

* `trailing`
* `subitem`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
