# Layout Guide

This guide covers how to create layouts using the `Layout` component and its sub-components.

> **See also:** [Layout API Reference](./components/content/Layout.md) for detailed props documentation.

## Introduction

The `Layout` component provides a structured way to build application layouts with headers, footers, sidebars, and content areas. It handles:

- **Overflow management** - Content scrolls properly without breaking the layout
- **Panel coordination** - Side panels automatically adjust the main content area
- **Flexible composition** - Mix and match sub-components for any layout pattern

### Two-Element Architecture

Internally, Layout uses a wrapper + inner content model. The outer wrapper has `overflow: hidden` while an inner element uses absolute positioning with insets that adjust based on panel sizes. This ensures:

- Content never overflows the layout bounds
- Panels automatically push the content area without overlapping
- Scrolling is contained within each content area

## Basic Layouts

### Header + Content + Footer

A typical layout with header, scrollable content area, and footer.

```jsx live=false
<Layout height="300px">              {/* block, Inner: flex column ↓ */}
  <Layout.Header title="Dashboard" />
  <Layout.Content>                   {/* flex column ↓, scrollable, fills remaining space */}
    <Text>Content between header and footer</Text>
  </Layout.Content>
  <Layout.Footer>                    {/* flex row →, space-between */}
    <Text>Status: Ready</Text>
    <Button type="primary">Save</Button>
  </Layout.Footer>
</Layout>
```

## Navigation Patterns

### Sidebar Layout

Use `Layout.Panel` for side navigation. Panels are absolutely positioned and automatically adjust the content area insets.

```jsx live=false
<Layout height="400px">              {/* block, Inner: flex column ↓ */}
  <Layout.Panel side="left" size={200} isOpen={isOpen}> {/* absolute left, pushes content via insets */}
    <Layout.PanelHeader isClosable title="Menu" onClose={() => setIsOpen(false)} />
    <Layout.Content padding=".5x" gap="1bw"> {/* flex column ↓, scrollable */}
      <ItemButton type="clear">Dashboard</ItemButton>
      <ItemButton type="clear">Settings</ItemButton>
    </Layout.Content>
  </Layout.Panel>
  <Layout.Toolbar>                   {/* flex row →, single item aligns left */}
    <Button onPress={() => setIsOpen(!isOpen)}>Toggle Menu</Button>
  </Layout.Toolbar>
  <Layout.Content>                   {/* flex column ↓, scrollable, fills remaining space */}
    <Text>Main content area</Text>
  </Layout.Content>
</Layout>
```

**Key props:**
- `side` - Panel position: `"left"`, `"right"`, `"top"`, `"bottom"`
- `size` - Panel width (for left/right) or height (for top/bottom)
- `isOpen` / `onOpenChange` - Control panel visibility

### Resizable Panel

Add `isResizable` to allow users to resize the panel.

```jsx live=false
<Layout.Panel
  isResizable
  side="left"                        {/* absolute left, pushes content via insets */}
  size={size}
  minSize={150}
  maxSize={400}
  onSizeChange={setSize}
>
  {/* Panel content */}
</Layout.Panel>
```

**Resize behavior:**
- Drag the edge handle to resize
- Double-click the handle to reset to default size
- Use `minSize` and `maxSize` to constrain resize range

### Persistent Panel Size

Use `sizeStorageKey` to persist the panel size in localStorage. The size will be restored automatically when the component mounts.

```jsx live=false
<Layout.Panel
  isResizable
  side="left"                        {/* absolute left, pushes content via insets */}
  sizeStorageKey="my-app-sidebar-size"
  defaultSize={250}
  minSize={150}
  maxSize={400}
>
  {/* Panel content */}
</Layout.Panel>
```

**Notes:**
- The `sizeStorageKey` must be unique across your application
- Size is persisted after drag operations complete
- Double-clicking to reset also updates the stored value
- If no stored value exists, `defaultSize` is used

## Toolbar Patterns

