@milkdown/crepe 7.12.1 → 7.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/lib/cjs/feature/block-edit/index.js +248 -229
  2. package/lib/cjs/feature/block-edit/index.js.map +1 -1
  3. package/lib/cjs/feature/latex/index.js +41 -3
  4. package/lib/cjs/feature/latex/index.js.map +1 -1
  5. package/lib/cjs/feature/placeholder/index.js.map +1 -1
  6. package/lib/cjs/feature/toolbar/index.js +213 -160
  7. package/lib/cjs/feature/toolbar/index.js.map +1 -1
  8. package/lib/cjs/index.js +408 -390
  9. package/lib/cjs/index.js.map +1 -1
  10. package/lib/esm/feature/block-edit/index.js +250 -231
  11. package/lib/esm/feature/block-edit/index.js.map +1 -1
  12. package/lib/esm/feature/latex/index.js +42 -4
  13. package/lib/esm/feature/latex/index.js.map +1 -1
  14. package/lib/esm/feature/placeholder/index.js.map +1 -1
  15. package/lib/esm/feature/toolbar/index.js +217 -164
  16. package/lib/esm/feature/toolbar/index.js.map +1 -1
  17. package/lib/esm/index.js +414 -396
  18. package/lib/esm/index.js.map +1 -1
  19. package/lib/tsconfig.tsbuildinfo +1 -1
  20. package/lib/types/feature/block-edit/index.d.ts +78 -38
  21. package/lib/types/feature/block-edit/index.d.ts.map +1 -1
  22. package/lib/types/feature/block-edit/menu/config.d.ts +3 -2
  23. package/lib/types/feature/block-edit/menu/config.d.ts.map +1 -1
  24. package/lib/types/feature/block-edit/menu/utils.d.ts +2 -24
  25. package/lib/types/feature/block-edit/menu/utils.d.ts.map +1 -1
  26. package/lib/types/feature/latex/command.d.ts +2 -0
  27. package/lib/types/feature/latex/command.d.ts.map +1 -0
  28. package/lib/types/feature/latex/index.d.ts.map +1 -1
  29. package/lib/types/feature/toolbar/component.d.ts +1 -1
  30. package/lib/types/feature/toolbar/component.d.ts.map +1 -1
  31. package/lib/types/feature/toolbar/config.d.ts +12 -0
  32. package/lib/types/feature/toolbar/config.d.ts.map +1 -0
  33. package/lib/types/feature/toolbar/index.d.ts +3 -0
  34. package/lib/types/feature/toolbar/index.d.ts.map +1 -1
  35. package/lib/types/utils/checker.d.ts +4 -0
  36. package/lib/types/utils/checker.d.ts.map +1 -0
  37. package/lib/types/utils/group-builder.d.ts +43 -0
  38. package/lib/types/utils/group-builder.d.ts.map +1 -0
  39. package/lib/types/utils/index.d.ts +3 -3
  40. package/lib/types/utils/index.d.ts.map +1 -1
  41. package/lib/types/utils/types.d.ts +4 -0
  42. package/lib/types/utils/types.d.ts.map +1 -0
  43. package/package.json +2 -2
  44. package/src/feature/block-edit/index.ts +78 -38
  45. package/src/feature/block-edit/menu/config.ts +306 -240
  46. package/src/feature/block-edit/menu/utils.ts +1 -106
  47. package/src/feature/latex/command.ts +48 -0
  48. package/src/feature/latex/index.ts +2 -0
  49. package/src/feature/toolbar/component.tsx +44 -194
  50. package/src/feature/toolbar/config.ts +136 -0
  51. package/src/feature/toolbar/index.ts +3 -0
  52. package/src/utils/checker.ts +11 -0
  53. package/src/utils/group-builder.ts +68 -0
  54. package/src/utils/index.ts +3 -11
  55. package/src/utils/types.ts +9 -0
  56. package/lib/types/feature/block-edit/menu/group-builder.d.ts +0 -29
  57. package/lib/types/feature/block-edit/menu/group-builder.d.ts.map +0 -1
  58. package/src/feature/block-edit/menu/group-builder.ts +0 -49
