@kopexa/tiptap 17.2.0 → 17.2.2
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/dist/{chunk-E5NW3MJZ.mjs → chunk-3ZPLSXTZ.mjs} +3 -3
- package/dist/{chunk-7SRL3P4B.mjs → chunk-5QFCLKHL.mjs} +7 -7
- package/dist/{chunk-NEHW62L7.mjs → chunk-6552DQWB.mjs} +2 -2
- package/dist/{chunk-5GFFTVMZ.mjs → chunk-DSBJFMHK.mjs} +4 -28
- package/dist/chunk-EAAQE5ZV.mjs +283 -0
- package/dist/chunk-HTJ2RXOG.mjs +32 -0
- package/dist/{chunk-LMCQMSW2.mjs → chunk-KYLBKQ2E.mjs} +12 -154
- package/dist/chunk-N3JE67CS.mjs +81 -0
- package/dist/{chunk-UU6JK5HX.mjs → chunk-SSJMKQ5G.mjs} +33 -20
- package/dist/chunk-Z365KVQY.mjs +34 -0
- package/dist/extensions/image/image-view.d.mts +3 -3
- package/dist/extensions/image/image-view.d.ts +3 -3
- package/dist/extensions/image/image-view.js +13 -181
- package/dist/extensions/image/image-view.mjs +2 -2
- package/dist/extensions/image/index.d.mts +12 -49
- package/dist/extensions/image/index.d.ts +12 -49
- package/dist/extensions/image/index.js +18 -231
- package/dist/extensions/image/index.mjs +3 -3
- package/dist/extensions/image/messages.d.mts +2 -30
- package/dist/extensions/image/messages.d.ts +2 -30
- package/dist/extensions/image/messages.js +4 -32
- package/dist/extensions/image/messages.mjs +1 -1
- package/dist/extensions/image-upload/image-upload-view.d.mts +12 -0
- package/dist/extensions/image-upload/image-upload-view.d.ts +12 -0
- package/dist/extensions/image-upload/image-upload-view.js +338 -0
- package/dist/extensions/image-upload/image-upload-view.mjs +12 -0
- package/dist/extensions/image-upload/index.d.mts +46 -0
- package/dist/extensions/image-upload/index.d.ts +46 -0
- package/dist/extensions/image-upload/index.js +414 -0
- package/dist/extensions/image-upload/index.mjs +16 -0
- package/dist/extensions/image-upload/messages.d.mts +32 -0
- package/dist/extensions/image-upload/messages.d.ts +32 -0
- package/dist/extensions/image-upload/messages.js +61 -0
- package/dist/extensions/image-upload/messages.mjs +7 -0
- package/dist/extensions/math/index.mjs +1 -1
- package/dist/hooks/use-create-editor.js +562 -393
- package/dist/hooks/use-create-editor.mjs +13 -10
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +956 -785
- package/dist/index.mjs +39 -33
- package/dist/presets/basic/editor-header.mjs +14 -14
- package/dist/presets/basic/index.js +953 -784
- package/dist/presets/basic/index.mjs +32 -29
- package/dist/ui/slash-dropdown-menu/index.js +2 -2
- package/dist/ui/slash-dropdown-menu/index.mjs +4 -4
- package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.js +2 -2
- package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.mjs +2 -2
- package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.js +2 -2
- package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.mjs +1 -1
- package/package.json +25 -24
- package/dist/chunk-WAAH3NLG.mjs +0 -77
- package/dist/{chunk-QAE2D4KV.mjs → chunk-FDPXD6VC.mjs} +11 -11
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
ImageUploadNodeView
|
|
4
|
+
} from "./chunk-EAAQE5ZV.mjs";
|
|
5
|
+
|
|
6
|
+
// src/extensions/image-upload/index.ts
|
|
7
|
+
import { Node } from "@tiptap/core";
|
|
8
|
+
import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
9
|
+
var ImageUploadNode = Node.create({
|
|
10
|
+
name: "imageUpload",
|
|
11
|
+
group: "block",
|
|
12
|
+
atom: true,
|
|
13
|
+
draggable: true,
|
|
14
|
+
selectable: true,
|
|
15
|
+
addOptions() {
|
|
16
|
+
return {
|
|
17
|
+
accept: "image/*",
|
|
18
|
+
maxSize: 0,
|
|
19
|
+
HTMLAttributes: {}
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
addAttributes() {
|
|
23
|
+
return {
|
|
24
|
+
// Upload state tracking
|
|
25
|
+
uploadState: {
|
|
26
|
+
default: null,
|
|
27
|
+
rendered: false
|
|
28
|
+
},
|
|
29
|
+
uploadProgress: {
|
|
30
|
+
default: null,
|
|
31
|
+
rendered: false
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
parseHTML() {
|
|
36
|
+
return [
|
|
37
|
+
{
|
|
38
|
+
tag: 'div[data-type="image-upload"]'
|
|
39
|
+
}
|
|
40
|
+
];
|
|
41
|
+
},
|
|
42
|
+
renderHTML({ HTMLAttributes }) {
|
|
43
|
+
return ["div", { ...HTMLAttributes, "data-type": "image-upload" }];
|
|
44
|
+
},
|
|
45
|
+
addNodeView() {
|
|
46
|
+
return ReactNodeViewRenderer(ImageUploadNodeView);
|
|
47
|
+
},
|
|
48
|
+
addCommands() {
|
|
49
|
+
return {
|
|
50
|
+
setImageUpload: () => ({ commands }) => {
|
|
51
|
+
return commands.insertContent({
|
|
52
|
+
type: this.name
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
addKeyboardShortcuts() {
|
|
58
|
+
return {
|
|
59
|
+
Enter: ({ editor }) => {
|
|
60
|
+
const { selection } = editor.state;
|
|
61
|
+
const { $from } = selection;
|
|
62
|
+
const node = $from.nodeAfter;
|
|
63
|
+
if ((node == null ? void 0 : node.type.name) === "imageUpload" && editor.isActive("imageUpload")) {
|
|
64
|
+
const nodeEl = editor.view.nodeDOM($from.pos);
|
|
65
|
+
if (nodeEl instanceof HTMLElement) {
|
|
66
|
+
const input = nodeEl.querySelector('input[type="file"]');
|
|
67
|
+
if (input instanceof HTMLElement) {
|
|
68
|
+
input.click();
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
ImageUploadNode
|
|
81
|
+
};
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
TrailingNode
|
|
4
|
+
} from "./chunk-H6LC4LDQ.mjs";
|
|
5
|
+
import {
|
|
6
|
+
MathBlock
|
|
7
|
+
} from "./chunk-2U5CQUZH.mjs";
|
|
8
|
+
import {
|
|
9
|
+
InlineMath
|
|
10
|
+
} from "./chunk-7VW67NVL.mjs";
|
|
2
11
|
import {
|
|
3
12
|
Selection
|
|
4
13
|
} from "./chunk-U5XAL46P.mjs";
|
|
5
14
|
import {
|
|
6
15
|
TocNode
|
|
7
16
|
} from "./chunk-IFXRPGIJ.mjs";
|
|
8
|
-
import {
|
|
9
|
-
TrailingNode
|
|
10
|
-
} from "./chunk-H6LC4LDQ.mjs";
|
|
11
17
|
import {
|
|
12
18
|
ImageNode
|
|
13
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-HTJ2RXOG.mjs";
|
|
20
|
+
import {
|
|
21
|
+
ImageUploadNode
|
|
22
|
+
} from "./chunk-N3JE67CS.mjs";
|
|
14
23
|
import {
|
|
15
24
|
Link
|
|
16
25
|
} from "./chunk-YLDL3VYY.mjs";
|
|
17
|
-
import {
|
|
18
|
-
MathBlock
|
|
19
|
-
} from "./chunk-2U5CQUZH.mjs";
|
|
20
|
-
import {
|
|
21
|
-
InlineMath
|
|
22
|
-
} from "./chunk-7VW67NVL.mjs";
|
|
23
26
|
import {
|
|
24
27
|
UiState
|
|
25
28
|
} from "./chunk-KR42JAVB.mjs";
|
|
@@ -56,7 +59,7 @@ import {
|
|
|
56
59
|
useEditor
|
|
57
60
|
} from "@tiptap/react";
|
|
58
61
|
import { StarterKit } from "@tiptap/starter-kit";
|
|
59
|
-
import { useEffect } from "react";
|
|
62
|
+
import { useEffect, useMemo } from "react";
|
|
60
63
|
var useCreateEditor = ({
|
|
61
64
|
content,
|
|
62
65
|
editable = true,
|
|
@@ -69,6 +72,18 @@ var useCreateEditor = ({
|
|
|
69
72
|
}) => {
|
|
70
73
|
const fileHandlerFromContext = useEditorFile();
|
|
71
74
|
const fileHandler = fileHandlerProp != null ? fileHandlerProp : fileHandlerFromContext;
|
|
75
|
+
const extensions = useMemo(
|
|
76
|
+
() => getExtensions({
|
|
77
|
+
editable,
|
|
78
|
+
placeholder,
|
|
79
|
+
enableControls,
|
|
80
|
+
controlResolver,
|
|
81
|
+
fileHandler
|
|
82
|
+
}),
|
|
83
|
+
// Only recreate extensions when these values change
|
|
84
|
+
// Note: fileHandler and controlResolver are object references, so they should be stable
|
|
85
|
+
[editable, placeholder, enableControls, controlResolver, fileHandler]
|
|
86
|
+
);
|
|
72
87
|
const editor = useEditor({
|
|
73
88
|
editorProps: {
|
|
74
89
|
attributes: {
|
|
@@ -80,13 +95,7 @@ var useCreateEditor = ({
|
|
|
80
95
|
},
|
|
81
96
|
immediatelyRender: false,
|
|
82
97
|
shouldRerenderOnTransaction: false,
|
|
83
|
-
extensions
|
|
84
|
-
editable,
|
|
85
|
-
placeholder,
|
|
86
|
-
enableControls,
|
|
87
|
-
controlResolver,
|
|
88
|
-
fileHandler
|
|
89
|
-
}),
|
|
98
|
+
extensions,
|
|
90
99
|
editable,
|
|
91
100
|
onUpdate: ({ editor: editor2 }) => {
|
|
92
101
|
onChange == null ? void 0 : onChange(editor2.getJSON());
|
|
@@ -158,8 +167,12 @@ function getExtensions({
|
|
|
158
167
|
CalloutNode,
|
|
159
168
|
MathBlock,
|
|
160
169
|
InlineMath,
|
|
161
|
-
// Image support -
|
|
162
|
-
ImageNode
|
|
170
|
+
// Image support - extended with file reference resolution
|
|
171
|
+
ImageNode.configure({
|
|
172
|
+
allowBase64: true
|
|
173
|
+
}),
|
|
174
|
+
// Image upload placeholder
|
|
175
|
+
ImageUploadNode,
|
|
163
176
|
Placeholder.configure({
|
|
164
177
|
placeholder,
|
|
165
178
|
emptyNodeClass: "is-empty with-slash"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/extensions/image/messages.ts
|
|
4
|
+
import { defineMessages } from "react-intl";
|
|
5
|
+
var messages = defineMessages({
|
|
6
|
+
loading: {
|
|
7
|
+
id: "editor.image.loading",
|
|
8
|
+
defaultMessage: "Loading image..."
|
|
9
|
+
},
|
|
10
|
+
uploading: {
|
|
11
|
+
id: "editor.image.uploading",
|
|
12
|
+
defaultMessage: "Uploading..."
|
|
13
|
+
},
|
|
14
|
+
error: {
|
|
15
|
+
id: "editor.image.error",
|
|
16
|
+
defaultMessage: "Failed to load image"
|
|
17
|
+
},
|
|
18
|
+
upload_error: {
|
|
19
|
+
id: "editor.image.upload_error",
|
|
20
|
+
defaultMessage: "Failed to upload image"
|
|
21
|
+
},
|
|
22
|
+
retry: {
|
|
23
|
+
id: "editor.image.retry",
|
|
24
|
+
defaultMessage: "Retry"
|
|
25
|
+
},
|
|
26
|
+
remove: {
|
|
27
|
+
id: "editor.image.remove",
|
|
28
|
+
defaultMessage: "Remove"
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
messages
|
|
34
|
+
};
|
|
@@ -6,9 +6,9 @@ import { NodeViewProps } from '@tiptap/react';
|
|
|
6
6
|
*
|
|
7
7
|
* Handles:
|
|
8
8
|
* - Resolving file references to displayable URLs
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
9
|
+
* - Upload states for drag & drop / paste uploads
|
|
10
|
+
* - Loading states while resolving URLs
|
|
11
|
+
* - Error handling for failed resolution
|
|
12
12
|
*/
|
|
13
13
|
declare function ImageNodeView({ editor, node, getPos }: NodeViewProps): react_jsx_runtime.JSX.Element;
|
|
14
14
|
|
|
@@ -6,9 +6,9 @@ import { NodeViewProps } from '@tiptap/react';
|
|
|
6
6
|
*
|
|
7
7
|
* Handles:
|
|
8
8
|
* - Resolving file references to displayable URLs
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
9
|
+
* - Upload states for drag & drop / paste uploads
|
|
10
|
+
* - Loading states while resolving URLs
|
|
11
|
+
* - Error handling for failed resolution
|
|
12
12
|
*/
|
|
13
13
|
declare function ImageNodeView({ editor, node, getPos }: NodeViewProps): react_jsx_runtime.JSX.Element;
|
|
14
14
|
|
|
@@ -50,6 +50,10 @@ var messages = (0, import_react_intl.defineMessages)({
|
|
|
50
50
|
id: "editor.image.loading",
|
|
51
51
|
defaultMessage: "Loading image..."
|
|
52
52
|
},
|
|
53
|
+
uploading: {
|
|
54
|
+
id: "editor.image.uploading",
|
|
55
|
+
defaultMessage: "Uploading..."
|
|
56
|
+
},
|
|
53
57
|
error: {
|
|
54
58
|
id: "editor.image.error",
|
|
55
59
|
defaultMessage: "Failed to load image"
|
|
@@ -58,38 +62,6 @@ var messages = (0, import_react_intl.defineMessages)({
|
|
|
58
62
|
id: "editor.image.upload_error",
|
|
59
63
|
defaultMessage: "Failed to upload image"
|
|
60
64
|
},
|
|
61
|
-
uploading: {
|
|
62
|
-
id: "editor.image.uploading",
|
|
63
|
-
defaultMessage: "Uploading..."
|
|
64
|
-
},
|
|
65
|
-
upload_placeholder: {
|
|
66
|
-
id: "editor.image.upload_placeholder",
|
|
67
|
-
defaultMessage: "Click to upload or drag & drop"
|
|
68
|
-
},
|
|
69
|
-
upload_hint: {
|
|
70
|
-
id: "editor.image.upload_hint",
|
|
71
|
-
defaultMessage: "PNG, JPG, GIF, WebP, SVG"
|
|
72
|
-
},
|
|
73
|
-
alt_text: {
|
|
74
|
-
id: "editor.image.alt_text",
|
|
75
|
-
defaultMessage: "Alt text"
|
|
76
|
-
},
|
|
77
|
-
alt_placeholder: {
|
|
78
|
-
id: "editor.image.alt_placeholder",
|
|
79
|
-
defaultMessage: "Describe the image..."
|
|
80
|
-
},
|
|
81
|
-
files_not_supported: {
|
|
82
|
-
id: "editor.image.files_not_supported",
|
|
83
|
-
defaultMessage: "File upload is not configured"
|
|
84
|
-
},
|
|
85
|
-
file_too_large: {
|
|
86
|
-
id: "editor.image.file_too_large",
|
|
87
|
-
defaultMessage: "File is too large (max {maxSize})"
|
|
88
|
-
},
|
|
89
|
-
invalid_type: {
|
|
90
|
-
id: "editor.image.invalid_type",
|
|
91
|
-
defaultMessage: "Invalid file type"
|
|
92
|
-
},
|
|
93
65
|
retry: {
|
|
94
66
|
id: "editor.image.retry",
|
|
95
67
|
defaultMessage: "Retry"
|
|
@@ -106,7 +78,7 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
106
78
|
var _a;
|
|
107
79
|
const intl = (0, import_react_intl2.useIntl)();
|
|
108
80
|
const fileHandler = useEditorFile();
|
|
109
|
-
const
|
|
81
|
+
const { src, alt, title, uploadState, uploadProgress } = node.attrs;
|
|
110
82
|
const isEditable = (0, import_react2.useEditorState)({
|
|
111
83
|
editor,
|
|
112
84
|
selector: ({ editor: e }) => {
|
|
@@ -114,7 +86,6 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
114
86
|
return (_a2 = e == null ? void 0 : e.isEditable) != null ? _a2 : false;
|
|
115
87
|
}
|
|
116
88
|
});
|
|
117
|
-
const { src, alt, title, uploadState, uploadProgress } = attrs;
|
|
118
89
|
const [resolvedUrl, setResolvedUrl] = (0, import_react3.useState)(null);
|
|
119
90
|
const [resolveState, setResolveState] = (0, import_react3.useState)("idle");
|
|
120
91
|
const needsResolve = (_a = fileHandler == null ? void 0 : fileHandler.isReference(src)) != null ? _a : false;
|
|
@@ -126,7 +97,8 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
126
97
|
return;
|
|
127
98
|
}
|
|
128
99
|
if (!fileHandler) {
|
|
129
|
-
|
|
100
|
+
setResolvedUrl(src);
|
|
101
|
+
setResolveState("resolved");
|
|
130
102
|
return;
|
|
131
103
|
}
|
|
132
104
|
setResolveState("loading");
|
|
@@ -152,156 +124,16 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
152
124
|
to: pos + node.nodeSize
|
|
153
125
|
});
|
|
154
126
|
}, [editor, getPos, node.nodeSize]);
|
|
155
|
-
const fileInputRef = (0, import_react3.useRef)(null);
|
|
156
|
-
const handleFileSelect = (0, import_react3.useCallback)(
|
|
157
|
-
async (file) => {
|
|
158
|
-
if (!fileHandler) return;
|
|
159
|
-
const pos = getPos();
|
|
160
|
-
if (pos === void 0) return;
|
|
161
|
-
editor.view.dispatch(
|
|
162
|
-
editor.state.tr.setNodeMarkup(pos, void 0, {
|
|
163
|
-
...attrs,
|
|
164
|
-
uploadState: "uploading",
|
|
165
|
-
uploadProgress: 0
|
|
166
|
-
})
|
|
167
|
-
);
|
|
168
|
-
try {
|
|
169
|
-
const ref = await fileHandler.upload(file, (percent) => {
|
|
170
|
-
const currentPos = getPos();
|
|
171
|
-
if (currentPos === void 0) return;
|
|
172
|
-
editor.view.dispatch(
|
|
173
|
-
editor.state.tr.setNodeMarkup(currentPos, void 0, {
|
|
174
|
-
...attrs,
|
|
175
|
-
uploadState: "uploading",
|
|
176
|
-
uploadProgress: percent
|
|
177
|
-
})
|
|
178
|
-
);
|
|
179
|
-
});
|
|
180
|
-
const finalPos = getPos();
|
|
181
|
-
if (finalPos === void 0) return;
|
|
182
|
-
editor.view.dispatch(
|
|
183
|
-
editor.state.tr.setNodeMarkup(finalPos, void 0, {
|
|
184
|
-
src: ref,
|
|
185
|
-
uploadState: null,
|
|
186
|
-
uploadProgress: null
|
|
187
|
-
})
|
|
188
|
-
);
|
|
189
|
-
} catch {
|
|
190
|
-
const errorPos = getPos();
|
|
191
|
-
if (errorPos === void 0) return;
|
|
192
|
-
editor.view.dispatch(
|
|
193
|
-
editor.state.tr.setNodeMarkup(errorPos, void 0, {
|
|
194
|
-
...attrs,
|
|
195
|
-
uploadState: "error",
|
|
196
|
-
uploadProgress: null
|
|
197
|
-
})
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
[fileHandler, editor, getPos, attrs]
|
|
202
|
-
);
|
|
203
|
-
const handleInputChange = (0, import_react3.useCallback)(
|
|
204
|
-
(e) => {
|
|
205
|
-
var _a2;
|
|
206
|
-
const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
|
|
207
|
-
if (file) {
|
|
208
|
-
handleFileSelect(file);
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
[handleFileSelect]
|
|
212
|
-
);
|
|
213
|
-
const handleDrop = (0, import_react3.useCallback)(
|
|
214
|
-
(e) => {
|
|
215
|
-
e.preventDefault();
|
|
216
|
-
e.stopPropagation();
|
|
217
|
-
const file = e.dataTransfer.files[0];
|
|
218
|
-
if (file == null ? void 0 : file.type.startsWith("image/")) {
|
|
219
|
-
handleFileSelect(file);
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
[handleFileSelect]
|
|
223
|
-
);
|
|
224
|
-
const handleDragOver = (0, import_react3.useCallback)((e) => {
|
|
225
|
-
e.preventDefault();
|
|
226
|
-
e.stopPropagation();
|
|
227
|
-
}, []);
|
|
228
|
-
const styles = (0, import_react3.useMemo)(() => (0, import_theme.imagePlaceholder)({ size: "md" }), []);
|
|
229
127
|
const errorStyles = (0, import_react3.useMemo)(
|
|
230
128
|
() => (0, import_theme.imagePlaceholder)({ size: "md", variant: "error" }),
|
|
231
129
|
[]
|
|
232
130
|
);
|
|
233
|
-
const
|
|
131
|
+
const loadingStyles = (0, import_react3.useMemo)(
|
|
234
132
|
() => (0, import_theme.imagePlaceholder)({ size: "md", variant: "uploading" }),
|
|
235
133
|
[]
|
|
236
134
|
);
|
|
237
|
-
const disabledStyles = (0, import_react3.useMemo)(
|
|
238
|
-
() => (0, import_theme.imagePlaceholder)({ size: "md", variant: "disabled" }),
|
|
239
|
-
[]
|
|
240
|
-
);
|
|
241
|
-
const isEmpty = !src;
|
|
242
|
-
if (isEmpty && !uploadState) {
|
|
243
|
-
if (!fileHandler) {
|
|
244
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: disabledStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: disabledStyles.content(), children: [
|
|
245
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.ImageIcon, { className: disabledStyles.icon() }),
|
|
246
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: disabledStyles.text(), children: intl.formatMessage(messages.files_not_supported) }),
|
|
247
|
-
isEditable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
248
|
-
import_button.IconButton,
|
|
249
|
-
{
|
|
250
|
-
size: "sm",
|
|
251
|
-
variant: "ghost",
|
|
252
|
-
onClick: handleRemove,
|
|
253
|
-
"aria-label": intl.formatMessage(messages.remove),
|
|
254
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.TrashIcon, { className: "size-4" })
|
|
255
|
-
}
|
|
256
|
-
)
|
|
257
|
-
] }) }) });
|
|
258
|
-
}
|
|
259
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
260
|
-
"div",
|
|
261
|
-
{
|
|
262
|
-
className: styles.root(),
|
|
263
|
-
onClick: () => {
|
|
264
|
-
var _a2;
|
|
265
|
-
return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
|
|
266
|
-
},
|
|
267
|
-
onDrop: handleDrop,
|
|
268
|
-
onDragOver: handleDragOver,
|
|
269
|
-
children: [
|
|
270
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: styles.content(), children: [
|
|
271
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.UploadIcon, { className: styles.icon() }),
|
|
272
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: styles.text(), children: intl.formatMessage(messages.upload_placeholder) }),
|
|
273
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: styles.hint(), children: intl.formatMessage(messages.upload_hint) })
|
|
274
|
-
] }),
|
|
275
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
276
|
-
"input",
|
|
277
|
-
{
|
|
278
|
-
ref: fileInputRef,
|
|
279
|
-
type: "file",
|
|
280
|
-
accept: "image/*",
|
|
281
|
-
className: "hidden",
|
|
282
|
-
onChange: handleInputChange
|
|
283
|
-
}
|
|
284
|
-
),
|
|
285
|
-
isEditable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
286
|
-
import_button.IconButton,
|
|
287
|
-
{
|
|
288
|
-
size: "sm",
|
|
289
|
-
variant: "ghost",
|
|
290
|
-
className: styles.removeButton(),
|
|
291
|
-
onClick: (e) => {
|
|
292
|
-
e.stopPropagation();
|
|
293
|
-
handleRemove();
|
|
294
|
-
},
|
|
295
|
-
"aria-label": intl.formatMessage(messages.remove),
|
|
296
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.TrashIcon, { className: "size-3.5" })
|
|
297
|
-
}
|
|
298
|
-
)
|
|
299
|
-
]
|
|
300
|
-
}
|
|
301
|
-
) });
|
|
302
|
-
}
|
|
303
135
|
if (uploadState === "uploading") {
|
|
304
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className:
|
|
136
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: loadingStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: loadingStyles.content(), children: [
|
|
305
137
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "relative size-12", children: [
|
|
306
138
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
307
139
|
"svg",
|
|
@@ -343,14 +175,14 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
343
175
|
"%"
|
|
344
176
|
] })
|
|
345
177
|
] }),
|
|
346
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className:
|
|
178
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: loadingStyles.text(), children: intl.formatMessage(messages.uploading) })
|
|
347
179
|
] }) }) });
|
|
348
180
|
}
|
|
349
181
|
if (uploadState === "error") {
|
|
350
182
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: errorStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: errorStyles.content(), children: [
|
|
351
183
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.AlertCircleIcon, { className: errorStyles.icon() }),
|
|
352
184
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: errorStyles.text(), children: intl.formatMessage(messages.upload_error) }),
|
|
353
|
-
isEditable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
185
|
+
isEditable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
354
186
|
import_button.IconButton,
|
|
355
187
|
{
|
|
356
188
|
size: "sm",
|
|
@@ -359,11 +191,11 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
359
191
|
"aria-label": intl.formatMessage(messages.remove),
|
|
360
192
|
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.TrashIcon, { className: "size-4" })
|
|
361
193
|
}
|
|
362
|
-
)
|
|
194
|
+
)
|
|
363
195
|
] }) }) });
|
|
364
196
|
}
|
|
365
197
|
if (resolveState === "loading") {
|
|
366
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `${
|
|
198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `${loadingStyles.root()} animate-pulse`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: loadingStyles.text(), children: intl.formatMessage(messages.loading) }) }) });
|
|
367
199
|
}
|
|
368
200
|
if (resolveState === "error") {
|
|
369
201
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: errorStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: errorStyles.content(), children: [
|
|
@@ -1,39 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _tiptap_core from '@tiptap/core';
|
|
2
2
|
export { default as ImageNodeView } from './image-view.mjs';
|
|
3
3
|
export { messages as imageMessages } from './messages.mjs';
|
|
4
4
|
import 'react/jsx-runtime';
|
|
5
5
|
import '@tiptap/react';
|
|
6
6
|
|
|
7
|
-
interface ImageNodeAttrs {
|
|
8
|
-
/**
|
|
9
|
-
* The image source - can be a URL or a file reference
|
|
10
|
-
*/
|
|
11
|
-
src: string;
|
|
12
|
-
/**
|
|
13
|
-
* Alt text for accessibility
|
|
14
|
-
*/
|
|
15
|
-
alt?: string;
|
|
16
|
-
/**
|
|
17
|
-
* Optional title attribute
|
|
18
|
-
*/
|
|
19
|
-
title?: string;
|
|
20
|
-
/**
|
|
21
|
-
* Image width (optional)
|
|
22
|
-
*/
|
|
23
|
-
width?: number | string;
|
|
24
|
-
/**
|
|
25
|
-
* Image height (optional)
|
|
26
|
-
*/
|
|
27
|
-
height?: number | string;
|
|
28
|
-
/**
|
|
29
|
-
* Upload state for pending uploads
|
|
30
|
-
*/
|
|
31
|
-
uploadState?: "uploading" | "error" | null;
|
|
32
|
-
/**
|
|
33
|
-
* Upload progress (0-100)
|
|
34
|
-
*/
|
|
35
|
-
uploadProgress?: number;
|
|
36
|
-
}
|
|
37
7
|
interface ImageNodeOptions {
|
|
38
8
|
/**
|
|
39
9
|
* Whether to allow base64 images
|
|
@@ -45,22 +15,15 @@ interface ImageNodeOptions {
|
|
|
45
15
|
*/
|
|
46
16
|
HTMLAttributes: Record<string, unknown>;
|
|
47
17
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
width?: number | string;
|
|
59
|
-
height?: number | string;
|
|
60
|
-
}) => ReturnType;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
declare const ImageNode: Node<ImageNodeOptions, any>;
|
|
18
|
+
/**
|
|
19
|
+
* Extended Image extension with file reference resolution support
|
|
20
|
+
*
|
|
21
|
+
* This extension wraps @tiptap/extension-image and adds:
|
|
22
|
+
* - File reference resolution via EditorFileProvider
|
|
23
|
+
* - Loading states while resolving URLs
|
|
24
|
+
* - Error handling for failed resolution
|
|
25
|
+
* - Upload state tracking for drag & drop uploads
|
|
26
|
+
*/
|
|
27
|
+
declare const ImageNode: _tiptap_core.Node<ImageNodeOptions, any>;
|
|
65
28
|
|
|
66
|
-
export { ImageNode, type
|
|
29
|
+
export { ImageNode, type ImageNodeOptions };
|
|
@@ -1,39 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _tiptap_core from '@tiptap/core';
|
|
2
2
|
export { default as ImageNodeView } from './image-view.js';
|
|
3
3
|
export { messages as imageMessages } from './messages.js';
|
|
4
4
|
import 'react/jsx-runtime';
|
|
5
5
|
import '@tiptap/react';
|
|
6
6
|
|
|
7
|
-
interface ImageNodeAttrs {
|
|
8
|
-
/**
|
|
9
|
-
* The image source - can be a URL or a file reference
|
|
10
|
-
*/
|
|
11
|
-
src: string;
|
|
12
|
-
/**
|
|
13
|
-
* Alt text for accessibility
|
|
14
|
-
*/
|
|
15
|
-
alt?: string;
|
|
16
|
-
/**
|
|
17
|
-
* Optional title attribute
|
|
18
|
-
*/
|
|
19
|
-
title?: string;
|
|
20
|
-
/**
|
|
21
|
-
* Image width (optional)
|
|
22
|
-
*/
|
|
23
|
-
width?: number | string;
|
|
24
|
-
/**
|
|
25
|
-
* Image height (optional)
|
|
26
|
-
*/
|
|
27
|
-
height?: number | string;
|
|
28
|
-
/**
|
|
29
|
-
* Upload state for pending uploads
|
|
30
|
-
*/
|
|
31
|
-
uploadState?: "uploading" | "error" | null;
|
|
32
|
-
/**
|
|
33
|
-
* Upload progress (0-100)
|
|
34
|
-
*/
|
|
35
|
-
uploadProgress?: number;
|
|
36
|
-
}
|
|
37
7
|
interface ImageNodeOptions {
|
|
38
8
|
/**
|
|
39
9
|
* Whether to allow base64 images
|
|
@@ -45,22 +15,15 @@ interface ImageNodeOptions {
|
|
|
45
15
|
*/
|
|
46
16
|
HTMLAttributes: Record<string, unknown>;
|
|
47
17
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
width?: number | string;
|
|
59
|
-
height?: number | string;
|
|
60
|
-
}) => ReturnType;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
declare const ImageNode: Node<ImageNodeOptions, any>;
|
|
18
|
+
/**
|
|
19
|
+
* Extended Image extension with file reference resolution support
|
|
20
|
+
*
|
|
21
|
+
* This extension wraps @tiptap/extension-image and adds:
|
|
22
|
+
* - File reference resolution via EditorFileProvider
|
|
23
|
+
* - Loading states while resolving URLs
|
|
24
|
+
* - Error handling for failed resolution
|
|
25
|
+
* - Upload state tracking for drag & drop uploads
|
|
26
|
+
*/
|
|
27
|
+
declare const ImageNode: _tiptap_core.Node<ImageNodeOptions, any>;
|
|
65
28
|
|
|
66
|
-
export { ImageNode, type
|
|
29
|
+
export { ImageNode, type ImageNodeOptions };
|