@jonahschulte/rtf-editor
v0.3.0
Published
React WYSIWYG editor for RTF documents with track changes support
Maintainers
Readme
@jonahschulte/rtf-editor
React WYSIWYG editor for RTF documents with track changes support.
Features
- WYSIWYG Editing - Rich text editing powered by Quill
- Track Changes Support - Visual display of insertions and deletions
- Accept/Reject Changes - Individual or bulk change management
- Multiple View Modes - Markup, Final, and Original views
- Customizable Styling - Custom colors for track changes
- Responsive Design - Works on desktop and mobile
Installation
npm install @jonahschulte/rtf-editorPeer Dependencies
npm install react react-domUsage
Basic Usage
import { useState } from 'react';
import { RTFEditor } from '@jonahschulte/rtf-editor';
function App() {
const [rtfContent, setRtfContent] = useState('');
return (
<RTFEditor
value={rtfContent}
onChange={(rtf, html) => setRtfContent(rtf)}
showSidebar
showTrackChangesToolbar
/>
);
}With Track Changes Callbacks
import { RTFEditor } from '@jonahschulte/rtf-editor';
function App() {
const handleTrackChangesUpdate = (doc, changes) => {
console.log(`${changes.length} changes remaining`);
};
return (
<RTFEditor
value={rtfContent}
onChange={handleChange}
onTrackChangesUpdate={handleTrackChangesUpdate}
showSidebar
showTrackChangesToolbar
/>
);
}Custom Colors
<RTFEditor
value={rtfContent}
onChange={handleChange}
trackChangesColors={{
insertionColor: '#e6ffe6',
deletionColor: '#ffe6e6',
insertionBorderColor: '#00cc00',
deletionBorderColor: '#cc0000',
}}
/>Read-Only Mode
<RTFEditor
value={rtfContent}
readOnly
showSidebar
defaultViewMode="final"
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | '' | RTF content |
| onChange | (rtf: string, html: string) => void | - | Called when content changes |
| onTrackChangesUpdate | (doc, changes) => void | - | Called when changes are accepted/rejected |
| readOnly | boolean | false | Disable editing |
| allowEditingWithChanges | boolean | false | Allow editing when track changes exist (not recommended) |
| placeholder | string | 'Start typing...' | Placeholder text |
| showSidebar | boolean | true | Show track changes sidebar |
| showTrackChangesToolbar | boolean | true | Show track changes toolbar |
| defaultViewMode | 'markup' \| 'final' \| 'original' | 'markup' | Initial view mode |
| className | string | '' | Custom CSS class |
| height | string \| number | 400 | Editor height |
| toolbarOptions | array | - | Custom Quill toolbar options |
| trackChangesColors | object | - | Custom colors for track changes |
View Modes
| Mode | Description |
|------|-------------|
| markup | Shows all changes with visual styling (green for insertions, red strikethrough for deletions) |
| final | Shows the document as if all changes were accepted |
| original | Shows the document as if all changes were rejected |
Read-Only Mode with Track Changes
By default, the editor becomes read-only when unresolved track changes exist. This prevents data loss and confusion:
- ✅ Prevents edits from being lost when accepting/rejecting changes
- ✅ Clear workflow: resolve all changes first, then edit the clean document
- ✅ Visual indicator explains why editing is disabled
- ✅ Matches behavior of professional editors like Microsoft Word
To enable editing:
- Accept or reject all track changes to remove them
- Or set
allowEditingWithChanges={true}to override (not recommended)
Why read-only by default?
When you edit a document with track changes and then accept/reject a change, the entire document structure is regenerated to apply the change. Any edits you made will be lost because they exist only in the HTML layer, not the underlying RTF structure. Read-only mode prevents this confusion.
Undo/Redo Track Changes
The editor supports undoing and redoing track changes operations (accept/reject):
- Keyboard shortcuts:
Ctrl/Cmd + Z- Undo last accept/reject operationCtrl/Cmd + Shift + Z- Redo last undone operation
- Toolbar buttons: Undo and Redo buttons appear in the track changes toolbar when available
- Automatic: Undo stack is cleared when loading new documents
- Scope: Only affects accept/reject operations, not content editing (which uses Quill's built-in undo)
Components
The package also exports individual components for custom layouts:
import {
RTFEditor,
TrackChangesSidebar,
TrackChangesToolbar
} from '@jonahschulte/rtf-editor';Known Limitations
Lossy HTML-to-RTF Conversion
When editing content in the WYSIWYG editor, the onChange callback provides both RTF and HTML. However, the HTML-to-RTF conversion is lossy and will not preserve:
- Track changes metadata (insertions, deletions, author info, timestamps)
- Custom fonts (defaults to Times New Roman)
- Color tables
- Revision tables
- Other RTF-specific formatting
This is because:
- The editor uses Quill (HTML-based) for WYSIWYG editing
- Quill doesn't understand RTF-specific concepts like track changes
- The
convertHTMLToRTFfunction creates a new RTF document from scratch
Recommendations:
- Use this editor primarily for viewing RTF documents with track changes
- For editing, consider storing the HTML output separately
- If you need to preserve the original RTF, keep a copy and only use the HTML for display
- Accept/reject track changes through the UI before editing content
Debounced onChange
The onChange callback is debounced (500ms) to prevent performance issues during rapid typing. This means:
- Changes are not emitted on every keystroke
- The callback fires 500ms after the user stops typing
- This is intentional to avoid re-render loops
Related
- @jonahschulte/rtf-toolkit - Core RTF parsing and rendering library
License
MIT