### Left/Right Toolbar

`Layout.Toolbar` uses `space-between` alignment, placing first and last children at opposite ends.

```jsx live=false
<Layout.Toolbar>                     {/* flex row →, space-between */}
  <Title level={4}>App Name</Title>  {/* left (first item) */}
  <Button type="primary">Action</Button> {/* right (last item) */}
</Layout.Toolbar>
```

### Left/Center/Right Toolbar

Use `Space` components to create three sections.

```jsx live=false
<Layout.Toolbar>                     {/* flex row →, space-between */}
  <Space>                            {/* flex row → */}
    <Button>Back</Button>
  </Space>
  <Title level={4}>Page Title</Title>{/* center (middle item) */}
  <Space>                            {/* flex row → */}
    <Button>Help</Button>
    <Button type="primary">Save</Button>
  </Space>
</Layout.Toolbar>
```

## Header Patterns

### Header with Breadcrumbs

`Layout.Header` supports breadcrumbs, subtitle, and extra content.

```jsx live=false
<Layout.Header                       {/* grid with named areas: breadcrumbs/title/suffix/extra/subtitle */}
  title="User Details"
  breadcrumbs={[
    ['Home', '/'],
    ['Users', '/users'],
  ]}
  extra={                            {/* right side (extra area) */}
    <Space>                          {/* flex row → */}
      <Button>Edit</Button>
      <Button type="primary">Save</Button>
    </Space>
  }
/>
```

**Header props:**
- `title` - Page title
- `subtitle` - Text below the title
- `breadcrumbs` - Array of `[label, href]` tuples
- `extra` - Content on the right side
- `suffix` - Content next to the title
- `level` - Heading level (1-6)

## Footer Patterns

### Footer with Actions

Use `invertOrder` to place primary actions on the right.

```jsx live=false
<Layout.Footer invertOrder>          {/* flex row-reverse ←, space-between */}
  <Button.Group flow="row-reverse">  {/* flex row-reverse ← */}
    <Button type="primary">Submit</Button>
    <Button>Cancel</Button>
  </Button.Group>
  <Text preset="t4" color="#dark-03">Draft saved</Text> {/* left side due to row-reverse */}
</Layout.Footer>
```

## Panel Patterns

### Panel Modes

Panels support four rendering modes via the `mode` prop:

- **`default`** — Standard panel, pushes content (Content Push: Yes, Overlay: No)
- **`sticky`** — Floats over content (Content Push: No, Overlay: No)
- **`overlay`** — With dismissable backdrop (Content Push: Yes, Overlay: Yes)
- **`dialog`** — Renders as modal dialog (Content Push: No, Overlay: Dialog)

### Sticky Panel

Panels with `mode="sticky"` float over content without pushing it aside.

```jsx live=false
<Layout.Panel
  mode="sticky"                      {/* absolute, does NOT push content */}
  side="right"
  size={260}
  isOpen={isOpen}
  onOpenChange={setIsOpen}
>
  <Layout.PanelHeader isClosable title="Quick Actions" onClose={() => setIsOpen(false)} />
  <Layout.Content>
    <Text>Floating panel content</Text>
  </Layout.Content>
</Layout.Panel>
```

### Overlay Panel

Panels with `mode="overlay"` show a backdrop and dismiss on:
- Clicking the backdrop
- Pressing Escape anywhere in the Layout
- Moving focus to the main content area

```jsx live=false
<Layout.Panel
  mode="overlay"                     {/* absolute, backdrop behind panel */}
  side="right"
  size={300}
  isOpen={isOpen}
  onOpenChange={setIsOpen}
  overlayStyles={{ fill: '#dark.5' }} {/* optional custom backdrop */}
>
  <Layout.PanelHeader isClosable title="Details" onClose={() => setIsOpen(false)} />
  <Layout.Content>
    <Text>Panel with backdrop overlay</Text>
  </Layout.Content>
</Layout.Panel>
```

