@jvs-milkdown/components 1.2.1 → 1.2.3

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 (132) hide show
  1. package/lib/__internal__/components/icon.d.ts +24 -0
  2. package/lib/__internal__/components/icon.d.ts.map +1 -0
  3. package/lib/__internal__/components/image-input.d.ts +17 -0
  4. package/lib/__internal__/components/image-input.d.ts.map +1 -0
  5. package/lib/__internal__/keep-alive.d.ts +2 -0
  6. package/lib/__internal__/keep-alive.d.ts.map +1 -0
  7. package/lib/__internal__/meta.d.ts +3 -0
  8. package/lib/__internal__/meta.d.ts.map +1 -0
  9. package/lib/__tests__/setup.d.ts +2 -0
  10. package/lib/__tests__/setup.d.ts.map +1 -0
  11. package/lib/code-block/config.d.ts +25 -0
  12. package/lib/code-block/config.d.ts.map +1 -0
  13. package/lib/code-block/index.d.ts +5 -0
  14. package/lib/code-block/index.d.ts.map +1 -0
  15. package/lib/code-block/view/components/code-block.d.ts +18 -0
  16. package/lib/code-block/view/components/code-block.d.ts.map +1 -0
  17. package/lib/code-block/view/components/copy-button.d.ts +9 -0
  18. package/lib/code-block/view/components/copy-button.d.ts.map +1 -0
  19. package/lib/code-block/view/components/language-picker.d.ts +5 -0
  20. package/lib/code-block/view/components/language-picker.d.ts.map +1 -0
  21. package/lib/code-block/view/components/preview-panel.d.ts +9 -0
  22. package/lib/code-block/view/components/preview-panel.d.ts.map +1 -0
  23. package/lib/code-block/view/index.d.ts +3 -0
  24. package/lib/code-block/view/index.d.ts.map +1 -0
  25. package/lib/code-block/view/loader.d.ts +13 -0
  26. package/lib/code-block/view/loader.d.ts.map +1 -0
  27. package/lib/code-block/view/node-view.d.ts +43 -0
  28. package/lib/code-block/view/node-view.d.ts.map +1 -0
  29. package/lib/image-block/config.d.ts +21 -0
  30. package/lib/image-block/config.d.ts.map +1 -0
  31. package/lib/image-block/convert-plugin.d.ts +2 -0
  32. package/lib/image-block/convert-plugin.d.ts.map +1 -0
  33. package/lib/image-block/index.d.ts +9 -0
  34. package/lib/image-block/index.d.ts.map +1 -0
  35. package/lib/image-block/index.js +120 -56
  36. package/lib/image-block/index.js.map +1 -1
  37. package/lib/image-block/paste-rule.d.ts +2 -0
  38. package/lib/image-block/paste-rule.d.ts.map +1 -0
  39. package/lib/image-block/remark-plugin.d.ts +2 -0
  40. package/lib/image-block/remark-plugin.d.ts.map +1 -0
  41. package/lib/image-block/schema.d.ts +3 -0
  42. package/lib/image-block/schema.d.ts.map +1 -0
  43. package/lib/image-block/view/components/__tests__/image-viewer.onImageLoadError.spec.d.ts +2 -0
  44. package/lib/image-block/view/components/__tests__/image-viewer.onImageLoadError.spec.d.ts.map +1 -0
  45. package/lib/image-block/view/components/image-block.d.ts +27 -0
  46. package/lib/image-block/view/components/image-block.d.ts.map +1 -0
  47. package/lib/image-block/view/components/image-viewer.d.ts +3 -0
  48. package/lib/image-block/view/components/image-viewer.d.ts.map +1 -0
  49. package/lib/image-block/view/index.d.ts +3 -0
  50. package/lib/image-block/view/index.d.ts.map +1 -0
  51. package/lib/image-inline/components/image-inline.d.ts +18 -0
  52. package/lib/image-inline/components/image-inline.d.ts.map +1 -0
  53. package/lib/image-inline/config.d.ts +11 -0
  54. package/lib/image-inline/config.d.ts.map +1 -0
  55. package/lib/image-inline/index.d.ts +5 -0
  56. package/lib/image-inline/index.d.ts.map +1 -0
  57. package/lib/image-inline/view.d.ts +3 -0
  58. package/lib/image-inline/view.d.ts.map +1 -0
  59. package/lib/index.d.ts +2 -0
  60. package/lib/index.d.ts.map +1 -0
  61. package/lib/link-tooltip/command.d.ts +2 -0
  62. package/lib/link-tooltip/command.d.ts.map +1 -0
  63. package/lib/link-tooltip/configure.d.ts +3 -0
  64. package/lib/link-tooltip/configure.d.ts.map +1 -0
  65. package/lib/link-tooltip/edit/component.d.ts +11 -0
  66. package/lib/link-tooltip/edit/component.d.ts.map +1 -0
  67. package/lib/link-tooltip/edit/edit-configure.d.ts +3 -0
  68. package/lib/link-tooltip/edit/edit-configure.d.ts.map +1 -0
  69. package/lib/link-tooltip/edit/edit-view.d.ts +15 -0
  70. package/lib/link-tooltip/edit/edit-view.d.ts.map +1 -0
  71. package/lib/link-tooltip/index.d.ts +7 -0
  72. package/lib/link-tooltip/index.d.ts.map +1 -0
  73. package/lib/link-tooltip/index.js +1 -2
  74. package/lib/link-tooltip/index.js.map +1 -1
  75. package/lib/link-tooltip/preview/component.d.ts +11 -0
  76. package/lib/link-tooltip/preview/component.d.ts.map +1 -0
  77. package/lib/link-tooltip/preview/preview-configure.d.ts +3 -0
  78. package/lib/link-tooltip/preview/preview-configure.d.ts.map +1 -0
  79. package/lib/link-tooltip/preview/preview-view.d.ts +14 -0
  80. package/lib/link-tooltip/preview/preview-view.d.ts.map +1 -0
  81. package/lib/link-tooltip/slices.d.ts +34 -0
  82. package/lib/link-tooltip/slices.d.ts.map +1 -0
  83. package/lib/link-tooltip/tooltips.d.ts +3 -0
  84. package/lib/link-tooltip/tooltips.d.ts.map +1 -0
  85. package/lib/link-tooltip/utils.d.ts +14 -0
  86. package/lib/link-tooltip/utils.d.ts.map +1 -0
  87. package/lib/list-item-block/component.d.ts +19 -0
  88. package/lib/list-item-block/component.d.ts.map +1 -0
  89. package/lib/list-item-block/config.d.ts +13 -0
  90. package/lib/list-item-block/config.d.ts.map +1 -0
  91. package/lib/list-item-block/index.d.ts +6 -0
  92. package/lib/list-item-block/index.d.ts.map +1 -0
  93. package/lib/list-item-block/view.d.ts +3 -0
  94. package/lib/list-item-block/view.d.ts.map +1 -0
  95. package/lib/table-block/config.d.ts +8 -0
  96. package/lib/table-block/config.d.ts.map +1 -0
  97. package/lib/table-block/dnd/calc-drag-over.d.ts +3 -0
  98. package/lib/table-block/dnd/calc-drag-over.d.ts.map +1 -0
  99. package/lib/table-block/dnd/create-drag-handler.d.ts +5 -0
  100. package/lib/table-block/dnd/create-drag-handler.d.ts.map +1 -0
  101. package/lib/table-block/dnd/drag-over-handler.d.ts +3 -0
  102. package/lib/table-block/dnd/drag-over-handler.d.ts.map +1 -0
  103. package/lib/table-block/dnd/prepare-dnd-context.d.ts +3 -0
  104. package/lib/table-block/dnd/prepare-dnd-context.d.ts.map +1 -0
  105. package/lib/table-block/dnd/preview.d.ts +3 -0
  106. package/lib/table-block/dnd/preview.d.ts.map +1 -0
  107. package/lib/table-block/index.d.ts +5 -0
  108. package/lib/table-block/index.d.ts.map +1 -0
  109. package/lib/table-block/index.js.map +1 -1
  110. package/lib/table-block/view/component.d.ts +16 -0
  111. package/lib/table-block/view/component.d.ts.map +1 -0
  112. package/lib/table-block/view/drag.d.ts +10 -0
  113. package/lib/table-block/view/drag.d.ts.map +1 -0
  114. package/lib/table-block/view/index.d.ts +2 -0
  115. package/lib/table-block/view/index.d.ts.map +1 -0
  116. package/lib/table-block/view/operation.d.ts +13 -0
  117. package/lib/table-block/view/operation.d.ts.map +1 -0
  118. package/lib/table-block/view/pointer.d.ts +7 -0
  119. package/lib/table-block/view/pointer.d.ts.map +1 -0
  120. package/lib/table-block/view/types.d.ts +28 -0
  121. package/lib/table-block/view/types.d.ts.map +1 -0
  122. package/lib/table-block/view/utils.d.ts +12 -0
  123. package/lib/table-block/view/utils.d.ts.map +1 -0
  124. package/lib/table-block/view/view.d.ts +22 -0
  125. package/lib/table-block/view/view.d.ts.map +1 -0
  126. package/lib/tsconfig.tsbuildinfo +1 -1
  127. package/package.json +10 -10
  128. package/src/image-block/convert-plugin.ts +1 -1
  129. package/src/image-block/paste-rule.ts +1 -21
  130. package/src/image-block/view/components/image-viewer.tsx +139 -53
  131. package/src/link-tooltip/edit/component.tsx +0 -1
  132. package/src/table-block/view/utils.ts +4 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jvs-milkdown/components",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "keywords": [
