import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks'
import * as AppShellStories from './AppShell.stories'

<Meta of={AppShellStories} />

# AppShell

The frame of an app, in three manners: **`solid`** — the structured
frame, a solid TopBar over a Sidebar and the content beside it —
**`inset`** — the same frame the other way round, the TopBar and the
Sidebar standing on the ground and the content a lighter card beside
them — and **`floating`** — the TopBar floating over the top edge, a Rail
standing on the background, and the content living in the rounded card.
Layout only: no data, no routes.

<Canvas of={AppShellStories.Solid} />

<Canvas of={AppShellStories.Inset} />

<Canvas of={AppShellStories.Floating} />

## When

- **`solid` + Sidebar** — a place-by-place app: labelled entries, counts,
  groups. Sidebar and main scroll independently, so a long list never
  scrolls the navigation away.
- **`inset` + Sidebar** — the same place-by-place app, when its pages
  read as one sheet on a desk: the content is a card 16px from the right
  and bottom, with 8px corners, and the Sidebar drops its line and surface
  by itself. Any theme: the ground and the card are its base and surface.
- **`floating` + Rail** — an app with a handful of top-level places and
  its content in one card; the `menu` button in the bar collapses the
  rail (the collapsing stays the app's).
- The **banner belongs to the content area**: it draws at the top of the
  main column — inside the card, in the floating manner — never across
  the navigation.

<Canvas of={AppShellStories.FloatingWithBanner} />

## When not

- Panels *inside* the content — lists beside conversations, side rails —
  are layout components, not the shell's business. A list beside the
  content is **ListColumn**.
- Mixing the pairs (a rail in the solid frame, a sidebar in the floating
  one) is possible but is a new design, not a port — take it to the
  designer first.

## How

**The page contract, in the solid manner.** The frame owns the page's
scrollbar: the content column is a ScrollArea, and `main` inside it is a
flex column. A page is a flex child of `main`, and says one of two things:

- `flex-1` — it fills the frame and, when taller, scrolls in the frame's
  bar. A list page. (Its empty state centres on its own.)
- `flex-1 min-h-0 [contain:size]` — it takes exactly the frame's height
  and scrolls inside itself, in regions of its own. A detail page with a
  content column and a rail.

Never `h-full`: the frame's content box is *at least* the viewport's
height and grows with a tall page — which is what lets the bar know the
page changed — so a percentage height has nothing to resolve against.

```tsx
import { AppShell, Banner, IdentityMenu, Rail, RailItem } from '@estiva-app/ui'

<AppShell
  variant="floating"
  menu={menuButton}
  logo="Estiva"
  onSearch={openLauncher}
  identity={<IdentityMenu me={me} signedIn={signedIn} />}
  banner={notice && <Banner tone={notice.tone}>{notice.text}</Banner>}
  nav={<Rail>…</Rail>}
>
  {page}
</AppShell>
```

- Give it a height: it fills `h-full` and manages `min-h-0` internally so
  navigation and content scroll apart.
- `menu`, `logo`, `search`, `onSearch` and `searchPlaceholder` pass through to
  the **TopBar**: with `onSearch` the bar draws the search field and answers
  Ctrl+K.
- In the floating manner the card owns `overflow-hidden` — your content
  manages its own scrolling inside it.
- Desktop only for now — no narrow-screen behaviour is provided.
- In the Signal theme the floating frame draws the control-room dot grid on
  its ground, behind the card. Nothing to add: the preset makes it.

- In the floating manner the bar takes the top 52px; the card sits 16px from
  the right and the bottom, with 16px corners, beside the 64px rail.
- In the floating manner the card owns `overflow-hidden`, so anything in it
  that can grow sits in a **ScrollArea** — a list column most of all, which
  **ListColumn** draws with its own. Without one it is cut off at the fold.
- **Planned:** `SplitLayout`, resizable panels, in `@estiva-app/ui/layout`
  (migration stage 8). It may take the list and side columns' widths.

## What it owns

It does these by itself. Write none of them around it.

| It does | So you never write | Refused when written by hand |
|---|---|---|
| Scrolls the page's content column, in a ScrollArea | `overflow-auto` on the page or on `main` |  |

## Props

<Controls of={AppShellStories.Solid} />