Set `isDismissable={false}` to prevent automatic dismissal.

### Dialog Mode Panel

Panels with `mode="dialog"` render as a modal dialog instead of inline.

```jsx live=false
<Layout.Panel
  mode="dialog"                      {/* renders as modal overlay instead of inline */}
  side="left"
  size={300}
  isDialogOpen={isOpen}
  onDialogOpenChange={setIsOpen}
>
  <Layout.PanelHeader isClosable title="Settings" onClose={() => setIsOpen(false)} />
  <Layout.Content>                   {/* flex column ↓, scrollable */}
    <Text>Panel content as dialog overlay</Text>
  </Layout.Content>
</Layout.Panel>
```

**Use cases:**
- Mobile-responsive layouts where sidebars become modal dialogs
- Settings panels that need full focus
- Any panel that should overlay rather than push content

## Pane Patterns

### Resizable Panes

`Layout.Pane` creates inline resizable sections that participate in the flex flow (unlike `Panel` which is absolutely positioned).

```jsx live=false
<Layout.Flex>                        {/* flex row →, scrollable */}
  <Layout.Pane
    isResizable
    resizeEdge="right"               {/* inline in flex flow, not absolute */}
    size={leftSize}
    minSize={120}
    maxSize={350}
    onSizeChange={setLeftSize}
  >
    <Title level={5}>Left Pane</Title>
  </Layout.Pane>
  <Layout.Content width="min 150px"> {/* flex column ↓, scrollable, fills remaining space */}
    <Title level={5}>Content</Title>
  </Layout.Content>
</Layout.Flex>
```

**Panel vs Pane:**

- **`Position`** — Panel: Absolute (overlays layout); Pane: Inline (participates in flex)
- **`Use case`** — Panel: Sidebars, drawers; Pane: Split views, code editors
- **`Content adjustment`** — Panel: Pushes content via insets; Pane: Takes space in flex container
- **`resizeEdge`** — Panel: Based on `side` prop; Pane: `"right"` or `"bottom"`

## Advanced Patterns

### Nested Layouts

Layouts can be nested for complex structures.

```jsx live=false
<Layout height="400px">              {/* block, Inner: flex column ↓ */}
  <Layout.Header title="Outer Layout" />
  <Layout flow="row">                {/* block, Inner: flex row → */}
    <Layout width="180px" border="right"> {/* block, Inner: flex column ↓ */}
      <Layout.Content>Sidebar</Layout.Content> {/* flex column ↓, scrollable */}
    </Layout>
    <Layout>                         {/* block, Inner: flex column ↓ */}
      <Layout.Toolbar>Inner Toolbar</Layout.Toolbar> {/* flex row →, single item aligns left */}
      <Layout.Content>Inner content</Layout.Content> {/* flex column ↓, scrollable */}
    </Layout>
  </Layout>
</Layout>
```

### Grid Dashboard

Use `Layout.Grid` for grid-based layouts.

```jsx live=false
<Layout.Grid                         {/* grid 2×2, scrollable */}
  columns="repeat(2, 1fr)"
  rows="repeat(2, 1fr)"
  gap="1x"
  padding="1x"
>
  <Card>Metrics</Card>               {/* grid cell 1,1 */}
  <Card>Charts</Card>                {/* grid cell 1,2 */}
  <Card>Activity</Card>              {/* grid cell 2,1 */}
  <Card>Stats</Card>                 {/* grid cell 2,2 */}
</Layout.Grid>
```

### Container Layout

Use `Layout.Container` for content that should be horizontally centered with a constrained max-width. Ideal for articles, forms, and focused content.

```jsx live=false
<Layout.Container>      {/* flex column ↓, scrollable, horizontally centered */}
  <Title>Article Title</Title>       {/* constrained width: min 40x, max 120x */}
  <Text>Content is centered with a comfortable reading width.</Text>
  <Space>
    <Button>Previous</Button>
    <Button type="primary">Next</Button>
  </Space>
</Layout.Container>
```

