SIG—10 Signature system
Annotator
Review pins on anything: drop numbered pins, discuss in threads, resolve and reopen, and find every conversation in the list beside the work.
Live — this one is real
Illustrative review. Press C (or the Comment button), then click the draft to drop a pin; ⌘/Ctrl+Enter posts. Drag pins to move them, or use arrow keys on a focused pin.
Pricing page
3 open · 1 resolved
Pricing · draft 3
Plans for every team.
Start free, invite your team when the work needs it, and keep every draft.
Press C for comment mode, then click the work or press Enter to place a pin. Arrow keys move a focused pin.
Usage
import { useState } from "react";
import { Annotator, type Annotation } from "mizu-ui";
export function Example() {
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="/images/field.svg" alt="Homepage draft" />
</Annotator>
);
}
This code, running — no configuration beyond the data
Homepage
1 open
Press C for comment mode, then click the work or press Enter to place a pin. Arrow keys move a focused pin.
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
Source & setup
Add this component to your project with the shadcn CLI. The command copies its source and styles into your configured UI directory.
npx shadcn@latest add 0xuser64bit/mizu/annotatorFor npm imports, import mizu-ui/styles.css once. Fonts are optional via mizu-ui/fonts.css. Override --mizu-* tokens or use className for local styling. Requires React and Motion.
Inspect signature/Annotator.tsx
Source is included in the npm package under src/signature/Annotator.tsx.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| 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. |
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.