Skip to content

Features

Each feature can be enabled, disabled, or customized through the features option.

Feature Overview

All features are enabled by default. Set any feature to false to disable it.

FeatureDescription
slashCommandSlash command menu (type / to open)
tableTable editing support
imageImage upload and resize
codeBlockCode blocks with syntax highlighting
dragHandleDrag handle for block reordering
characterCountCharacter and word counting
textColorText color and highlight
taskListCheckbox task lists
linkLink editing
markdownMarkdown import/export
mathematicsLaTeX math equations
embedURL embeds (YouTube, etc.)
detailsCollapsible content blocks
diagramMermaid/GraphViz diagrams

Disabling Features

Set a feature to false to disable it:

typescript
const editor = useVizelEditor({
  features: {
    slashCommand: false,  // Disable slash commands
    dragHandle: false,    // Disable drag handle
    table: false,         // Disable tables
  },
});

Slash Commands

Type / to open the command menu for block insertion.

Options

PropertyTypeDescription
itemsSlashCommandItem[]Custom command items
suggestionobjectSuggestion configuration

Custom Commands

typescript
import type { SlashCommandItem } from '@vizel/core';

const customItems: SlashCommandItem[] = [
  {
    title: 'Custom Block',
    description: 'Insert a custom block',
    icon: 'lucide:box',
    keywords: ['custom', 'block'],
    group: 'custom',
    command: ({ editor, range }) => {
      editor.chain().focus().deleteRange(range).insertContent({
        type: 'paragraph',
        content: [{ type: 'text', text: 'Custom content' }],
      }).run();
    },
  },
];

const editor = useVizelEditor({
  features: {
    slashCommand: {
      items: customItems, // Add custom items
    },
  },
});

Default Commands

GroupCommands
TextParagraph, Heading 1-3, Quote, Code
ListsBullet List, Numbered List, Task List
MediaImage, Horizontal Rule
AdvancedDetails, Embed, Diagram, Math Block

Images

Supports drag and drop, paste, and resize.

Options

PropertyTypeDefaultDescription
resizebooleantrueEnable image resizing
onUpload(file: File) => Promise<string>Base64Upload handler
maxFileSizenumber-Max file size in bytes
allowedTypesstring[]See belowAllowed MIME types
onValidationError(error) => void-Validation error callback
onUploadError(error, file) => void-Upload error callback

Default Allowed Types

typescript
['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml']

Example: Custom Upload

typescript
const editor = useVizelEditor({
  features: {
    image: {
      onUpload: async (file) => {
        const formData = new FormData();
        formData.append('image', file);
        
        const res = await fetch('/api/upload', {
          method: 'POST',
          body: formData,
        });
        
        const { url } = await res.json();
        return url;
      },
      maxFileSize: 5 * 1024 * 1024, // 5MB
      allowedTypes: ['image/jpeg', 'image/png', 'image/webp'],
      onValidationError: (error) => {
        if (error.type === 'file-too-large') {
          alert('File is too large. Maximum size is 5MB.');
        } else if (error.type === 'invalid-type') {
          alert('Invalid file type. Only JPEG, PNG, and WebP are allowed.');
        }
      },
      onUploadError: (error, file) => {
        console.error(`Failed to upload ${file.name}:`, error);
        alert('Upload failed. Please try again.');
      },
    },
  },
});

Code Blocks

Code blocks with syntax highlighting and language selection.

Options

PropertyTypeDefaultDescription
defaultLanguagestring"plaintext"Default language
lineNumbersbooleanfalseShow line numbers
lowlightLowlightAll languagesCustom Lowlight instance

Example: Limited Languages

typescript
import { createLowlight, common } from 'lowlight';

const lowlight = createLowlight(common);

const editor = useVizelEditor({
  features: {
    codeBlock: {
      defaultLanguage: 'typescript',
      lineNumbers: true,
      lowlight, // Only common languages
    },
  },
});

Character Count

Track character and word counts.

Options

PropertyTypeDefaultDescription
limitnumber | nullnullMax characters (null = unlimited)
mode"textSize" | "nodeSize""textSize"Counting mode
wordCounter(text: string) => number-Custom word counter

Example: Character Limit

typescript
const editor = useVizelEditor({
  features: {
    characterCount: {
      limit: 10000, // Max 10,000 characters
      mode: 'textSize',
    },
  },
});

// Access counts
const chars = editor.storage.characterCount.characters();
const words = editor.storage.characterCount.words();
const limit = editor.storage.characterCount.limit;
const percentage = (chars / limit) * 100;

Text Color & Highlight

Text color and background highlight support.

Options

PropertyTypeDescription
textColorsColorDefinition[]Custom text color palette
highlightColorsColorDefinition[]Custom highlight color palette
multicolorbooleanEnable multicolor highlights

Custom Color Palette

typescript
import type { ColorDefinition } from '@vizel/core';

const customColors: ColorDefinition[] = [
  { name: 'Brand', color: '#6366f1' },
  { name: 'Success', color: '#22c55e' },
  { name: 'Warning', color: '#f59e0b' },
  { name: 'Error', color: '#ef4444' },
];