5
5
  "milkdown",
6
6
  "milkdown plugin"
@@ -50,15 +50,15 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@floating-ui/dom": "^1.5.1",
53
- "@jvs-milkdown/core": "^1.2.1",
54
- "@jvs-milkdown/ctx": "^1.2.1",
55
- "@jvs-milkdown/exception": "^1.2.1",
56
- "@jvs-milkdown/plugin-tooltip": "^1.2.1",
57
- "@jvs-milkdown/preset-commonmark": "^1.2.1",
58
- "@jvs-milkdown/preset-gfm": "^1.2.1",
59
- "@jvs-milkdown/prose": "^1.2.1",
60
- "@jvs-milkdown/transformer": "^1.2.1",
61
- "@jvs-milkdown/utils": "^1.2.1",
53
+ "@jvs-milkdown/core": "^1.2.3",
54
+ "@jvs-milkdown/ctx": "^1.2.3",
55
+ "@jvs-milkdown/exception": "^1.2.3",
56
+ "@jvs-milkdown/plugin-tooltip": "^1.2.3",
57
+ "@jvs-milkdown/preset-commonmark": "^1.2.3",
58
+ "@jvs-milkdown/preset-gfm": "^1.2.3",
59
+ "@jvs-milkdown/prose": "^1.2.3",
60
+ "@jvs-milkdown/transformer": "^1.2.3",
61
+ "@jvs-milkdown/utils": "^1.2.3",
62
62
  "@types/lodash-es": "^4.17.12",
