@fvc/richtext
v1.6.10
Published
`@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 `v
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