Skip to content

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

Scenario

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.

Solo€0Up to 3 seats
Most chosenTeam€12Per seat, monthly
Enterprise—Volume and SSO

Press C for comment mode, then click the work or press Enter to place a pin. Arrow keys move a focused pin.

Usage

tsx
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

Homepage draft

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.

sh
npx shadcn@latest add 0xuser64bit/mizu/annotator

For 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.

Open full source ↗

Props

PropTypeDefaultDescription
label / childrenstring / ReactNode—Region name and the work under review: an image, a page or a live composition.
annotations / defaultAnnotations / onAnnotationsChangeAnnotation[]—id, x and y (0–1 of the surface), author, body, time, resolved and replies.
author / nowstring—Name and time label for new comments and replies. Omit author for read-only review.
selected / defaultSelected / onSelectedChangestring | 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.

Works alongside