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

<Meta of={IdentityMenuStories} />

# IdentityMenu

Who you are, and where you are: the identity trigger for a top bar, and
the menu it opens — ready-made, because every app needs one and it is
built of nothing but shared parts.

<Canvas of={IdentityMenuStories.SignedIn} />

## When

- The account control of any app. The trigger is a face and a name —
  never a key — or, `compact`, the face alone at 36px.
- Anonymous is the silhouette and the word "Anonymous": the truth of the
  situation rather than hex posing as a name.
- **Every section hides when the app cannot fill it** — no `relayUrl`, no
  workspace section; no `onCopyKey`, no copy item; no `idBase`, no
  sign-in surface. Only offer actions that can succeed. The MinimalApp
  story is the floor: identity alone.

<Canvas of={IdentityMenuStories.MinimalApp} />

## When not

- Any other menu → **Menu**.
- Showing a person who is not the viewer → **Person**.
- A trigger that opens something of your own → **PersonTrigger** plus
  your menu.

## How

```tsx
import { IdentityMenu } from '@estiva-app/ui'

<IdentityMenu
  me={{ name: me.name, picture: me.picture, email: me.email }}
  signedIn={signedIn}
  relayUrl={relayUrl}
  idBase={ID_BASE}
  onSignOut={signOut}
/>
```

- App-specific rows go through `children`, drawn as their own group
  between the workspace section and the actions. Pass a function to
  receive `close`, so a row can shut the menu before opening what it
  opens.
- Items are text only — no icons in this menu, by ruling.
- **IdentityPanel** draws the same rows as a plain surface, without the menu
  around them — for a docs canvas, or a surface that wants the panel and not
  the trigger.
- The trigger's toggle, its `aria-expanded`, the placement, the focus return
  and the accessible-name rules (the row is named by the person; only the bare
  compact face takes an `aria-label`) are all wired inside — bring nothing.
- **The panel hangs from the face, not from the wrapper around it** (stage 4).
  It used to hang from the wrapper, whose box belongs to the app's layout: in
  a flex row with the default `align-items: stretch` the wrapper takes the
  row's full height, and the panel hung from the bottom of *that* — measured
  360px below the face, with a scrollbar it should not have had.

## 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 |
|---|---|---|
| Everything a Menu owns: it floats, stays attached, closes on a press outside or on Escape, and walks its rows with the arrow keys | a menu of your own around the face |  |
| Gives focus back to the face when it closes | focus code |  |

## Keys

Since stage 4 the panel is a Base UI `Menu`, and **the arrow keys walk the
actions only**: they step over the identity block, the
workspace line and the notes, because those are not things you can do.

| Input | What happens |
|---|---|
| click / Enter / Space on the face | opens the menu |
| ↑ / ↓ | move between the actions — Edit your profile, Copy public key, Sign out, and any row the app adds — and wrap |
| Enter on an action | runs it, and closes the menu |
| Escape | closes, and gives focus back to the face |
| a press on the face while open | closes it |

The identity and workspace sections are `Menu.Group`s labelled by their
headings, so a screen reader announces them as named groups rather than as
menu items that are not items.

## Props

<Controls of={IdentityMenuStories.SignedIn} />
