@domternal/angular
v1.2.0
Published
MIT-licensed Angular components for the Domternal rich text editor
Maintainers
Readme
@domternal/angular
Angular components for the Domternal editor: six standalone,
signals-driven, OnPush, zoneless-ready components that wrap the headless core with
Angular-native APIs. DomternalEditorComponent implements ControlValueAccessor, so
it drops into ngModel and reactive forms. The toolbar, bubble menu, floating menu,
emoji picker, and Notion color picker auto-render from the extensions you load.
Links
Website • Documentation • Live examples
Install
pnpm add @domternal/angular @domternal/core @domternal/theme@angular/core (>=17.1), @angular/forms (>=17.1), @angular/platform-browser (>=17.1), and @domternal/core (>=1.2.0 <2.0.0)
are peer dependencies. Add the theme (@domternal/theme)
to your global stylesheet (e.g. styles.scss):
@use '@domternal/theme';This package is part of the coordinated Domternal 1.2.0 release.
Upgrade installed @domternal/* packages together.
Usage
import { Component, signal } from '@angular/core';
import {
DomternalEditorComponent,
DomternalToolbarComponent,
DomternalBubbleMenuComponent,
} from '@domternal/angular';
import { Editor, StarterKit, BubbleMenu } from '@domternal/core';
@Component({
selector: 'app-editor',
imports: [
DomternalEditorComponent,
DomternalToolbarComponent,
DomternalBubbleMenuComponent,
],
template: `
@if (editor(); as ed) {
<domternal-toolbar [editor]="ed" />
}
<domternal-editor
[extensions]="extensions"
[content]="content"
(editorCreated)="editor.set($event)"
/>
@if (editor(); as ed) {
<domternal-bubble-menu [editor]="ed" />
}
`,
})
export class EditorComponent {
editor = signal<Editor | null>(null);
extensions = [StarterKit, BubbleMenu];
content = '<p>Hello from Angular!</p>';
}The toolbar and bubble menu render their buttons from the loaded extensions, so no manual button wiring is needed.
Presets
preset="notion" switches the editor to the Notion-style experience in one input. It paints
the dm-notion-mode class on the component host for you, and preset-aware code follows it:
the bubble menu serves the Notion text context, and images offer align controls instead of
float. 'classic' is the default, and the input is read once, when the editor is created.
<domternal-editor [extensions]="extensions" preset="notion" />Localization
Pass an I18nOptions object through the reactive i18n input. Replacing it updates
the existing editor and its open UI without recreating the editor or changing authored
content. The wrapper has no locale subpath: its built-in toolbar, menus, and pickers use
deMessages and deSearchAliases from @domternal/core/locales/de. Merge locale entries
from any loaded extensions. See the i18n guide
for the catalog shape, English fallback, and live language switching.
<domternal-editor [extensions]="extensions" [i18n]="german" />Toolbar, bubble-menu, and floating-menu icons inputs accept raw SVG through IconSet.
Use only trusted, developer-authored constants. Never build an IconSet from user input,
persisted document content, or an API response.
Reactive forms
DomternalEditorComponent is a ControlValueAccessor, so it binds directly to
ngModel or a FormControl. Set outputFormat="json" to emit JSON instead of HTML;
calling disable()/enable() on the bound FormControl toggles the editor's editable
state.
import { Component } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { DomternalEditorComponent } from '@domternal/angular';
import { StarterKit } from '@domternal/core';
@Component({
selector: 'app-form-editor',
imports: [ReactiveFormsModule, DomternalEditorComponent],
template: `
<domternal-editor [extensions]="extensions" [formControl]="editorControl" />
`,
})
export class FormEditorComponent {
extensions = [StarterKit];
editorControl = new FormControl('<p>Initial content</p>');
}Components
All components are standalone (no NgModule). Import them directly from
@domternal/angular:
DomternalEditorComponent(<domternal-editor>): the editor, withextensions/history/content/editable/preset/i18n/autofocus/outputFormatinputs (extensions,content,editable,i18n, andoutputFormatare reactive; the rest are read once at creation),editorCreated,contentUpdated,selectionChanged,focusChanged,blurChanged, andeditorDestroyedoutputs, and read-onlyhtmlContent,jsonContent,isEmpty,isFocused,isEditablesignals.DomternalToolbarComponent(<domternal-toolbar>): auto-rendered formatting toolbar with keyboard navigation, customicons, andlayoutoverrides.DomternalBubbleMenuComponent(<domternal-bubble-menu>): inline selection menu withitems/contexts/shouldShowcontrols and content projection.DomternalFloatingMenuComponent(<domternal-floating-menu>): insert menu shown on empty lines.DomternalEmojiPickerComponent(<domternal-emoji-picker>): searchable emoji panel, driven by anemojis: EmojiPickerItem[]input.DomternalNotionColorPickerComponent(<domternal-notion-color-picker>): Notion-style text and background color palette.
DEFAULT_EXTENSIONS ([Document, Paragraph, Text, BaseKeymap, History]) and the core
Editor class plus Content, AnyExtension, FocusPosition, I18nOptions, Messages,
and JSONContent types are re-exported for convenience.
