Markdown Editor

Compact rich text editor powered by Tiptap, embedded in a form field, with a markdown formatting toolbar, variants, and an invalid state.

import { MarkdownEditor } from "@plexui/ui/components/MarkdownEditor";

Examples

Placeholder

All formatting

With Field

Supports bold, italic, lists, and links.

Toolbar end slot

Variants

Disabled

Invalid

API

PropTypeDefaultDescription
variant"outline" | "soft""outline"Visual style of the editor
disabledbooleanfalseDisable the editor
invalidbooleanfalseMark as invalid
placeholderstring—Placeholder text when empty
valuestring—Controlled markdown value
defaultValuestring—Initial markdown for uncontrolled mode
onChange(markdown: string) => void—Called on content change
toolbarEndReactNode—Content rendered at the end of the toolbar
rowsnumber1Minimum visible rows
idstring—id of the editable element (Field sets it)
aria-labelstring—Accessible name of the editable element
aria-labelledbystring—Id of the element that names the editor, such as a visible label
aria-describedbystring—aria-describedby of the editable element (Field sets it)
aria-invalidboolean—Sets aria-invalid on the editable element and the invalid style (Field sets it with errorMessage)
classNamestring—Applied to the container

The editable element is a textbox with aria-multiline. A <label for>, including the label Field renders, cannot name a contenteditable region, so give the editor aria-label, or aria-labelledby pointing at a visible label. Toolbar buttons are toggles (aria-pressed) that follow the formatting at the caret, and a click in the text places the caret there. In the link dialog, Enter in a field saves the link, Enter on a button runs that button, Escape cancels, and Tab stays inside the dialog. onChange also fires once when the editor is created and whenever disabled changes.

Styling

Markdown Editor reads these component tokens. Override them at any scope to restyle it:

  • --input-border-color-invalid: border color invalid (default var(--color-border-danger-outline))
  • --input-outline-border-color: outline border color (default var(--color-border-primary-outline))
  • --input-outline-border-color-focus: outline border color focus (default var(--alpha-50))
  • --input-outline-border-color-hover: outline border color hover (default light-dark(var(--alpha-25), var(--alpha-30)))
  • --input-placeholder-text-color: placeholder text color (default var(--color-text-tertiary))
  • --input-soft-background-color: soft background color (default var(--color-background-primary-soft-alpha))
  • --input-soft-border-color-focus: soft border color focus (default var(--alpha-20))
  • --link-primary-text-color: primary text color (default light-dark(var(--blue-500), var(--blue-300)))