const editor = useVizelEditor({
  features: {
    textColor: {
      textColors: customColors,
      highlightColors: customColors.map(c => ({
        ...c,
        color: `${c.color}40`, // Add transparency
      })),
    },
  },
});

Markdown

Enable Markdown import/export.

Options

PropertyTypeDefaultDescription
indentation{ style, size }{ style: 'space', size: 2 }Indentation config
gfmbooleantrueGitHub Flavored Markdown
breaksbooleanfalseConvert newlines to <br>

Example

typescript
const editor = useVizelEditor({
  features: {
    markdown: {
      gfm: true,
      breaks: false,
      indentation: {
        style: 'space',
        size: 2,
      },
    },
  },
});

// Export to Markdown
const md = editor.storage.markdown.getMarkdown();

// Import from Markdown
editor.commands.setContent(
  editor.storage.markdown.parseMarkdown('# Hello\n\nWorld')
);

Mathematics

LaTeX math equations rendered with KaTeX.

Options

PropertyTypeDefaultDescription
katexOptionsKatexOptions{}KaTeX rendering options
inlineInputRulesbooleantrueEnable $...$ input rules
blockInputRulesbooleantrueEnable $$...$$ input rules

Example

typescript
const editor = useVizelEditor({
  features: {
    mathematics: {
      katexOptions: {
        throwOnError: false,
        strict: false,
      },
      inlineInputRules: true,
      blockInputRules: true,
    },
  },
});

Usage

  • Inline math: Type $E=mc^2$ and press space
  • Block math: Type $$ on a new line, enter equation, type $$

Embeds

Embed content from URLs (YouTube, Vimeo, Twitter).

Options

PropertyTypeDefaultDescription
fetchEmbedDataFunctionBuilt-inCustom fetch function
providersEmbedProvider[]Default providersCustom/additional providers
pasteHandlerbooleantrueAuto-embed pasted URLs
inlinebooleanfalseInline vs block embeds

Default Providers

  • YouTube
  • Vimeo
  • Twitter/X
  • CodePen
  • CodeSandbox
  • Figma
  • Loom
  • Spotify

Example: Custom Provider

typescript
import type { EmbedProvider } from '@vizel/core';

const customProvider: EmbedProvider = {
  name: 'MyService',
  pattern: /^https?:\/\/myservice\.com\/embed\/(\w+)/,
  transform: (url, match) => ({
    type: 'iframe',
    url: `https://myservice.com/embed/${match[1]}`,
    width: 640,
    height: 360,
  }),
};

const editor = useVizelEditor({
  features: {
    embed: {
      providers: [customProvider],
      pasteHandler: true,
    },
  },
});

Details

Collapsible content blocks (accordion/disclosure).

Options

PropertyTypeDescription
detailsobjectDetails container options
detailsContentobjectContent area options
detailsSummaryobjectSummary/header options

Example

typescript
const editor = useVizelEditor({
  features: {
    details: true, // Enable with defaults
  },
});

Usage

Use the slash command /details or /toggle to insert a collapsible block.


Diagrams

Mermaid and GraphViz diagrams.

Options

PropertyTypeDefaultDescription
mermaidConfigMermaidConfig{}Mermaid configuration
graphvizEnginestring"dot"GraphViz layout engine
defaultType"mermaid" | "graphviz""mermaid"Default diagram type
defaultCodestring-Default Mermaid code
defaultGraphvizCodestring-Default GraphViz code

GraphViz Engines

  • dot - Hierarchical (default)
  • neato - Spring model
  • fdp - Force-directed
  • sfdp - Scalable force-directed
  • twopi - Radial
  • circo - Circular

Example

typescript
const editor = useVizelEditor({
  features: {
    diagram: {
      mermaidConfig: {
        theme: 'neutral',
        securityLevel: 'loose',
      },
      defaultType: 'mermaid',
      defaultCode: `graph TD
    A[Start] --> B[End]`,
    },
  },
});

Link editing and auto-linking.

Options

PropertyTypeDefaultDescription
openOnClickbooleantrueOpen links on click
autolinkbooleantrueAuto-link URLs while typing
linkOnPastebooleantrueLink pasted URLs
defaultProtocolstring"https"Default protocol
HTMLAttributesobject-HTML attributes for links

Example

typescript
const editor = useVizelEditor({
  features: {
    link: {
      openOnClick: true,
      autolink: true,
      linkOnPaste: true,
      defaultProtocol: 'https',
      HTMLAttributes: {
        target: '_blank',
        rel: 'noopener noreferrer',
      },
    },
  },
});

Task Lists

Checkbox task lists.

Options

PropertyTypeDescription
taskListTaskListOptionsTask list container options
taskItemTaskItemOptionsTask item options

Example

typescript
const editor = useVizelEditor({
  features: {
    taskList: {
      taskItem: {
        nested: true, // Allow nested task lists
      },
    },
  },
});

Drag Handle

Handle for drag-and-drop block reordering.

Options

PropertyTypeDefaultDescription
enabledbooleantrueShow drag handle

Example

typescript
const editor = useVizelEditor({
  features: {
    dragHandle: {
      enabled: true,
    },
  },
});

Next Steps

Released under the MIT License.