Skip to content

@vizel/vue

Vue 3 components and composables for Vizel editor.

Looking for a guide?

See the Vue Guide for step-by-step tutorials and common patterns.

Installation

bash
npm install @vizel/vue

Components

Vizel

All-in-one editor component with built-in bubble menu. This is the recommended way to get started.

vue
<script setup lang="ts">
import { Vizel } from '@vizel/vue';
import '@vizel/core/styles.css';
</script>

<template>
  <Vizel
    :initialContent="{ type: 'doc', content: [] }"
    placeholder="Start writing..."
    :editable="true"
    autofocus="end"
    :showBubbleMenu="true"
    :enableEmbed="true"
    class="my-editor"
    :features="{ markdown: true }"
    @update="({ editor }) => {}"
    @create="({ editor }) => {}"
    @focus="({ editor }) => {}"
    @blur="({ editor }) => {}"
  />
</template>

Props:

PropTypeDefaultDescription
initialContentJSONContent-Initial editor content (JSON)
initialMarkdownstring-Initial editor content (Markdown)
v-model:markdownstring-Two-way Markdown binding
placeholderstring-Placeholder text
editablebooleantrueEditable state
autofocusboolean | 'start' | 'end' | 'all' | number-Auto focus behavior
featuresVizelFeatureOptions-Feature configuration
classstring-CSS class name
showBubbleMenubooleantrueShow bubble menu on selection
enableEmbedboolean-Enable embed in link editor

Events:

EventPayloadDescription
update{ editor: Editor }Content updated
update:markdownstringMarkdown content changed
create{ editor: Editor }Editor created
destroy-Editor destroyed
selectionUpdate{ editor: Editor }Selection changed
focus{ editor: Editor }Editor focused
blur{ editor: Editor }Editor blurred

Composables

useVizelEditor

Creates and manages a Vizel editor instance.

typescript
import { useVizelEditor } from '@vizel/vue';

const editor = useVizelEditor(options?: VizelEditorOptions);

Returns: ShallowRef<Editor | null>

useVizelState

Forces re-render on editor state changes.

typescript
import { useVizelState } from '@vizel/vue';

const updateCount = useVizelState(() => editor.value);

Returns: Ref<number> (update count)

useVizelEditorState

Tracks specific editor state properties reactively.

typescript
import { useVizelEditorState } from '@vizel/vue';

const isBold = useVizelEditorState(
  () => editor.value,
  (editor) => editor.isActive('bold')
);

Returns: ComputedRef with the value returned by the selector function

useVizelAutoSave

Auto-saves editor content with debouncing.

typescript
import { useVizelAutoSave } from '@vizel/vue';

const result = useVizelAutoSave(
  getEditor: () => Editor | null,
  options?: VizelAutoSaveOptions
);

Returns:

PropertyTypeDescription
statusComputedRef<VizelSaveStatus>Current save status
hasUnsavedChangesComputedRef<boolean>Has unsaved changes
lastSavedComputedRef<Date | null>Last save timestamp
errorComputedRef<Error | null>Last error
save() => Promise<void>Manual save function
restore() => Promise<JSONContent | null>Manual restore

useVizelMarkdown

Provides two-way Markdown synchronization with debouncing.

typescript
import { useVizelMarkdown } from '@vizel/vue';

const result = useVizelMarkdown(
  getEditor: () => Editor | null,
  options?: VizelMarkdownSyncOptions
);

Options:

OptionTypeDefaultDescription
debounceMsnumber300Debounce delay in milliseconds

Returns:

PropertyTypeDescription
markdownRef<string>Current Markdown content
setMarkdown(md: string) => voidUpdate editor from Markdown
isPendingRef<boolean>Whether sync is pending

useVizelTheme

Access theme state within VizelThemeProvider.

typescript
import { useVizelTheme } from '@vizel/vue';

const { theme, resolvedTheme, systemTheme, setTheme } = useVizelTheme();

Returns:

PropertyTypeDescription
themeRef<VizelTheme>Current theme setting
resolvedThemeComputedRef<VizelResolvedTheme>Resolved theme
systemThemeRef<VizelResolvedTheme>System preference
setTheme(theme: VizelTheme) => voidSet theme function

