or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

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.