or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-tiptap--extension-list-keymap

Keyboard shortcuts extension for list operations in Tiptap rich text editor

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tiptap/extension-list-keymap@3.4.x

To install, run

npx @tessl/cli install tessl/npm-tiptap--extension-list-keymap@3.4.0

index.mddocs/

Tiptap Extension List Keymap

This extension provides enhanced keyboard shortcuts for list operations in Tiptap rich text editors. It customizes the behavior of backspace and delete keys to improve list editing by properly joining paragraphs between list items instead of the default ProseMirror behavior of lifting or sinking items.

Package Information

  • Package Name: @tiptap/extension-list-keymap
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @tiptap/extension-list-keymap
  • Status: Deprecated (use @tiptap/extension-list instead)

Core Imports

import { ListKeymap, listHelpers } from "@tiptap/extension-list-keymap";
import type { ListKeymapOptions } from "@tiptap/extension-list-keymap";

For types and editor integration:

import { Editor } from "@tiptap/core";
import type { Extension } from "@tiptap/core";

Default import:

import ListKeymap from "@tiptap/extension-list-keymap";

CommonJS:

const { ListKeymap, listHelpers } = require("@tiptap/extension-list-keymap");

Basic Usage

import { Editor } from "@tiptap/core";
import { ListKeymap } from "@tiptap/extension-list-keymap";

const editor = new Editor({
  extensions: [
    ListKeymap.configure({
      listTypes: [
        {
          itemName: 'listItem',
          wrapperNames: ['bulletList', 'orderedList'],
        },
        {
          itemName: 'taskItem',
          wrapperNames: ['taskList'],
        },
      ],
    }),
  ],
});

Capabilities

ListKeymap Extension

The main extension that registers custom keyboard shortcuts for enhanced list editing behavior.

const ListKeymap: Extension<ListKeymapOptions>;

Keyboard Shortcuts Provided:

  • Delete: Handles forward deletion within list items
  • Mod-Delete: Handles modified forward deletion (Ctrl/Cmd + Delete)
  • Backspace: Handles backward deletion within list items
  • Mod-Backspace: Handles modified backward deletion (Ctrl/Cmd + Backspace)

The extension prevents default ProseMirror behavior where backspace/delete operations lift or sink list items when joining paragraphs. Instead, it joins paragraphs from two list items into a single list item for better user experience.

Configuration Options

Configuration interface for customizing list types and behavior.

interface ListKeymapOptions {
  /**
   * An array of list types. This is used for item and wrapper list matching.
   * @default [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }, { itemName: 'taskItem', wrapperNames: ['taskList'] }]
   */
  listTypes: Array<{
    itemName: string;
    wrapperNames: string[];
  }>;
}

Default Configuration:

  • Supports standard list items (listItem) with bullet and ordered lists
  • Supports task items (taskItem) with task lists

List Helper Functions

Collection of utility functions for advanced list operations and state checking.

namespace listHelpers {
  /**
   * Handles backspace key behavior in lists
   * @param editor - The Tiptap editor instance
   * @param name - The list item type name
   * @param parentListTypes - Array of parent list type names
   * @returns true if the keypress was handled, false otherwise
   */
  function handleBackspace(editor: Editor, name: string, parentListTypes: string[]): boolean;

  /**
   * Handles delete key behavior in lists
   * @param editor - The Tiptap editor instance
   * @param name - The list item type name
   * @returns true if the keypress was handled, false otherwise
   */
  function handleDelete(editor: Editor, name: string): boolean;

  /**
   * Finds the position and depth of a list item in the document
   * @param typeOrName - The node type or name to search for
   * @param state - The current editor state
   * @returns Object with resolved position and depth, or null if not found
   */
  function findListItemPos(typeOrName: string | NodeType, state: EditorState): {
    $pos: ResolvedPos;
    depth: number;
  } | null;

  /**
   * Gets the depth of the next list item
   * @param typeOrName - The node type or name
   * @param state - The current editor state
   * @returns The depth number or false if not found
   */
  function getNextListDepth(typeOrName: string, state: EditorState): number | false;

  /**
   * Checks if there's a list before the current position
   * @param editorState - The current editor state
   * @param name - The item type name
   * @param parentListTypes - Array of parent list type names
   * @returns true if a list exists before current position
   */
  function hasListBefore(editorState: EditorState, name: string, parentListTypes: string[]): boolean;

  /**
   * Checks if there's a list item before the current position
   * @param typeOrName - The node type or name
   * @param state - The current editor state
   * @returns true if a list item exists before current position
   */
  function hasListItemBefore(typeOrName: string, state: EditorState): boolean;

  /**
   * Checks if there's a list item after the current position
   * @param typeOrName - The node type or name
   * @param state - The current editor state
   * @returns true if a list item exists after current position
   */
  function hasListItemAfter(typeOrName: string, state: EditorState): boolean;

  /**
   * Checks if a list item contains a sub-list
   * @param name - The item type name
   * @param state - The current editor state
   * @param node - Optional node to check (defaults to current selection)
   * @returns true if the list item has a sub-list
   */
  function listItemHasSubList(name: string, state: EditorState, node?: Node): boolean;

  /**
   * Checks if the next list has a deeper nesting level
   * @param typeOrName - The node type or name
   * @param state - The current editor state
   * @returns true if next list is at a deeper level
   */
  function nextListIsDeeper(typeOrName: string, state: EditorState): boolean;

  /**
   * Checks if the next list has a higher (less nested) level
   * @param typeOrName - The node type or name
   * @param state - The current editor state
   * @returns true if next list is at a higher level
   */
  function nextListIsHigher(typeOrName: string, state: EditorState): boolean;
}

Types

// Core types from @tiptap/core
import type { Editor } from "@tiptap/core";

// ProseMirror types from @tiptap/pm
import type { EditorState } from "@tiptap/pm/state";
import type { Node, NodeType, ResolvedPos } from "@tiptap/pm/model";

// Extension-specific types
export type ListKeymapOptions = {
  /**
   * An array of list types. This is used for item and wrapper list matching.
   * @default [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }, { itemName: 'taskItem', wrapperNames: ['taskList'] }]
   */
  listTypes: Array<{
    itemName: string;
    wrapperNames: string[];
  }>;
};

Usage Examples

Custom List Types

import { ListKeymap } from "@tiptap/extension-list-keymap";

const editor = new Editor({
  extensions: [
    ListKeymap.configure({
      listTypes: [
        {
          itemName: 'customListItem',
          wrapperNames: ['customBulletList', 'customOrderedList'],
        },
      ],
    }),
  ],
});

Using Helper Functions

import { listHelpers } from "@tiptap/extension-list-keymap";
import { Editor } from "@tiptap/core";

// Example with editor instance
const editor = new Editor({
  extensions: [/* your extensions */],
});

// Check if backspace should be handled specially
const shouldHandle = listHelpers.handleBackspace(editor, 'listItem', ['bulletList', 'orderedList']);

// Find current list item position
const listItemPos = listHelpers.findListItemPos('listItem', editor.state);
if (listItemPos) {
  console.log('List item found at depth:', listItemPos.depth);
}

// Check list nesting and navigation
const isDeeper = listHelpers.nextListIsDeeper('listItem', editor.state);
const hasItemBefore = listHelpers.hasListItemBefore('listItem', editor.state);
const hasItemAfter = listHelpers.hasListItemAfter('listItem', editor.state);

Migration Note

This package is deprecated. For new projects, use @tiptap/extension-list directly:

import { ListKeymap, listHelpers } from "@tiptap/extension-list";

The API remains identical, but the recommended import path is from the main extension package.