Document
Preview

TipTap-based document viewer with composable features.

Overview

A composable document viewer built on TipTap. Render rich text content with Tailwind Typography styling and layer in features like annotations through nested providers. Use the compound components with defaults for quick setup, or customize with nested sub-components and headless hooks for full control.

Usage

import {
  Document,
  useAnnotatable,
  useHasSelection,
  type DocumentProps,
  type DocumentContentType,
  type AnnotationData,
  type AnnotatableProps,
} from "@tilt-legal/cubitt-components/composites";
// Basic viewer with markdown (default)
<Document content="# Hello World\n\nThis is **markdown** content.">
  <Document.Viewer />
</Document>

// With HTML content
<Document content="<h1>Hello</h1><p>HTML content</p>" contentType="html">
  <Document.Viewer />
</Document>

// With JSON content
<Document content={jsonContent} contentType="json">
  <Document.Viewer />
</Document>

// With annotations
<Document content={markdownContent}>
  <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>
</Document>

// With annotations (custom structure)
<Document content={content}>
  <Document.Annotatable
    annotations={annotations}
    onAnnotationCreate={handleCreate}
    onAnnotationUpdate={handleUpdate}
    onAnnotationDelete={handleDelete}
  >
    <Document.Viewer />

    <Document.Annotation.Sidebar>
      <Document.Annotation.SidebarHeader />
      <Document.Annotation.SidebarList>
        <Document.Annotation.SidebarItem annotation={annotation}>
          <Document.Annotation.SidebarItemCitation />
          <Document.Annotation.SidebarItemTextarea />
          <Document.Annotation.SidebarItemDelete />
        </Document.Annotation.SidebarItem>
      </Document.Annotation.SidebarList>
      <Document.Annotation.SidebarEmpty />
    </Document.Annotation.Sidebar>

    <Document.Toolbar.Selection>
      <Document.Annotation.AddButton />
    </Document.Toolbar.Selection>
  </Document.Annotatable>
</Document>

Architecture

The Document system uses a layered provider pattern:

Document                              # Root - TipTap setup
├── Document.Viewer                  # Shared content renderer
├── Document.Toolbar.*                # Shared toolbar components
├── Document.Annotatable              # Annotation feature provider
│   └── Document.Annotation.*         # Annotation UI components
└── Document.Editable (future)        # Editing feature provider
    └── Document.Editing.*            # Editing UI components

Root Provider

Document is the root component that initializes the TipTap editor. It accepts content as markdown (default), HTML, or TipTap JSON and provides the editor instance to all descendants via context.

Feature Providers

Feature providers like Document.Annotatable wrap content to enable specific capabilities. They:

  • Add their own context for feature-specific state and actions
  • Can be composed together (e.g., annotate + edit in the future)
  • Don't affect each other - each manages its own concerns

Shared Components

Document.Viewer renders the TipTap editor and is shared across all modes. The parent provider determines its behavior:

  • Inside Document alone → read-only viewer
  • Inside Document.Annotatable → text selection triggers annotation toolbar
  • Inside Document.Editable (future) → full editing capabilities

Component Namespacing

UI components are namespaced under their feature:

NamespaceComponents
Document.Toolbar.*Selection (shared toolbar infrastructure)
Document.Annotation.*Sidebar, SidebarItem, AddButton
Document.Editing.*(future) Bold, Italic, Heading, etc.

Props

Document

PropTypeDefaultDescription
contentstring | JSONContent-Document content (markdown, HTML, or JSON)
contentType"markdown" | "html" | "json""markdown"Format of the content
extensionsExtension[]-Additional TipTap extensions
editorOptionsPartial<EditorOptions>-TipTap editor options
classNamestring-Container class

Document.Viewer

PropTypeDescription
classNamestringAdditional classes

On this page