@@ -1,22 +1,26 @@
1
1
  import type { Ctx } from '@milkdown/kit/ctx'
2
2
 
3
3
  import { imageBlockSchema } from '@milkdown/kit/component/image-block'
4
- import { editorViewCtx } from '@milkdown/kit/core'
4
+ import { commandsCtx, editorViewCtx } from '@milkdown/kit/core'
5
5
  import {
6
+ addBlockTypeCommand,
6
7
  blockquoteSchema,
7
8
  bulletListSchema,
9
+ clearTextInCurrentBlockCommand,
8
10
  codeBlockSchema,
9
11
  headingSchema,
10
12
  hrSchema,
11
13
  listItemSchema,
12
14
  orderedListSchema,
13
15
  paragraphSchema,
16
+ selectTextNearPosCommand,
17
+ setBlockTypeCommand,
18
+ wrapInBlockTypeCommand,
14
19
  } from '@milkdown/kit/preset/commonmark'
15
20
  import { createTable } from '@milkdown/kit/preset/gfm'
16
- import { TextSelection } from '@milkdown/kit/prose/state'
17
21
 
18
22
  import type { BlockEditFeatureConfig } from '../index'
19
- import type { MenuItemGroup } from './utils'
23
+ import type { SlashMenuItem } from './utils'
20
24
 
21
25
  import { useCrepeFeatures } from '../../../core/slice'
22
26
  import { CrepeFeature } from '../../../feature'
@@ -38,13 +42,7 @@ import {
38
42
  textIcon,
39
43
  todoListIcon,
40
44
  } from '../../../icons'
41
- import { GroupBuilder } from './group-builder'
42
- import {
43
- clearContentAndAddBlockType,
44
- clearContentAndSetBlockType,
45
- clearContentAndWrapInBlockType,
46
- clearRange,
47
- } from './utils'
45
+ import { GroupBuilder, type MenuItemGroup } from '../../../utils/group-builder'
48
46
 
