Skip to content

HyMarkdownEditor

Usage examples on this page are written for Lit / plain HTML (<hy-markdown-editor>). The same component ships as HyMarkdownEditor in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

Markdown editor with a CodeMirror 6 source pane and a unified-pipeline preview, presented either as a single pane with a Source ⇄ Preview toggle or as a side-by-side split.

The view prop picks the layout strategy. The default view="single" shows one pane with a Source ⇄ Preview eye toggle. view="auto" makes it responsive — a container query renders source + preview side-by-side when the editor is wide and collapses back to the single-pane toggle when it is narrow. view="split" pins the side-by-side layout with a draggable hy-splitter handle so the panes can be resized. In any split layout the preview refreshes live (debounced) as you type.

Examples

Basic (single pane with Source ⇄ Preview toggle)

html
<hy-markdown-editor label="Description" placeholder="Type Markdown..."></hy-markdown-editor>

Responsive (auto split when wide, eye toggle when narrow)

html
<hy-markdown-editor view="auto" label="Notes" value="# Live preview"></hy-markdown-editor>

Pinned side-by-side split

html
<hy-markdown-editor view="split" label="Notes" value="# Live preview"></hy-markdown-editor>

Mode-locked preview

html
<hy-markdown-editor mode="preview" no-mode-toggle value="# Hello"></hy-markdown-editor>

Autofocus inside a dialog (overlay-discovery contract)

html
<hy-dialog>
  <hy-markdown-editor autofocus autoselect value="# Existing"></hy-markdown-editor>
</hy-dialog>

API

Properties

PropertyAttributeTypeDefaultDescription
editorViewEditorView | nullAccess the live CM6 view. Public for tests / advanced consumers (e.g. wiring custom keymap extensions). Returns null before the widget has mounted (SSR, pre-firstUpdated).
uniqueIdunique-idstring''
valuevaluestring''
modemode'source' | 'preview''source'
viewview'auto' | 'single' | 'split''single'Pane layout strategy — single (default) | auto | split. Reflected so the container-query split rules in the stylesheet can branch on it. See MarkdownEditorView. The mode toggle still governs which pane shows in single-pane layouts; in a split layout both panes are visible and the toggle is hidden.
noModeToggleno-mode-togglebooleanfalse
placeholderplaceholderstring''
labellabelstring''
disableddisabledbooleanfalse
autofocusautofocusbooleanfalseFocus the source pane on first connect. Per .claude/rules/focus.md, this is primarily the marker overlay containers (dialog, drawer, popover) discover on show; secondarily a page-load focus shortcut with the same UX caveats as native HTML autofocus.
autoselectautoselectbooleanfalsePre-select the source-pane contents after autofocus (or after .focus() followed by .select()). Mirrors text-area / text-input.
namenamestring''Form-field name. Set when the editor participates in a <form>.
requiredrequiredbooleanfalseMarks the editor as required for form validation.
readonlyreadonlybooleanfalseRead-only: source pane is non-editable but still focusable.
spellcheckspellcheckbooleantrueOverride the default spellcheck="true" on the source pane. Note this shadows the inherited HTMLElement.spellcheck boolean — the inner textarea reads from this property only.
maxlengthmaxlengthnumber | nullnullMaximum character length of the markdown source.
minlengthminlengthnumber | nullnullMinimum character length of the markdown source.
uploadImageImageUploadHandler | undefinedHost-provided async upload hook. When set, the image dialog gains a drop/pick upload affordance (an embedded hy-file-upload); the host wires this to its asset store (e.g. Supabase Storage behind the Clerk session). When absent, the image dialog is URL-only. Library-side property, not an attribute — the consuming app injects the function.
acceptedImageTypesaccepted-image-typesstring'image/*'accept filter forwarded to the embedded hy-file-upload. Defaults to image/*.
maxImageBytesmax-image-bytesnumber | nullnullMax upload size in bytes, forwarded to hy-file-upload's max-size.

Events

EventDetailDescription
inputDetail { value: string }. Fired on every keystroke.
changeDetail { value: string }. Fired on blur after the value changed.
mode-changeDetail { mode, previous }. Fired when the mode-toggle button is clicked. Not fired for programmatic el.mode = ... assignment.
image-upload-startDetail { file: File }. Fired when a picked/dropped image starts uploading via the uploadImage callback.
image-upload-errorDetail { file: File, message: string }. Fired when the uploadImage callback rejects.

Slots

SlotDescription
extra-toolsExtra toolbar items, rendered in the toolbar's trailing cluster next to the mode toggle. Use for primary actions anchored to the editing surface (e.g. Save / Cancel on an editable document). Only visible while the toolbar is — source / split mode; hidden in single-pane preview. React mirror: the extraTools prop.

CSS Parts

PartDescription
baseOuter wrapper.
toolbarTop bar holding the formatting controls and mode toggle.
format-toolsLeading group of formatting controls (source mode only).
mode-toggleThe Source ⇄ Preview toggle button.
bodyThe editing / preview surface.
sourceThe source pane (CodeMirror 6 mount).
previewThe preview pane.
preview-skeletonLoading placeholder shown while the cold preview pipeline loads.
live-regionScreen-reader announcement region for mode pivots.
image-dialogThe insert-image dialog (hy-dialog).

CSS Custom Properties

PropertyDescription
--hy-markdown-editor-min-heightMinimum height of the body. Defaults to 12rem.
--hy-markdown-editor-padding-verticalVertical padding inside source / preview. Defaults to --hy-padding-form-md.
--hy-markdown-editor-padding-horizontalHorizontal padding inside source / preview. Defaults to --hy-padding-layout-lg.
--hy-markdown-editor-toolbar-padding-verticalVertical padding inside the toolbar. Defaults to --hy-padding-form-sm.
--hy-markdown-editor-toolbar-divider-heightHeight of the vertical toolbar separator. Defaults to --hy-icon-size-lg.
--hy-markdown-editor-gapGap between toolbar items. Defaults to --hy-gap-form-sm.
--hy-markdown-editor-radiusBorder radius of the outer wrapper. Defaults to --hy-radius-form-md.
--hy-markdown-editor-border-widthBorder width. Defaults to --hy-stroke-sm.
--hy-markdown-editor-border-colorBorder color. Defaults to --hy-border-default-rest.
--hy-markdown-editor-backgroundBackground color. Defaults to --hy-background-surface-base.
--hy-markdown-editor-foregroundForeground / text color. Defaults to --hy-foreground-default-rest.
--hy-markdown-editor-font-familySource-pane font family. Defaults to --hy-code-sm-font-family.

Methods

focus()

Focus the CM6 editor. No-op when the source pane can't be shown (single-pane preview) or before mount.

select()

Select the entire source-pane content. No-op when the source pane can't be shown.

Built with Lit. Documented with VitePress.