| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
modelValue | null | string | JSONContent | JSONContent[]
| |
contentType | 'json' | "json" | "html" | "markdown"The content type the content is provided as. |
starterKit | { headings: { levels: [1, 2, 3, 4] }, link: { openOnClick: false }, dropcursor: { color: 'var(--ui-primary)', width: 2 } } | Partial<StarterKitOptions>The starter kit options to configure the editor. |
placeholder | string | PlaceholderOptionsThe placeholder text to show in empty paragraphs.
| |
handlers | Partial<EditorHandlers>Custom item handlers to override or extend the default handlers. These handlers are provided to all child components (toolbar, suggestion menu, etc.). | |
extensions | ExtensionsThe extensions to use | |
injectCSS | boolean Whether to inject base CSS styles | |
injectNonce | stringA nonce to use for CSP while injecting styles | |
autofocus | null | number | false | true | "start" | "end" | "all"The editor's initial focus position | |
editable | boolean Whether the editor is editable | |
textDirection | "ltr" | "rtl" | "auto"The default text direction for all content in the editor. When set to 'ltr' or 'rtl', all nodes will have the corresponding dir attribute. When set to 'auto', the dir attribute will be set based on content detection. When undefined, no dir attribute will be added. | |
editorProps | EditorProps<any>The editor's props | |
parseOptions | ParseOptionsThe editor's content parser options
| |
coreExtensionOptions | { clipboardTextSerializer?: { blockSeparator?: string | undefined; } | undefined; delete?: { async?: boolean | undefined; filterTransaction?: ((transaction: Transaction) => boolean) | undefined; } | undefined; }The editor's core extension options
| |
enableInputRules | false | true | (string | AnyExtension)[]Whether to enable input rules behavior | |
enablePasteRules | false | true | (string | AnyExtension)[]Whether to enable paste rules behavior | |
enableCoreExtensions | boolean | Partial<Record<"editable" | "textDirection" | "delete" | "clipboardTextSerializer" | "commands" | "focusEvents" | "keymap" | "tabindex" | "drop" | "paste", false>> Determines whether core extensions are enabled. If set to | |
enableContentCheck | boolean If | |
emitContentError | boolean If | |
onBeforeCreate | (props: { editor: Editor; }): voidCalled before the editor is constructed. | |
onCreate | (props: { editor: Editor; }): voidCalled after the editor is constructed. | |
onMount | (props: { editor: Editor; }): voidCalled when the editor is mounted. | |
onUnmount | (props: { editor: Editor; }): voidCalled when the editor is unmounted. | |
onContentError | (props: { editor: Editor; error: Error; disableCollaboration: () => void; }): voidCalled when the editor encounters an error while parsing the content.
Only enabled if | |
onUpdate | (props: { editor: Editor; transaction: Transaction; appendedTransactions: Transaction[]; }): voidCalled when the editor's content is updated. | |
onSelectionUpdate | (props: { editor: Editor; transaction: Transaction; }): voidCalled when the editor's selection is updated. | |
onTransaction | (props: { editor: Editor; transaction: Transaction; appendedTransactions: Transaction[]; }): voidCalled after a transaction is applied to the editor. | |
onFocus | (props: { editor: Editor; event: FocusEvent; transaction: Transaction; }): voidCalled on focus events. | |
onBlur | (props: { editor: Editor; event: FocusEvent; transaction: Transaction; }): voidCalled on blur events. | |
onDestroy | (props: void): voidCalled when the editor is destroyed. | |
onPaste | (e: ClipboardEvent, slice: Slice): voidCalled when content is pasted into the editor. | |
onDrop | (e: DragEvent, slice: Slice, moved: boolean): voidCalled when content is dropped into the editor. | |
onDelete | (props: { editor: Editor; deletedRange: Range; newRange: Range; transaction: Transaction; combinedTransform: Transform; partial: boolean; from: number; to: number; } & ({ ...; } | { ...; })): voidCalled when content is deleted from the editor. | |
ui | { root?: ClassNameValue; content?: ClassNameValue; base?: ClassNameValue; } |
| Slot | Type |
|---|---|
default | { editor: Editor; handlers: EditorHandlers; } |
| Event | Type |
|---|---|
update:modelValue | [value: Content] |
export default defineAppConfig({
ui: {
editor: {
slots: {
root: '',
content: 'relative size-full flex-1',
base: [
'w-full outline-none *:my-5 *:first:mt-0 *:last:mb-0 sm:px-8 selection:bg-primary/10',
'[&_:is(p,h1,h2,h3,h4).is-empty]:before:content-[attr(data-placeholder)] [&_:is(p,h1,h2,h3,h4).is-empty]:before:text-dimmed [&_:is(p,h1,h2,h3,h4).is-empty]:before:float-left [&_:is(p,h1,h2,h3,h4).is-empty]:before:h-0 [&_:is(p,h1,h2,h3,h4).is-empty]:before:pointer-events-none',
'[&_li_.is-empty]:before:content-none',
'[&_p]:leading-7',
'[&_a]:text-primary [&_a]:border-b [&_a]:border-transparent [&_a]:hover:border-primary [&_a]:font-medium',
'[&_a]:transition-colors',
'[&_.mention]:text-primary [&_.mention]:font-medium',
'[&_:is(h1,h2,h3,h4)]:text-highlighted [&_:is(h1,h2,h3,h4)]:font-bold',
'[&_h1]:text-3xl',
'[&_h2]:text-2xl',
'[&_h3]:text-xl',
'[&_h4]:text-lg',
'[&_blockquote]:border-s-4 [&_blockquote]:border-accented [&_blockquote]:ps-4 [&_blockquote]:italic',
'[&_[data-type=horizontalRule]]:my-8 [&_[data-type=horizontalRule]]:py-2',
'[&_hr]:border-t [&_hr]:border-default',
'[&_pre]:text-sm/6 [&_pre]:border [&_pre]:border-muted [&_pre]:bg-muted [&_pre]:rounded-md [&_pre]:px-4 [&_pre]:py-3 [&_pre]:whitespace-pre-wrap [&_pre]:break-words [&_pre]:overflow-x-auto',
'[&_pre_code]:p-0 [&_pre_code]:text-inherit [&_pre_code]:font-inherit [&_pre_code]:rounded-none [&_pre_code]:inline [&_pre_code]:border-0 [&_pre_code]:bg-transparent',
'[&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm [&_code]:font-mono [&_code]:font-medium [&_code]:rounded-md [&_code]:inline-block [&_code]:border [&_code]:border-muted [&_code]:text-highlighted [&_code]:bg-muted',
'[&_:is(ul,ol)]:ps-6',
'[&_ul]:list-disc [&_ul]:marker:text-(--ui-border-accented)',
'[&_ol]:list-decimal [&_ol]:marker:text-muted',
'[&_li]:my-1.5 [&_li]:ps-1.5',
'[&_img]:rounded-md [&_img]:block [&_img]:max-w-full [&_img.ProseMirror-selectednode]:outline-2 [&_img.ProseMirror-selectednode]:outline-primary',
'[&_.ProseMirror-selectednode:not(img):not(pre):not([data-node-view-wrapper])]:bg-primary/10'
]
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
editor: {
slots: {
root: '',
content: 'relative size-full flex-1',
base: [
'w-full outline-none *:my-5 *:first:mt-0 *:last:mb-0 sm:px-8 selection:bg-primary/10',
'[&_:is(p,h1,h2,h3,h4).is-empty]:before:content-[attr(data-placeholder)] [&_:is(p,h1,h2,h3,h4).is-empty]:before:text-dimmed [&_:is(p,h1,h2,h3,h4).is-empty]:before:float-left [&_:is(p,h1,h2,h3,h4).is-empty]:before:h-0 [&_:is(p,h1,h2,h3,h4).is-empty]:before:pointer-events-none',
'[&_li_.is-empty]:before:content-none',
'[&_p]:leading-7',
'[&_a]:text-primary [&_a]:border-b [&_a]:border-transparent [&_a]:hover:border-primary [&_a]:font-medium',
'[&_a]:transition-colors',
'[&_.mention]:text-primary [&_.mention]:font-medium',
'[&_:is(h1,h2,h3,h4)]:text-highlighted [&_:is(h1,h2,h3,h4)]:font-bold',
'[&_h1]:text-3xl',
'[&_h2]:text-2xl',
'[&_h3]:text-xl',
'[&_h4]:text-lg',
'[&_blockquote]:border-s-4 [&_blockquote]:border-accented [&_blockquote]:ps-4 [&_blockquote]:italic',
'[&_[data-type=horizontalRule]]:my-8 [&_[data-type=horizontalRule]]:py-2',
'[&_hr]:border-t [&_hr]:border-default',
'[&_pre]:text-sm/6 [&_pre]:border [&_pre]:border-muted [&_pre]:bg-muted [&_pre]:rounded-md [&_pre]:px-4 [&_pre]:py-3 [&_pre]:whitespace-pre-wrap [&_pre]:break-words [&_pre]:overflow-x-auto',
'[&_pre_code]:p-0 [&_pre_code]:text-inherit [&_pre_code]:font-inherit [&_pre_code]:rounded-none [&_pre_code]:inline [&_pre_code]:border-0 [&_pre_code]:bg-transparent',
'[&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm [&_code]:font-mono [&_code]:font-medium [&_code]:rounded-md [&_code]:inline-block [&_code]:border [&_code]:border-muted [&_code]:text-highlighted [&_code]:bg-muted',
'[&_:is(ul,ol)]:ps-6',
'[&_ul]:list-disc [&_ul]:marker:text-(--ui-border-accented)',
'[&_ol]:list-decimal [&_ol]:marker:text-muted',
'[&_li]:my-1.5 [&_li]:ps-1.5',
'[&_img]:rounded-md [&_img]:block [&_img]:max-w-full [&_img.ProseMirror-selectednode]:outline-2 [&_img.ProseMirror-selectednode]:outline-primary',
'[&_.ProseMirror-selectednode:not(img):not(pre):not([data-node-view-wrapper])]:bg-primary/10'
]
}
}
}
})
]
})