49
47
  export function getGroups(
50
48
  filter?: string,
@@ -56,239 +54,307 @@ export function getGroups(
56
54
  const isImageBlockEnabled = flags?.includes(CrepeFeature.ImageBlock)
57
55
  const isTableEnabled = flags?.includes(CrepeFeature.Table)
58
56
 
59
- const groupBuilder = new GroupBuilder()
60
- groupBuilder
61
- .addGroup('text', config?.slashMenuTextGroupLabel ?? 'Text')
62
- .addItem('text', {
63
- label: config?.slashMenuTextLabel ?? 'Text',
64
- icon: config?.slashMenuTextIcon ?? textIcon,
65
- onRun: (ctx) => {
66
- const view = ctx.get(editorViewCtx)
67
- const { dispatch, state } = view
68
-
69
- const command = clearContentAndSetBlockType(paragraphSchema.type(ctx))
70
- command(state, dispatch)
71
- },
72
- })
73
- .addItem('h1', {
74
- label: config?.slashMenuH1Label ?? 'Heading 1',
75
- icon: config?.slashMenuH1Icon ?? h1Icon,
76
- onRun: (ctx) => {
77
- const view = ctx.get(editorViewCtx)
78
- const { dispatch, state } = view
79
-
80
- const command = clearContentAndSetBlockType(headingSchema.type(ctx), {
81
- level: 1,
82
- })
83
- command(state, dispatch)
84
- },
85
- })
86
- .addItem('h2', {
87
- label: config?.slashMenuH2Label ?? 'Heading 2',
88
- icon: config?.slashMenuH2Icon ?? h2Icon,
89
- onRun: (ctx) => {
90
- const view = ctx.get(editorViewCtx)
91
- const { dispatch, state } = view
92
-
93
- const command = clearContentAndSetBlockType(headingSchema.type(ctx), {
94
- level: 2,
95
- })
96
- command(state, dispatch)
97
- },
98
- })
99
- .addItem('h3', {
100
- label: config?.slashMenuH3Label ?? 'Heading 3',
101
- icon: config?.slashMenuH3Icon ?? h3Icon,
102
- onRun: (ctx) => {
103
- const view = ctx.get(editorViewCtx)
104
- const { dispatch, state } = view
105
-
106
- const command = clearContentAndSetBlockType(headingSchema.type(ctx), {
107
- level: 3,
108
- })
109
- command(state, dispatch)
110
- },
111
- })
112
- .addItem('h4', {
113
- label: config?.slashMenuH4Label ?? 'Heading 4',
114
- icon: config?.slashMenuH4Icon ?? h4Icon,
115
- onRun: (ctx) => {
116
- const view = ctx.get(editorViewCtx)
117
- const { dispatch, state } = view
118
-
119
- const command = clearContentAndSetBlockType(headingSchema.type(ctx), {
120
- level: 4,
121
- })
122
- command(state, dispatch)
123
- },
124
- })
125
- .addItem('h5', {
126
- label: config?.slashMenuH5Label ?? 'Heading 5',
127
- icon: config?.slashMenuH5Icon ?? h5Icon,
128
- onRun: (ctx) => {
129
- const view = ctx.get(editorViewCtx)
130
- const { dispatch, state } = view
131
-
132
- const command = clearContentAndSetBlockType(headingSchema.type(ctx), {
133
- level: 5,
134
- })
135
- command(state, dispatch)
136
- },
137
- })
138
- .addItem('h6', {
139
- label: config?.slashMenuH6Label ?? 'Heading 6',
140
- icon: config?.slashMenuH6Icon ?? h6Icon,
141
- onRun: (ctx) => {
142
- const view = ctx.get(editorViewCtx)
143
- const { dispatch, state } = view
144
-
145
- const command = clearContentAndSetBlockType(headingSchema.type(ctx), {
146
- level: 6,
147
- })
148
- command(state, dispatch)
149
- },
150
- })
151
- .addItem('quote', {
152
- label: config?.slashMenuQuoteLabel ?? 'Quote',
153
- icon: config?.slashMenuQuoteIcon ?? quoteIcon,
154
- onRun: (ctx) => {
155
- const view = ctx.get(editorViewCtx)
156
- const { dispatch, state } = view
157
-
158
- const command = clearContentAndWrapInBlockType(
159
- blockquoteSchema.type(ctx)
160
- )
161
- command(state, dispatch)
162
- },
163
- })
164
- .addItem('divider', {
165
- label: config?.slashMenuDividerLabel ?? 'Divider',
166
- icon: config?.slashMenuDividerIcon ?? dividerIcon,
167
- onRun: (ctx) => {
168
- const view = ctx.get(editorViewCtx)
169
- const { dispatch, state } = view
170
-
171
- const command = clearContentAndAddBlockType(hrSchema.type(ctx))
172
- command(state, dispatch)
173
- },
174
- })
175
-
176
- groupBuilder
177
- .addGroup('list', config?.slashMenuListGroupLabel ?? 'List')
178
- .addItem('bullet-list', {
179
- label: config?.slashMenuBulletListLabel ?? 'Bullet List',
180
- icon: config?.slashMenuBulletListIcon ?? bulletListIcon,
181
- onRun: (ctx) => {
182
- const view = ctx.get(editorViewCtx)
183
- const { dispatch, state } = view
184
-
185
- const command = clearContentAndWrapInBlockType(
186
- bulletListSchema.type(ctx)
187
- )
188
- command(state, dispatch)
189
- },
190
- })
191
- .addItem('ordered-list', {
192
- label: config?.slashMenuOrderedListLabel ?? 'Ordered List',
193
- icon: config?.slashMenuOrderedListIcon ?? orderedListIcon,
194
- onRun: (ctx) => {
195
- const view = ctx.get(editorViewCtx)
196
- const { dispatch, state } = view
197
-
198
- const command = clearContentAndWrapInBlockType(
199
- orderedListSchema.type(ctx)
200
- )
201
- command(state, dispatch)
202
- },
203
- })
204
- .addItem('todo-list', {
205
- label: config?.slashMenuTaskListLabel ?? 'Todo List',
206
- icon: config?.slashMenuTaskListIcon ?? todoListIcon,
207
- onRun: (ctx) => {
208
- const view = ctx.get(editorViewCtx)
209
- const { dispatch, state } = view
210
-
211
- const command = clearContentAndWrapInBlockType(
212
- listItemSchema.type(ctx),
213
- { checked: false }
214
- )
215
- command(state, dispatch)
216
- },
217
- })
218
-
219
- const advancedGroup = groupBuilder.addGroup(
220
- 'advanced',
221
- config?.slashMenuAdvancedGroupLabel ?? 'Advanced'
222
- )
223
-
224
- if (isImageBlockEnabled) {
225
- advancedGroup.addItem('image', {
226
- label: config?.slashMenuImageLabel ?? 'Image',
227
- icon: config?.slashMenuImageIcon ?? imageIcon,
228
- onRun: (ctx) => {
229
- const view = ctx.get(editorViewCtx)
230
- const { dispatch, state } = view
231
-
232
- const command = clearContentAndAddBlockType(imageBlockSchema.type(ctx))
233
- command(state, dispatch)
234
- },
235
- })
57
+ const groupBuilder = new GroupBuilder<SlashMenuItem>()
58
+ if (config?.textGroup !== null) {
59
+ const textGroup = groupBuilder.addGroup(
60
+ 'text',
61
+ config?.textGroup?.label ?? 'Text'
62
+ )
63
+ if (config?.textGroup?.text !== null) {
64
+ textGroup.addItem('text', {
65
+ label: config?.textGroup?.text?.label ?? 'Text',
66
+ icon: config?.textGroup?.text?.icon ?? textIcon,
67
+ onRun: (ctx) => {
68
+ const commands = ctx.get(commandsCtx)
69
+ const paragraph = paragraphSchema.type(ctx)
70
+
71
+ commands.call(clearTextInCurrentBlockCommand.key)
72
+ commands.call(setBlockTypeCommand.key, {
73
+ nodeType: paragraph,
74
+ })
75
+ },
76
+ })
77
+ }
78
+
79
+ if (config?.textGroup?.h1 !== null) {
80
+ textGroup.addItem('h1', {
81
+ label: config?.textGroup?.h1?.label ?? 'Heading 1',
82
+ icon: config?.textGroup?.h1?.icon ?? h1Icon,
83
+ onRun: (ctx) => {
84
+ const commands = ctx.get(commandsCtx)
85
+ const heading = headingSchema.type(ctx)
86
+
87
+ commands.call(clearTextInCurrentBlockCommand.key)
88
+ commands.call(setBlockTypeCommand.key, {
89
+ nodeType: heading,
90
+ attrs: {
91
+ level: 1,
92
+ },
93
+ })
94
+ },
95
+ })
96
+ }
97
+
98
+ if (config?.textGroup?.h2 !== null) {
99
+ textGroup.addItem('h2', {
100
+ label: config?.textGroup?.h2?.label ?? 'Heading 2',
101
+ icon: config?.textGroup?.h2?.icon ?? h2Icon,
102
+ onRun: (ctx) => {
103
+ const commands = ctx.get(commandsCtx)
104
+ const heading = headingSchema.type(ctx)
105
+
106
+ commands.call(clearTextInCurrentBlockCommand.key)
107
+ commands.call(setBlockTypeCommand.key, {
108
+ nodeType: heading,
109
+ attrs: {
110
+ level: 2,
111
+ },
112
+ })
113
+ },
114
+ })
115
+ }
116
+
117
+ if (config?.textGroup?.h3 !== null) {
118
+ textGroup.addItem('h3', {
119
+ label: config?.textGroup?.h3?.label ?? 'Heading 3',
120
+ icon: config?.textGroup?.h3?.icon ?? h3Icon,
121
+ onRun: (ctx) => {
122
+ const commands = ctx.get(commandsCtx)
123
+ const heading = headingSchema.type(ctx)
124
+
125
+ commands.call(clearTextInCurrentBlockCommand.key)
126
+ commands.call(setBlockTypeCommand.key, {
127
+ nodeType: heading,
128
+ attrs: {
129
+ level: 3,
130
+ },
131
+ })
132
+ },
133
+ })
134
+ }
135
+
136
+ if (config?.textGroup?.h4 !== null) {
137
+ textGroup.addItem('h4', {
138
+ label: config?.textGroup?.h4?.label ?? 'Heading 4',
139
+ icon: config?.textGroup?.h4?.icon ?? h4Icon,
140
+ onRun: (ctx) => {
141
+ const commands = ctx.get(commandsCtx)
142
+ const heading = headingSchema.type(ctx)
143
+
144
+ commands.call(clearTextInCurrentBlockCommand.key)
145
+ commands.call(setBlockTypeCommand.key, {
146
+ nodeType: heading,
147
+ attrs: {
148
+ level: 4,
149
+ },
150
+ })
151
+ },
152
+ })
153
+ }
154
+
155
+ if (config?.textGroup?.h5 !== null) {
156
+ textGroup.addItem('h5', {
157
+ label: config?.textGroup?.h5?.label ?? 'Heading 5',
158
+ icon: config?.textGroup?.h5?.icon ?? h5Icon,
159
+ onRun: (ctx) => {
160
+ const commands = ctx.get(commandsCtx)
161
+ const heading = headingSchema.type(ctx)
162
+
163
+ commands.call(clearTextInCurrentBlockCommand.key)
164
+ commands.call(setBlockTypeCommand.key, {
165
+ nodeType: heading,
166
+ attrs: {
167
+ level: 5,
168
+ },
169
+ })
170
+ },
171
+ })
172
+ }
173
+
174
+ if (config?.textGroup?.h6 !== null) {
175
+ textGroup.addItem('h6', {
176
+ label: config?.textGroup?.h6?.label ?? 'Heading 6',
177
+ icon: config?.textGroup?.h6?.icon ?? h6Icon,
178
+ onRun: (ctx) => {
179
+ const commands = ctx.get(commandsCtx)
180
+ const heading = headingSchema.type(ctx)
181
+
182
+ commands.call(clearTextInCurrentBlockCommand.key)
183
+ commands.call(setBlockTypeCommand.key, {
184
+ nodeType: heading,
185
+ attrs: {
186
+ level: 6,
187
+ },
188
+ })
189
+ },
190
+ })
191
+ }
192
+
193
+ if (config?.textGroup?.quote !== null) {
194
+ textGroup.addItem('quote', {
195
+ label: config?.textGroup?.quote?.label ?? 'Quote',
196
+ icon: config?.textGroup?.quote?.icon ?? quoteIcon,
197
+ onRun: (ctx) => {
198
+ const commands = ctx.get(commandsCtx)
199
+ const blockquote = blockquoteSchema.type(ctx)
200
+
201
+ commands.call(clearTextInCurrentBlockCommand.key)
202
+ commands.call(wrapInBlockTypeCommand.key, {
203
+ nodeType: blockquote,
204
+ })
205
+ },
206
+ })
207
+ }
208
+
209
+ if (config?.textGroup?.divider !== null) {
210
+ textGroup.addItem('divider', {
211
+ label: config?.textGroup?.divider?.label ?? 'Divider',
212
+ icon: config?.textGroup?.divider?.icon ?? dividerIcon,
213
+ onRun: (ctx) => {
214
+ const commands = ctx.get(commandsCtx)
215
+ const hr = hrSchema.type(ctx)
216
+
217
+ commands.call(clearTextInCurrentBlockCommand.key)
218
+ commands.call(addBlockTypeCommand.key, {
219
+ nodeType: hr,
220
+ })
221
+ },
222
+ })
223
+ }
236
224
  }
237
225
 
238
- advancedGroup.addItem('code', {
239
- label: config?.slashMenuCodeBlockLabel ?? 'Code',
240
- icon: config?.slashMenuCodeBlockIcon ?? codeIcon,
241
- onRun: (ctx) => {
242
- const view = ctx.get(editorViewCtx)
243
- const { dispatch, state } = view
244
-
245
- const command = clearContentAndAddBlockType(codeBlockSchema.type(ctx))
246
- command(state, dispatch)
247
- },
248
- })
249
-
250
- if (isTableEnabled) {
251
- advancedGroup.addItem('table', {
252
- label: config?.slashMenuTableLabel ?? 'Table',
253
- icon: config?.slashMenuTableIcon ?? tableIcon,
254
- onRun: (ctx) => {
255
- const view = ctx.get(editorViewCtx)
256
- const { dispatch, state } = view
257
- let { tr } = state
258
- tr = clearRange(tr)
259
- const from = tr.selection.from
260
- const table = createTable(ctx, 3, 3)
261
- tr = tr.replaceSelectionWith(table)
262
- dispatch(tr)
263
-
264
- requestAnimationFrame(() => {
265
- const docSize = view.state.doc.content.size
266
- const $pos = view.state.doc.resolve(
267
- from > docSize ? docSize : from < 0 ? 0 : from
268
- )
269
- const selection = TextSelection.near($pos)
270
- const tr = view.state.tr
271
- tr.setSelection(selection)
272
- dispatch(tr.scrollIntoView())
273
- })
274
- },
275
- })
226
+ if (config?.listGroup !== null) {
227
+ const listGroup = groupBuilder.addGroup(
228
+ 'list',
229
+ config?.listGroup?.label ?? 'List'
230
+ )
231
+ if (config?.listGroup?.bulletList !== null) {
232
+ listGroup.addItem('bullet-list', {
233
+ label: config?.listGroup?.bulletList?.label ?? 'Bullet List',
234
+ icon: config?.listGroup?.bulletList?.icon ?? bulletListIcon,
235
+ onRun: (ctx) => {
236
+ const commands = ctx.get(commandsCtx)
237
+ const bulletList = bulletListSchema.type(ctx)
238
+
239
+ commands.call(clearTextInCurrentBlockCommand.key)
240
+ commands.call(wrapInBlockTypeCommand.key, {
241
+ nodeType: bulletList,
242
+ })
243
+ },
244
+ })
245
+ }
246
+
247
+ if (config?.listGroup?.orderedList !== null) {
248
+ listGroup.addItem('ordered-list', {
249
+ label: config?.listGroup?.orderedList?.label ?? 'Ordered List',
250
+ icon: config?.listGroup?.orderedList?.icon ?? orderedListIcon,
251
+ onRun: (ctx) => {
252
+ const commands = ctx.get(commandsCtx)
253
+ const orderedList = orderedListSchema.type(ctx)
254
+
255
+ commands.call(clearTextInCurrentBlockCommand.key)
256
+ commands.call(wrapInBlockTypeCommand.key, {
257
+ nodeType: orderedList,
258
+ })
259
+ },
260
+ })
261
+ }
262
+
263
+ if (config?.listGroup?.taskList !== null) {
264
+ listGroup.addItem('task-list', {
265
+ label: config?.listGroup?.taskList?.label ?? 'Task List',
266
+ icon: config?.listGroup?.taskList?.icon ?? todoListIcon,
267
+ onRun: (ctx) => {
268
+ const commands = ctx.get(commandsCtx)
269
+ const listItem = listItemSchema.type(ctx)
270
+
271
+ commands.call(clearTextInCurrentBlockCommand.key)
272
+ commands.call(wrapInBlockTypeCommand.key, {
273
+ nodeType: listItem,
274
+ attrs: { checked: false },
275
+ })
276
+ },
277
+ })
278
+ }
276
279
  }
277
280
 
278
- if (isLatexEnabled) {
279
- advancedGroup.addItem('math', {
280
- label: config?.slashMenuMathLabel ?? 'Math',
281
- icon: config?.slashMenuMathIcon ?? functionsIcon,
282
- onRun: (ctx) => {
283
- const view = ctx.get(editorViewCtx)
284
- const { dispatch, state } = view
285
-
286
- const command = clearContentAndAddBlockType(codeBlockSchema.type(ctx), {
287
- language: 'LaTex',
288
- })
289
- command(state, dispatch)
290
- },
291
- })
281
+ if (config?.advancedGroup !== null) {
282
+ const advancedGroup = groupBuilder.addGroup(
283
+ 'advanced',
284
+ config?.advancedGroup?.label ?? 'Advanced'
285
+ )
286
+
287
+ if (config?.advancedGroup?.image !== null && isImageBlockEnabled) {
288
+ advancedGroup.addItem('image', {
289
+ label: config?.advancedGroup?.image?.label ?? 'Image',
290
+ icon: config?.advancedGroup?.image?.icon ?? imageIcon,
291
+ onRun: (ctx) => {
292
+ const commands = ctx.get(commandsCtx)
293
+ const imageBlock = imageBlockSchema.type(ctx)
294
+
295
+ commands.call(clearTextInCurrentBlockCommand.key)
296
+ commands.call(addBlockTypeCommand.key, {
297
+ nodeType: imageBlock,
298
+ })
299
+ },
300
+ })
301
+ }
302
+
303
+ if (config?.advancedGroup?.codeBlock !== null) {
304
+ advancedGroup.addItem('code', {
305
+ label: config?.advancedGroup?.codeBlock?.label ?? 'Code',
306
+ icon: config?.advancedGroup?.codeBlock?.icon ?? codeIcon,
307
+ onRun: (ctx) => {
308
+ const commands = ctx.get(commandsCtx)
309
+ const codeBlock = codeBlockSchema.type(ctx)
310
+
311
+ commands.call(clearTextInCurrentBlockCommand.key)
312
+ commands.call(setBlockTypeCommand.key, {
313
+ nodeType: codeBlock,
314
+ })
315
+ },
316
+ })
317
+ }
318
+
319
+ if (config?.advancedGroup?.table !== null && isTableEnabled) {
320
+ advancedGroup.addItem('table', {
321
+ label: config?.advancedGroup?.table?.label ?? 'Table',
322
+ icon: config?.advancedGroup?.table?.icon ?? tableIcon,
323
+ onRun: (ctx) => {
324
+ const commands = ctx.get(commandsCtx)
325
+ const view = ctx.get(editorViewCtx)
326
+
327
+ commands.call(clearTextInCurrentBlockCommand.key)
328
+
329
+ // record the position before the table is inserted
330
+ const { from } = view.state.selection
331
+ commands.call(addBlockTypeCommand.key, {
332
+ nodeType: createTable(ctx, 3, 3),
333
+ })
334
+
335
+ commands.call(selectTextNearPosCommand.key, {
336
+ pos: from,
337
+ })
338
+ },
339
+ })
340
+ }
341
+
342
+ if (config?.advancedGroup?.math !== null && isLatexEnabled) {
343
+ advancedGroup.addItem('math', {
344
+ label: config?.advancedGroup?.math?.label ?? 'Math',
345
+ icon: config?.advancedGroup?.math?.icon ?? functionsIcon,
346
+ onRun: (ctx) => {
347
+ const commands = ctx.get(commandsCtx)
348
+ const codeBlock = codeBlockSchema.type(ctx)
349
+
350
+ commands.call(clearTextInCurrentBlockCommand.key)
351
+ commands.call(addBlockTypeCommand.key, {
352
+ nodeType: codeBlock,
353
+ attrs: { language: 'LaTex' },
354
+ })
355
+ },
356
+ })
357
+ }
292
358
  }
293
359
 
294
360
  config?.buildMenu?.(groupBuilder)
@@ -324,7 +390,7 @@ export function getGroups(
324
390
  }, 0)
325
391
 
326
392
  return {
327
- groups: groups as MenuItemGroup[],
393
+ groups: groups as MenuItemGroup<SlashMenuItem>[],
328
394
  size: items.length,
329
395
  }
330
396
  }