63
63
  "clsx": "^2.0.0",
64
64
  "dompurify": "^3.2.5",
@@ -30,7 +30,7 @@ export const imageBlockConvertPlugin = $prose((ctx) => {
30
30
 
31
31
  // Debug: log all paragraphs with their children
32
32
  let foundImages = 0
33
- newState.doc.descendants((node, pos) => {
33
+ newState.doc.descendants((node) => {
34
34
  if (node.type === imageType) foundImages++
35
35
  })
36
36
  if (foundImages > 0) {
@@ -21,27 +21,7 @@ function toImageBlock(
21
21
  })
22
22
  }
23
23
 
24
- /// Check if a paragraph contains only images (and trailing hard_breaks / empty text).
25
- /// Returns the list of image nodes found, or null if there's other content.
26
- function extractParagraphImages(
27
- node: ProsemirrorNode,
28
- imageType: ProsemirrorNode['type']
29
- ): ProsemirrorNode[] | null {
30
- const images: ProsemirrorNode[] = []
31
- for (let i = 0; i < node.childCount; i++) {
32
- const child = node.child(i)
33
- if (child.type === imageType) {
34
- images.push(child)
35
- } else if (child.type.name === 'hardbreak') {
36
- continue
37
- } else if (child.isText && child.text?.trim() === '') {
38
- continue
39
- } else {
40
- return null
41
- }
42
- }
43
- return images.length > 0 ? images : null
44
- }
24
+
45
25
 
46
26
  /// A paste rule that converts standalone inline images to image-block nodes.
47
27
  /// Handles the slice structures produced when pasting HTML from external pages
@@ -57,9 +57,11 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
57
57
  const showBorderPanel = ref(false)
58
58
  const isCropping = ref(false)
59
59
 
60
- // Display dimensions (set in onImageLoad)
61
- const displayW = ref(0)
62
- const displayH = ref(0)
60
+ const baseDisplayW = ref(0)
61
+ const baseDisplayH = ref(0)
62
+ const liveRatio = ref<number | null>(null)
63
+ const localBorderWidth = ref<number | null>(null)
64
+ const localBorderColor = ref<string | null>(null)
63
65
 
64
66
  // Local crop state for interactive editing
65
67
  const localCrop = ref({ top: 0, left: 0, width: 1, height: 1 })
@@ -92,22 +94,20 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
92
94
 
93
95
  const height = image.naturalHeight
94
96
  const width = image.naturalWidth
95
- let transformedHeight =
96
- width < maxWidth ? height : maxWidth * (height / width)
97
+ if (!height || !width) return
97
98
 
98
- if (config.maxHeight && transformedHeight > config.maxHeight)
99
- transformedHeight = config.maxHeight
99
+ const aspect = width / height
100
100
 
101
- const h = (transformedHeight * (ratio.value ?? 1)).toFixed(2)
102
- image.dataset.origin = transformedHeight.toFixed(2)
103
- image.dataset.height = h
104
- image.style.height = `${h}px`
101
+ let transformedWidth = width < maxWidth ? width : maxWidth
102
+ let transformedHeight = transformedWidth / aspect
105
103
 
106
- if (config.maxWidth) image.style.maxWidth = `${config.maxWidth}px`
104
+ if (config.maxHeight && transformedHeight > config.maxHeight) {
105
+ transformedHeight = config.maxHeight
106
+ transformedWidth = transformedHeight * aspect
107
+ }
107
108
 
108
- const dw = width < maxWidth ? width : maxWidth
109
- displayW.value = dw
110
- displayH.value = parseFloat(h)
109
+ baseDisplayH.value = transformedHeight
110
+ baseDisplayW.value = transformedWidth
111
111
  }
112
112
 
113
113
  const onToggleCaption = (e: MouseEvent) => {
@@ -140,8 +140,6 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
140
140
 
141
141
  const onResizeHandlePointerMove = (e: PointerEvent) => {
142
142
  e.preventDefault()
143
- const image = imageRef.value
144
- if (!image) return
145
143
 
146
144
  const deltaY = e.clientY - startY
147
145
  const deltaX = e.clientX - startX
@@ -149,6 +147,7 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
149
147
  const aspect = startHeight / (startWidth || 1)
150
148
  let dhY = resizeDir.includes('bottom') ? deltaY : -deltaY
151
149
  let dhX = 0
150
+
152
151
  if (resizeDir.includes('right')) {
153
152
  dhX = deltaX * aspect
154
153
  } else if (resizeDir.includes('left')) {
@@ -156,32 +155,53 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
156
155
  }
157
156
 
158
157
  const dh = Math.abs(dhX) > Math.abs(dhY) ? dhX : dhY
159
- let height = startHeight + dh
158
+ let newWrapperHeight = startHeight + dh
159
+
160
+ let newWrapperWidth = newWrapperHeight * (startWidth / (startHeight || 1))
161
+
162
+ if (newWrapperHeight < 20) {
163
+ newWrapperHeight = 20
164
+ newWrapperWidth = newWrapperHeight * (startWidth / (startHeight || 1))
165
+ }
166
+
167
+ if (newWrapperWidth < 20) {
168
+ newWrapperWidth = 20
169
+ newWrapperHeight = newWrapperWidth / (startWidth / (startHeight || 1))
170
+ }
171
+
172
+ const image = imageRef.value
173
+ const host = image?.closest('.milkdown-image-block')
174
+ const hostWidth = host?.getBoundingClientRect().width
175
+ const maxW =
176
+ config.maxWidth && hostWidth
177
+ ? Math.min(config.maxWidth, hostWidth)
178
+ : hostWidth || Infinity
179
+
180
+ if (newWrapperWidth > maxW) {
181
+ newWrapperWidth = maxW
182
+ newWrapperHeight = newWrapperWidth / (startWidth / (startHeight || 1))
183
+ }
184
+
185
+ if (config.maxHeight && newWrapperHeight > config.maxHeight) {
186
+ newWrapperHeight = config.maxHeight
187
+ }
160
188
 
161
- if (height < 20) height = 20
162
- if (config.maxHeight && height > config.maxHeight)
163
- height = config.maxHeight
189
+ const cHeight =
190
+ isCropped() && !isCropping.value ? (cropHeight.value ?? 1) : 1
191
+ const newBaseHeight = newWrapperHeight / cHeight
164
192
 
165
- const h = Number(height).toFixed(2)
166
- image.dataset.height = h
167
- image.style.height = `${h}px`
193
+ const newRatio = newBaseHeight / (baseDisplayH.value || 1)
194
+ liveRatio.value = Number(newRatio.toFixed(2))
168
195
  }
169
196
 
170
197
  const onResizeHandlePointerUp = () => {
171
198
  window.removeEventListener('pointermove', onResizeHandlePointerMove)
172
199
  window.removeEventListener('pointerup', onResizeHandlePointerUp)
173
200
 
174
- const image = imageRef.value
175
- if (!image) return
176
-
177
- const originHeight = Number(image.dataset.origin)
178
- const currentHeight = Number(image.dataset.height)
179
- const ratio = Number.parseFloat(
180
- Number(currentHeight / originHeight).toFixed(2)
181
- )
182
- if (Number.isNaN(ratio)) return
183
-
184
- setAttr('ratio', ratio)
201
+ if (liveRatio.value !== null) {
202
+ setAttr('ratio', liveRatio.value)
203
+ liveRatio.value = null
204
+ }
185
205
  }
186
206
 
187
207
  const onResizeHandlePointerDown = (e: PointerEvent, dir: string) => {
@@ -191,11 +211,12 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
191
211
  resizeDir = dir
192
212
  startY = e.clientY
193
213
  startX = e.clientX
194
- const image = imageRef.value
195
- if (image) {
196
- startHeight = image.getBoundingClientRect().height
197
- startWidth = image.getBoundingClientRect().width
214
+ const wrapper = wrapperRef.value
215
+ if (wrapper) {
216
+ startHeight = wrapper.getBoundingClientRect().height
217
+ startWidth = wrapper.getBoundingClientRect().width
198
218
  }
219
+ liveRatio.value = ratio.value ?? 1
199
220
  window.addEventListener('pointermove', onResizeHandlePointerMove)
200
221
  window.addEventListener('pointerup', onResizeHandlePointerUp)
201
222
  }
@@ -362,8 +383,14 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
362
383
 
363
384
  return () => {
364
385
  const currentBorderStyle = borderStyle.value ?? 'none'
365
- const currentBorderWidth = borderWidth.value ?? 0
366
- const currentBorderColor = borderColor.value ?? '#000000'
386
+ const currentBorderWidth =
387
+ localBorderWidth.value !== null
388
+ ? localBorderWidth.value
389
+ : (borderWidth.value ?? 0)
390
+ const currentBorderColor =
391
+ localBorderColor.value !== null
392
+ ? localBorderColor.value
393
+ : (borderColor.value ?? '#000000')
367
394
  const cTop = cropTop.value ?? 0
368
395
  const cLeft = cropLeft.value ?? 0
369
396
  const cWidth = cropWidth.value ?? 1
@@ -376,22 +403,46 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
376
403
  ? `${currentBorderWidth}px ${currentBorderStyle} ${currentBorderColor}`
377
404
  : undefined
378
405
 
379
- const dw = displayW.value
380
- const dh = displayH.value
406
+ const currentRatio =
407
+ liveRatio.value !== null ? liveRatio.value : (ratio.value ?? 1)
408
+
409
+ let baseW = baseDisplayW.value * currentRatio
410
+ let baseH = baseDisplayH.value * currentRatio
381
411
 
382
- // Use actual rendered dimensions when available for accurate crop margins
383
- const imgEl = imageRef.value
384
- const actualW = imgEl ? imgEl.getBoundingClientRect().width : dw
385
- const actualH = imgEl ? imgEl.getBoundingClientRect().height : dh
386
- const baseW = cropped && !isCropping.value && imgEl ? actualW : dw
387
- const baseH = cropped && !isCropping.value && imgEl ? actualH : dh
412
+ const image = imageRef.value
413
+ const host = image?.closest('.milkdown-image-block')
414
+ const hostWidth = host?.getBoundingClientRect().width
415
+ const maxW =
416
+ config.maxWidth && hostWidth
417
+ ? Math.min(config.maxWidth, hostWidth)
418
+ : hostWidth || Infinity
419
+
420
+ const visibleW = isCropping.value
421
+ ? baseW
422
+ : cropped
423
+ ? baseW * cWidth
424
+ : baseW
425
+
426
+ if (visibleW > maxW && maxW > 0) {
427
+ const scale = maxW / visibleW
428
+ baseW = baseW * scale
429
+ baseH = baseH * scale
430
+ }
388
431
 
389
432
  const cropPxW = baseW * cWidth
390
433
  const cropPxH = baseH * cHeight
391
434
  const cropPxL = baseW * cLeft
392
435
  const cropPxT = baseH * cTop
393
436
 
394
- const wrapperStyle: Record<string, string> = {}
437
+ const wrapperStyle: Record<string, string> = {
438
+ minWidth: '20px',
439
+ minHeight: '20px',
440
+ border: !isCropping.value ? (borderStyleStr ?? '') : '',
441
+ }
442
+ if (cropped && !isCropping.value && cropPxW > 0 && cropPxH > 0) {
443
+ wrapperStyle.width = `${cropPxW}px`
444
+ wrapperStyle.height = `${cropPxH}px`
445
+ }
395
446
  const cropClipStyle: Record<string, string> | null =
396
447
  cropped && !isCropping.value && baseW > 0 && baseH > 0
397
448
  ? {
@@ -401,16 +452,22 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
401
452
  }
402
453
  : null
403
454
 
404
- const imgStyle: Record<string, string> = {}
455
+ const imgStyle: Record<string, string> = {
456
+ minWidth: '0px',
457
+ minHeight: '0px',
458
+ }
405
459
  if (cropped && !isCropping.value && baseW > 0 && baseH > 0) {
406
460
  imgStyle.width = `${baseW}px`
407
461
  imgStyle.height = `${baseH}px`
408
462
  imgStyle.maxWidth = 'none'
409
463
  imgStyle.marginLeft = `${-cropPxL}px`
410
464
  imgStyle.marginTop = `${-cropPxT}px`
411
- imgStyle.border = borderStyleStr ?? ''
412
465
  } else {
413
- imgStyle.border = borderStyleStr ?? ''
466
+ if (baseH > 0 && baseW > 0) {
467
+ imgStyle.width = `${baseW}px`
468
+ imgStyle.height = `${baseH}px`
469
+ if (config.maxWidth) imgStyle.maxWidth = `${config.maxWidth}px`
470
+ }
414
471
  }
415
472
 
416
473
  return (
@@ -466,7 +523,14 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
466
523
  {showBorderPanel.value ? (
467
524
  <div
468
525
  class="setting-panel border-panel"
526
+ draggable="true"
469
527
  onClick={(e) => e.stopPropagation()}
528
+ onMousedown={(e) => e.stopPropagation()}
529
+ onPointerdown={(e) => e.stopPropagation()}
530
+ onDragstart={(e) => {
531
+ e.preventDefault()
532
+ e.stopPropagation()
533
+ }}
470
534
  >
471
535
  <div class="setting-panel-title">{'边框设置'}</div>
472
536
  <div class="setting-row">
@@ -495,16 +559,27 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
495
559
  <div class="setting-row">
496
560
  <span class="setting-label">{'宽度'}</span>
497
561
  <input
562
+ draggable="true"
498
563
  type="range"
499
564
  min="1"
500
565
  max="10"
501
566
  value={currentBorderWidth}
502
567
  onInput={(e: Event) => {
568
+ const target = e.target as HTMLInputElement
569
+ localBorderWidth.value = Number(target.value)
570
+ }}
571
+ onChange={(e: Event) => {
503
572
  const target = e.target as HTMLInputElement
504
573
  setAttr('borderWidth', Number(target.value))
574
+ localBorderWidth.value = null
505
575
  }}
506
576
  onClick={(e: MouseEvent) => e.stopPropagation()}
577
+ onMousedown={(e: MouseEvent) => e.stopPropagation()}
507
578
  onPointerdown={(e: PointerEvent) => e.stopPropagation()}
579
+ onDragstart={(e: DragEvent) => {
580
+ e.preventDefault()
581
+ e.stopPropagation()
582
+ }}
508
583
  />
509
584
  <span class="setting-value">{currentBorderWidth}px</span>
510
585
  </div>
@@ -513,14 +588,25 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
513
588
  <div class="setting-row">
514
589
  <span class="setting-label">{'颜色'}</span>
515
590
  <input
591
+ draggable="true"
516
592
  type="color"
517
593
  value={currentBorderColor}
518
594
  onInput={(e: Event) => {
595
+ const target = e.target as HTMLInputElement
596
+ localBorderColor.value = target.value
597
+ }}
598
+ onChange={(e: Event) => {
519
599
  const target = e.target as HTMLInputElement
520
600
  setAttr('borderColor', target.value)
601
+ localBorderColor.value = null
521
602
  }}
522
603
  onClick={(e: MouseEvent) => e.stopPropagation()}
604
+ onMousedown={(e: MouseEvent) => e.stopPropagation()}
523
605
  onPointerdown={(e: PointerEvent) => e.stopPropagation()}
606
+ onDragstart={(e: DragEvent) => {
607
+ e.preventDefault()
608
+ e.stopPropagation()
609
+ }}
524
610
  />
525
611
  </div>
526
612
  ) : null}
@@ -87,7 +87,6 @@ export const EditLink = defineComponent<EditLinkProps>({
87
87
  class={clsx('button confirm', !isValidUrl(link.value) && 'disabled')}
88
88
  icon={config.value.confirmButton}
89
89
  onClick={onConfirmEdit}
90
- style={!isValidUrl(link.value) ? { opacity: 0.5, cursor: 'not-allowed' } : undefined}
91
90
  />
92
91
  ) : null}
93
92
  </div>
@@ -3,7 +3,8 @@ import type { EditorView } from '@jvs-milkdown/prose/view'
3
3
  import type { Ref } from 'vue'
4
4
 
5
5
  import { findParent } from '@jvs-milkdown/prose'
6
- import { CellSelection, findTable } from '@jvs-milkdown/prose/tables'
6
+ import { findTable } from '@jvs-milkdown/prose/tables'
7
+ import type { CellSelection } from '@jvs-milkdown/prose/tables'
7
8
 
8
9
  import type { CellIndex, Refs } from './types'
9
10
 
@@ -99,13 +100,13 @@ export function recoveryStateBetweenUpdate(
99
100
  const table = findTable($from)
100
101
  if (!table || table.node !== node) return
101
102
 
102
- if (selection.isColSelection()) {
103
+ if ((selection as any as CellSelection).isColSelection()) {
103
104
  const { $head } = selection
104
105
  const colIndex = $head.index($head.depth - 1)
105
106
  refs.hoverIndex.value = [0, colIndex]
106
107
  return
107
108
  }
108
- if (selection.isRowSelection()) {
109
+ if ((selection as any as CellSelection).isRowSelection()) {
109
110
  const { $head } = selection
110
111
  const rowNode = findParent(
111
112
  (node) =>