Components

VizelEditor

Renders the editor content area.

vue
<VizelEditor :editor="editor" class="my-editor" />

Props:

PropTypeDefaultDescription
editorEditor | null-Editor instance
classstring-CSS class name

VizelBubbleMenu

Floating formatting bubble menu.

vue
<VizelBubbleMenu 
  :editor="editor"
  class="my-bubble-menu"
/>

Props:

PropTypeDefaultDescription
editorEditor | null-Editor instance
classstring-CSS class name

Slots:

SlotDescription
defaultCustom bubble menu content

VizelBubbleMenuDefault

Default bubble menu with all formatting buttons.

vue
<VizelBubbleMenuDefault 
  :editor="editor"
  :enableEmbed="false"
/>

Props:

PropTypeDefaultDescription
editorEditor | null-Editor instance
enableEmbedbooleanfalseEnable embed in links

VizelBubbleMenuButton

Individual bubble menu button.

vue
<VizelBubbleMenuButton
  icon="lucide:bold"
  :isActive="editor.isActive('bold')"
  @click="editor.chain().focus().toggleBold().run()"
/>

VizelBubbleMenuDivider

Bubble menu divider.

vue
<VizelBubbleMenuDivider />

VizelThemeProvider

Provides theme context.

vue
<VizelThemeProvider
  defaultTheme="system"
  storageKey="vizel-theme"
  :disableTransitionOnChange="false"
>
  <slot />
</VizelThemeProvider>

Props:

PropTypeDefaultDescription
defaultThemeVizelTheme"system"Default theme
storageKeystring"vizel-theme"Storage key
targetSelectorstring-Theme target
disableTransitionOnChangebooleanfalseDisable transitions

VizelSaveIndicator

Displays save status.

vue
<VizelSaveIndicator :status="status" :lastSaved="lastSaved" />

Props:

PropTypeDescription
statusVizelSaveStatusSave status
lastSavedDate | nullLast save time
classstringCSS class name

VizelPortal

Renders content in a portal.

vue
<VizelPortal :container="document.body">
  <slot />
</VizelPortal>

Props:

PropTypeDescription
containerHTMLElementPortal target

VizelColorPicker

Color selection component.

vue
<VizelColorPicker
  :colors="colors"
  :value="currentColor"
  :recentColors="recentColors"
  @update:value="setColor"
/>

VizelIconProvider

Provides custom icons for Vizel components.

vue
<script setup lang="ts">
import { VizelIconProvider } from '@vizel/vue';
import type { CustomIconMap } from '@vizel/core';

const icons: CustomIconMap = {
  bold: 'mdi:format-bold',
  italic: 'mdi:format-italic',
};
</script>

<template>
  <VizelIconProvider :icons="icons">
    <Vizel />
  </VizelIconProvider>
</template>

Props:

PropTypeDescription
iconsCustomIconMapMap of icon names to Iconify icon IDs

Slots:

SlotDescription
defaultChildren

VizelSlashMenu

Slash command menu component.

vue
<VizelSlashMenu
  :items="items"
  :command="handleCommand"
  class="my-menu"
/>

Utilities

createVizelSlashMenuRenderer

Creates slash menu renderer for the SlashCommand extension.

typescript
import { createVizelSlashMenuRenderer } from '@vizel/vue';

const suggestion = createVizelSlashMenuRenderer();

const editor = useVizelEditor({
  features: {
    slashCommand: {
      suggestion,
    },
  },
});

Importing from @vizel/core and @tiptap/core

Framework packages do not re-export from @vizel/core. Import directly:

typescript
// Framework-specific components and composables
import { 
  Vizel, 
  VizelEditor, 
  VizelBubbleMenu, 
  VizelThemeProvider,
  useVizelEditor,
  useVizelMarkdown,
  useVizelAutoSave,
} from '@vizel/vue';

// Vizel types and utilities from @vizel/core
import { getVizelEditorState, VIZEL_TEXT_COLORS } from '@vizel/core';
import type { VizelEditorOptions, VizelSaveStatus } from '@vizel/core';

// Tiptap types from @tiptap/core
import { Editor } from '@tiptap/core';
import type { JSONContent } from '@tiptap/core';

Released under the MIT License.