import { Meta, Canvas } from '@storybook/addon-docs/blocks'
import * as ReferenceCardsStories from './ReferenceCards.stories'

<Meta of={ReferenceCardsStories} />

# ReferenceCards

A chip in a document can ask for a card after its line: compact, detailed or
none. The choice is the chip's own `embed`, so the card moves and goes with it.
This draws no card itself. It places a slot after each line that asks for
one, and the app draws its own card into it.

<Canvas of={ReferenceCardsStories.InAnEditor} />

## When

- **An editor of a document whose chips can carry a card**: pair it with
  **ReferenceNode**, which holds the choice, and **SelectionToolbar**, where
  the app offers it for the selected chip.

## When not

- A new editor of a document → **LinkPlaces**: since §13.3's line rule, a
  card draws in a lone link's row's place, and a card on a link in a sentence
  draws nothing. **DocumentEditor** uses it; this stays for an editor that has
  not moved yet.
- A document that is only read → **RichText**, with each block's cards drawn
  after it from the text's own description of them.
- A text whose cards travel beside it rather than on its chips → the app keeps
  that choice itself, and this has nothing to read.

## How

```tsx
import { createPortal } from 'react-dom'
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { ToolbarButton } from '@estiva-app/ui'
import {
  BlockId,
  ReferenceCards,
  ReferenceNode,
  SelectionToolbar,
  referenceAtSelection,
  setReferenceCard,
  useReferenceCards,
  type ReferenceCard,
  type ReferenceViewProps,
} from '@estiva-app/ui/editor'

const Reference = ({ uri }: ReferenceViewProps) => <span>{uri}</span>
const Cards = ({ cards }: { cards: ReferenceCard[] }) => <div>{cards.map((card) => card.layout).join(', ')}</div>

const editor = useEditor({ extensions: [StarterKit, BlockId, ReferenceNode.configure({ view: Reference }), ReferenceCards] })
const slots = useReferenceCards(editor)
const chip = editor ? referenceAtSelection(editor.state) : null

;<>
  <EditorContent editor={editor} />
  {slots.map((slot) => createPortal(<Cards cards={slot.cards} />, slot.element, slot.key))}
  <SelectionToolbar editor={editor}>
    {chip && editor && (
      <ToolbarButton aria-label="Detailed" pressed={chip.layout === 'detailed'} onMouseDown={(e) => e.preventDefault()} onClick={() => setReferenceCard(editor, chip.layout === 'detailed' ? 'none' : 'detailed')}>
        D
      </ToolbarButton>
    )}
  </SelectionToolbar>
</>
```

- **A slot keeps its element while its line lives.** It is keyed by the
  line's block id, so typing above a card does not make it load again.
- **The slot is not text.** It cannot be typed into or selected, and a click
  on a card stays the card's.
- **A layout this version does not know draws as compact.** The writer asked
  for a card, and the smallest is the safe reading.
- **Press without taking the focus.** A button in the toolbar prevents its
  press's default, or the editor loses the chip's selection and the toolbar
  goes.

## What it owns

Nothing. It only draws. Clicks and keys are yours.
