# Annotator

Review pins on anything: drop numbered pins, discuss in threads, resolve and reopen, and find every conversation in the list beside the work.

- Family: Signature, imported from `mizu-ui` or `mizu-ui/signature`
- Docs: https://mizu.user64bit.world/components/annotator
- Source: https://github.com/0xuser64bit/mizu/blob/main/packages/mizu/src/signature/Annotator.tsx

## Usage

```tsx
"use client";

import { useState } from "react";
import { Annotator, type Annotation } from "mizu-ui";

export function Example() {
  const field = (ground: string, mark: string) =>
    `data:image/svg+xml,${encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" width="720" height="360"><pattern id="d" width="36" height="36" patternUnits="userSpaceOnUse"><path d="M18 13l5 5-5 5-5-5z" fill="${mark}"/></pattern><rect width="720" height="360" fill="${ground}"/><rect width="720" height="360" fill="url(#d)"/></svg>`)}`;
  const [notes, setNotes] = useState<Annotation[]>([
    {
      id: "a",
      x: 0.3,
      y: 0.4,
      author: "Rin",
      body: "Can this headline be shorter?",
    },
  ]);
  return (
    <Annotator
      label="Homepage"
      author="You"
      annotations={notes}
      onAnnotationsChange={setNotes}
    >
      <img src={field("#141413", "#7e776b")} alt="Homepage draft" />
    </Annotator>
  );
}
```

## Copy it with the shadcn CLI

```sh
npx shadcn@latest init 0xuser64bit/mizu/preset # once, where there is no components.json
npx shadcn@latest add 0xuser64bit/mizu/annotator
```

## Props

- `label / children`: `string / ReactNode`. Region name and the work under review: an image, a page or a live composition.
- `annotations / defaultAnnotations / onAnnotationsChange`: `Annotation[]`. id, x and y (0–1 of the surface), author, body, time, resolved and replies.
- `author / now`: `string`. Name and time label for new comments and replies. Omit author for read-only review.
- `selected / defaultSelected / onSelectedChange`: `string | null`. The open thread.
- `createId`: `() => string`. Id factory for new comments and replies.

## Keyboard

- C: Toggle comment mode
- Enter: In comment mode: place a pin at the centre
- Alt + ← → ↑ ↓: While writing: move the new pin (Shift: further)
- ⌘/Ctrl + Enter: Post the comment or reply
- ← → ↑ ↓: On a pin: move it
- Esc: Close the thread or discard the draft

## Accessibility

Pins are buttons named with their number, author, state and text, in reading order; threads are labelled dialogs that return focus to their pin. C toggles comment mode, where Enter places a pin that arrow keys (or Alt+arrows while typing) move before posting. Every action is announced; the comment list offers the same threads without the surface.

## Motion

Pins drop in on a spring and send out a single impact ring. Threads unfold from the side of their pin; a pin being placed breathes until it is posted. Resolving settles the pin into a quiet outline. Reduced motion places and opens everything directly.
