import { RichTextEditor } from "@samplehc/ui/components";
import { useTaskState } from "@samplehc/ui/lib";
import { useRef, useEffect } from "react";

function PersistentEditor() {
  const [content, setContent] = useTaskState("documentContent", "");
  const [isSaving, setIsSaving] = useState(false);
  const editorRef = useRef();

  const handleUpdate = async ({ editor }) => {
    setIsSaving(true);
    const html = editor.getHTML();
    
    // Debounce saves to avoid too frequent updates
    setTimeout(() => {
      setContent(html);
      setIsSaving(false);
    }, 1000);
  };

  return (
    <RichTextEditor
      editorRef={editorRef}
      defaultValue={content}
      onUpdate={handleUpdate}
      isSaving={isSaving}
    />
  );
}

Overview

The RichTextEditor is a powerful, extensible rich text editor built on Tiptap. It includes healthcare-specific extensions for citations, page breaks, and document formatting, making it ideal for creating medical reports, clinical notes, and other healthcare documentation.

Basic Usage

import { RichTextEditor } from "@samplehc/ui/components";
import { useRef } from "react";

function DocumentEditor() {
  const editorRef = useRef();

  return (
    <RichTextEditor
      editorRef={editorRef}
      defaultValue="<p>Start typing your document...</p>"
      onUpdate={({ editor }) => {
        console.log("Content updated:", editor.getHTML());
      }}
    />
  );
}

Advanced Features

Citation Support

The editor includes built-in support for citations that can link to source documents:

import { RichTextEditor } from "@samplehc/ui/components";

function CitationEditor() {
  const handleCitationClick = (citations) => {
    console.log("Citation clicked:", citations);
    // Handle citation navigation or display source
  };

  return (
    <RichTextEditor
      onCitationClick={handleCitationClick}
      defaultValue="<p>According to the medical records <citation-paragraph data-citations='[{"documentId": "doc123", "pageNumber": 1}]'>the patient has no known allergies</citation-paragraph>.</p>"
    />
  );
}

Custom Extensions

Add your own Tiptap extensions to enhance functionality:

import { RichTextEditor } from "@samplehc/ui/components";
import { Highlight } from "@tiptap/extension-highlight";

function ExtendedEditor() {
  return (
    <RichTextEditor
      extraExtensions={[
        Highlight.configure({
          multicolor: true,
        }),
      ]}
      defaultValue="<p>Highlight important <mark>medical findings</mark>.</p>"
    />
  );
}

API Reference

EditorProps

className
string

Additional CSS classes to apply to the editor container.

editorRef
Ref<EditorHandle>

Ref to access the editor instance and methods.

defaultValue
JSONContent | string

Initial content for the editor. Can be HTML string or Tiptap JSON format.

extraExtensions
Extensions

Additional Tiptap extensions to include in the editor.

onUpdate
function

Callback fired when editor content changes.

onUpdate?: (props: EditorEvents["update"]) => void
isSaving
boolean

Show saving indicator in the toolbar.

onSelectionUpdate
function

Callback fired when text selection changes.

onSelectionUpdate?: (props: EditorEvents["selectionUpdate"]) => void
disableEditable
boolean

Make the editor read-only. Defaults to false.

onCitationClick
function

Callback fired when a citation is clicked.

onCitationClick?: (citations: Citation[]) => void

EditorHandle

The editorRef provides access to the underlying Tiptap editor instance:

editor
Editor | null

The Tiptap editor instance with full API access.

// Access editor methods
const content = editorRef.current?.editor?.getHTML();
const isEmpty = editorRef.current?.editor?.isEmpty;

// Execute commands
editorRef.current?.editor?.chain().focus().toggleBold().run();

Built-in Extensions

The RichTextEditor comes with a comprehensive set of pre-installed extensions:

  • Bold, Italic, Underline - Basic text styling
  • Strikethrough - Strike through text
  • Code - Inline code formatting
  • Superscript/Subscript - Scientific notation
  • Text Align - Left, center, right, justify

Workflow Integration

Saving to Task State

Integrate with the workflow system to persist editor content:

import { RichTextEditor } from "@samplehc/ui/components";
import { useTaskState } from "@samplehc/ui/lib";
import { useRef, useEffect } from "react";

function PersistentEditor() {
  const [content, setContent] = useTaskState("documentContent", "");
  const [isSaving, setIsSaving] = useState(false);
  const editorRef = useRef();

  const handleUpdate = async ({ editor }) => {
    setIsSaving(true);
    const html = editor.getHTML();
    
    // Debounce saves to avoid too frequent updates
    setTimeout(() => {
      setContent(html);
      setIsSaving(false);
    }, 1000);
  };

  return (
    <RichTextEditor
      editorRef={editorRef}
      defaultValue={content}
      onUpdate={handleUpdate}
      isSaving={isSaving}
    />
  );
}

Document Templates

Create reusable document templates:

import { RichTextEditor } from "@samplehc/ui/components";

const MEDICAL_REPORT_TEMPLATE = `
<h1>Medical Report</h1>
<h2>Patient Information</h2>
<p><strong>Patient Name:</strong> [Patient Name]</p>
<p><strong>Date of Birth:</strong> [DOB]</p>
<p><strong>MRN:</strong> [Medical Record Number]</p>

<h2>Chief Complaint</h2>
<p>[Chief complaint...]</p>

<h2>History of Present Illness</h2>
<p>[HPI details...]</p>

<h2>Assessment and Plan</h2>
<p>[Assessment and plan...]</p>

<h2>Physician Signature</h2>
<p>[Physician name and credentials]</p>
<p>[Date signed]</p>
`;

function MedicalReportEditor() {
  return (
    <RichTextEditor
      defaultValue={MEDICAL_REPORT_TEMPLATE}
      onUpdate={({ editor }) => {
        // Auto-save functionality
        localStorage.setItem("medical-report-draft", editor.getHTML());
      }}
    />
  );
}

Keyboard Shortcuts

The editor supports standard keyboard shortcuts for efficient editing:

Styling and Theming

The editor inherits styles from your application’s theme and can be customized:

import { RichTextEditor } from "@samplehc/ui/components";

function StyledEditor() {
  return (
    <RichTextEditor
      className="min-h-[400px] max-h-[800px] border-2 border-primary"
      defaultValue="<p>Custom styled editor</p>"
    />
  );
}

The editor uses CSS classes that are compatible with Tailwind CSS and can be styled using your existing design system.

Citation System

The citation system allows linking text segments to source documents:

// Citations are created by wrapping text in citation-paragraph elements
const citedText = `
<p>According to the lab results 
<citation-paragraph data-citations='[{"documentId": "lab-123", "pageNumber": 2, "section": "Blood Work"}]'>
the patient's glucose levels are within normal range
</citation-paragraph>.</p>
`;

Best Practices

Performance: For large documents, consider implementing lazy loading or pagination to maintain smooth editing performance.

Auto-save: Implement debounced auto-saving to prevent data loss while avoiding excessive API calls.

Content Validation: Always validate and sanitize content before saving, especially when accepting user input.

Accessibility: The editor includes built-in accessibility features. Ensure any custom extensions also follow accessibility guidelines.