Rich text / foldkit-mixins-richtext
The Markdown source editor
Source mode is SourceSession | null in the application's Model: foldkit-richtext-markdown's
openSource sets it, and closeSource ends it. While it is set, draw this instead of the rich
editor:
import { sourceEditor } from 'foldkit-mixins-richtext'
sourceEditor<Message>()(
{
session: model.source,
document: model.document,
drafted: draft => DraftedSource({ draft }),
moved: caret => MovedInSource({ caret }),
done: LeftSource(),
},
h,
)- The text area holds the draft and sends
draftedas it changes. When drawn it takes focus with its caret atsession.caret, whereopenSource(document, { selection })put the rich editor's caret, then sendsmovedas the caret moves. The application keeps that insession.caret, socloseSource(...).selectionis the caret back in the rich editor. The caret is placed when the text area appears, not on every render, since a Mount reads its args once. - The warnings under it name what switching back would lose or refuse, read from
closeSource, so there are none until the draft is edited. They are computed once per draft. doneis the way back. The application'supdatedecides whether to commitcloseSource(...).documentat once or to ask first when there are warnings.
Split mode is the same session drawn twice: sourcePreview<Message>()({ session, document,
rendering? }) beside the editor renders the document switching back would commit, through the
read-only renderer, so it dispatches nothing. It shares the editor's parse of the draft, and
while the draft is unedited it shows the document the application holds now.
| Slot | Capability | Renders |
|---|---|---|
root | Container | the editor's wrapper |
text | TextInput | the Markdown, data-source="text" |
warnings | Collection | the list, data-source="warnings" |
warning | Base | one loss, with data-code and data-detail for a Style to key on |
done | Interactive | the way back, data-source="done" |
What it does not draw
- The placeholder is the editor's own, placed with
editorAt, because it is drawn inside the editable subtree this package stays out of. - Positioning is
foldkit-richtext-dom/toolbar's:selectionAnchorfor a floating toolbar,blockAnchorandblockDragfor the handle.
Checks
pnpm --filter foldkit-mixins-richtext typecheck
pnpm vitest run packages/mixins-richtext/testsmoke/ checks the built richtext packages the way a consumer meets them: through each
package's exports map, from dist. Everything inside this workspace resolves them from
source, so nothing else catches a wrong exports path, a missing file, or a wrong types
condition. Build first, then:
pnpm build
pnpm --filter foldkit-mixins-richtext smoke