# Drawer

**When to use:** Inline horizontal panel that collapses and expands by animating its width — side panels, navigation rails, detail/filter panes that slide open beside the main content. Unlike `Modal`, it lives in the normal layout flow (no portal, no backdrop) and pushes/sits beside its siblings.

**Keywords:** collapsible panel

**Import:** `import { Drawer } from '@ahrowe/ui'`

The drawer animates between a **closed** width (default `0`) and an **open** width (default the content's natural width). Its children stay mounted the whole time — when closed they're simply clipped (`overflow-x: hidden`), so state and scroll position are preserved across toggles.

```tsx
import { useState } from 'react';
import { Drawer } from '@ahrowe/ui';

function Example() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <div style={{ display: 'flex', height: '100%' }}>
      <Drawer isOpen={isOpen}>
        <nav style={{ width: 240 }}>
          <a href="#">Dashboard</a>
          <a href="#">Settings</a>
        </nav>
      </Drawer>
      <main>
        <button onClick={() => setIsOpen((o) => !o)}>Toggle panel</button>
      </main>
    </div>
  );
}
```

```tsx
// Collapse to a fixed rail instead of fully closing (e.g. an icon-only nav rail)
<Drawer isOpen={isOpen} closedWidth="56px">
  <SidebarNav collapsed={!isOpen} />
</Drawer>

// Pin the open width instead of using the content's natural width
<Drawer isOpen={isOpen} openedWidth="320px">
  <FilterPanel />
</Drawer>

// Responsive open width
<Drawer isOpen={isOpen} openedWidth="90vw">
  <DetailPane />
</Drawer>
```

**Key props:**

| Prop | Type | Description |
|------|------|-------------|
| `isOpen` | `boolean` | Open/closed state (default `false`) |
| `closedWidth` | `string` | Width when closed — any CSS length (default `0`); use e.g. `'56px'` for a collapsed rail |
| `openedWidth` | `string` | Width when open — any CSS length (default: the content's measured natural width) |
| `children` | `ReactNode` | Panel content; stays mounted and is clipped while closed |
| `className` | `string` | Root element class |

**Notes:**

- It's an **inline** element with `height: 100%` and a `width` transition — place it in a flex/grid layout next to your main content; it doesn't overlay.
- When `openedWidth` is omitted, the open width tracks the content's `scrollWidth` via a `ResizeObserver`, so it grows/shrinks with dynamic content.
- For a full-screen overlay dialog instead, use `Modal`; for a collapsing scroll header, see `Overscroll`.

**Slots:** `root` `content` `inner`
