# halkyon_editor Halkyon's rich text, shared by its apps: the document as an app keeps it, the one editor and the one read-only view of it, built on [`appflowy_editor`](https://github.com/AppFlowy-IO/appflowy-editor) (our fork, pinned, as every app's), with their texts in British English, American English and German. Moved out of Halkyon Learn on 6 Nov 2026, when Halkyon Todo took editor documents too (ADR 0033, D37). ## Using it An app installs `HalkyonEditorLocalizations.delegate` beside its other delegates, and halkyon_ui's, whose sheets the Insert menu opens in. ```dart // Stored: RichContent is the editor's document JSON and its format's version. final content = RichContent.plain('Buy milk'); // or RichContent.empty() content.plainText; // 'Buy milk' content.isBlank; // false final stored = content.toJson(); RichContent.fromJson(stored); RichContentEditor( initialContent: content, onChanged: (content) => save(content), formatBar: true, ); RichContentView(content: content); ``` ## What it holds - **`RichContent`** (`lib/src/content/`): pure Dart, the document in JSON. `content_blocks.dart` names every block's type and attributes across the apps, for `plainText` and for what a block's type is called for good. - **`RichContentEditor`, `RichContentView`** (`lib/src/editor/`): the editor, with the `FormatBar` docked below it while it has the focus, copying and pasting that keep the formats (`EditorClipboard`), links (`editLink`, Ctrl+K) and superscript and subscript; the view, display only, taking the height of its content. - **`EditorBlocks`**: what an editor knows. `basicBlocks` is what it knows without an app (the editor's own builders; headings, lists, a checklist, a quote, a divider and a table to insert). An app adds its own blocks, and passes them as `blocks:` or through `EditorBlocksScope`, with: - `builders`, `insertable` (the Insert sheet and the desktop's `/` menu show the same list) and `shortcuts`; - `textMarks`, how marks of its own are drawn, each wrapping the one before it, and `formatActions`, their buttons, after subscript; - `onEditorClosed`, for what its text left outside the editor. `plus` joins two sets, `offering` narrows what is offered and nothing else. - **`AtomicBlock`, `BlockNotice`**: for an app's block taken whole, selected and removed as one. A type nothing knows shows as needing a newer app, and stays as it is. `RichContentEditor`'s `wrapEditor` puts what an app adds around the editor itself, knowing its state and focus (Learn's check of the spelling). Editors are tested as in Learn: host one in a scrollable body with a slot of fixed height, `pump(const Duration(seconds: 1))` after changes, and find its text with `findRichText: true`. ## Licence GNU Affero General Public License, version 3 or any later version (`AGPL-3.0-or-later`), as the other packages of the apps; see [LICENSE](LICENSE).