# Annotations

Areas, arrows and notes on an image, kept in one format your tools can share.

Package: @reuse-sh/annotations

## Principles

These are the rules to keep when you adapt this library. The code is one way to keep them. An adaptation on any framework must keep every one.

- Store one versioned format. Annotations live in one version 1 JSON document, and an unknown version throws instead of being guessed.

- Place marks in percent. Coordinates are percentages of the image, so every mark keeps its place at any size.

- Check input at the edge. Parsing clamps coordinates, drops invalid marks, and escapes marker text except strong, em and code.

- Render without a browser. The same document renders to HTML on the server, with no DOM needed.

- Leave storage to the host. The editor reports every change through onChange, and your code decides where the document goes.

- Edit from the keyboard. Marks can be created, selected, moved and deleted with keys, and one drag is one undo step.

## Install

```bash
npm install @reuse-sh/annotations
```

## Integration notes

- The stored document is { version: 1, annotations: [...] }. A bare array of annotations is also accepted.

- Marker text may hold strong, em and code. Everything else is escaped when it is read.

- On a narrow image, pointer labels turn into numbered markers with a list below.

## API

- `parseAnnotations(value)`: Reads a version 1 document, its JSON string, or a bare array. Invalid annotations are dropped. An unknown version throws.

- `serializeAnnotations(value)`: Writes the version 1 JSON document.

- `annotationsToHtml(value), annotationsFromHtml(element)`: Writes the annotations as an ordered list in HTML, and reads them back from it.

- `renderAnnotations(value, { ratio, id })`: Returns the overlay markup for an image ratio and a unique id, for server rendering.

- `createAnnotatedImage(root, options)`: Renders an image with its annotations and keeps them placed on resize. Returns update and destroy.

- `createAnnotationEditor(root, options)`: A controlled editor. It reports every change through onChange and leaves storage to you.

- `setAnnotations, setTool, updateSelection, removeSelection, undo, redo, destroy`: The editor's methods. The keyboard reaches the same actions.

- `AnnotatedImage, AnnotationEditor`: The React components around the same code. The editor adds a toolbar and a label field.

## Browser JavaScript

```js
import {
  parseAnnotations,
  createAnnotatedImage,
} from "@reuse-sh/annotations";
import "@reuse-sh/annotations/styles.css";

const annotations = parseAnnotations([{
  kind: "area",
  box: [10, 20, 35, 25],
  label: "Bands too tight",
}]);
const image = createAnnotatedImage(root, {
  src: "/prints/coral-sky.jpg",
  alt: "A marble print in coral, sand and blue",
  width: 1600, height: 1200, annotations,
});

// Later, when the image leaves the page
image.destroy();
```

## React

```tsx
import { AnnotationEditor } from "@reuse-sh/annotations/react";
import "@reuse-sh/annotations/styles.css";

<AnnotationEditor
  src="/prints/coral-sky.jpg"
  alt="A marble print in coral, sand and blue"
  annotations={annotations}
  onChange={setAnnotations}
  width={1600}
  height={1200}
/>
```

## Agent workflow

1. Inspect the project and read the installed package's types and stylesheet.

2. Reuse the native controller. Use the React adapter only in a React surface.

3. Adapt styles and data connections to the project. Keep every principle above. Do not recreate the gesture or state engine.

4. Connect destroy and unsubscribe callbacks to the owner lifecycle.

5. Verify keyboard access, pointer/touch behavior, resize, empty/one-item states, errors, reduced motion, and teardown where applicable.

6. Report the actual checks and remaining browser/device limits.

## Source

https://github.com/reuse-sh/reuse/tree/main/packages/annotations/src

License: MIT for original library code. Preserve dependency and asset license notices.
