React rich text editor with track changes functionality
npm install react-smart-editorA modern React editor with change tracking capabilities, built on top of Slate.js.
- Rich text formatting
- Change tracking (additions and deletions)
- Personal change tracking for each user
- Change approval/rejection system
- Serialization support for database storage
- Full TypeScript support
- Modern React (hooks-based)
- Custom styles support
- Responsive design
- React 18 or higher
- TypeScript 5.0 or higher
- Support for modern browsers (Chrome, Firefox, Safari, Edge)
``bash`
npm install react-smart-editoror
yarn add react-smart-editor
`typescript
import {
ReactSmartEditor,
Document,
User,
serializeDocument,
deserializeDocument,
} from 'react-smart-editor'
import 'react-smart-editor/dist/index.css'
const MyEditor = () => {
const [document, setDocument] = useState
content: [
{
type: 'paragraph',
children: [{ text: 'Start editing...' }],
},
],
changes: [],
})
const user: User = {
id: 'userId',
name: 'John Doe',
color: '#ff0000',
role: 'editor',
}
const handleChange = (newDocument: Document) => {
setDocument(newDocument)
// Optional: serialization for storage
const serialized = serializeDocument(newDocument)
// Save to database...
}
const handleAutoSave = (newDocument: Document) => {
console.log('Auto save', newDocument)
}
return (
user={user}
onChange={handleChange}
onAutoSave={handleAutoSave}
onApprove={(changeId) => {
console.log('Change approved:', changeId)
}}
onReject={(changeId) => {
console.log('Change rejected:', changeId)
}}
/>
)
}
`
`typescript
import 'react-smart-editor/dist/index.css'
import './custom-styles.css'
// custom-styles.css
.editor-container {
border: 1px solid #ccc;
border-radius: 4px;
padding: 16px;
}
.toolbar {
background: #f5f5f5;
border-bottom: 1px solid #ddd;
}
`
| Prop | Type | Required | Description |
| ---------------------------- | ---------------------------- | -------- | ----------------------------------------------------------------- |
| initialContent | Document | Yes | Initial document content and changes |
| user | User | Yes | Current user information |
| readOnly | boolean | No | Read-only mode |
| placeholder | string | No | Placeholder for empty editor |
| formattingToolbarTop | number | No | Sticky top distance value |
| hideFormattingToolbarActions | boolean | No | Hides all formatting actions except approve and reject for owner |
| showOwnerChanges | boolean | No | By default true. if false - owner changes will not be highlighted |
| onChange | (document: Document) => void | No | Called when document unfocused |
| onAutoSave | (document: Document) => void | No | Called every 3 sec when document changes |
| onApprove | (changeId: string) => void | No | Called when a change is approved |
| onReject | (changeId: string) => void | No | Called when a change is rejected |
| onFocus | () => void | No | Called when document focused |
| onBlur | () => void | No | Called when document unfocused |
`typescript
interface Document {
content: Descendant[] // Slate nodes
changes: ChangeMetadata[]
hasOwnerChanges: boolean
}
interface User {
id: string
name: string
color: string
role: 'editor' | 'owner'
}
interface ChangeMetadata {
id: string
userId: string
userName: string
userColor: string
userRole: 'editor' | 'owner'
date: string
type: 'insert' | 'delete'
description: string
content: string
status: 'pending' | 'accepted' | 'rejected'
}
`
- serializeDocument(document: Document): SerializedDocument - Serialization for storagedeserializeDocument(serialized: SerializedDocument): Document` - Deserialization from storage
-
MIT