Forms
Editor
A rich text editor that stays out of the way: a calm toolbar, a menu above selected text, blocks behind a slash, Markdown shortcuts, and clean HTML or JSON out.
Installation #
With the Nuxt module, every component is auto-imported — there is nothing to add. In a plain Vue project, import what you use:
import { JEditor } from '@juxtui/ui/editor'Usage #
<script setup lang="ts">
import { JEditor } from '@juxtui/ui/editor'
const content = ref('<p>Hello</p>')
</script>
<template>
<JEditor v-model="content" label="Post" />
</template>The editor is its own entry point, @juxtui/ui/editor, so apps that don’t use it never load its engine. With the Nuxt module, JEditor is auto-imported like everything else.
Under the hood it runs on Tiptap (ProseMirror), which handles the hard parts of editing: undo history, pasting from Word or Google Docs, IME input and nested lists. The interface, keyboard model and styling are juxt.ui.
Markdown shortcuts work while typing: # to ### for headings, - or * for lists, 1. for numbered lists, [ ] for to-dos, > for quotes, three backticks for code and --- for a divider.
Pasted and linked URLs are cleaned up: javascript: links are refused, bare domains get https://, and email addresses become mailto: links.
Variants & examples #
Comment box#
toolbar="minimal" keeps only marks, link and lists. Slash commands are off.
Field with a limit#
Label, description and error work like Input. limit counts characters and stops typing at the limit.
Read-only#
Render stored content with the same typography, without a toolbar.
API #
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| modelValue | string | JSONContent | '' | Content, bound with v-model. An empty document is an empty string. |
| format | 'html' | 'json' | 'html' | Shape of v-model: HTML, or ProseMirror JSON for structured storage. |
| label | string | — | Visible label; names the editing area. |
| description | string | — | Supporting text under the editor. |
| error | string | boolean | — | Error message, or true to mark it invalid. |
| placeholder | string | 'Write something, or type / for blocks…' | Shown while the document is empty. |
| toolbar | 'full' | 'minimal' | false | 'full' | Which toolbar to show. |
| bubbleMenu | boolean | true | Formatting menu above selected text. |
| slashCommands | boolean | true | Type / on a line for a menu of blocks. |
| limit | number | — | Maximum characters. Shown in the footer and enforced while typing. |
| showCount | boolean | false | Word and character count in the footer. |
| minHeight | string | '10rem' | Height of the writing area before it grows. |
| maxHeight | string | — | Height after which the writing area scrolls. |
| readonly | boolean | false | Show content without editing. |
| disabled | boolean | false | Not editable, visually muted. |
| required | boolean | false | Marks the field as required. |
| autofocus | boolean | 'start' | 'end' | false | Focus on mount. |
Events
| Event | Payload | Description |
|---|---|---|
| update:modelValue | string | JSONContent | On every change. |
| ready | Editor | The Tiptap editor instance, for advanced use. |
| focus, blur | — | The writing area gained or lost focus. |
Slots
| Slot | Props | Description |
|---|---|---|
| toolbar-end | { editor } | Extra controls before undo and redo. |
| label | — | Custom label content. |
Methods
| Method | Signature | Description |
|---|---|---|
| focus(position?) | (position?: 'start' | 'end') => void | Focus the writing area. |
| clear() | () => void | Empty the document. |
| editor | Editor | The underlying Tiptap editor. |
Accessibility #
- The writing area is
role="textbox"witharia-multiline, labelled by the field label and described by its description or error. - The toolbar is a single tab stop with arrow-key navigation (
role="toolbar"). Toggle buttons exposearia-pressed; every button has a label and a tooltip with its shortcut. - While the slash menu is open, the textbox points at it with
aria-controlsandaria-activedescendant, so screen readers announce the highlighted block while focus stays in the text. - Clicking toolbar buttons never steals the selection, so formatting applies to what you selected.
- To-do checkboxes are real checkboxes, operable with Space.
Keyboard #
| Key | Action |
|---|---|
| ⌘B | Bold. Also ⌘I italic, ⌘U underline, ⌘E inline code, ⌘⇧S strikethrough, ⌘⇧H highlight. |
| ⌘K | Add or edit a link at the selection. Enter applies, Esc cancels. |
| / | On a line: open the block menu. ↑ ↓ to choose, Enter or Tab to insert, Esc to close. |
| Tab | In a list: indent. Shift Tab outdents. |
| ⌘Z | Undo. ⌘⇧Z redoes. |
| ←→ | In the toolbar: move between tools. Tab leaves the toolbar. |