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

<Meta of={AttachmentCardStories} />

# AttachmentCard

Something attached — a document or an image — drawn as a card: posted, or
waiting to be sent.

<Canvas of={AttachmentCardStories.SeveralTogether} />

## When

The file decides the shape:

- **an image with a picture** (`src`) — a 180px thumbnail, which opens full
  screen when it is pressed. `onOpen` replaces that with the app's own.
- **anything else** — a 240px row: a type tile, the name, the type and size.
  `href` opens it in a new tab; without one the row is dimmed.
- `download` — a download control that fades in on hover or keyboard focus, and
  the card saves the file. `onDownload` instead when the app must do it itself.
- `remoteSrc` + `fetchImage` — a picture the reader needs permission for. The
  card waits and says so if it is refused; `state` says the same by hand.
- `state="loading"` — an image on its way. `state="unreadable"` — it could not
  be read: said, with a dashed hairline, never left as a gap.
- **`pending`** — waiting to be sent: a 200px row with a remove control on its
  corner (`onRemove`). `state` says what is happening to it: `ready` (its size),
  `uploading`, `failed` (the reason, in `note`), `warning` (something the sender
  should know, in `note`, with the full words in `noteHint`).

<Canvas of={AttachmentCardStories.Pending} />

## When not

- A whole thing standing for itself, not a file → **Card**.
- A word in a sentence that names a file → **InlineChip**.
- A value picked into a field → **InputChip**, inside **ChipInput**.

## How

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

// Posted, with the picture already in hand.
<AttachmentCard name={name} size={bytes} contentType={type} src={pictureUrl} download />

// Posted, on a relay: the card fetches it with your app's authorization, opens
// it full screen and saves it. The original is fetched only when it is opened.
<AttachmentCard
  name={name}
  size={bytes}
  contentType={type}
  remoteSrc={thumbUrl ?? mediaUrl}
  remoteFullSrc={mediaUrl}
  fetchImage={blobObjectUrl}
  download
/>

// Waiting to be sent.
<AttachmentCard pending name={name} size={bytes} state={uploading ? 'uploading' : 'ready'} src={localPreview} onRemove={remove} />
```

- **How to fetch is the app's, what to draw is the card's.** `fetchImage` takes
  a URL and returns one the browser can draw — an object URL, usually. The
  card owns the wait, the refusal and the swap; it knows nothing about relays,
  tokens or which app it is in.
- A picture already in hand needs none of that: pass `src`.
- A click on the picture, the download control and the remove control each stop
  there, so they never also click the card or row the attachment sits in.
- The name truncates. When it is cut off, the full name is on hover; a name
  that fits, and a size, show nothing extra. `noteHint` is always on hover, since
  it says more than the line.
- The remove control is a 20px round badge on the card's corner, a button
  on Base UI's `Button` like InputChip's ✕ — not an `IconButton`, the 24px
  square that fills on hover.

- A press on the picture opens it full screen, in **Lightbox**, unless `onOpen`
  says what else to do.

<Canvas of={AttachmentCardStories.OpenItFullScreen} />

## 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 |
|---|---|---|
| Stops the clicks on its picture, its download and its remove control, so they never also click the card or row around it | `stopPropagation` |  |
| Shows the full name on hover when the name is cut off | a tooltip of your own |  |
| Opens the picture full screen, in Lightbox | a viewer of your own, a portal, a scrim |  |
| Fetches a picture that needs permission, and draws the wait and the refusal | a loading hook of your own |  |
| Saves the file under its name, the original rather than the thumbnail | a `<a download>` of your own |  |

## Props

<Controls of={AttachmentCardStories.Document} />
