blokhaus

Commands

All Lexical commands exported by Blokhaus.

Blokhaus exports 15 custom Lexical commands created via createCommand(). Commands are the primary mechanism for inter-plugin communication. Any plugin can dispatch a command, and any plugin can listen for it.

Import

import {
  OPEN_SLASH_MENU_COMMAND,
  INSERT_IMAGE_COMMAND,
  OPEN_AI_PROMPT_COMMAND,
  INSERT_AI_PREVIEW_COMMAND,
  OPEN_EMOJI_PICKER_COMMAND,
  OPEN_LINK_INPUT_COMMAND,
  SET_TEXT_COLOR_COMMAND,
  SET_HIGHLIGHT_COLOR_COMMAND,
  INSERT_TABLE_COMMAND_BLOKHAUS,
  INSERT_CALLOUT_COMMAND,
  INSERT_VIDEO_COMMAND,
  OPEN_VIDEO_INPUT_COMMAND,
  INSERT_TOGGLE_COMMAND,
  SET_FONT_FAMILY_COMMAND,
  SET_BLOCK_DIRECTION_COMMAND,
} from "@blokhaus/core";

Command reference

CommandPayload TypeDescription
OPEN_SLASH_MENU_COMMANDvoidOpens the slash menu at the current cursor position. Dispatched by the InputRulePlugin when the user types /.
INSERT_IMAGE_COMMANDFileTriggers the image upload flow. The ImagePlugin listens for this command, creates a LoadingImageNode, and calls the UploadHandler.
OPEN_AI_PROMPT_COMMANDvoidOpens the AI prompt input popover at the current cursor position. Dispatched by the slash menu's "AI" item.
INSERT_AI_PREVIEW_COMMAND{ prompt: string }Inserts an AIPreviewNode below the current cursor with the given prompt. The AIPlugin handles context extraction and node creation.
OPEN_EMOJI_PICKER_COMMANDvoidOpens the emoji picker dropdown. Dispatched by the slash menu's "Emoji" item or by typing : followed by text.
OPEN_LINK_INPUT_COMMANDvoidOpens the link input popover for adding or editing a hyperlink on the current selection. Dispatched by the floating toolbar's link button.
SET_TEXT_COLOR_COMMANDstringSets the text color on the current selection. The payload is a CSS value (e.g., "var(--blokhaus-text-red)") or an empty string to reset to default.
SET_HIGHLIGHT_COLOR_COMMANDstringSets the background highlight color on the current selection. The payload is a CSS value or an empty string to reset.
INSERT_TABLE_COMMAND_BLOKHAUS{ rows: number; columns: number }Inserts a table at the current cursor position with the specified dimensions. Named with a _BLOKHAUS suffix to avoid collision with Lexical's built-in table command.
INSERT_CALLOUT_COMMAND{ emoji?: string; colorPreset?: string }Inserts a callout block at the current cursor position with optional emoji and color preset.
INSERT_VIDEO_COMMAND{ file: File } | { url: string }Inserts a video node. If the payload contains a file, it triggers the video upload flow. If it contains a url, it parses the URL for embed info.
OPEN_VIDEO_INPUT_COMMANDvoidOpens the video URL input popover. Dispatched by the slash menu's "Video" item.
INSERT_TOGGLE_COMMAND{ isOpen?: boolean } | undefinedInserts a toggle (collapsible) block at the current cursor position. The isOpen field controls whether the toggle starts expanded (default: true).
SET_FONT_FAMILY_COMMANDstringSets the font family on the current selection. The payload is a CSS font-family value or an empty string to reset to default.
SET_BLOCK_DIRECTION_COMMAND'ltr' | 'rtl'Sets the text direction on the current block-level element.

Dispatching commands

Use editor.dispatchCommand() to fire a command. The editor instance is available via useLexicalComposerContext():

"use client";

import { useLexicalComposerContext } from "@blokhaus/core";
import { INSERT_CALLOUT_COMMAND } from "@blokhaus/core";

function InsertCalloutButton() {
  const [editor] = useLexicalComposerContext();

  const handleClick = () => {
    editor.dispatchCommand(INSERT_CALLOUT_COMMAND, {
      emoji: "\u{1F4A1}",
      colorPreset: "info",
    });
  };

  return <button onClick={handleClick}>Insert Callout</button>;
}

For commands with a void payload, pass undefined:

editor.dispatchCommand(OPEN_SLASH_MENU_COMMAND, undefined);

Listening for commands

Use editor.registerCommand() to listen for a command. Choose the appropriate priority:

import { COMMAND_PRIORITY_LOW, COMMAND_PRIORITY_EDITOR } from "lexical";

useEffect(() => {
  return editor.registerCommand(
    INSERT_CALLOUT_COMMAND,
    (payload) => {
      // Handle the command
      editor.update(() => {
        const callout = $createCalloutNode({
          emoji: payload.emoji,
          colorPreset: payload.colorPreset,
        });
        // Insert at cursor...
      });
      return true; // Handled -- stop propagation
    },
    COMMAND_PRIORITY_LOW,
  );
}, [editor]);

Command priorities

Lexical commands propagate through registered listeners from highest to lowest priority. Return true from a handler to stop propagation.

PriorityConstantUse case
4 (highest)COMMAND_PRIORITY_CRITICALFramework-level overrides. Rarely used.
3COMMAND_PRIORITY_HIGHIntercepting commands before plugins handle them.
2COMMAND_PRIORITY_NORMALGeneral plugin handlers.
1COMMAND_PRIORITY_LOWDefault for most Blokhaus plugins.
0 (lowest)COMMAND_PRIORITY_EDITOREditor-scoped handlers. Automatically limited to the focused editor in multi-editor setups.

Blokhaus plugins typically register at COMMAND_PRIORITY_LOW. If you need to intercept a command before a Blokhaus plugin handles it, register at COMMAND_PRIORITY_NORMAL or higher and return true to prevent the default behavior.

Type safety

All Blokhaus commands are created with createCommand<PayloadType>(), which provides full TypeScript type checking for both dispatch and listen calls:

// TypeScript will enforce the correct payload type:
editor.dispatchCommand(INSERT_TABLE_COMMAND_BLOKHAUS, { rows: 3, columns: 4 }); // OK
editor.dispatchCommand(INSERT_TABLE_COMMAND_BLOKHAUS, { rows: 3 }); // Type error: missing 'columns'
editor.dispatchCommand(OPEN_SLASH_MENU_COMMAND, undefined); // OK (void payload)
  • Custom Plugins guide -- Building plugins that dispatch and listen for commands
  • EditorRoot -- The component that initializes the Lexical editor
  • Types -- Full type definitions for command payloads