Usage
Rich Text Editor lets people create structured HTML for clinical notes, email and document templates, instructions, and other content that needs more formatting than a Textarea provides. Its Nord toolbar supports inline text styles, headings, lists, indentation, horizontal rules, tables, colours, undo and redo.
Rich Text Editor uses Tiptap as its editing engine. Nord owns the component API, toolbar composition, accessibility behavior and HTML compatibility contract, so applications do not need to interact with Tiptap directly.
The editor is an opt-in package entry because Tiptap and ProseMirror are larger than typical Nord components. Import it explicitly in applications that use rich text:
import "@nordhealth/components/lib/RichTextEditor"
Rich Text Editor renders its built-in label, hint and error on its own. Wrapped in a Field, the Field takes over with a Field Label, Field Description and Field Error, and the built-in versions step aside automatically.
The value is canonical HTML. Setting it updates the document without firing input or change; user edits fire input, followed by change when focus leaves the editor.
Composition
Rich Text Editor owns the value, form behavior and Tiptap document. Compose its public parts when a task needs a specific toolbar or toolbar placement. If the Toolbar or Content parts are omitted, the editor renders its standard toolbar preset and editable surface automatically.
RichTextEditor
├── RichTextEditorToolbar (optional; replaces the preset)
│ ├── RichTextEditorToolbarGroup (optional grouping)
│ │ └── RichTextEditorCommand
│ └── Application controls (optional)
└── RichTextEditorContent (optional; implicit when omitted)
<nord-rich-text-editor label="Visit summary">
<nord-rich-text-editor-toolbar>
<nord-rich-text-editor-toolbar-group label="Text formatting">
<nord-rich-text-editor-command command="bold"></nord-rich-text-editor-command>
<nord-rich-text-editor-command command="italic"></nord-rich-text-editor-command>
</nord-rich-text-editor-toolbar-group>
</nord-rich-text-editor-toolbar>
<nord-rich-text-editor-content></nord-rich-text-editor-content>
</nord-rich-text-editor>
Rich Text Editor Content
Rich Text Editor Content provides the editable document surface. Put it after the Toolbar for the conventional layout, or before the Toolbar to place controls below the document. Omit it to use the implicit surface after the toolbar.
Rich Text Editor Toolbar
Rich Text Editor Toolbar holds formatting commands and application-owned controls. A nested Toolbar replaces the toolbar preset and provides the complete keyboard interaction model, including Alt+F10 and roving arrow-key navigation.
Rich Text Editor Toolbar Group
Rich Text Editor Toolbar Group gives related commands an accessible group label and keeps their visual spacing consistent.
Rich Text Editor Command
Rich Text Editor Command connects a Nord-owned command and optional value to its nearest editor. It keeps command behavior, active state, localization and disabled state connected without exposing Tiptap.
Examples
Standalone or inside a Field
Use the editor on its own with its built-in label, hint and error, or wrap it in a Field so the Field provides the labelling. Both render the same editor:
Compose a toolbar
Choose, group and order only the controls the task needs. The nested toolbar takes precedence over the toolbar preset.
Use value for commands that need an option, and render them as menu items inside a Dropdown:
<nord-dropdown size="s">
<nord-button slot="toggle" type="button" size="s">Text colour</nord-button>
<nord-rich-text-editor-command
variant="menu-item"
command="text-color"
value="#0063a3"
label="Blue"
>Blue</nord-rich-text-editor-command>
</nord-dropdown>
Available commands are:
- Text:
bold,italic,underline,strike,subscript,superscriptandclear-formatting. - Structure:
bullet-list,ordered-list,indent,outdent,horizontal-rule,paragraph-format,undoandredo. - Text styles:
font-family,font-size,text-colorandbackground-color. Supply the chosen option withvalue. - Tables:
table. It renders the complete Nord dropdown for inserting and editing tables; individual table actions are internal.
Application controls and templates
Place application-owned controls directly in the composed toolbar. Nord buttons, dropdowns and native form controls join the same arrow-key navigation as editor commands. Call insertContent() to insert content at the preserved selection. The options specify format: "html" | "text", whether an active selection is replaced, and whether focus returns to the document. Active selections are replaced and focus is restored by default. Pass { replace: true } to replace the complete document as one undoable action. In this example the Content component comes first, placing the toolbar below the editable surface.
Toolbar presets
The default full toolbar covers the formatting used by legacy Froala fields. Use toolbar="compact" for text styles, clear formatting, undo and redo, or toolbar="none" when no toolbar is needed. Presets are convenience compositions built from the same public toolbar and command components.
Hint placement
Like other Nord data-entry components, Rich Text Editor shows hint text below the label by default. Set hint-below when the guidance should follow the editor and any error message instead.
Character limit and resizing
Set maxlength to limit user input by grapheme characters and add character-counter to show the current count. Existing controlled content that is already over the limit remains editable so users can shorten it.
The default resize="vertical" lets users drag the lower edge. Set resize="auto" to grow the editable surface with its content instead.
Pasting content
Pasting is plain text by default, which avoids carrying styles from external documents. Set paste-mode="formatted" when supported headings, lists, tables and inline styles should be preserved. In either mode, pasted HTML is filtered through the editor schema.
<nord-rich-text-editor
label="Email template"
paste-mode="formatted"
></nord-rich-text-editor>
Controlled HTML values
Read and write HTML through value. Listen to input for live synchronization and change for a committed edit. Programmatic assignments do not emit either event.
const editor = document.querySelector("nord-rich-text-editor")
editor.value = "<p>Patient is recovering well.</p>"
editor.addEventListener("input", () => {
saveDraft(editor.value)
})
The editor canonicalizes content through its schema before exposing or submitting it. Continue to validate and sanitize untrusted HTML at the application boundary, especially before rendering stored content outside the editor.
Autosaving
Rich Text Editor does not send or schedule saves itself because persistence and retry behavior belong to the application. Use input to trigger an existing autosave mechanism. The value property and the form-associated HTML value are both synchronized before input is dispatched.
const form = document.querySelector("form")
const editor = form.querySelector("nord-rich-text-editor")
editor.addEventListener("input", () => {
queueAutosave({
html: editor.value,
formValue: new FormData(form).get(editor.name),
})
})
Existing media
Data images used by label and QR templates are supported. Set media-origin to preserve existing HTTP or HTTPS images from one configured origin; remote images from other origins are removed.
<nord-rich-text-editor
label="Label template"
media-origin="https://media.example.com"
></nord-rich-text-editor>
Legacy Froala content
The schema preserves supported legacy content, including headings, paragraphs and empty paragraphs, blockquotes, list indentation, horizontal rules, tables, Froala table classes, column widths, cell background colours, label images and QR SVG. Scripts, iframes, event-handler attributes and unsupported remote media are removed.
Read-only review and rendered output
For an in-product read-only review, keep the value in the component and combine readonly with toolbar="none". The document remains focusable and submitted with its form while headings, paragraphs, lists, blockquotes, tables, images and QR SVG use the same Nord-token styles as the editable view.
<nord-rich-text-editor
label="Saved clinical notes"
name="clinical_notes"
readonly
toolbar="none"
></nord-rich-text-editor>
HTML rendered outside the component, including email, PDF and label output, does not inherit shadow-DOM styles. Sanitize it on the backend, retain the canonical rich-text-editor-table class during rendering, and apply the application’s audited output stylesheet. Transitional fr-* classes remain only for migration-era renderers.
Forms and validation
Add name to include the editor HTML in FormData. The editor supports form reset, disabled fieldsets, required, maxlength, checkValidity() and reportValidity(). Read-only content stays focusable and is submitted; disabled content is omitted.
<form>
<nord-rich-text-editor
label="Discharge instructions"
name="discharge_instructions"
required
></nord-rich-text-editor>
<nord-button type="submit" variant="primary">Save</nord-button>
</form>
Narrow layouts
The toolbar wraps at narrow inline sizes without causing page overflow. Keep the editor container wide enough for readable document content when possible.
RTL
Rich Text Editor follows the document or container direction. The toolbar order and arrow-key navigation mirror in right-to-left layouts.
Accessibility
- Always provide an accessible name with the built-in
labelor a Field Label connected withfor. - Press Alt+F10 from the document to move to the toolbar. Use arrow keys, Home and End between controls, and Escape or Tab to return to the document.
- Use
erroror a Field Error to communicate validation; the message is associated with the editor and is not conveyed by colour alone. - Use
readonlywhen content should remain readable, focusable and included in form submission. Usedisabledonly when the content and control are unavailable. - Give every application control in a composed toolbar clear text or an accessible label. It becomes part of the toolbar's keyboard order.
- The character counter announces the remaining count near the limit, while
maxlengthexposes the corresponding form validity state. - Keep the default plain-text paste mode unless preserving supported document formatting is necessary for the task.
Verification status
Automated coverage includes Axe checks for basic, required/error, readonly, disabled and RTL composed-toolbar states. Browser tests also cover keyboard commands, 320 CSS pixel reflow at 200% text, RTL navigation, and minimum 44 by 44 CSS pixel touch targets. Visual snapshots cover Nord and Vet light/dark themes, forced colours, editor states, long content, legacy content and narrow layouts.
Manual keyboard, NVDA, VoiceOver, system high-contrast/forced-colour, 200% text, 400% browser zoom, RTL and touch-device checks are required before the component can move beyond Alpha. Automated emulation is not a substitute for those checks.
API reference
RichTextEditor
Rich text editor lets users create structured, formatted HTML content.
<nord-rich-text-editor></nord-rich-text-editor>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
toolbar | toolbar | Controls which legacy-compatible formatting controls are shown. | ToolbarPreset | 'full' |
mediaOrigin | media-origin | Optional origin from which existing media images may be preserved. | string | undefined | — |
placeholder | placeholder | Placeholder text shown when the document is empty. | string | undefined | — |
pasteMode | paste-mode | Controls whether pasted content keeps schema-supported formatting. | PasteMode | 'plain' |
resize | resize | Controls whether the editable surface can be resized vertically or grows automatically. | 'vertical' | 'auto' | 'vertical' |
maxLength | maxlength | Controls the maximum number of plain-text grapheme characters users can enter. | number | undefined | — |
characterCounter | character-counter | Controls whether a plain-text grapheme character count is shown. | boolean | false |
size | size | The size of the component. | 's' | 'm' | 'l' | 'm' |
required | required | Determines whether the control is required or not.
A required control is announced as such to assistive technology and, inside
a <nord-field>, drives the required indicator on the <nord-field-label>.
When using this property you need to also set “novalidate” attribute on a form element to prevent browser from displaying its own validation errors. | boolean | false |
readonly | readonly | Makes the component readonly, so that it is not editable. Readonly differs from disabled in that readonly fields are still focusable and will be submitted with a form. | boolean | false |
disabled | disabled | Makes the component disabled. This prevents users from being able to interact with the component, and conveys its inactive state to assistive technologies. | boolean | false |
name | name | The name of the form component. | string | undefined | — |
value | value | The value of the form component. | string | '' |
form | form | Gets the form, if any, associated with the form element. The setter accepts a string, which is the id of the form. | HTMLFormElement | null | — |
Field properties
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
label | label | Label for the control. Ignored when the control is wrapped in a
<nord-field>, which provides the label via <nord-field-label>. | string | '' |
hint | hint | Optional hint text shown with the control. Ignored inside a <nord-field>,
which provides it via <nord-field-description>. | string | undefined | — |
hintBelow | hint-below | Renders the hint below the control and any error instead of below the label. | boolean | false |
hideLabel | hide-label | Visually hide the label, but still expose it to assistive technologies. | boolean | false |
error | error | Optional error shown with the control. Ignored inside a <nord-field>,
which provides it via <nord-field-error>. | string | undefined | — |
hideRequired | hide-required | Visually hide the required indicator, but still expose the required state to assistive technologies. | boolean | false |
Slots
| Slot name | Description |
|---|---|
label | Use when a label requires more than plain text. |
hint | Optional slot that holds hint text for the editor. |
error | Optional slot that holds error text for the editor. |
Default slot | Optional Rich Text Editor Content and Toolbar composition. |
additional-controls | Optional application-owned controls shown in the toolbar. |
Methods
| Method name | Parameters | Description |
|---|---|---|
checkValidity() => boolean | N/A | Returns whether the editor satisfies its validation constraints. |
reportValidity() => boolean | N/A | Reports validation errors and returns whether the editor is valid. |
focus(options?: FocusOptions) => void | options: FocusOptions | Programmatically move focus to the component. |
blur() => void | N/A | Programmatically remove focus from the component. |
click() => void | N/A | Programmatically simulates a click on the component. |
insertContent(content: string, options: RichTextEditorInsertContentOptions) => boolean | content: stringoptions: RichTextEditorInsertContentOptions | Inserts schema-limited HTML or literal text at the current selection.
By default an active selection is replaced and focus returns to the editor.
Pass replace: true to replace the complete document as one undoable action. |
| Event | Detail Type | Description |
|---|---|---|
input | NordEvent | Fired as the user edits content or applies an editor command. |
change | NordEvent | Fired when focus leaves the editor after its value changed. |
CSS Properties
CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.
| Property | Description | Default |
|---|---|---|
--n-rich-text-editor-inline-size | Controls the inline size of the editor. | 100% |
--n-rich-text-editor-block-size | Controls the minimum block size of the editable surface. | 160px |
--n-rich-text-editor-max-block-size | Controls the maximum block size of the editable surface. | 500px |
--n-rich-text-editor-background | Controls the editor background. | var(--n-color-surface) |
--n-rich-text-editor-color | Controls the editor text color. | var(--n-color-text) |
--n-rich-text-editor-border-color | Controls the editor border color. | var(--n-color-border-strong) |
Parts
This component is made up of the following parts.
Rich Text Editor Command
Command renders one formatting control for the nearest Rich Text Editor.
<nord-rich-text-editor-command></nord-rich-text-editor-command>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
command | command | The Nord-owned formatting control to render. | Command | undefined | — |
label | label | Optional accessible label that overrides the localized command label. | string | undefined | — |
value | value | Optional serializable value used by parameterized commands. | string | undefined | — |
variant | variant | Renders the command as a toolbar button or a dropdown item. | 'button' | 'menu-item' | 'button' |
Methods
| Method name | Parameters | Description |
|---|---|---|
focus(options?: FocusOptions) => void | options: FocusOptions | |
click() => void | N/A |
Rich Text Editor Content
Content provides the editable surface within a composed Rich Text Editor. Place it before or after a Rich Text Editor Toolbar to control the visual order.
<nord-rich-text-editor-content></nord-rich-text-editor-content>Rich Text Editor Toolbar
Toolbar composes formatting commands and application controls for a Rich Text Editor.
<nord-rich-text-editor-toolbar></nord-rich-text-editor-toolbar>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
label | label | Accessible label for the toolbar. Defaults to the editor's localized label. | string | undefined | — |
Slots
| Slot name | Description |
|---|---|
Default slot | Rich text command groups and application controls. |
Rich Text Editor Toolbar Group
Toolbar Group groups related Rich Text Editor commands.
<nord-rich-text-editor-toolbar-group></nord-rich-text-editor-toolbar-group>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
label | label | Accessible label describing the related commands. | string | '' |
Slots
| Slot name | Description |
|---|---|
Default slot | Related Rich Text Editor commands. |
Dependencies
This component is internally dependent on the following components:
- <nord-button>
Button
Buttons are used for interface actions. Primary style should be used only once per section for main call-to-action, while other styles can appear more frequently.
- <nord-dropdown>
Dropdown
Dropdown menu displays a list of actions or selectable options for a user. Dropdown uses popout component internally to create the overlay functionality.
- <nord-icon>
Icon
Icons are used to provide additional meaning or in places where text label doesn’t fit. Icon component allows you to display an icon from the Nordicons library.
- <nord-tooltip>
Tooltip
Tooltips are floating containers for displaying additional information for the currently focused element. A tooltip can be useful when you want to e.g. give a hint about an existing Command Menu shortcut.
- <nord-visually-hidden>
VisuallyHidden
Visually hidden is used when an element needs to be available to assistive technologies like screen readers, but be otherwise hidden.