Package Exports
- @fvc/richtext
- @fvc/richtext/types
Readme
@fvc/richtext
@fvc/richtext provides a WYSIWYG rich text editor built on top of @cyber-wysiwyg/richtexteditor. It extends the base editor with HTML sanitization, a template dropdown, a custom link modal, and design-system integration for FE-VIS applications. The variant prop switches between a full toolbar editor and a compact input appearance.
Installation
bun add @fvc/richtextPeer Dependencies
The package expects these dependencies to be available in the consuming application:
bun add react antd @fvc/button @fvc/icons @cyber-wysiwyg/richtexteditorImport
import { Richtext } from '@fvc/richtext';Quick Start
import { Richtext } from '@fvc/richtext';
import { useState } from 'react';
export function NoteEditor() {
const [value, setValue] = useState('');
return <Richtext value={value} onChange={setValue} />;
}Common Usage
Basic Editor
<Richtext value={content} onChange={setContent} />Input Variant
The input variant renders a compact single-line editor suitable for short text fields.
<Richtext variant="input" value={value} onChange={setValue} />Error State
<Richtext error value={value} onChange={setValue} />Auto Sanitization
HTML from untrusted sources is sanitized automatically when autoSanitize is enabled.
<Richtext autoSanitize value={untrustedHtml} onChange={setValue} />Template Dropdown
Inject predefined text snippets from a map of label→value pairs.
<Richtext
enableTemplateDropdown
templateDropdownLabel="Templates"
templateMap={{
Greeting: 'Dear {{name}},',
Signature: 'Kind regards,\n{{sender}}',
}}
value={value}
onChange={setValue}
/>Custom Toolbar
Pass a function to extend the default toolbar settings.
<Richtext
toolbarSettings={(defaults) => ({
...defaults,
items: [...defaults.items, 'SourceCode'],
})}
value={value}
onChange={setValue}
/>Props
Extends all RichTextEditor props except toolbarSettings (see the custom toolbar example above).
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
'editor' | 'input' |
'editor' |
Switches between full toolbar editor and compact input mode. |
error |
boolean |
— | Applies error styling to the editor border. |
autoSanitize |
boolean |
— | Sanitizes HTML via DOMPurify on every value change. |
enableTemplateDropdown |
boolean |
— | Shows the template insertion dropdown in the toolbar. |
templateMap |
Record<string, string> |
— | Map of display label → template string to inject. |
templateDropdownLabel |
string |
— | Label shown on the template dropdown button. |
toolbarSettings |
ToolbarSettings | ((defaults: ToolbarSettings) => ToolbarSettings) |
— | Toolbar config or function that receives and mutates defaults. |
className |
string |
— | Additional CSS class names on the wrapper element. |
testId |
string |
— | Maps to data-testid on the root element. |
TypeScript
The package ships with type definitions. No @types/ install needed.
import type { RichTextProps, TemplateMap, LinkModalProps } from '@fvc/richtext/types';Consumer Example
import { Richtext } from '@fvc/richtext';
import { useState } from 'react';
export function ArticleEditor({ onSave }) {
const [body, setBody] = useState('');
return (
<Richtext
autoSanitize
enableTemplateDropdown
templateDropdownLabel="Insert snippet"
templateMap={{
Opening: '<p>Dear reader,</p>',
Closing: '<p>Thank you for reading.</p>',
}}
toolbarSettings={(defaults) => ({
...defaults,
items: defaults.items.filter((i) => i !== 'SourceCode'),
})}
value={body}
onChange={setBody}
/>
);
}Testing
Use testId to target the editor root in tests.
<Richtext testId="article-editor" value={value} onChange={setValue} />screen.getByTestId('article-editor');Customisation
@fvc/richtext exposes its visual tokens as CSS custom properties declared in src/styles/variables.scss. Override any of these in your own stylesheet — no fork, no file in the component, no re-bundle required.
/* consumer's own app stylesheet */
:root {
--richtext-error-border-color: #e53e3e;
--richtext-error-bg-color: #fff5f5;
--richtext-editor-bg-color: #fafafa;
}Available variables
| Variable | Default | Controls |
|---|---|---|
--richtext-default-border-radius |
4px |
Corner radius of the component wrapper |
--richtext-default-min-height |
83px |
Minimum height of the input variant |
--richtext-default-content-padding-y |
8px |
Top/bottom padding of the editable content area |
--richtext-editor-bg-color |
#f5f5f5 |
Background of the editor-variant outer shell |
--richtext-editor-min-height |
143px |
Minimum height of the editor variant |
--richtext-editor-content-bg-color |
#ffffff |
Background of the editor's inner content pane |
--richtext-editor-content-border-color |
#d1d1d1 |
Border color of the editor's inner content pane |
--richtext-editor-content-border-radius |
4px |
Corner radius of the editor's inner content pane |
--richtext-editor-content-max-width |
685px |
Max width of the editor's inner content pane |
--richtext-editor-content-padding |
16px |
Padding inside the editor's inner content pane |
--richtext-editor-content-fz |
12px |
Font size of text inside the editor content pane |
--richtext-editor-content-ff |
Arial, sans-serif |
Font family of text inside the editor content pane |
--richtext-error-border-color |
#ff1f48 |
Border color in the error state |
--richtext-error-bg-color |
#f5ece6 |
Background color in the error state |
--richtext-modal-overlay-bg |
rgba(0,0,0,0.4) |
Background of the modal overlay scrim |
--richtext-modal-bg-color |
#ffffff |
Background of the modal panel (link + special-char) |
--richtext-modal-border-radius |
8px |
Corner radius of the modal panel |
--richtext-modal-shadow |
0 4px 12px rgba(0,0,0,0.25) |
Box shadow of the modal panel |
--richtext-modal-text-color |
#333333 |
Text color used for modal headings and labels |
--richtext-modal-input-border-color |
#dddddd |
Default border color for text inputs inside modals |
--richtext-modal-input-border-radius |
4px |
Corner radius of text inputs inside modals |
--richtext-modal-input-focus-border-color |
#007acc |
Border color of focused text inputs inside modals |
--richtext-modal-input-focus-shadow |
0 0 0 2px rgba(0,122,204,0.2) |
Focus ring of text inputs inside modals |
--richtext-modal-char-btn-bg-color |
#ffffff |
Background of special-character grid buttons |
--richtext-modal-char-btn-border-color |
#dddddd |
Border of special-character grid buttons |
--richtext-modal-char-btn-hover-bg-color |
#f0f0f0 |
Background of special-character buttons on hover/focus |
--richtext-modal-char-btn-hover-border-color |
#aaaaaa |
Border of special-character buttons on hover/focus |
Development
bun run lint
bun run type-check
bun run test
bun run build