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

<Meta of={BannerStories} />

# Banner

The strip under the header where the app says something happened: one
line, one of four tones, gone when there is nothing to say.

<Canvas of={BannerStories.AllTones} />

## When

- The state of the whole surface: the reason the last read failed, a read-only
  notice.
- **`ok`** confirms, **`info`** informs, **`warning`** cautions,
  **`error`** reports a failure — and only `error` announces itself
  (`role="alert"`); the others are polite (`role="status"`).
- It belongs to the **content area** — at its top, never across the
  navigation. AppShell's `banner` slot places it exactly there.

## When not

- Feedback about one action, briefly → **Toast**. A failure is the exception:
  it stays, in the Banner, until the person acts on it.
- Something that floats over the page and must **not** fade → still
  **Toast**, with `durationMs: 0` and an action. A banner is the strip
  under the header at the app's full width; a floating pill is not one, even
  a permanent one.
- A standing property of one thing → **Chip** on that thing.
- More than one action, or a second line of text — that is a different
  component (not in the package yet).

## How

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

{notice && <Banner tone={notice.tone}>{notice.text}</Banner>}
```

- Render it only while there is something to say — an empty strip is not
  a state.
- One line of text, `body-2`. If it needs a **second line**, it has outgrown
  this component.
- `icon` puts a 16px icon before the line and `action` one small muted Button
  at the end of it, both in the tone. With either, the banner is one line and
  the text truncates. One action at most.

<Canvas of={BannerStories.WithIconAndAction} />

```tsx
<Banner tone="info" icon={<IconUserPlus size={16} stroke={1.5} />} action={{ label: 'Join', onClick: join }}>
  You are not in <span className="font-medium">{title}</span> yet
</Banner>
```

- `onDismiss` adds an ✕ at the right-hand end. Use it where
  the reader decides the notice is done with, rather than the app. The row
  is 40px rather than 36px with it, because the button is taller than the
  line of text; without it, nothing about the strip changes.

## 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 |
|---|---|---|
| Says what it is to assistive technology: an alert for an error, a status for the rest | `role="alert"` or `role="status"` | ✓ |
| Draws its own ✕ when you pass `onDismiss`, and its one small action when you pass `action` | a close button or an action button of your own |  |

## Props

<Controls of={BannerStories.Ok} />
