

## useAnnotatable [#useannotatable]

Access annotation context inside `Document.Annotatable`. Use this to build custom annotation UI.

```tsx
import { useAnnotatable } from "@tilt-legal/cubitt-components/composites";

function CustomButton() {
  const { createAnnotation, annotations } = useAnnotatable();

  return (
    <button onClick={() => createAnnotation()}>
      Add ({annotations.length})
    </button>
  );
}
```

### Returns [#returns]

| Property                           | Type                                                                                                                         | Description                                                                                                                                                                                                                    |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `annotations`                      | `AnnotationData[]`                                                                                                           | Current annotations                                                                                                                                                                                                            |
| `activeAnnotationId`               | `string \| null`                                                                                                             | Selected annotation                                                                                                                                                                                                            |
| `hoveredAnnotationId`              | `string \| null`                                                                                                             | Hovered annotation                                                                                                                                                                                                             |
| `createAnnotation`                 | `(initialText?: string) => void`                                                                                             | Create annotation from selection                                                                                                                                                                                               |
| `createAnnotationFromMarkdownText` | `(citedText: string, comment: string, options?: { instance?: number; author?: AnnotationAuthor }) => AnnotationData \| null` | Create annotation from markdown text. `instance` (1-indexed, default 1) specifies which occurrence when text appears multiple times. `author` overrides `defaultAuthor` for this annotation. Returns `null` if text not found. |
| `updateAnnotation`                 | `(id: string, text: string) => void`                                                                                         | Update annotation text                                                                                                                                                                                                         |
| `deleteAnnotation`                 | `(id: string) => void`                                                                                                       | Delete annotation                                                                                                                                                                                                              |
| `setActiveAnnotation`              | `(id: string \| null) => void`                                                                                               | Set active annotation                                                                                                                                                                                                          |
| `setHoveredAnnotation`             | `(id: string \| null) => void`                                                                                               | Set hovered annotation                                                                                                                                                                                                         |
| `scrollToAnnotation`               | `(id: string) => void`                                                                                                       | Scroll to annotation in document                                                                                                                                                                                               |
| `selectNextAnnotation`             | `() => void`                                                                                                                 | Navigate to next annotation                                                                                                                                                                                                    |
| `selectPreviousAnnotation`         | `() => void`                                                                                                                 | Navigate to previous annotation                                                                                                                                                                                                |
| `getAnnotationsWithPositions`      | `() => AnnotationData[]`                                                                                                     | Get annotations sorted by position                                                                                                                                                                                             |
| `getAnnotationById`                | `(id: string) => AnnotationData \| undefined`                                                                                | Find annotation by ID                                                                                                                                                                                                          |
| `getMarkdown`                      | `() => string`                                                                                                               | Get document as markdown                                                                                                                                                                                                       |
| `applyAnnotationMark`              | `(id: string) => void`                                                                                                       | Apply annotation mark to editor                                                                                                                                                                                                |
| `removeAnnotationMark`             | `(id: string) => void`                                                                                                       | Remove annotation mark from editor                                                                                                                                                                                             |

***

## useAnnotationCard [#useannotationcard]

Access per-card state inside `Document.Annotation.Sidebar.Card`. Use this to build custom card components.

```tsx
import { useAnnotationCard } from "@tilt-legal/cubitt-components/composites";

function CustomDelete() {
  const { remove, annotation, isActive } = useAnnotationCard();

  return (
    <button onClick={remove} disabled={!isActive}>
      Delete "{annotation.citedText.slice(0, 20)}..."
    </button>
  );
}
```

### Returns [#returns-1]

| Property       | Type                     | Description                          |
| -------------- | ------------------------ | ------------------------------------ |
| `annotation`   | `AnnotationData`         | The annotation data                  |
| `isActive`     | `boolean`                | Whether this card is selected        |
| `isHovered`    | `boolean`                | Whether this card is hovered         |
| `activate`     | `() => void`             | Select this annotation               |
| `selectText`   | `() => void`             | Select the annotation text in editor |
| `scrollToMark` | `() => void`             | Scroll to the mark in the document   |
| `update`       | `(text: string) => void` | Update the annotation text           |
| `remove`       | `() => void`             | Delete the annotation                |

***

## useHasSelection [#usehasselection]

Boolean indicating if valid text is selected in the document. Useful for enabling/disabling add buttons.

```tsx
import { useHasSelection, useAnnotatable } from "@tilt-legal/cubitt-components/composites";

function HeaderAddButton() {
  const hasSelection = useHasSelection();
  const { createAnnotation } = useAnnotatable();

  return (
    <button disabled={!hasSelection} onClick={() => createAnnotation()}>
      Add Annotation
    </button>
  );
}
```

### Returns [#returns-2]

`boolean` - `true` when valid text is selected.

***

## LLM Integration [#llm-integration]

When integrating with LLMs, you can have the model analyze document content and return citations that automatically become annotations. The LLM works with markdown text and doesn't need to know about editor positions.

1. **Export**: Call `getMarkdown()` to get the document content
2. **Analyze**: Send markdown to your LLM with citation requirements
3. **Annotate**: Pass LLM citations to `createAnnotationFromMarkdownText()`

### Structured Output Schema [#structured-output-schema]

Define a schema for LLM citations:

```ts
import {
  z } from "zod";

const citationSchema = z.object({
  citedText: z.object({
    text: z.string(),
  instance: z.number(),
  }),
  comment: z.string(),
  });
```

Then consume it:

```tsx
import { useAnnotatable } from "@tilt-legal/cubitt-components/composites";

const { createAnnotationFromMarkdownText } = useAnnotatable();

for (const { citedText, comment } of citations) {
  createAnnotationFromMarkdownText(citedText.text, comment, {
    instance: citedText.instance,
  });
}
```

### LLM System Prompt [#llm-system-prompt]

Include citation requirements in your system prompt:

```
## Citation Requirements

For EVERY issue you identify, you MUST provide:
- `citedText.text`: The exact quoted text from the document
- `citedText.instance`: Which occurrence of this text (1 = first, 2 = second, etc.)

Guidelines:
- Quote the exact text, do not paraphrase
- Keep citations concise but complete enough to identify the issue
- If an issue spans multiple sentences, quote the most relevant portion
- Always specify the instance, even if the text only appears once (use 1)
```
