@jvs-milkdown/components 1.1.4 → 1.1.6
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.
- package/lib/__internal__/components/image-input.d.ts.map +1 -1
- package/lib/code-block/index.js +12 -3382
- package/lib/code-block/index.js.map +1 -1
- package/lib/image-block/convert-plugin.d.ts +2 -0
- package/lib/image-block/convert-plugin.d.ts.map +1 -0
- package/lib/image-block/index.d.ts +2 -0
- package/lib/image-block/index.d.ts.map +1 -1
- package/lib/image-block/index.js +345 -75
- package/lib/image-block/index.js.map +1 -1
- package/lib/image-block/paste-rule.d.ts +2 -0
- package/lib/image-block/paste-rule.d.ts.map +1 -0
- package/lib/image-block/schema.d.ts.map +1 -1
- package/lib/image-block/view/components/image-block.d.ts +1 -0
- package/lib/image-block/view/components/image-block.d.ts.map +1 -1
- package/lib/image-block/view/components/image-viewer.d.ts.map +1 -1
- package/lib/image-block/view/index.d.ts.map +1 -1
- package/lib/image-inline/index.js +27 -6
- package/lib/image-inline/index.js.map +1 -1
- package/lib/link-tooltip/edit/component.d.ts.map +1 -1
- package/lib/link-tooltip/index.js +19 -1861
- package/lib/link-tooltip/index.js.map +1 -1
- package/lib/list-item-block/index.js +1 -1857
- package/lib/list-item-block/index.js.map +1 -1
- package/lib/table-block/dnd/drag-over-handler.d.ts.map +1 -1
- package/lib/table-block/index.js +140 -2984
- package/lib/table-block/index.js.map +1 -1
- package/lib/table-block/view/component.d.ts.map +1 -1
- package/lib/table-block/view/drag.d.ts +3 -0
- package/lib/table-block/view/drag.d.ts.map +1 -1
- package/lib/table-block/view/utils.d.ts.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/__internal__/components/image-input.tsx +45 -12
- package/src/image-block/__tests__/paste-rule.spec.ts +20 -0
- package/src/image-block/convert-plugin.ts +147 -0
- package/src/image-block/index.ts +6 -0
- package/src/image-block/paste-rule.ts +138 -0
- package/src/image-block/schema.ts +15 -0
- package/src/image-block/view/components/image-block.tsx +5 -0
- package/src/image-block/view/components/image-viewer.tsx +4 -0
- package/src/image-block/view/index.ts +8 -0
- package/src/link-tooltip/edit/component.tsx +27 -3
- package/src/table-block/dnd/create-drag-handler.ts +5 -1
- package/src/table-block/dnd/drag-over-handler.ts +29 -1
- package/src/table-block/dnd/preview.ts +3 -3
- package/src/table-block/view/component.tsx +121 -39
- package/src/table-block/view/drag.ts +29 -16
- package/src/table-block/view/utils.ts +6 -1
|
@@ -3,7 +3,11 @@ import type { Node } from '@jvs-milkdown/prose/model'
|
|
|
3
3
|
import type { EditorView } from '@jvs-milkdown/prose/view'
|
|
4
4
|
|
|
5
5
|
import { computePosition } from '@floating-ui/dom'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
CellSelection,
|
|
8
|
+
mergeCells,
|
|
9
|
+
splitCell,
|
|
10
|
+
} from '@jvs-milkdown/prose/tables'
|
|
7
11
|
import {
|
|
8
12
|
defineComponent,
|
|
9
13
|
ref,
|
|
@@ -12,6 +16,7 @@ import {
|
|
|
12
16
|
onMounted,
|
|
13
17
|
onBeforeUnmount,
|
|
14
18
|
type Ref,
|
|
19
|
+
watch,
|
|
15
20
|
} from 'vue'
|
|
16
21
|
|
|
17
22
|
import type { TableBlockConfig } from '../config'
|
|
@@ -122,7 +127,11 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
const { pointerLeave, pointerMove } = usePointerHandlers(refs, view)
|
|
125
|
-
const { dragRow, dragCol } = useDragHandlers(
|
|
130
|
+
const { dragRow, dragCol, onDragOver, onDragEnd, onDrop } = useDragHandlers(
|
|
131
|
+
refs,
|
|
132
|
+
ctx,
|
|
133
|
+
getPos
|
|
134
|
+
)
|
|
126
135
|
const {
|
|
127
136
|
addRowByIndex,
|
|
128
137
|
addColByIndex,
|
|
@@ -153,18 +162,16 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
153
162
|
return
|
|
154
163
|
}
|
|
155
164
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
canMerge.value = _cellCount > 1
|
|
167
|
-
canSplit.value = hasMerged
|
|
165
|
+
// Bypass instanceof checks due to potential multiple instances of prosemirror-tables
|
|
166
|
+
const isCellSelection = (sel: any) =>
|
|
167
|
+
sel &&
|
|
168
|
+
typeof sel.isColSelection === 'function' &&
|
|
169
|
+
typeof sel.forEachCell === 'function'
|
|
170
|
+
|
|
171
|
+
if (isCellSelection(selection)) {
|
|
172
|
+
// Use prosemirror-tables commands (without dispatch) to check if merge/split is currently possible
|
|
173
|
+
canMerge.value = mergeCells(view.state)
|
|
174
|
+
canSplit.value = splitCell(view.state)
|
|
168
175
|
} else {
|
|
169
176
|
// TextSelection: only show toolbar for CellSelection-based actions
|
|
170
177
|
showCellToolbar.value = false
|
|
@@ -176,6 +183,11 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
176
183
|
return
|
|
177
184
|
}
|
|
178
185
|
|
|
186
|
+
if (activeColIndex.value !== -1 || activeRowIndex.value !== -1) {
|
|
187
|
+
showCellToolbar.value = false
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
|
|
179
191
|
showCellToolbar.value = true
|
|
180
192
|
|
|
181
193
|
// Position toolbar above the first selected cell using floating-ui
|
|
@@ -306,27 +318,39 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
306
318
|
|
|
307
319
|
// Listen for ProseMirror state updates
|
|
308
320
|
const dispatchListener = () => {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
321
|
+
setTimeout(() => {
|
|
322
|
+
// Update active handler button groups based on selection
|
|
323
|
+
const { selection } = view.state
|
|
324
|
+
const isCellSelection = (sel: any) =>
|
|
325
|
+
sel &&
|
|
326
|
+
typeof sel.isColSelection === 'function' &&
|
|
327
|
+
typeof sel.forEachCell === 'function'
|
|
328
|
+
|
|
329
|
+
if (isCellSelection(selection)) {
|
|
330
|
+
const selAny = selection as any
|
|
331
|
+
if (selAny.isColSelection()) {
|
|
332
|
+
const $headCell = selAny.$headCell
|
|
333
|
+
activeColIndex.value = $headCell
|
|
334
|
+
? $headCell.index($headCell.depth)
|
|
335
|
+
: -1
|
|
336
|
+
activeRowIndex.value = -1
|
|
337
|
+
} else if (selAny.isRowSelection()) {
|
|
338
|
+
const $headCell = selAny.$headCell
|
|
339
|
+
activeColIndex.value = -1
|
|
340
|
+
activeRowIndex.value = $headCell
|
|
341
|
+
? $headCell.index($headCell.depth - 1)
|
|
342
|
+
: -1
|
|
343
|
+
} else {
|
|
344
|
+
activeColIndex.value = -1
|
|
345
|
+
activeRowIndex.value = -1
|
|
346
|
+
}
|
|
322
347
|
} else {
|
|
323
348
|
activeColIndex.value = -1
|
|
324
349
|
activeRowIndex.value = -1
|
|
325
350
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
351
|
+
|
|
352
|
+
updateCellToolbar()
|
|
353
|
+
}, 0)
|
|
330
354
|
}
|
|
331
355
|
|
|
332
356
|
onMounted(() => {
|
|
@@ -378,6 +402,10 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
378
402
|
}
|
|
379
403
|
})
|
|
380
404
|
|
|
405
|
+
watch(node, () => {
|
|
406
|
+
dispatchListener()
|
|
407
|
+
})
|
|
408
|
+
|
|
381
409
|
onBeforeUnmount(() => {
|
|
382
410
|
view.dom.removeEventListener('keyup', dispatchListener)
|
|
383
411
|
view.dom.removeEventListener('pointerup', dispatchListener)
|
|
@@ -386,12 +414,26 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
386
414
|
})
|
|
387
415
|
|
|
388
416
|
return () => {
|
|
389
|
-
updateCellToolbar()
|
|
390
|
-
|
|
391
417
|
return (
|
|
392
418
|
<div
|
|
393
|
-
|
|
394
|
-
onDragover={(e) =>
|
|
419
|
+
onDragend={onDragEnd}
|
|
420
|
+
onDragover={(e) => {
|
|
421
|
+
e.preventDefault()
|
|
422
|
+
onDragOver(e)
|
|
423
|
+
// Stop propagation during active drag to prevent ProseMirror interference
|
|
424
|
+
if (dragInfo.value) {
|
|
425
|
+
e.stopPropagation()
|
|
426
|
+
}
|
|
427
|
+
}}
|
|
428
|
+
onDrop={(e) => {
|
|
429
|
+
const isDragging = !!dragInfo.value
|
|
430
|
+
onDrop(e)
|
|
431
|
+
// Stop ProseMirror from handling the drop during table drag
|
|
432
|
+
if (isDragging) {
|
|
433
|
+
e.preventDefault()
|
|
434
|
+
e.stopPropagation()
|
|
435
|
+
}
|
|
436
|
+
}}
|
|
395
437
|
onDragleave={(e) => e.preventDefault()}
|
|
396
438
|
onPointermove={pointerMove}
|
|
397
439
|
onPointerleave={pointerLeave}
|
|
@@ -405,7 +447,7 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
405
447
|
contenteditable="false"
|
|
406
448
|
onPointerdown={(e: PointerEvent) => e.stopPropagation()}
|
|
407
449
|
>
|
|
408
|
-
{
|
|
450
|
+
{
|
|
409
451
|
<button
|
|
410
452
|
type="button"
|
|
411
453
|
class="cell-toolbar-btn"
|
|
@@ -413,8 +455,8 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
413
455
|
>
|
|
414
456
|
<Icon icon={config.renderButton('merge_cells')} />
|
|
415
457
|
</button>
|
|
416
|
-
|
|
417
|
-
{
|
|
458
|
+
}
|
|
459
|
+
{
|
|
418
460
|
<button
|
|
419
461
|
type="button"
|
|
420
462
|
class="cell-toolbar-btn"
|
|
@@ -422,7 +464,7 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
422
464
|
>
|
|
423
465
|
<Icon icon={config.renderButton('split_cell')} />
|
|
424
466
|
</button>
|
|
425
|
-
|
|
467
|
+
}
|
|
426
468
|
</div>
|
|
427
469
|
|
|
428
470
|
<div class="table-wrapper" ref={tableWrapperRef}>
|
|
@@ -442,6 +484,7 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
442
484
|
onClick={() => {
|
|
443
485
|
hoverIndex.value = [0, i]
|
|
444
486
|
selectCol()
|
|
487
|
+
dispatchListener()
|
|
445
488
|
activeColIndex.value = i
|
|
446
489
|
activeRowIndex.value = -1
|
|
447
490
|
}}
|
|
@@ -489,6 +532,16 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
489
532
|
>
|
|
490
533
|
<Icon icon={config.renderButton('delete_col')} />
|
|
491
534
|
</button>
|
|
535
|
+
{canMerge.value && (
|
|
536
|
+
<button type="button" onPointerdown={onMergeCells}>
|
|
537
|
+
<Icon icon={config.renderButton('merge_cells')} />
|
|
538
|
+
</button>
|
|
539
|
+
)}
|
|
540
|
+
{canSplit.value && (
|
|
541
|
+
<button type="button" onPointerdown={onSplitCell}>
|
|
542
|
+
<Icon icon={config.renderButton('split_cell')} />
|
|
543
|
+
</button>
|
|
544
|
+
)}
|
|
492
545
|
</div>
|
|
493
546
|
</div>
|
|
494
547
|
))}
|
|
@@ -548,6 +601,7 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
548
601
|
onClick={() => {
|
|
549
602
|
hoverIndex.value = [i, 0]
|
|
550
603
|
selectRow()
|
|
604
|
+
dispatchListener()
|
|
551
605
|
activeRowIndex.value = i
|
|
552
606
|
activeColIndex.value = -1
|
|
553
607
|
}}
|
|
@@ -567,6 +621,16 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
567
621
|
>
|
|
568
622
|
<Icon icon={config.renderButton('delete_row')} />
|
|
569
623
|
</button>
|
|
624
|
+
{canMerge.value && (
|
|
625
|
+
<button type="button" onPointerdown={onMergeCells}>
|
|
626
|
+
<Icon icon={config.renderButton('merge_cells')} />
|
|
627
|
+
</button>
|
|
628
|
+
)}
|
|
629
|
+
{canSplit.value && (
|
|
630
|
+
<button type="button" onPointerdown={onSplitCell}>
|
|
631
|
+
<Icon icon={config.renderButton('split_cell')} />
|
|
632
|
+
</button>
|
|
633
|
+
)}
|
|
570
634
|
</div>
|
|
571
635
|
</div>
|
|
572
636
|
))}
|
|
@@ -604,6 +668,24 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
604
668
|
</table>
|
|
605
669
|
</div>
|
|
606
670
|
|
|
671
|
+
{/* Drop Indicators */}
|
|
672
|
+
<div
|
|
673
|
+
data-show="false"
|
|
674
|
+
contenteditable="false"
|
|
675
|
+
data-display-type="indicator"
|
|
676
|
+
data-role="x-line-drag-handle"
|
|
677
|
+
class="handle line-handle"
|
|
678
|
+
ref={xLineHandleRef}
|
|
679
|
+
/>
|
|
680
|
+
<div
|
|
681
|
+
data-show="false"
|
|
682
|
+
contenteditable="false"
|
|
683
|
+
data-display-type="indicator"
|
|
684
|
+
data-role="y-line-drag-handle"
|
|
685
|
+
class="handle line-handle"
|
|
686
|
+
ref={yLineHandleRef}
|
|
687
|
+
/>
|
|
688
|
+
|
|
607
689
|
<table ref={contentWrapperFunctionRef} class="children">
|
|
608
690
|
<colgroup>
|
|
609
691
|
{colWidths.value.map((w, i) => (
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
selectColCommand,
|
|
8
8
|
selectRowCommand,
|
|
9
9
|
} from '@jvs-milkdown/preset-gfm'
|
|
10
|
-
import { onMounted, onUnmounted } from 'vue'
|
|
11
10
|
|
|
12
11
|
import type { CellIndex, Refs } from './types'
|
|
13
12
|
|
|
@@ -27,21 +26,25 @@ export function useDragHandlers(
|
|
|
27
26
|
const dragRow = createDragRowHandler(refs, ctx)
|
|
28
27
|
const dragCol = createDragColHandler(refs, ctx)
|
|
29
28
|
|
|
30
|
-
const onDragEnd = () => {
|
|
29
|
+
const onDragEnd = (e: DragEvent) => {
|
|
31
30
|
const preview = dragPreviewRef.value
|
|
32
31
|
if (!preview) return
|
|
33
32
|
|
|
34
33
|
if (preview.dataset.show === 'false') return
|
|
35
34
|
|
|
35
|
+
e.preventDefault()
|
|
36
|
+
e.stopPropagation()
|
|
37
|
+
|
|
36
38
|
const previewRoot = preview?.querySelector('tbody')
|
|
37
39
|
|
|
38
40
|
while (previewRoot?.firstChild)
|
|
39
41
|
previewRoot?.removeChild(previewRoot.firstChild)
|
|
40
42
|
|
|
41
43
|
if (preview) preview.dataset.show = 'false'
|
|
44
|
+
dragInfo.value = undefined
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
const onDrop = () => {
|
|
47
|
+
const onDrop = (e: DragEvent) => {
|
|
45
48
|
const preview = dragPreviewRef.value
|
|
46
49
|
if (!preview) return
|
|
47
50
|
const yHandle = yLineHandleRef.value
|
|
@@ -53,10 +56,22 @@ export function useDragHandlers(
|
|
|
53
56
|
if (!ctx) return
|
|
54
57
|
if (preview.dataset.show === 'false') return
|
|
55
58
|
|
|
59
|
+
// Prevent browser default drop behavior and stop ProseMirror from handling
|
|
60
|
+
e.preventDefault()
|
|
61
|
+
e.stopPropagation()
|
|
62
|
+
|
|
56
63
|
yHandle.dataset.show = 'false'
|
|
57
64
|
xHandle.dataset.show = 'false'
|
|
58
65
|
|
|
59
|
-
if (info.startIndex === info.endIndex)
|
|
66
|
+
if (info.startIndex === info.endIndex) {
|
|
67
|
+
// Clean up preview even when no move is needed
|
|
68
|
+
const previewRoot = preview?.querySelector('tbody')
|
|
69
|
+
while (previewRoot?.firstChild)
|
|
70
|
+
previewRoot?.removeChild(previewRoot.firstChild)
|
|
71
|
+
preview.dataset.show = 'false'
|
|
72
|
+
dragInfo.value = undefined
|
|
73
|
+
return
|
|
74
|
+
}
|
|
60
75
|
|
|
61
76
|
const commands = ctx.get(commandsCtx)
|
|
62
77
|
const payload = {
|
|
@@ -82,26 +97,24 @@ export function useDragHandlers(
|
|
|
82
97
|
refs.hoverIndex.value = index
|
|
83
98
|
}
|
|
84
99
|
|
|
100
|
+
// Clean up preview
|
|
101
|
+
const previewRoot = preview?.querySelector('tbody')
|
|
102
|
+
while (previewRoot?.firstChild)
|
|
103
|
+
previewRoot?.removeChild(previewRoot.firstChild)
|
|
104
|
+
preview.dataset.show = 'false'
|
|
105
|
+
dragInfo.value = undefined
|
|
106
|
+
|
|
85
107
|
requestAnimationFrame(() => {
|
|
86
108
|
ctx.get(editorViewCtx).focus()
|
|
87
109
|
})
|
|
88
110
|
}
|
|
89
111
|
const onDragOver = createDragOverHandler(refs)
|
|
90
112
|
|
|
91
|
-
onMounted(() => {
|
|
92
|
-
window.addEventListener('dragover', onDragOver)
|
|
93
|
-
window.addEventListener('dragend', onDragEnd)
|
|
94
|
-
window.addEventListener('drop', onDrop)
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
onUnmounted(() => {
|
|
98
|
-
window.removeEventListener('dragover', onDragOver)
|
|
99
|
-
window.removeEventListener('dragend', onDragEnd)
|
|
100
|
-
window.removeEventListener('drop', onDrop)
|
|
101
|
-
})
|
|
102
|
-
|
|
103
113
|
return {
|
|
104
114
|
dragRow,
|
|
105
115
|
dragCol,
|
|
116
|
+
onDragOver,
|
|
117
|
+
onDrop,
|
|
118
|
+
onDragEnd,
|
|
106
119
|
}
|
|
107
120
|
}
|
|
@@ -88,7 +88,12 @@ export function recoveryStateBetweenUpdate(
|
|
|
88
88
|
if (!node) return
|
|
89
89
|
if (!view) return
|
|
90
90
|
const { selection } = view.state
|
|
91
|
-
|
|
91
|
+
const isCellSelection = (sel: any) =>
|
|
92
|
+
sel &&
|
|
93
|
+
typeof sel.isColSelection === 'function' &&
|
|
94
|
+
typeof sel.forEachCell === 'function'
|
|
95
|
+
|
|
96
|
+
if (!isCellSelection(selection)) return
|
|
92
97
|
|
|
93
98
|
const { $from } = selection
|
|
94
99
|
const table = findTable($from)
|