**Use cases:**
- Article or documentation pages
- Forms and settings pages
- Any content that benefits from constrained width

### Center Layout

Use `Layout.Center` for content that should be centered both horizontally and vertically. Ideal for empty states, loading screens, and hero sections.

```jsx live=false
<Layout.Center>         {/* flex column ↓, scrollable, centered both axes */}
  <Title>No Results Found</Title>    {/* text-align: center by default */}
  <Text>Try adjusting your search criteria.</Text>
  <Button type="primary">Clear Filters</Button>
</Layout.Center>
```

**Use cases:**
- Empty states ("No items found")
- Loading screens
- Welcome/onboarding screens
- Error pages (404, 500)

### When to Use Container vs Center

- **Article/documentation content** — `Layout.Container`
- **Forms with top-aligned content** — `Layout.Container`
- **Empty states** — `Layout.Center`
- **Loading/splash screens** — `Layout.Center`
- **Error pages** — `Layout.Center`

## Using Space Component

`Space` is a simple flex wrapper for arranging elements inline.

```jsx live=false
// Horizontal (default)
<Space gap="1x">                     {/* flex row → */}
  <Button>One</Button>
  <Button>Two</Button>
</Space>

// Vertical
<Space direction="vertical" gap="1x">{/* flex column ↓ */}
  <Button>One</Button>
  <Button>Two</Button>
</Space>
```

### When to Use Space vs Layout.Flex

- **Inline button groups** — `Space`
- **Quick horizontal/vertical arrangement** — `Space`
- **Scrollable flex container** — `Layout.Flex`
- **Part of Layout structure** — `Layout.Flex`
- **Standalone flex wrapper** — `Space`

## Sub-Components Reference

- **`Layout`** — Root wrapper, provides context
- **`Layout.Content`** — Scrollable content area, fills available space
- **`Layout.Container`** — Horizontally centered content with constrained width
- **`Layout.Center`** — Centered content (both axes) with text-align center
- **`Layout.Header`** — Page header with title, breadcrumbs, actions
- **`Layout.Footer`** — Footer bar, typically for actions
- **`Layout.Toolbar`** — Horizontal bar with space-between layout
- **`Layout.Panel`** — Side panel with modes: default, sticky, overlay, dialog
- **`Layout.PanelHeader`** — Header for panels with close button
- **`Layout.Pane`** — Inline resizable section
- **`Layout.Flex`** — Scrollable flex container
- **`Layout.Grid`** — Scrollable grid container
- **`Layout.Block`** — Simple block container

## Common Props

### Layout

- `height` - Layout height (required for proper containment)
- `contentPadding` - Default padding for content areas
- `hasTransition` - Enable slide animations for panels
- `flow` - Flex direction for inner content

### Content Components

All content components (`Content`, `Header`, `Footer`, `Toolbar`, `Flex`, `Grid`) support:

- `padding` - Inner padding
- `scrollbar` - Scrollbar style: `"default"`, `"thin"`, `"tiny"`, `"none"`
- `gap` - Gap between children

## Recommended Topics

The following topics would be valuable additions to this documentation:

1. **Responsive Layouts** - Media query patterns for adapting layouts to different screen sizes
2. **Animation Patterns** - Using `hasTransition` effectively, custom transition timing
3. **Keyboard Navigation** - Focus management within layouts, panel accessibility
4. **State Persistence** - Panel sizes can be persisted using `sizeStorageKey` (see Persistent Panel Size). Open states could be added similarly.
5. **Performance Optimization** - Best practices for large content areas, virtualization
6. **Testing Layouts** - Strategies for testing layout components
7. **Integration with Router** - Layouts with route-based content switching
8. **Dark Mode Support** - Theme-aware layout styling
9. **Print Layouts** - Adapting layouts for print media
10. **Mobile Patterns** - Touch interactions, swipe gestures for panels
