Annotations
Add annotation capabilities to documents.
Overview
Document.Annotatable is a feature provider that enables annotation functionality. Users can select text in the document to create annotations, which appear as highlights in the content and are managed through a sidebar. You control the annotation data through callbacks, making it easy to sync with your backend or local state. The active annotation state can be managed internally or controlled externally for features like URL-based deep linking.
Usage
import {
Document,
type AnnotatableProps,
type AnnotationAuthor,
type AnnotationData,
useAnnotatable,
useAnnotationCard,
useHasSelection,
} from "@tilt-legal/cubitt-components/document";// Basic - Cubitt handles UI
<Document.Annotatable
annotations={annotations}
onAnnotationCreate={handleCreate}
onAnnotationUpdate={handleUpdate}
onAnnotationDelete={handleDelete}
>
<Document.Viewer />
<Document.Annotation.Sidebar />
<Document.Toolbar.Selection>
<Document.Annotation.AddButton />
</Document.Toolbar.Selection>
</Document.Annotatable>// Custom structure
<Document.Annotatable
annotations={annotations}
onAnnotationCreate={handleCreate}
onAnnotationUpdate={handleUpdate}
onAnnotationDelete={handleDelete}
>
<Document.Viewer />
<Document.Annotation.Sidebar>
<Document.Annotation.Sidebar.Header />
<Document.Annotation.Sidebar.List>
<Document.Annotation.Sidebar.Card annotation={annotation}>
<Document.Annotation.Sidebar.Card.Citation />
<Document.Annotation.Sidebar.Card.Textarea />
<Document.Annotation.Sidebar.Card.Delete />
</Document.Annotation.Sidebar.Card>
</Document.Annotation.Sidebar.List>
<Document.Annotation.Sidebar.Empty />
</Document.Annotation.Sidebar>
<Document.Toolbar.Selection>
<Document.Annotation.AddButton />
</Document.Toolbar.Selection>
</Document.Annotatable>Controlled vs Uncontrolled Active State
By default, the component manages which annotation is "active" (selected) internally.
// Uncontrolled - component manages active state
<Document.Annotatable
annotations={annotations}
onAnnotationCreate={handleCreate}
onAnnotationUpdate={handleUpdate}
onAnnotationDelete={handleDelete}
>To control it externally (e.g., for URL sync):
// Controlled - you manage active state
const [activeId, setActiveId] = useState<string | null>(null);
<Document.Annotatable
annotations={annotations}
activeAnnotationId={activeId}
onActiveAnnotationChange={setActiveId}
onAnnotationCreate={handleCreate}
onAnnotationUpdate={handleUpdate}
onAnnotationDelete={handleDelete}
>API Reference
Document.Annotatable
| Prop | Type | Description |
|---|---|---|
annotations | AnnotationData[] | Current annotations (required) |
onAnnotationCreate | (annotation: AnnotationData) => void | Called when annotation created (required) |
onAnnotationUpdate | (id: string, text: string) => void | Called when annotation text changes (required) |
onAnnotationDelete | (id: string) => void | Called when annotation deleted (required) |
activeAnnotationId | string | null | Controlled active state (optional) |
onActiveAnnotationChange | (id: string | null) => void | Active state callback (optional) |
defaultAuthor | AnnotationAuthor | Default author for new annotations (optional) |
AnnotationData
Core data structure for annotations.
| Property | Type | Description |
|---|---|---|
id | string | Unique identifier |
text | string | User's annotation text |
citedText | string | The highlighted text from the document |
from | number | Start position in document |
to | number | End position in document |
createdAt | number | Unix timestamp |
author | AnnotationAuthor | Optional author info |
AnnotationAuthor
Author information for annotations.
| Property | Type | Description |
|---|---|---|
name | string | Display name (required) |
avatarUrl | string | URL to avatar image (optional) |