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
Toolbar end slot
Variants
Disabled
Invalid
API
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "outline" | "soft" | "outline" | Visual style of the editor |
disabled | boolean | false | Disable the editor |
invalid | boolean | false | Mark as invalid |
placeholder | string | — | Placeholder text when empty |
value | string | — | Controlled markdown value |
defaultValue | string | — | Initial markdown for uncontrolled mode |
onChange | (markdown: string) => void | — | Called on content change |
toolbarEnd | ReactNode | — | Content rendered at the end of the toolbar |
rows | number | 1 | Minimum visible rows |
id | string | — | id of the editable element (Field sets it) |
aria-label | string | — | Accessible name of the editable element |
aria-labelledby | string | — | Id of the element that names the editor, such as a visible label |
aria-describedby | string | — | aria-describedby of the editable element (Field sets it) |
aria-invalid | boolean | — | Sets aria-invalid on the editable element and the invalid style (Field sets it with errorMessage) |
className | string | — | 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 (defaultvar(--color-border-danger-outline))--input-outline-border-color: outline border color (defaultvar(--color-border-primary-outline))--input-outline-border-color-focus: outline border color focus (defaultvar(--alpha-50))--input-outline-border-color-hover: outline border color hover (defaultlight-dark(var(--alpha-25), var(--alpha-30)))--input-placeholder-text-color: placeholder text color (defaultvar(--color-text-tertiary))--input-soft-background-color: soft background color (defaultvar(--color-background-primary-soft-alpha))--input-soft-border-color-focus: soft border color focus (defaultvar(--alpha-20))--link-primary-text-color: primary text color (defaultlight-dark(var(--blue-500), var(--blue-300)))