@jvs-milkdown/components 1.2.5 → 1.2.7
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/image-block/config.d.ts +0 -3
- package/lib/image-block/config.d.ts.map +1 -1
- package/lib/image-block/index.js +96 -93
- package/lib/image-block/index.js.map +1 -1
- package/lib/image-block/paste-rule.d.ts.map +1 -1
- package/lib/image-block/view/components/image-viewer.d.ts.map +1 -1
- package/lib/image-inline/index.js +7 -2
- 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 +7 -2
- package/lib/link-tooltip/index.js.map +1 -1
- package/lib/table-block/index.js.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 +14 -5
- package/src/image-block/config.ts +0 -6
- package/src/image-block/paste-rule.ts +0 -2
- package/src/image-block/view/components/image-viewer.tsx +25 -26
- package/src/link-tooltip/edit/component.tsx +7 -2
- package/src/table-block/view/component.tsx +1 -1
- package/src/table-block/view/utils.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jvs-milkdown/components",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
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.
|
|
54
|
-
"@jvs-milkdown/ctx": "^1.2.
|
|
55
|
-
"@jvs-milkdown/exception": "^1.2.
|
|
56
|
-
"@jvs-milkdown/plugin-tooltip": "^1.2.
|
|
57
|
-
"@jvs-milkdown/preset-commonmark": "^1.2.
|
|
58
|
-
"@jvs-milkdown/preset-gfm": "^1.2.
|
|
59
|
-
"@jvs-milkdown/prose": "^1.2.
|
|
60
|
-
"@jvs-milkdown/transformer": "^1.2.
|
|
61
|
-
"@jvs-milkdown/utils": "^1.2.
|
|
53
|
+
"@jvs-milkdown/core": "^1.2.7",
|
|
54
|
+
"@jvs-milkdown/ctx": "^1.2.7",
|
|
55
|
+
"@jvs-milkdown/exception": "^1.2.7",
|
|
56
|
+
"@jvs-milkdown/plugin-tooltip": "^1.2.7",
|
|
57
|
+
"@jvs-milkdown/preset-commonmark": "^1.2.7",
|
|
58
|
+
"@jvs-milkdown/preset-gfm": "^1.2.7",
|
|
59
|
+
"@jvs-milkdown/prose": "^1.2.7",
|
|
60
|
+
"@jvs-milkdown/transformer": "^1.2.7",
|
|
61
|
+
"@jvs-milkdown/utils": "^1.2.7",
|
|
62
62
|
"@types/lodash-es": "^4.17.12",
|
|
63
63
|
"clsx": "^2.0.0",
|
|
64
64
|
"dompurify": "^3.2.5",
|
|
@@ -96,14 +96,16 @@ export const ImageInput = defineComponent<ImageInputProps>({
|
|
|
96
96
|
const isValidUrl = (url: string) => {
|
|
97
97
|
if (!url) return false
|
|
98
98
|
const trimmedUrl = url.trim()
|
|
99
|
-
return /^(https?:\/\/|\/|\.\.?\/|data:image\/|blob:|[a-zA-Z0-9-]+\.[a-zA-Z]+)/i.test(
|
|
99
|
+
return /^(https?:\/\/|\/|\.\.?\/|data:image\/|blob:|[a-zA-Z0-9-]+\.[a-zA-Z]+)/i.test(
|
|
100
|
+
trimmedUrl
|
|
101
|
+
)
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
const onKeydown = (e: KeyboardEvent) => {
|
|
103
105
|
if (e.key === 'Enter') {
|
|
104
106
|
const val = linkInputRef.value?.value?.trim() ?? ''
|
|
105
107
|
|
|
106
|
-
// Stop bubbling so ProseMirror doesn't handle the Enter key
|
|
108
|
+
// Stop bubbling so ProseMirror doesn't handle the Enter key
|
|
107
109
|
// regardless of whether the URL is valid or not.
|
|
108
110
|
e.preventDefault()
|
|
109
111
|
e.stopPropagation()
|
|
@@ -185,15 +187,22 @@ export const ImageInput = defineComponent<ImageInputProps>({
|
|
|
185
187
|
src={currentLink.value}
|
|
186
188
|
alt=""
|
|
187
189
|
onError={(e) =>
|
|
188
|
-
Promise.resolve(onImageLoadError?.(e)).catch(() => {
|
|
190
|
+
Promise.resolve(onImageLoadError?.(e)).catch(() => {})
|
|
189
191
|
}
|
|
190
192
|
/>
|
|
191
193
|
</div>
|
|
192
194
|
)}
|
|
193
195
|
<div
|
|
194
|
-
class={clsx(
|
|
196
|
+
class={clsx(
|
|
197
|
+
'confirm',
|
|
198
|
+
!isValidUrl(currentLink.value) && 'disabled'
|
|
199
|
+
)}
|
|
195
200
|
onClick={() => onConfirmLinkInput()}
|
|
196
|
-
style={
|
|
201
|
+
style={
|
|
202
|
+
!isValidUrl(currentLink.value)
|
|
203
|
+
? { opacity: 0.5, cursor: 'not-allowed' }
|
|
204
|
+
: undefined
|
|
205
|
+
}
|
|
197
206
|
>
|
|
198
207
|
<Icon icon={confirmButton} />
|
|
199
208
|
</div>
|
|
@@ -7,9 +7,6 @@ export interface ImageBlockConfig {
|
|
|
7
7
|
captionIcon: string | undefined
|
|
8
8
|
cropIcon: string | undefined
|
|
9
9
|
borderIcon: string | undefined
|
|
10
|
-
confirmIcon: string | undefined
|
|
11
|
-
cancelIcon: string | undefined
|
|
12
|
-
resetCropIcon: string | undefined
|
|
13
10
|
uploadButton: string | undefined
|
|
14
11
|
confirmButton: string | undefined
|
|
15
12
|
uploadPlaceholderText: string
|
|
@@ -26,9 +23,6 @@ export const defaultImageBlockConfig: ImageBlockConfig = {
|
|
|
26
23
|
captionIcon: '💬',
|
|
27
24
|
cropIcon: '✂️',
|
|
28
25
|
borderIcon: '🔲',
|
|
29
|
-
confirmIcon: '✓',
|
|
30
|
-
cancelIcon: '✕',
|
|
31
|
-
resetCropIcon: '↩',
|
|
32
26
|
uploadButton: 'Upload file',
|
|
33
27
|
confirmButton: 'Confirm ⏎',
|
|
34
28
|
uploadPlaceholderText: 'or paste the image link ...',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, ref, h, Fragment } from 'vue'
|
|
1
|
+
import { defineComponent, ref, h, Fragment, onMounted, onUnmounted } from 'vue'
|
|
2
2
|
|
|
3
3
|
import type { MilkdownImageBlockProps } from './image-block'
|
|
4
4
|
|
|
@@ -263,6 +263,7 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
const applyCrop = () => {
|
|
266
|
+
if (!isCropping.value) return
|
|
266
267
|
setAttr('cropTop', localCrop.value.top)
|
|
267
268
|
setAttr('cropLeft', localCrop.value.left)
|
|
268
269
|
setAttr('cropWidth', localCrop.value.width)
|
|
@@ -270,10 +271,22 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
|
|
|
270
271
|
isCropping.value = false
|
|
271
272
|
}
|
|
272
273
|
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
// Global listener for clicking outside to apply crop
|
|
275
|
+
const handleGlobalPointerDown = (e: PointerEvent) => {
|
|
276
|
+
if (!isCropping.value) return
|
|
277
|
+
if (wrapperRef.value && !wrapperRef.value.contains(e.target as Node)) {
|
|
278
|
+
applyCrop()
|
|
279
|
+
}
|
|
275
280
|
}
|
|
276
281
|
|
|
282
|
+
onMounted(() => {
|
|
283
|
+
window.addEventListener('pointerdown', handleGlobalPointerDown)
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
onUnmounted(() => {
|
|
287
|
+
window.removeEventListener('pointerdown', handleGlobalPointerDown)
|
|
288
|
+
})
|
|
289
|
+
|
|
277
290
|
const resetCrop = () => {
|
|
278
291
|
setAttr('cropTop', 0)
|
|
279
292
|
setAttr('cropLeft', 0)
|
|
@@ -507,7 +520,7 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
|
|
|
507
520
|
resetCrop()
|
|
508
521
|
}}
|
|
509
522
|
>
|
|
510
|
-
<Icon icon={
|
|
523
|
+
<Icon icon={'↩'} />
|
|
511
524
|
</div>
|
|
512
525
|
) : null}
|
|
513
526
|
{config.borderIcon ? (
|
|
@@ -655,9 +668,16 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
|
|
|
655
668
|
|
|
656
669
|
{/* Crop overlay */}
|
|
657
670
|
{isCropping.value ? (
|
|
658
|
-
<div
|
|
671
|
+
<div
|
|
672
|
+
class="crop-overlay"
|
|
673
|
+
onClick={(e) => {
|
|
674
|
+
e.stopPropagation()
|
|
675
|
+
applyCrop()
|
|
676
|
+
}}
|
|
677
|
+
>
|
|
659
678
|
<div
|
|
660
679
|
class="crop-box"
|
|
680
|
+
onClick={(e) => e.stopPropagation()}
|
|
661
681
|
style={{
|
|
662
682
|
top: `${(localCrop.value.top * 100).toFixed(2)}%`,
|
|
663
683
|
left: `${(localCrop.value.left * 100).toFixed(2)}%`,
|
|
@@ -726,27 +746,6 @@ export const ImageViewer = defineComponent<MilkdownImageBlockProps>({
|
|
|
726
746
|
}
|
|
727
747
|
/>
|
|
728
748
|
</div>
|
|
729
|
-
{/* Bottom toolbar */}
|
|
730
|
-
<div class="crop-toolbar">
|
|
731
|
-
<div
|
|
732
|
-
class="crop-toolbar-btn"
|
|
733
|
-
onClick={(e: MouseEvent) => {
|
|
734
|
-
e.stopPropagation()
|
|
735
|
-
applyCrop()
|
|
736
|
-
}}
|
|
737
|
-
>
|
|
738
|
-
<Icon icon={config.confirmIcon ?? '✓'} />
|
|
739
|
-
</div>
|
|
740
|
-
<div
|
|
741
|
-
class="crop-toolbar-btn"
|
|
742
|
-
onClick={(e: MouseEvent) => {
|
|
743
|
-
e.stopPropagation()
|
|
744
|
-
cancelCrop()
|
|
745
|
-
}}
|
|
746
|
-
>
|
|
747
|
-
<Icon icon={config.cancelIcon ?? '✕'} />
|
|
748
|
-
</div>
|
|
749
|
-
</div>
|
|
750
749
|
</div>
|
|
751
750
|
) : null}
|
|
752
751
|
|
|
@@ -45,7 +45,9 @@ export const EditLink = defineComponent<EditLinkProps>({
|
|
|
45
45
|
if (!url) return false
|
|
46
46
|
const trimmedUrl = url.trim()
|
|
47
47
|
// Accept standard http/https links, relative links, anchors, or mailto
|
|
48
|
-
return /^(https?:\/\/|\/|\.\.?\/|mailto:|#|[a-zA-Z0-9-]+\.[a-zA-Z]+)/i.test(
|
|
48
|
+
return /^(https?:\/\/|\/|\.\.?\/|mailto:|#|[a-zA-Z0-9-]+\.[a-zA-Z]+)/i.test(
|
|
49
|
+
trimmedUrl
|
|
50
|
+
)
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
const onConfirmEdit = () => {
|
|
@@ -84,7 +86,10 @@ export const EditLink = defineComponent<EditLinkProps>({
|
|
|
84
86
|
/>
|
|
85
87
|
{link.value ? (
|
|
86
88
|
<Icon
|
|
87
|
-
class={clsx(
|
|
89
|
+
class={clsx(
|
|
90
|
+
'button confirm',
|
|
91
|
+
!isValidUrl(link.value) && 'disabled'
|
|
92
|
+
)}
|
|
88
93
|
icon={config.value.confirmButton}
|
|
89
94
|
onClick={onConfirmEdit}
|
|
90
95
|
/>
|
|
@@ -400,7 +400,7 @@ export const TableBlock = defineComponent<TableBlockProps>({
|
|
|
400
400
|
if (isCellSelection(selection)) {
|
|
401
401
|
const selAny = selection as any
|
|
402
402
|
const rect = selectedRect(view.state)
|
|
403
|
-
|
|
403
|
+
|
|
404
404
|
if (selAny.isColSelection()) {
|
|
405
405
|
if (
|
|
406
406
|
activeColIndex.value >= rect.left &&
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { Node } from '@jvs-milkdown/prose/model'
|
|
2
|
+
import type { CellSelection } from '@jvs-milkdown/prose/tables'
|
|
2
3
|
import type { EditorView } from '@jvs-milkdown/prose/view'
|
|
3
4
|
import type { Ref } from 'vue'
|
|
4
5
|
|
|
5
6
|
import { findParent } from '@jvs-milkdown/prose'
|
|
6
7
|
import { findTable } from '@jvs-milkdown/prose/tables'
|
|
7
|
-
import type { CellSelection } from '@jvs-milkdown/prose/tables'
|
|
8
8
|
|
|
9
9
|
import type { CellIndex, Refs } from './types'
|
|
10
10
|
|