0
# Tiptap Extension List Keymap
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: @tiptap/extension-list-keymap
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @tiptap/extension-list-keymap`
10
- **Status**: Deprecated (use @tiptap/extension-list instead)
11
12
## Core Imports
13
14
```typescript
15
import { ListKeymap, listHelpers } from "@tiptap/extension-list-keymap";
16
import type { ListKeymapOptions } from "@tiptap/extension-list-keymap";
17
```
18
19
For types and editor integration:
20
21
```typescript
22
import { Editor } from "@tiptap/core";
23
import type { Extension } from "@tiptap/core";
24
```
25
26
Default import:
27
28
```typescript
29
import ListKeymap from "@tiptap/extension-list-keymap";
30
```
31
32
CommonJS:
33
34
```javascript
35
const { ListKeymap, listHelpers } = require("@tiptap/extension-list-keymap");
36
```
37
38
## Basic Usage
39
40
```typescript
41
import { Editor } from "@tiptap/core";
42
import { ListKeymap } from "@tiptap/extension-list-keymap";
43
44
const editor = new Editor({
45
extensions: [
46
ListKeymap.configure({
47
listTypes: [
48
{
49
itemName: 'listItem',
50
wrapperNames: ['bulletList', 'orderedList'],
51
},
52
{
53
itemName: 'taskItem',
54
wrapperNames: ['taskList'],
55
},
56
],
57
}),
58
],
59
});
60
```
61
62
## Capabilities
63
64
### ListKeymap Extension
65
66
The main extension that registers custom keyboard shortcuts for enhanced list editing behavior.
67
68
```typescript { .api }
69
const ListKeymap: Extension<ListKeymapOptions>;
70
```
71
72
**Keyboard Shortcuts Provided:**
73
- `Delete`: Handles forward deletion within list items
74
- `Mod-Delete`: Handles modified forward deletion (Ctrl/Cmd + Delete)
75
- `Backspace`: Handles backward deletion within list items
76
- `Mod-Backspace`: Handles modified backward deletion (Ctrl/Cmd + Backspace)
77
78
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.
79
80
### Configuration Options
81
82
Configuration interface for customizing list types and behavior.
83
84
```typescript { .api }
85
interface ListKeymapOptions {
86
/**
87
* An array of list types. This is used for item and wrapper list matching.
88
* @default [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }, { itemName: 'taskItem', wrapperNames: ['taskList'] }]
89
*/
90
listTypes: Array<{
91
itemName: string;
92
wrapperNames: string[];
93
}>;
94
}
95
```
96
97
**Default Configuration:**
98
- Supports standard list items (`listItem`) with bullet and ordered lists
99
- Supports task items (`taskItem`) with task lists
100
101
### List Helper Functions
102
103
Collection of utility functions for advanced list operations and state checking.
104
105
```typescript { .api }
106
namespace listHelpers {
107
/**
108
* Handles backspace key behavior in lists
109
* @param editor - The Tiptap editor instance
110
* @param name - The list item type name
111
* @param parentListTypes - Array of parent list type names
112
* @returns true if the keypress was handled, false otherwise
113
*/
114
function handleBackspace(editor: Editor, name: string, parentListTypes: string[]): boolean;
115
116
/**
117
* Handles delete key behavior in lists
118
* @param editor - The Tiptap editor instance
119
* @param name - The list item type name
120
* @returns true if the keypress was handled, false otherwise
121
*/
122
function handleDelete(editor: Editor, name: string): boolean;
123
124
/**
125
* Finds the position and depth of a list item in the document
126
* @param typeOrName - The node type or name to search for
127
* @param state - The current editor state
128
* @returns Object with resolved position and depth, or null if not found
129
*/
130
function findListItemPos(typeOrName: string | NodeType, state: EditorState): {
131
$pos: ResolvedPos;
132
depth: number;
133
} | null;
134
135
/**
136
* Gets the depth of the next list item
137
* @param typeOrName - The node type or name
138
* @param state - The current editor state
139
* @returns The depth number or false if not found
140
*/
141
function getNextListDepth(typeOrName: string, state: EditorState): number | false;
142
143
/**
144
* Checks if there's a list before the current position
145
* @param editorState - The current editor state
146
* @param name - The item type name
147
* @param parentListTypes - Array of parent list type names
148
* @returns true if a list exists before current position
149
*/
150
function hasListBefore(editorState: EditorState, name: string, parentListTypes: string[]): boolean;
151
152
/**
153
* Checks if there's a list item before the current position
154
* @param typeOrName - The node type or name
155
* @param state - The current editor state
156
* @returns true if a list item exists before current position
157
*/
158
function hasListItemBefore(typeOrName: string, state: EditorState): boolean;
159
160
/**
161
* Checks if there's a list item after the current position
162
* @param typeOrName - The node type or name
163
* @param state - The current editor state
164
* @returns true if a list item exists after current position
165
*/
166
function hasListItemAfter(typeOrName: string, state: EditorState): boolean;
167
168
/**
169
* Checks if a list item contains a sub-list
170
* @param name - The item type name
171
* @param state - The current editor state
172
* @param node - Optional node to check (defaults to current selection)
173
* @returns true if the list item has a sub-list
174
*/
175
function listItemHasSubList(name: string, state: EditorState, node?: Node): boolean;
176
177
/**
178
* Checks if the next list has a deeper nesting level
179
* @param typeOrName - The node type or name
180
* @param state - The current editor state
181
* @returns true if next list is at a deeper level
182
*/
183
function nextListIsDeeper(typeOrName: string, state: EditorState): boolean;
184
185
/**
186
* Checks if the next list has a higher (less nested) level
187
* @param typeOrName - The node type or name
188
* @param state - The current editor state
189
* @returns true if next list is at a higher level
190
*/
191
function nextListIsHigher(typeOrName: string, state: EditorState): boolean;
192
}
193
```
194
195
## Types
196
197
```typescript { .api }
198
// Core types from @tiptap/core
199
import type { Editor } from "@tiptap/core";
200
201
// ProseMirror types from @tiptap/pm
202
import type { EditorState } from "@tiptap/pm/state";
203
import type { Node, NodeType, ResolvedPos } from "@tiptap/pm/model";
204
205
// Extension-specific types
206
export type ListKeymapOptions = {
207
/**
208
* An array of list types. This is used for item and wrapper list matching.
209
* @default [{ itemName: 'listItem', wrapperNames: ['bulletList', 'orderedList'] }, { itemName: 'taskItem', wrapperNames: ['taskList'] }]
210
*/
211
listTypes: Array<{
212
itemName: string;
213
wrapperNames: string[];
214
}>;
215
};
216
```
217
218
## Usage Examples
219
220
### Custom List Types
221
222
```typescript
223
import { ListKeymap } from "@tiptap/extension-list-keymap";
224
225
const editor = new Editor({
226
extensions: [
227
ListKeymap.configure({
228
listTypes: [
229
{
230
itemName: 'customListItem',
231
wrapperNames: ['customBulletList', 'customOrderedList'],
232
},
233
],
234
}),
235
],
236
});
237
```
238
239
### Using Helper Functions
240
241
```typescript
242
import { listHelpers } from "@tiptap/extension-list-keymap";
243
import { Editor } from "@tiptap/core";
244
245
// Example with editor instance
246
const editor = new Editor({
247
extensions: [/* your extensions */],
248
});
249
250
// Check if backspace should be handled specially
251
const shouldHandle = listHelpers.handleBackspace(editor, 'listItem', ['bulletList', 'orderedList']);
252
253
// Find current list item position
254
const listItemPos = listHelpers.findListItemPos('listItem', editor.state);
255
if (listItemPos) {
256
console.log('List item found at depth:', listItemPos.depth);
257
}
258
259
// Check list nesting and navigation
260
const isDeeper = listHelpers.nextListIsDeeper('listItem', editor.state);
261
const hasItemBefore = listHelpers.hasListItemBefore('listItem', editor.state);
262
const hasItemAfter = listHelpers.hasListItemAfter('listItem', editor.state);
263
```
264
265
## Migration Note
266
267
This package is deprecated. For new projects, use `@tiptap/extension-list` directly:
268
269
```typescript
270
import { ListKeymap, listHelpers } from "@tiptap/extension-list";
271
```
272
273
The API remains identical, but the recommended import path is from the main extension package.