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
Basic Editor
Read-only Viewer
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
Additional CSS classes to apply to the editor container.
Ref to access the editor instance and methods.
Initial content for the editor. Can be HTML string or Tiptap JSON format.
Additional Tiptap extensions to include in the editor.
Callback fired when editor content changes.
onUpdate ?: ( props : EditorEvents [ "update" ]) => void
Show saving indicator in the toolbar.
Callback fired when text selection changes.
onSelectionUpdate ?: ( props : EditorEvents [ "selectionUpdate" ]) => void
Make the editor read-only. Defaults to false.
Callback fired when a citation is clicked.
onCitationClick ?: ( citations : Citation []) => void
EditorHandle
The editorRef
provides access to the underlying Tiptap editor instance:
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:
Text Formatting Structure Healthcare-Specific Media & Links
Bold, Italic, Underline - Basic text styling
Strikethrough - Strike through text
Code - Inline code formatting
Superscript/Subscript - Scientific notation
Text Align - Left, center, right, justify
Bold, Italic, Underline - Basic text styling
Strikethrough - Strike through text
Code - Inline code formatting
Superscript/Subscript - Scientific notation
Text Align - Left, center, right, justify
Headings - H1 through H6 headings
Paragraphs - Standard paragraph blocks
Lists - Ordered and unordered lists
Blockquotes - Quote formatting
Code Blocks - Multi-line code with syntax highlighting
Citations - Link text to source documents
Page Breaks - Insert page breaks for printing
Image Resizer - Resize images with handles
Document Structure - Headers, footers, sections
Images - Insert and resize images
Links - Hyperlink support
Tables - Create and edit tables
Horizontal Rules - Section dividers
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:
Ctrl/Cmd + B - Bold
Ctrl/Cmd + I - Italic
Ctrl/Cmd + U - Underline
Ctrl/Cmd + Shift + S - Strikethrough
Ctrl/Cmd + E - Inline code
Ctrl/Cmd + Alt + 1-6 - Headings H1-H6
Ctrl/Cmd + Shift + 7 - Ordered list
Ctrl/Cmd + Shift + 8 - Bullet list
Ctrl/Cmd + Shift + 9 - Blockquote
Ctrl/Cmd + Alt + C - Code block
Ctrl/Cmd + Z - Undo
Ctrl/Cmd + Y - Redo
Ctrl/Cmd + A - Select all
Ctrl/Cmd + K - Insert link
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:
Creating Citations Handling Citation Clicks Citation Data Structure // 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>
` ;
// 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>
` ;
function DocumentWithCitations () {
const handleCitationClick = ( citations ) => {
// Navigate to source document
citations . forEach ( citation => {
console . log ( "Source:" , citation . documentId );
console . log ( "Page:" , citation . pageNumber );
// Open document viewer or navigate to source
});
};
return (
< RichTextEditor
onCitationClick = { handleCitationClick }
defaultValue = { citedText }
/>
);
}
type Citation = {
documentId : string ;
pageNumber ?: number ;
section ?: string ;
startIndex ?: number ;
endIndex ?: number ;
metadata ?: Record < string , unknown >;
};
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.