Skip to main content

Rich Content

Imports

import {
DefaultContentEditableAdapter,
RichContentService,
type RichContentConfig,
} from '@codella-software/utils/rich-content'
import {
RichContentProvider,
useRichContent,
useRichContentContext,
} from '@codella-software/react'

Core service

const service = RichContentService.create({
enableHistory: true,
maxHistorySteps: 100,
placeholder: 'Write something…',
})

service.insertText('Hello')
service.toggleMark('bold')
service.insertHeading(2)
service.insertList('unordered')
service.undo()

Public methods include:

  • getContent$()
  • getState$()
  • getCanUndo$()
  • getCanRedo$()
  • getIsFocused$()
  • getMentions$()
  • getSelectedFormats$()
  • getContent()
  • getState()
  • getPlainText()
  • attachAdapter(adapter)
  • detachAdapter()
  • getAdapter()
  • insertText(text, marks?)
  • insertParagraph()
  • insertHeading(level)
  • insertImage(url, attrs?)
  • uploadImage(file)
  • insertMention(id, label, meta?)
  • insertList(listType)
  • toggleMark(mark)
  • deleteContent()
  • setFocus(focused)
  • setSelection(selection)
  • undo()
  • redo()
  • clearHistory()

React hook

function Editor() {
const editorRef = useRef<HTMLDivElement>(null)
const {
content,
isFocused,
canUndo,
canRedo,
selectedFormats,
toggleMark,
insertHeading,
undo,
redo,
setFocus,
} = useRichContent({
editorRef,
placeholder: 'Write something…',
})

return (
<>
<button onClick={() => toggleMark('bold')}>
{selectedFormats.has('bold') ? 'Bold ✓' : 'Bold'}
</button>
<button onClick={() => insertHeading(2)}>H2</button>
<button onClick={undo} disabled={!canUndo}>Undo</button>
<button onClick={redo} disabled={!canRedo}>Redo</button>
<div
ref={editorRef}
contentEditable
suppressContentEditableWarning
onFocus={() => setFocus(true)}
onBlur={() => setFocus(false)}
style={{ minHeight: 160, border: isFocused ? '2px solid #3b82f6' : '1px solid #ccc' }}
/>
<pre>{JSON.stringify(content, null, 2)}</pre>
</>
)
}

useRichContent() returns:

  • service
  • content
  • state
  • isFocused
  • canUndo
  • canRedo
  • selectedFormats
  • selection
  • isDirty
  • insertText
  • insertParagraph
  • insertHeading
  • insertImage
  • uploadImage
  • insertMention
  • insertList
  • toggleMark
  • deleteContent
  • undo
  • redo
  • clearHistory
  • focus
  • setFocus
  • getPlainText
  • setSelection

Provider pattern

function RichEditor() {
return (
<RichContentProvider config={{ placeholder: 'Write something…' }}>
<Toolbar />
</RichContentProvider>
)
}

function Toolbar() {
const { service } = useRichContentContext()
return <button onClick={() => service.toggleMark('bold')}>Bold</button>
}