@lumir-company/editor 0.4.1 → 0.4.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.
- package/README.md +341 -9
- package/dist/index.d.mts +870 -3
- package/dist/index.d.ts +870 -3
- package/dist/index.js +2759 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2749 -38
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +878 -0
- package/package.json +14 -2
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/components/LumirEditor.tsx
|
|
4
|
-
import { useEffect, useMemo, useCallback, useState, useRef } from "react";
|
|
4
|
+
import { useEffect as useEffect7, useMemo, useCallback as useCallback13, useState as useState7, useRef as useRef8 } from "react";
|
|
5
5
|
import {
|
|
6
6
|
useCreateBlockNote,
|
|
7
7
|
SideMenu as BlockSideMenu,
|
|
8
8
|
SideMenuController,
|
|
9
9
|
DragHandleButton,
|
|
10
10
|
SuggestionMenuController,
|
|
11
|
-
getDefaultReactSlashMenuItems
|
|
11
|
+
getDefaultReactSlashMenuItems,
|
|
12
|
+
LinkToolbarController,
|
|
13
|
+
useBlockNoteEditor,
|
|
14
|
+
useComponentsContext,
|
|
15
|
+
EditLinkButton,
|
|
16
|
+
OpenLinkButton,
|
|
17
|
+
DeleteLinkButton
|
|
12
18
|
} from "@blocknote/react";
|
|
13
19
|
import { BlockNoteView } from "@blocknote/mantine";
|
|
20
|
+
import { insertOrUpdateBlock } from "@blocknote/core";
|
|
14
21
|
|
|
15
22
|
// src/utils/cn.ts
|
|
16
23
|
function cn(...inputs) {
|
|
@@ -18,6 +25,29 @@ function cn(...inputs) {
|
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
// src/utils/s3-uploader.ts
|
|
28
|
+
function validateS3Url(url, fieldName) {
|
|
29
|
+
if (typeof url !== "string" || !url || url.trim() === "") {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`${fieldName} is required and must be a non-empty string`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
if (!url.startsWith("https://")) {
|
|
35
|
+
throw new Error(`${fieldName} must use HTTPS protocol`);
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const urlObj = new URL(url);
|
|
39
|
+
const hostname = urlObj.hostname.toLowerCase();
|
|
40
|
+
if (hostname === "localhost" || hostname.startsWith("127.") || hostname.startsWith("192.168.") || hostname.startsWith("10.") || hostname === "169.254.169.254") {
|
|
41
|
+
throw new Error(`${fieldName} cannot point to internal/private networks`);
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (error instanceof Error && error.message.includes("cannot point to")) {
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`${fieldName} is not a valid URL format`);
|
|
48
|
+
}
|
|
49
|
+
return url;
|
|
50
|
+
}
|
|
21
51
|
var generateUUID = () => {
|
|
22
52
|
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
23
53
|
return crypto.randomUUID();
|
|
@@ -93,7 +123,9 @@ var createS3Uploader = (config) => {
|
|
|
93
123
|
}
|
|
94
124
|
const responseData = await response.json();
|
|
95
125
|
const { presignedUrl, publicUrl } = responseData;
|
|
96
|
-
const
|
|
126
|
+
const validatedPresignedUrl = validateS3Url(presignedUrl, "presignedUrl");
|
|
127
|
+
const validatedPublicUrl = validateS3Url(publicUrl, "publicUrl");
|
|
128
|
+
const uploadResponse = await fetch(validatedPresignedUrl, {
|
|
97
129
|
method: "PUT",
|
|
98
130
|
headers: {
|
|
99
131
|
"Content-Type": file.type || "application/octet-stream"
|
|
@@ -103,7 +135,7 @@ var createS3Uploader = (config) => {
|
|
|
103
135
|
if (!uploadResponse.ok) {
|
|
104
136
|
throw new Error(`Failed to upload file: ${uploadResponse.statusText}`);
|
|
105
137
|
}
|
|
106
|
-
return
|
|
138
|
+
return validatedPublicUrl;
|
|
107
139
|
} catch (error) {
|
|
108
140
|
console.error("S3 upload failed:", error);
|
|
109
141
|
throw error;
|
|
@@ -111,8 +143,2315 @@ var createS3Uploader = (config) => {
|
|
|
111
143
|
};
|
|
112
144
|
};
|
|
113
145
|
|
|
146
|
+
// src/blocks/HtmlPreview.tsx
|
|
147
|
+
import { createReactBlockSpec as createReactBlockSpec2 } from "@blocknote/react";
|
|
148
|
+
import {
|
|
149
|
+
defaultBlockSpecs,
|
|
150
|
+
BlockNoteSchema,
|
|
151
|
+
defaultInlineContentSpecs,
|
|
152
|
+
defaultStyleSpecs
|
|
153
|
+
} from "@blocknote/core";
|
|
154
|
+
|
|
155
|
+
// src/blocks/LinkPreview.tsx
|
|
156
|
+
import { createReactBlockSpec } from "@blocknote/react";
|
|
157
|
+
import { useState, useEffect, useCallback, useRef } from "react";
|
|
158
|
+
|
|
159
|
+
// src/blocks/defaultLogo.ts
|
|
160
|
+
var DEFAULT_LINK_PREVIEW_IMAGE = "data:image/png;base64,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em1RHrY9EhgB5JWPq9DabLnDWKK8KrQqj2dIoXVQj+a8flLfBJN6T2FxKe//POeH76ctPvCWE/otMJ1HREREREREREREJJlUannNa4uGYNuPAV0rjavQ2my5w1iivCq0Ko9nSKGVFQzw84U706NFvQQTe9fcpetK3v1h9h3/N7TrVaaziIiIiIiIiIiIiCSLSi2veG1Rc+BubPvEKstUaG223GEsUV4VWpXHM6TQAjilfxueOKJngon9YdJfC+d+8du8g64+ZvufTGcRERERERERERERqS2VWl7w2qJTiBdaTaosU6G12XKHsUR5VWhVHs+gQis/J8jkS3elXaM8/G7l2iL77e9iYz79Ze7xz1y8R7HpPCIiIiIiIiIiIiI1pVIrk722yAIeA4ZvU6GhQqvyGxVaniq0AC7bI8Rtw7skmNyffpu5bNWnv8w96pLDtvvQdBYRERERERERERGRmlCplYnGLA5g22cAdwMNVGhVZy6HsUR5VWhVHs+wQqtxnRymX7krjepkJ9iBf63bUMy7381655XPZxzx+nX7FprOIyIiIiIiIiIiIrItVGplmjGLO2LbTwFDgG0rNFRoVX6jQstzhRY23LF/Fy7ZI5RgBwLwxz9LV3/ww+xjLj+677ums4iIiIiIiIiIiIhUl0qtTDJm8WnY9n1AA0CFVrXmchhLlFeFVuXxDCy02jeqw+TLd6FOdqUl4mDdhmI++H7WW+9/N+uIJy7dU8/aEhEREREREREREddTqZUJxixuDjyBbR9SPqZCS4XWFrP6r9ACeOqonpy0Y5sEOxEnv85YsvzTH2fvf+m/tv/adBYRERERERERERGRLVGp5XZjFh8EPIlttygfU6GlQmuLWf1ZaPVqWZ+fL9qZgP5U22Yr1xTab07659GTh3U/z3QWERERERERERERkUR0+tetxizOB+4FzqpRMbWl11tarkJrC/tQoVWtdR23cd5tsgotgDdP7ssBPZon2JFUx4Rf58a++XPBblce32+W6SwiIiIiIiIiIiIim1Op5UZjFm8HvAr0UqFVzXVVaPm60NqtQwGfn90/wY5kW8xbsrb4va9nnnvGQb2eMJ1FREREREREREREpCKVWm4zZvFZwH1AHRVa1VxXhZavC60ANhPP3YmBVqMEO5NtVVRcyrtfRz/86NvogY9ePqTYdB4RERERERERERER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";
|
|
161
|
+
|
|
162
|
+
// src/blocks/LinkPreview.tsx
|
|
163
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
164
|
+
var metadataCache = /* @__PURE__ */ new Map();
|
|
165
|
+
async function fetchLinkMetadata(url, apiEndpoint) {
|
|
166
|
+
const cached = metadataCache.get(url);
|
|
167
|
+
if (cached) return cached;
|
|
168
|
+
const response = await fetch(
|
|
169
|
+
`${apiEndpoint}?url=${encodeURIComponent(url)}`
|
|
170
|
+
);
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
throw new Error(`Failed to fetch metadata: ${response.status}`);
|
|
173
|
+
}
|
|
174
|
+
const metadata = await response.json();
|
|
175
|
+
metadataCache.set(url, metadata);
|
|
176
|
+
return metadata;
|
|
177
|
+
}
|
|
178
|
+
function clearMetadataCache() {
|
|
179
|
+
metadataCache.clear();
|
|
180
|
+
}
|
|
181
|
+
function extractDomain(url) {
|
|
182
|
+
try {
|
|
183
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
184
|
+
} catch {
|
|
185
|
+
return url;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
var LinkPreviewCard = ({
|
|
189
|
+
url,
|
|
190
|
+
title,
|
|
191
|
+
description,
|
|
192
|
+
image,
|
|
193
|
+
domain,
|
|
194
|
+
editable,
|
|
195
|
+
onDelete,
|
|
196
|
+
width,
|
|
197
|
+
onWidthChange,
|
|
198
|
+
height,
|
|
199
|
+
onHeightChange
|
|
200
|
+
}) => {
|
|
201
|
+
const [imgError, setImgError] = useState(false);
|
|
202
|
+
const [hovered, setHovered] = useState(false);
|
|
203
|
+
const [resizeParams, setResizeParams] = useState(void 0);
|
|
204
|
+
const [localWidth, setLocalWidth] = useState(width);
|
|
205
|
+
const [localHeight, setLocalHeight] = useState(height);
|
|
206
|
+
const cardRef = useRef(null);
|
|
207
|
+
const justResizedRef = useRef(false);
|
|
208
|
+
useEffect(() => {
|
|
209
|
+
setLocalWidth(width);
|
|
210
|
+
}, [width]);
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
setLocalHeight(height);
|
|
213
|
+
}, [height]);
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
if (!resizeParams) return;
|
|
216
|
+
const onMouseMove = (e) => {
|
|
217
|
+
if (resizeParams.handleUsed === "bottom") {
|
|
218
|
+
const delta = e.clientY - resizeParams.initialClientY;
|
|
219
|
+
setLocalHeight(Math.min(Math.max(resizeParams.initialHeight + delta, 100), 600));
|
|
220
|
+
} else {
|
|
221
|
+
const delta = resizeParams.handleUsed === "left" ? resizeParams.initialClientX - e.clientX : e.clientX - resizeParams.initialClientX;
|
|
222
|
+
setLocalWidth(Math.min(
|
|
223
|
+
Math.max(resizeParams.initialWidth + delta, 200),
|
|
224
|
+
cardRef.current?.parentElement?.clientWidth || 800
|
|
225
|
+
));
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
const onMouseUp = () => {
|
|
229
|
+
const handle = resizeParams.handleUsed;
|
|
230
|
+
setResizeParams(void 0);
|
|
231
|
+
justResizedRef.current = true;
|
|
232
|
+
setTimeout(() => {
|
|
233
|
+
justResizedRef.current = false;
|
|
234
|
+
}, 50);
|
|
235
|
+
if (handle === "bottom") {
|
|
236
|
+
if (localHeight && onHeightChange) onHeightChange(localHeight);
|
|
237
|
+
} else {
|
|
238
|
+
if (localWidth && onWidthChange) onWidthChange(localWidth);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
window.addEventListener("mousemove", onMouseMove);
|
|
242
|
+
window.addEventListener("mouseup", onMouseUp);
|
|
243
|
+
return () => {
|
|
244
|
+
window.removeEventListener("mousemove", onMouseMove);
|
|
245
|
+
window.removeEventListener("mouseup", onMouseUp);
|
|
246
|
+
};
|
|
247
|
+
}, [resizeParams, localWidth, localHeight, onWidthChange, onHeightChange]);
|
|
248
|
+
const handleLeftDown = useCallback((e) => {
|
|
249
|
+
e.preventDefault();
|
|
250
|
+
e.stopPropagation();
|
|
251
|
+
setResizeParams({
|
|
252
|
+
handleUsed: "left",
|
|
253
|
+
initialWidth: cardRef.current.clientWidth,
|
|
254
|
+
initialHeight: localHeight || 200,
|
|
255
|
+
initialClientX: e.clientX,
|
|
256
|
+
initialClientY: e.clientY
|
|
257
|
+
});
|
|
258
|
+
}, [localHeight]);
|
|
259
|
+
const handleRightDown = useCallback((e) => {
|
|
260
|
+
e.preventDefault();
|
|
261
|
+
e.stopPropagation();
|
|
262
|
+
setResizeParams({
|
|
263
|
+
handleUsed: "right",
|
|
264
|
+
initialWidth: cardRef.current.clientWidth,
|
|
265
|
+
initialHeight: localHeight || 200,
|
|
266
|
+
initialClientX: e.clientX,
|
|
267
|
+
initialClientY: e.clientY
|
|
268
|
+
});
|
|
269
|
+
}, [localHeight]);
|
|
270
|
+
const handleBottomDown = useCallback((e) => {
|
|
271
|
+
e.preventDefault();
|
|
272
|
+
e.stopPropagation();
|
|
273
|
+
setResizeParams({
|
|
274
|
+
handleUsed: "bottom",
|
|
275
|
+
initialWidth: cardRef.current.clientWidth,
|
|
276
|
+
initialHeight: localHeight || 200,
|
|
277
|
+
initialClientX: e.clientX,
|
|
278
|
+
initialClientY: e.clientY
|
|
279
|
+
});
|
|
280
|
+
}, [localHeight]);
|
|
281
|
+
const handleClick = useCallback(() => {
|
|
282
|
+
if (url && !resizeParams && !justResizedRef.current) {
|
|
283
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
284
|
+
}
|
|
285
|
+
}, [url, resizeParams]);
|
|
286
|
+
const resizeCursor = resizeParams ? resizeParams.handleUsed === "bottom" ? "ns-resize" : "ew-resize" : "pointer";
|
|
287
|
+
return /* @__PURE__ */ jsxs(
|
|
288
|
+
"div",
|
|
289
|
+
{
|
|
290
|
+
ref: cardRef,
|
|
291
|
+
className: "lumir-link-preview-card",
|
|
292
|
+
onClick: handleClick,
|
|
293
|
+
style: {
|
|
294
|
+
border: "1px solid #e0e0e0",
|
|
295
|
+
borderRadius: "8px",
|
|
296
|
+
overflow: "hidden",
|
|
297
|
+
cursor: resizeCursor,
|
|
298
|
+
width: localWidth ? `${localWidth}px` : void 0,
|
|
299
|
+
maxWidth: "100%",
|
|
300
|
+
backgroundColor: "#fff",
|
|
301
|
+
transition: resizeParams ? "none" : "box-shadow 0.2s",
|
|
302
|
+
position: "relative"
|
|
303
|
+
},
|
|
304
|
+
onMouseEnter: () => {
|
|
305
|
+
if (!resizeParams) setHovered(true);
|
|
306
|
+
},
|
|
307
|
+
onMouseLeave: () => {
|
|
308
|
+
if (!resizeParams) setHovered(false);
|
|
309
|
+
},
|
|
310
|
+
children: [
|
|
311
|
+
editable && onDelete && /* @__PURE__ */ jsx(
|
|
312
|
+
"button",
|
|
313
|
+
{
|
|
314
|
+
type: "button",
|
|
315
|
+
onClick: (e) => {
|
|
316
|
+
e.stopPropagation();
|
|
317
|
+
onDelete();
|
|
318
|
+
},
|
|
319
|
+
className: "lumir-link-preview-delete",
|
|
320
|
+
style: {
|
|
321
|
+
position: "absolute",
|
|
322
|
+
top: "8px",
|
|
323
|
+
right: "8px",
|
|
324
|
+
width: "24px",
|
|
325
|
+
height: "24px",
|
|
326
|
+
borderRadius: "50%",
|
|
327
|
+
border: "none",
|
|
328
|
+
backgroundColor: "rgba(0,0,0,0.5)",
|
|
329
|
+
color: "#fff",
|
|
330
|
+
cursor: "pointer",
|
|
331
|
+
display: "flex",
|
|
332
|
+
alignItems: "center",
|
|
333
|
+
justifyContent: "center",
|
|
334
|
+
fontSize: "14px",
|
|
335
|
+
lineHeight: 1,
|
|
336
|
+
zIndex: 2,
|
|
337
|
+
opacity: 0,
|
|
338
|
+
transition: "opacity 0.2s"
|
|
339
|
+
},
|
|
340
|
+
title: "\uC0AD\uC81C",
|
|
341
|
+
children: "\u2715"
|
|
342
|
+
}
|
|
343
|
+
),
|
|
344
|
+
editable && (hovered || resizeParams) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
345
|
+
/* @__PURE__ */ jsx(
|
|
346
|
+
"div",
|
|
347
|
+
{
|
|
348
|
+
className: "lumir-resize-handle",
|
|
349
|
+
style: { left: "4px" },
|
|
350
|
+
onMouseDown: handleLeftDown
|
|
351
|
+
}
|
|
352
|
+
),
|
|
353
|
+
/* @__PURE__ */ jsx(
|
|
354
|
+
"div",
|
|
355
|
+
{
|
|
356
|
+
className: "lumir-resize-handle",
|
|
357
|
+
style: { right: "4px" },
|
|
358
|
+
onMouseDown: handleRightDown
|
|
359
|
+
}
|
|
360
|
+
)
|
|
361
|
+
] }),
|
|
362
|
+
image && !imgError && /* @__PURE__ */ jsxs(
|
|
363
|
+
"div",
|
|
364
|
+
{
|
|
365
|
+
style: {
|
|
366
|
+
width: "100%",
|
|
367
|
+
height: `${localHeight || 200}px`,
|
|
368
|
+
overflow: "hidden",
|
|
369
|
+
backgroundColor: "#f0f0f0",
|
|
370
|
+
position: "relative"
|
|
371
|
+
},
|
|
372
|
+
children: [
|
|
373
|
+
/* @__PURE__ */ jsx(
|
|
374
|
+
"img",
|
|
375
|
+
{
|
|
376
|
+
src: image,
|
|
377
|
+
alt: title || "Link preview",
|
|
378
|
+
onError: () => setImgError(true),
|
|
379
|
+
style: {
|
|
380
|
+
width: "100%",
|
|
381
|
+
height: "100%",
|
|
382
|
+
objectFit: "cover",
|
|
383
|
+
display: "block"
|
|
384
|
+
},
|
|
385
|
+
referrerPolicy: "no-referrer",
|
|
386
|
+
loading: "lazy"
|
|
387
|
+
}
|
|
388
|
+
),
|
|
389
|
+
editable && (hovered || resizeParams) && /* @__PURE__ */ jsx(
|
|
390
|
+
"div",
|
|
391
|
+
{
|
|
392
|
+
className: "lumir-resize-handle-bottom",
|
|
393
|
+
onMouseDown: handleBottomDown
|
|
394
|
+
}
|
|
395
|
+
)
|
|
396
|
+
]
|
|
397
|
+
}
|
|
398
|
+
),
|
|
399
|
+
/* @__PURE__ */ jsxs("div", { style: { padding: "12px 16px" }, children: [
|
|
400
|
+
/* @__PURE__ */ jsx(
|
|
401
|
+
"div",
|
|
402
|
+
{
|
|
403
|
+
style: {
|
|
404
|
+
fontSize: "14px",
|
|
405
|
+
fontWeight: 600,
|
|
406
|
+
color: "#1a1a1a",
|
|
407
|
+
lineHeight: 1.4,
|
|
408
|
+
marginBottom: description ? "4px" : "8px",
|
|
409
|
+
overflow: "hidden",
|
|
410
|
+
textOverflow: "ellipsis",
|
|
411
|
+
whiteSpace: "nowrap"
|
|
412
|
+
},
|
|
413
|
+
children: title || domain
|
|
414
|
+
}
|
|
415
|
+
),
|
|
416
|
+
description && /* @__PURE__ */ jsx(
|
|
417
|
+
"div",
|
|
418
|
+
{
|
|
419
|
+
style: {
|
|
420
|
+
fontSize: "12px",
|
|
421
|
+
color: "#666",
|
|
422
|
+
lineHeight: 1.4,
|
|
423
|
+
marginBottom: "8px",
|
|
424
|
+
overflow: "hidden",
|
|
425
|
+
textOverflow: "ellipsis",
|
|
426
|
+
display: "-webkit-box",
|
|
427
|
+
WebkitLineClamp: 2,
|
|
428
|
+
WebkitBoxOrient: "vertical"
|
|
429
|
+
},
|
|
430
|
+
children: description
|
|
431
|
+
}
|
|
432
|
+
),
|
|
433
|
+
/* @__PURE__ */ jsx(
|
|
434
|
+
"div",
|
|
435
|
+
{
|
|
436
|
+
style: {
|
|
437
|
+
fontSize: "12px",
|
|
438
|
+
color: "#999",
|
|
439
|
+
overflow: "hidden",
|
|
440
|
+
textOverflow: "ellipsis",
|
|
441
|
+
whiteSpace: "nowrap"
|
|
442
|
+
},
|
|
443
|
+
children: domain
|
|
444
|
+
}
|
|
445
|
+
)
|
|
446
|
+
] })
|
|
447
|
+
]
|
|
448
|
+
}
|
|
449
|
+
);
|
|
450
|
+
};
|
|
451
|
+
var LinkPreviewSkeleton = () => /* @__PURE__ */ jsxs(
|
|
452
|
+
"div",
|
|
453
|
+
{
|
|
454
|
+
className: "lumir-link-preview-skeleton",
|
|
455
|
+
style: {
|
|
456
|
+
border: "1px solid #e0e0e0",
|
|
457
|
+
borderRadius: "8px",
|
|
458
|
+
overflow: "hidden",
|
|
459
|
+
maxWidth: "400px",
|
|
460
|
+
backgroundColor: "#fff"
|
|
461
|
+
},
|
|
462
|
+
children: [
|
|
463
|
+
/* @__PURE__ */ jsx(
|
|
464
|
+
"div",
|
|
465
|
+
{
|
|
466
|
+
style: {
|
|
467
|
+
width: "100%",
|
|
468
|
+
height: "200px",
|
|
469
|
+
backgroundColor: "#f0f0f0",
|
|
470
|
+
animation: "lumir-skeleton-pulse 1.5s ease-in-out infinite"
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
),
|
|
474
|
+
/* @__PURE__ */ jsxs("div", { style: { padding: "12px 16px" }, children: [
|
|
475
|
+
/* @__PURE__ */ jsx(
|
|
476
|
+
"div",
|
|
477
|
+
{
|
|
478
|
+
style: {
|
|
479
|
+
height: "16px",
|
|
480
|
+
width: "70%",
|
|
481
|
+
backgroundColor: "#f0f0f0",
|
|
482
|
+
borderRadius: "4px",
|
|
483
|
+
marginBottom: "8px",
|
|
484
|
+
animation: "lumir-skeleton-pulse 1.5s ease-in-out infinite"
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
),
|
|
488
|
+
/* @__PURE__ */ jsx(
|
|
489
|
+
"div",
|
|
490
|
+
{
|
|
491
|
+
style: {
|
|
492
|
+
height: "12px",
|
|
493
|
+
width: "90%",
|
|
494
|
+
backgroundColor: "#f0f0f0",
|
|
495
|
+
borderRadius: "4px",
|
|
496
|
+
marginBottom: "8px",
|
|
497
|
+
animation: "lumir-skeleton-pulse 1.5s ease-in-out infinite"
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
),
|
|
501
|
+
/* @__PURE__ */ jsx(
|
|
502
|
+
"div",
|
|
503
|
+
{
|
|
504
|
+
style: {
|
|
505
|
+
height: "12px",
|
|
506
|
+
width: "40%",
|
|
507
|
+
backgroundColor: "#f0f0f0",
|
|
508
|
+
borderRadius: "4px",
|
|
509
|
+
animation: "lumir-skeleton-pulse 1.5s ease-in-out infinite"
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
)
|
|
513
|
+
] })
|
|
514
|
+
]
|
|
515
|
+
}
|
|
516
|
+
);
|
|
517
|
+
var LinkPreviewError = ({
|
|
518
|
+
url,
|
|
519
|
+
onRetry
|
|
520
|
+
}) => {
|
|
521
|
+
const domain = (() => {
|
|
522
|
+
try {
|
|
523
|
+
return new URL(url).hostname;
|
|
524
|
+
} catch {
|
|
525
|
+
return url;
|
|
526
|
+
}
|
|
527
|
+
})();
|
|
528
|
+
return /* @__PURE__ */ jsxs(
|
|
529
|
+
"div",
|
|
530
|
+
{
|
|
531
|
+
className: "lumir-link-preview-error",
|
|
532
|
+
style: {
|
|
533
|
+
border: "1px solid #e0e0e0",
|
|
534
|
+
borderRadius: "8px",
|
|
535
|
+
overflow: "hidden",
|
|
536
|
+
maxWidth: "400px",
|
|
537
|
+
backgroundColor: "#fff",
|
|
538
|
+
cursor: "pointer",
|
|
539
|
+
position: "relative"
|
|
540
|
+
},
|
|
541
|
+
onClick: () => window.open(url, "_blank", "noopener,noreferrer"),
|
|
542
|
+
children: [
|
|
543
|
+
/* @__PURE__ */ jsx(
|
|
544
|
+
"div",
|
|
545
|
+
{
|
|
546
|
+
style: {
|
|
547
|
+
width: "100%",
|
|
548
|
+
height: "160px",
|
|
549
|
+
overflow: "hidden",
|
|
550
|
+
backgroundColor: "#f0f0f0",
|
|
551
|
+
display: "flex",
|
|
552
|
+
alignItems: "center",
|
|
553
|
+
justifyContent: "center"
|
|
554
|
+
},
|
|
555
|
+
children: /* @__PURE__ */ jsx(
|
|
556
|
+
"img",
|
|
557
|
+
{
|
|
558
|
+
src: DEFAULT_LINK_PREVIEW_IMAGE,
|
|
559
|
+
alt: "Lumir",
|
|
560
|
+
style: {
|
|
561
|
+
width: "100%",
|
|
562
|
+
height: "100%",
|
|
563
|
+
objectFit: "contain",
|
|
564
|
+
display: "block",
|
|
565
|
+
padding: "20px",
|
|
566
|
+
boxSizing: "border-box"
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
)
|
|
570
|
+
}
|
|
571
|
+
),
|
|
572
|
+
/* @__PURE__ */ jsxs("div", { style: { padding: "12px 16px" }, children: [
|
|
573
|
+
/* @__PURE__ */ jsx(
|
|
574
|
+
"div",
|
|
575
|
+
{
|
|
576
|
+
style: {
|
|
577
|
+
fontSize: "13px",
|
|
578
|
+
color: "#999",
|
|
579
|
+
marginBottom: "4px"
|
|
580
|
+
},
|
|
581
|
+
children: "\uBBF8\uB9AC\uBCF4\uAE30\uB97C \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4"
|
|
582
|
+
}
|
|
583
|
+
),
|
|
584
|
+
/* @__PURE__ */ jsx(
|
|
585
|
+
"div",
|
|
586
|
+
{
|
|
587
|
+
style: {
|
|
588
|
+
fontSize: "12px",
|
|
589
|
+
color: "#1a73e8",
|
|
590
|
+
overflow: "hidden",
|
|
591
|
+
textOverflow: "ellipsis",
|
|
592
|
+
whiteSpace: "nowrap"
|
|
593
|
+
},
|
|
594
|
+
children: domain
|
|
595
|
+
}
|
|
596
|
+
)
|
|
597
|
+
] }),
|
|
598
|
+
onRetry && /* @__PURE__ */ jsx(
|
|
599
|
+
"button",
|
|
600
|
+
{
|
|
601
|
+
type: "button",
|
|
602
|
+
onClick: (e) => {
|
|
603
|
+
e.stopPropagation();
|
|
604
|
+
onRetry();
|
|
605
|
+
},
|
|
606
|
+
style: {
|
|
607
|
+
position: "absolute",
|
|
608
|
+
top: "8px",
|
|
609
|
+
right: "8px",
|
|
610
|
+
background: "rgba(0,0,0,0.5)",
|
|
611
|
+
border: "none",
|
|
612
|
+
borderRadius: "4px",
|
|
613
|
+
padding: "4px 8px",
|
|
614
|
+
cursor: "pointer",
|
|
615
|
+
fontSize: "12px",
|
|
616
|
+
color: "#fff",
|
|
617
|
+
whiteSpace: "nowrap"
|
|
618
|
+
},
|
|
619
|
+
children: "\uC7AC\uC2DC\uB3C4"
|
|
620
|
+
}
|
|
621
|
+
)
|
|
622
|
+
]
|
|
623
|
+
}
|
|
624
|
+
);
|
|
625
|
+
};
|
|
626
|
+
var LinkPreviewUrlInput = ({
|
|
627
|
+
onSubmit
|
|
628
|
+
}) => {
|
|
629
|
+
const [inputUrl, setInputUrl] = useState("");
|
|
630
|
+
const inputRef = useRef(null);
|
|
631
|
+
useEffect(() => {
|
|
632
|
+
inputRef.current?.focus();
|
|
633
|
+
}, []);
|
|
634
|
+
const handleSubmit = useCallback(() => {
|
|
635
|
+
const trimmed = inputUrl.trim();
|
|
636
|
+
if (!trimmed) return;
|
|
637
|
+
const normalized = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
|
|
638
|
+
onSubmit(normalized);
|
|
639
|
+
}, [inputUrl, onSubmit]);
|
|
640
|
+
return /* @__PURE__ */ jsxs(
|
|
641
|
+
"div",
|
|
642
|
+
{
|
|
643
|
+
className: "lumir-link-preview-input",
|
|
644
|
+
style: {
|
|
645
|
+
border: "1px solid #e0e0e0",
|
|
646
|
+
borderRadius: "8px",
|
|
647
|
+
padding: "16px",
|
|
648
|
+
maxWidth: "400px",
|
|
649
|
+
backgroundColor: "#fafafa",
|
|
650
|
+
display: "flex",
|
|
651
|
+
alignItems: "center",
|
|
652
|
+
gap: "8px"
|
|
653
|
+
},
|
|
654
|
+
children: [
|
|
655
|
+
/* @__PURE__ */ jsxs(
|
|
656
|
+
"svg",
|
|
657
|
+
{
|
|
658
|
+
width: "18",
|
|
659
|
+
height: "18",
|
|
660
|
+
viewBox: "0 0 24 24",
|
|
661
|
+
fill: "none",
|
|
662
|
+
stroke: "#999",
|
|
663
|
+
strokeWidth: "2",
|
|
664
|
+
strokeLinecap: "round",
|
|
665
|
+
strokeLinejoin: "round",
|
|
666
|
+
style: { flexShrink: 0 },
|
|
667
|
+
children: [
|
|
668
|
+
/* @__PURE__ */ jsx("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
|
|
669
|
+
/* @__PURE__ */ jsx("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
|
|
670
|
+
]
|
|
671
|
+
}
|
|
672
|
+
),
|
|
673
|
+
/* @__PURE__ */ jsx(
|
|
674
|
+
"input",
|
|
675
|
+
{
|
|
676
|
+
ref: inputRef,
|
|
677
|
+
type: "text",
|
|
678
|
+
value: inputUrl,
|
|
679
|
+
onChange: (e) => setInputUrl(e.target.value),
|
|
680
|
+
onKeyDown: (e) => {
|
|
681
|
+
if (e.key === "Enter") {
|
|
682
|
+
e.preventDefault();
|
|
683
|
+
handleSubmit();
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
placeholder: "URL\uC744 \uC785\uB825\uD558\uC138\uC694 (\uC608: https://example.com)",
|
|
687
|
+
style: {
|
|
688
|
+
flex: 1,
|
|
689
|
+
border: "none",
|
|
690
|
+
outline: "none",
|
|
691
|
+
backgroundColor: "transparent",
|
|
692
|
+
fontSize: "13px",
|
|
693
|
+
color: "#333",
|
|
694
|
+
minWidth: 0
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
),
|
|
698
|
+
/* @__PURE__ */ jsx(
|
|
699
|
+
"button",
|
|
700
|
+
{
|
|
701
|
+
type: "button",
|
|
702
|
+
onClick: handleSubmit,
|
|
703
|
+
disabled: !inputUrl.trim(),
|
|
704
|
+
style: {
|
|
705
|
+
flexShrink: 0,
|
|
706
|
+
padding: "4px 12px",
|
|
707
|
+
border: "none",
|
|
708
|
+
borderRadius: "4px",
|
|
709
|
+
backgroundColor: inputUrl.trim() ? "#3b82f6" : "#d1d5db",
|
|
710
|
+
color: "#fff",
|
|
711
|
+
fontSize: "12px",
|
|
712
|
+
fontWeight: 500,
|
|
713
|
+
cursor: inputUrl.trim() ? "pointer" : "not-allowed",
|
|
714
|
+
transition: "background-color 0.15s"
|
|
715
|
+
},
|
|
716
|
+
children: "\uD655\uC778"
|
|
717
|
+
}
|
|
718
|
+
)
|
|
719
|
+
]
|
|
720
|
+
}
|
|
721
|
+
);
|
|
722
|
+
};
|
|
723
|
+
var LinkPreviewBlock = createReactBlockSpec(
|
|
724
|
+
{
|
|
725
|
+
type: "linkPreview",
|
|
726
|
+
propSchema: {
|
|
727
|
+
url: { default: "" },
|
|
728
|
+
title: { default: "" },
|
|
729
|
+
description: { default: "" },
|
|
730
|
+
image: { default: "" },
|
|
731
|
+
domain: { default: "" },
|
|
732
|
+
previewWidth: { default: 400 },
|
|
733
|
+
previewHeight: { default: 200 }
|
|
734
|
+
},
|
|
735
|
+
content: "none"
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
render: (props) => {
|
|
739
|
+
const { url, title, description, image, domain } = props.block.props;
|
|
740
|
+
const [status, setStatus] = useState(
|
|
741
|
+
!url ? "idle" : title ? "idle" : "loading"
|
|
742
|
+
);
|
|
743
|
+
const fetchedRef = useRef(false);
|
|
744
|
+
const editable = props.editor.isEditable;
|
|
745
|
+
useEffect(() => {
|
|
746
|
+
if (!url || title || fetchedRef.current) {
|
|
747
|
+
if (!url) setStatus("idle");
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const getApiEndpoint = () => props.editor._linkPreviewApiEndpoint;
|
|
751
|
+
const doFetch = (endpoint2) => {
|
|
752
|
+
fetchedRef.current = true;
|
|
753
|
+
setStatus("loading");
|
|
754
|
+
fetchLinkMetadata(url, endpoint2).then((metadata) => {
|
|
755
|
+
props.editor.updateBlock(props.block, {
|
|
756
|
+
props: {
|
|
757
|
+
title: metadata.title || "",
|
|
758
|
+
description: metadata.description || "",
|
|
759
|
+
image: metadata.image || "",
|
|
760
|
+
domain: metadata.domain || extractDomain(url)
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
setStatus("idle");
|
|
764
|
+
}).catch(() => {
|
|
765
|
+
props.editor.updateBlock(props.block, {
|
|
766
|
+
props: { domain: extractDomain(url) }
|
|
767
|
+
});
|
|
768
|
+
setStatus("error");
|
|
769
|
+
});
|
|
770
|
+
};
|
|
771
|
+
const endpoint = getApiEndpoint();
|
|
772
|
+
if (endpoint) {
|
|
773
|
+
doFetch(endpoint);
|
|
774
|
+
} else {
|
|
775
|
+
const timer = setTimeout(() => {
|
|
776
|
+
const retryEndpoint = getApiEndpoint();
|
|
777
|
+
if (retryEndpoint) {
|
|
778
|
+
doFetch(retryEndpoint);
|
|
779
|
+
} else {
|
|
780
|
+
setStatus("error");
|
|
781
|
+
}
|
|
782
|
+
}, 100);
|
|
783
|
+
return () => clearTimeout(timer);
|
|
784
|
+
}
|
|
785
|
+
}, [url, title]);
|
|
786
|
+
const handleRetry = useCallback(() => {
|
|
787
|
+
const endpoint = props.editor._linkPreviewApiEndpoint;
|
|
788
|
+
if (!url || !endpoint) return;
|
|
789
|
+
metadataCache.delete(url);
|
|
790
|
+
fetchedRef.current = false;
|
|
791
|
+
setStatus("loading");
|
|
792
|
+
fetchLinkMetadata(url, endpoint).then((metadata) => {
|
|
793
|
+
props.editor.updateBlock(props.block, {
|
|
794
|
+
props: {
|
|
795
|
+
title: metadata.title || "",
|
|
796
|
+
description: metadata.description || "",
|
|
797
|
+
image: metadata.image || "",
|
|
798
|
+
domain: metadata.domain || extractDomain(url)
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
setStatus("idle");
|
|
802
|
+
}).catch(() => {
|
|
803
|
+
setStatus("error");
|
|
804
|
+
});
|
|
805
|
+
}, [url, props.editor, props.block]);
|
|
806
|
+
const handleDelete = useCallback(() => {
|
|
807
|
+
props.editor.removeBlocks([props.block]);
|
|
808
|
+
}, [props.editor, props.block]);
|
|
809
|
+
if (!url) {
|
|
810
|
+
if (!editable) {
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
return /* @__PURE__ */ jsx(
|
|
814
|
+
LinkPreviewUrlInput,
|
|
815
|
+
{
|
|
816
|
+
onSubmit: (newUrl) => {
|
|
817
|
+
props.editor.updateBlock(props.block, {
|
|
818
|
+
props: { url: newUrl }
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
if (status === "loading") {
|
|
825
|
+
return /* @__PURE__ */ jsx(LinkPreviewSkeleton, {});
|
|
826
|
+
}
|
|
827
|
+
if (status === "error") {
|
|
828
|
+
return /* @__PURE__ */ jsx(LinkPreviewError, { url, onRetry: handleRetry });
|
|
829
|
+
}
|
|
830
|
+
return /* @__PURE__ */ jsx(
|
|
831
|
+
LinkPreviewCard,
|
|
832
|
+
{
|
|
833
|
+
url,
|
|
834
|
+
title,
|
|
835
|
+
description,
|
|
836
|
+
image,
|
|
837
|
+
domain: domain || extractDomain(url),
|
|
838
|
+
editable,
|
|
839
|
+
onDelete: handleDelete,
|
|
840
|
+
width: props.block.props.previewWidth,
|
|
841
|
+
onWidthChange: (newWidth) => {
|
|
842
|
+
props.editor.updateBlock(props.block, {
|
|
843
|
+
props: { previewWidth: newWidth }
|
|
844
|
+
});
|
|
845
|
+
},
|
|
846
|
+
height: props.block.props.previewHeight,
|
|
847
|
+
onHeightChange: (newHeight) => {
|
|
848
|
+
props.editor.updateBlock(props.block, {
|
|
849
|
+
props: { previewHeight: newHeight }
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
);
|
|
857
|
+
|
|
858
|
+
// src/blocks/HtmlPreview.tsx
|
|
859
|
+
import { useState as useState2, useRef as useRef2, useCallback as useCallback2, useEffect as useEffect2 } from "react";
|
|
860
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
861
|
+
var MIN_HEIGHT = 100;
|
|
862
|
+
var MAX_HEIGHT = 1200;
|
|
863
|
+
var ensureCharset = (html) => {
|
|
864
|
+
const hasCharset = /<meta[^>]+charset\s*=/i.test(html);
|
|
865
|
+
if (hasCharset) {
|
|
866
|
+
return html;
|
|
867
|
+
}
|
|
868
|
+
if (/<head[^>]*>/i.test(html)) {
|
|
869
|
+
return html.replace(/(<head[^>]*>)/i, '$1\n<meta charset="UTF-8">');
|
|
870
|
+
}
|
|
871
|
+
if (/<html[^>]*>/i.test(html)) {
|
|
872
|
+
return html.replace(
|
|
873
|
+
/(<html[^>]*>)/i,
|
|
874
|
+
'$1\n<head><meta charset="UTF-8"></head>'
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
return `<!DOCTYPE html>
|
|
878
|
+
<html>
|
|
879
|
+
<head><meta charset="UTF-8"></head>
|
|
880
|
+
<body>
|
|
881
|
+
${html}
|
|
882
|
+
</body>
|
|
883
|
+
</html>`;
|
|
884
|
+
};
|
|
885
|
+
var sanitizeFileName = (fileName) => {
|
|
886
|
+
if (!fileName || typeof fileName !== "string") {
|
|
887
|
+
return `document_${Date.now()}.html`;
|
|
888
|
+
}
|
|
889
|
+
return fileName.replace(/\0/g, "").replace(/[\/\\]/g, "_").replace(/[<>:"|?*\x00-\x1f]/g, "").replace(/\.{2,}/g, ".").trim().replace(/^\.+|\.+$/g, "") || `document_${Date.now()}.html`;
|
|
890
|
+
};
|
|
891
|
+
var createSecureBlobUrl = (htmlContent) => {
|
|
892
|
+
const htmlWithCharset = ensureCharset(htmlContent);
|
|
893
|
+
const blob = new Blob([htmlWithCharset], {
|
|
894
|
+
type: "text/html;charset=utf-8"
|
|
895
|
+
});
|
|
896
|
+
return URL.createObjectURL(blob);
|
|
897
|
+
};
|
|
898
|
+
var HtmlPreviewBlock = createReactBlockSpec2(
|
|
899
|
+
{
|
|
900
|
+
type: "htmlPreview",
|
|
901
|
+
propSchema: {
|
|
902
|
+
htmlContent: {
|
|
903
|
+
default: ""
|
|
904
|
+
},
|
|
905
|
+
fileName: {
|
|
906
|
+
default: ""
|
|
907
|
+
},
|
|
908
|
+
height: {
|
|
909
|
+
default: "400px"
|
|
910
|
+
}
|
|
911
|
+
},
|
|
912
|
+
content: "none"
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
render: (props) => {
|
|
916
|
+
const [isExpanded, setIsExpanded] = useState2(true);
|
|
917
|
+
const [isResizing, setIsResizing] = useState2(false);
|
|
918
|
+
const [blobUrl, setBlobUrl] = useState2("");
|
|
919
|
+
const containerRef = useRef2(null);
|
|
920
|
+
const htmlContent = props.block.props.htmlContent || "";
|
|
921
|
+
const fileName = props.block.props.fileName || "HTML Document";
|
|
922
|
+
const savedHeight = props.block.props.height || "400px";
|
|
923
|
+
const currentHeight = parseInt(savedHeight, 10) || 400;
|
|
924
|
+
useEffect2(() => {
|
|
925
|
+
if (htmlContent) {
|
|
926
|
+
const url = createSecureBlobUrl(htmlContent);
|
|
927
|
+
setBlobUrl(url);
|
|
928
|
+
return () => {
|
|
929
|
+
URL.revokeObjectURL(url);
|
|
930
|
+
};
|
|
931
|
+
}
|
|
932
|
+
}, [htmlContent]);
|
|
933
|
+
const handleResizeStart = useCallback2(
|
|
934
|
+
(e) => {
|
|
935
|
+
e.preventDefault();
|
|
936
|
+
e.stopPropagation();
|
|
937
|
+
setIsResizing(true);
|
|
938
|
+
const startY = e.clientY;
|
|
939
|
+
const startHeight = currentHeight;
|
|
940
|
+
const handleMouseMove = (moveEvent) => {
|
|
941
|
+
const deltaY = moveEvent.clientY - startY;
|
|
942
|
+
const newHeight = Math.min(
|
|
943
|
+
MAX_HEIGHT,
|
|
944
|
+
Math.max(MIN_HEIGHT, startHeight + deltaY)
|
|
945
|
+
);
|
|
946
|
+
props.editor.updateBlock(props.block, {
|
|
947
|
+
props: { height: `${newHeight}px` }
|
|
948
|
+
});
|
|
949
|
+
};
|
|
950
|
+
const handleMouseUp = () => {
|
|
951
|
+
setIsResizing(false);
|
|
952
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
953
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
954
|
+
};
|
|
955
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
956
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
957
|
+
},
|
|
958
|
+
[currentHeight, props.editor, props.block]
|
|
959
|
+
);
|
|
960
|
+
const handleExport = useCallback2(
|
|
961
|
+
(e) => {
|
|
962
|
+
e.stopPropagation();
|
|
963
|
+
const safeFileName = sanitizeFileName(fileName);
|
|
964
|
+
const downloadName = safeFileName.endsWith(".html") ? safeFileName : `${safeFileName}.html`;
|
|
965
|
+
const htmlWithCharset = ensureCharset(htmlContent);
|
|
966
|
+
const blob = new Blob([htmlWithCharset], {
|
|
967
|
+
type: "text/html;charset=utf-8"
|
|
968
|
+
});
|
|
969
|
+
const url = URL.createObjectURL(blob);
|
|
970
|
+
const a = document.createElement("a");
|
|
971
|
+
a.href = url;
|
|
972
|
+
a.download = downloadName;
|
|
973
|
+
a.rel = "noopener noreferrer";
|
|
974
|
+
document.body.appendChild(a);
|
|
975
|
+
a.click();
|
|
976
|
+
document.body.removeChild(a);
|
|
977
|
+
URL.revokeObjectURL(url);
|
|
978
|
+
},
|
|
979
|
+
[htmlContent, fileName]
|
|
980
|
+
);
|
|
981
|
+
const handleOpenNewWindow = useCallback2(
|
|
982
|
+
(e) => {
|
|
983
|
+
e.stopPropagation();
|
|
984
|
+
if (typeof window === "undefined") return;
|
|
985
|
+
const url = createSecureBlobUrl(htmlContent);
|
|
986
|
+
const newWindow = window.open(url, "_blank", "noopener,noreferrer");
|
|
987
|
+
if (newWindow) {
|
|
988
|
+
setTimeout(() => URL.revokeObjectURL(url), 1e3);
|
|
989
|
+
} else {
|
|
990
|
+
URL.revokeObjectURL(url);
|
|
991
|
+
}
|
|
992
|
+
},
|
|
993
|
+
[htmlContent]
|
|
994
|
+
);
|
|
995
|
+
return /* @__PURE__ */ jsxs2(
|
|
996
|
+
"div",
|
|
997
|
+
{
|
|
998
|
+
ref: containerRef,
|
|
999
|
+
style: {
|
|
1000
|
+
border: "1px solid #e0e0e0",
|
|
1001
|
+
borderRadius: "8px",
|
|
1002
|
+
overflow: "hidden",
|
|
1003
|
+
backgroundColor: "#f9f9f9",
|
|
1004
|
+
marginBottom: "2px",
|
|
1005
|
+
width: "100%",
|
|
1006
|
+
userSelect: isResizing ? "none" : "auto",
|
|
1007
|
+
outline: "none",
|
|
1008
|
+
boxShadow: "none"
|
|
1009
|
+
},
|
|
1010
|
+
children: [
|
|
1011
|
+
/* @__PURE__ */ jsxs2(
|
|
1012
|
+
"div",
|
|
1013
|
+
{
|
|
1014
|
+
style: {
|
|
1015
|
+
display: "flex",
|
|
1016
|
+
alignItems: "center",
|
|
1017
|
+
justifyContent: "space-between",
|
|
1018
|
+
padding: "4px 16px",
|
|
1019
|
+
backgroundColor: "#fff",
|
|
1020
|
+
borderBottom: isExpanded ? "1px solid #e0e0e0" : "none"
|
|
1021
|
+
},
|
|
1022
|
+
children: [
|
|
1023
|
+
/* @__PURE__ */ jsxs2(
|
|
1024
|
+
"div",
|
|
1025
|
+
{
|
|
1026
|
+
style: {
|
|
1027
|
+
display: "flex",
|
|
1028
|
+
alignItems: "center",
|
|
1029
|
+
gap: "8px",
|
|
1030
|
+
cursor: "pointer",
|
|
1031
|
+
flex: 1
|
|
1032
|
+
},
|
|
1033
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
1034
|
+
children: [
|
|
1035
|
+
/* @__PURE__ */ jsx2(
|
|
1036
|
+
"svg",
|
|
1037
|
+
{
|
|
1038
|
+
width: "16",
|
|
1039
|
+
height: "16",
|
|
1040
|
+
viewBox: "0 0 24 24",
|
|
1041
|
+
fill: "none",
|
|
1042
|
+
stroke: "currentColor",
|
|
1043
|
+
strokeWidth: "2",
|
|
1044
|
+
strokeLinecap: "round",
|
|
1045
|
+
strokeLinejoin: "round",
|
|
1046
|
+
style: {
|
|
1047
|
+
transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
|
|
1048
|
+
transition: "transform 0.2s"
|
|
1049
|
+
},
|
|
1050
|
+
children: /* @__PURE__ */ jsx2("polyline", { points: "6 9 12 15 18 9" })
|
|
1051
|
+
}
|
|
1052
|
+
),
|
|
1053
|
+
/* @__PURE__ */ jsx2("span", { style: { fontWeight: 500, fontSize: "14px" }, children: fileName })
|
|
1054
|
+
]
|
|
1055
|
+
}
|
|
1056
|
+
),
|
|
1057
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
|
|
1058
|
+
/* @__PURE__ */ jsx2(
|
|
1059
|
+
"button",
|
|
1060
|
+
{
|
|
1061
|
+
onClick: handleOpenNewWindow,
|
|
1062
|
+
style: {
|
|
1063
|
+
background: "none",
|
|
1064
|
+
border: "none",
|
|
1065
|
+
cursor: "pointer",
|
|
1066
|
+
padding: "4px",
|
|
1067
|
+
display: "flex",
|
|
1068
|
+
alignItems: "center",
|
|
1069
|
+
justifyContent: "center",
|
|
1070
|
+
color: "#666",
|
|
1071
|
+
borderRadius: "4px"
|
|
1072
|
+
},
|
|
1073
|
+
title: "\uC0C8 \uCC3D\uC5D0\uC11C \uC5F4\uAE30",
|
|
1074
|
+
type: "button",
|
|
1075
|
+
onMouseEnter: (e) => {
|
|
1076
|
+
e.currentTarget.style.backgroundColor = "#f0f0f0";
|
|
1077
|
+
},
|
|
1078
|
+
onMouseLeave: (e) => {
|
|
1079
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
1080
|
+
},
|
|
1081
|
+
children: /* @__PURE__ */ jsxs2(
|
|
1082
|
+
"svg",
|
|
1083
|
+
{
|
|
1084
|
+
width: "16",
|
|
1085
|
+
height: "16",
|
|
1086
|
+
viewBox: "0 0 24 24",
|
|
1087
|
+
fill: "none",
|
|
1088
|
+
stroke: "currentColor",
|
|
1089
|
+
strokeWidth: "2",
|
|
1090
|
+
strokeLinecap: "round",
|
|
1091
|
+
strokeLinejoin: "round",
|
|
1092
|
+
children: [
|
|
1093
|
+
/* @__PURE__ */ jsx2("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
1094
|
+
/* @__PURE__ */ jsx2("polyline", { points: "15 3 21 3 21 9" }),
|
|
1095
|
+
/* @__PURE__ */ jsx2("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
1096
|
+
]
|
|
1097
|
+
}
|
|
1098
|
+
)
|
|
1099
|
+
}
|
|
1100
|
+
),
|
|
1101
|
+
/* @__PURE__ */ jsx2(
|
|
1102
|
+
"button",
|
|
1103
|
+
{
|
|
1104
|
+
onClick: handleExport,
|
|
1105
|
+
style: {
|
|
1106
|
+
background: "none",
|
|
1107
|
+
border: "none",
|
|
1108
|
+
cursor: "pointer",
|
|
1109
|
+
padding: "4px",
|
|
1110
|
+
display: "flex",
|
|
1111
|
+
alignItems: "center",
|
|
1112
|
+
justifyContent: "center",
|
|
1113
|
+
color: "#666",
|
|
1114
|
+
borderRadius: "4px"
|
|
1115
|
+
},
|
|
1116
|
+
title: "HTML \uB2E4\uC6B4\uB85C\uB4DC",
|
|
1117
|
+
type: "button",
|
|
1118
|
+
onMouseEnter: (e) => {
|
|
1119
|
+
e.currentTarget.style.backgroundColor = "#f0f0f0";
|
|
1120
|
+
},
|
|
1121
|
+
onMouseLeave: (e) => {
|
|
1122
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
1123
|
+
},
|
|
1124
|
+
children: /* @__PURE__ */ jsxs2(
|
|
1125
|
+
"svg",
|
|
1126
|
+
{
|
|
1127
|
+
width: "16",
|
|
1128
|
+
height: "16",
|
|
1129
|
+
viewBox: "0 0 24 24",
|
|
1130
|
+
fill: "none",
|
|
1131
|
+
stroke: "currentColor",
|
|
1132
|
+
strokeWidth: "2",
|
|
1133
|
+
strokeLinecap: "round",
|
|
1134
|
+
strokeLinejoin: "round",
|
|
1135
|
+
children: [
|
|
1136
|
+
/* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
1137
|
+
/* @__PURE__ */ jsx2("polyline", { points: "7 10 12 15 17 10" }),
|
|
1138
|
+
/* @__PURE__ */ jsx2("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
|
|
1139
|
+
]
|
|
1140
|
+
}
|
|
1141
|
+
)
|
|
1142
|
+
}
|
|
1143
|
+
)
|
|
1144
|
+
] })
|
|
1145
|
+
]
|
|
1146
|
+
}
|
|
1147
|
+
),
|
|
1148
|
+
isExpanded && /* @__PURE__ */ jsxs2(
|
|
1149
|
+
"div",
|
|
1150
|
+
{
|
|
1151
|
+
style: {
|
|
1152
|
+
padding: "0",
|
|
1153
|
+
backgroundColor: "#fff",
|
|
1154
|
+
position: "relative"
|
|
1155
|
+
},
|
|
1156
|
+
children: [
|
|
1157
|
+
/* @__PURE__ */ jsx2(
|
|
1158
|
+
"iframe",
|
|
1159
|
+
{
|
|
1160
|
+
src: blobUrl || "about:blank",
|
|
1161
|
+
style: {
|
|
1162
|
+
width: "100%",
|
|
1163
|
+
height: `${currentHeight}px`,
|
|
1164
|
+
border: "none",
|
|
1165
|
+
display: "block",
|
|
1166
|
+
pointerEvents: isResizing ? "none" : "auto"
|
|
1167
|
+
},
|
|
1168
|
+
sandbox: "allow-popups allow-forms",
|
|
1169
|
+
title: fileName,
|
|
1170
|
+
referrerPolicy: "no-referrer",
|
|
1171
|
+
loading: "lazy"
|
|
1172
|
+
}
|
|
1173
|
+
),
|
|
1174
|
+
/* @__PURE__ */ jsx2(
|
|
1175
|
+
"div",
|
|
1176
|
+
{
|
|
1177
|
+
onMouseDown: handleResizeStart,
|
|
1178
|
+
style: {
|
|
1179
|
+
position: "absolute",
|
|
1180
|
+
bottom: 0,
|
|
1181
|
+
left: 0,
|
|
1182
|
+
right: 0,
|
|
1183
|
+
height: "12px",
|
|
1184
|
+
cursor: "ns-resize",
|
|
1185
|
+
backgroundColor: isResizing ? "rgba(59, 130, 246, 0.3)" : "transparent",
|
|
1186
|
+
display: "flex",
|
|
1187
|
+
alignItems: "center",
|
|
1188
|
+
justifyContent: "center",
|
|
1189
|
+
transition: "background-color 0.2s"
|
|
1190
|
+
},
|
|
1191
|
+
onMouseEnter: (e) => {
|
|
1192
|
+
e.currentTarget.style.backgroundColor = "rgba(59, 130, 246, 0.2)";
|
|
1193
|
+
},
|
|
1194
|
+
onMouseLeave: (e) => {
|
|
1195
|
+
if (!isResizing) {
|
|
1196
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
children: /* @__PURE__ */ jsx2(
|
|
1200
|
+
"div",
|
|
1201
|
+
{
|
|
1202
|
+
style: {
|
|
1203
|
+
width: "40px",
|
|
1204
|
+
height: "4px",
|
|
1205
|
+
backgroundColor: "#ccc",
|
|
1206
|
+
borderRadius: "2px"
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
)
|
|
1210
|
+
}
|
|
1211
|
+
)
|
|
1212
|
+
]
|
|
1213
|
+
}
|
|
1214
|
+
)
|
|
1215
|
+
]
|
|
1216
|
+
}
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
);
|
|
1221
|
+
var schema = BlockNoteSchema.create({
|
|
1222
|
+
blockSpecs: {
|
|
1223
|
+
...defaultBlockSpecs,
|
|
1224
|
+
htmlPreview: HtmlPreviewBlock,
|
|
1225
|
+
linkPreview: LinkPreviewBlock
|
|
1226
|
+
},
|
|
1227
|
+
inlineContentSpecs: defaultInlineContentSpecs,
|
|
1228
|
+
styleSpecs: defaultStyleSpecs
|
|
1229
|
+
});
|
|
1230
|
+
|
|
1231
|
+
// src/components/FloatingMenu/index.tsx
|
|
1232
|
+
import { useState as useState6, useEffect as useEffect6, useRef as useRef7 } from "react";
|
|
1233
|
+
|
|
1234
|
+
// src/components/FloatingMenu/Icons.tsx
|
|
1235
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1236
|
+
var Icons = {
|
|
1237
|
+
undo: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z" }) }),
|
|
1238
|
+
redo: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z" }) }),
|
|
1239
|
+
bold: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z" }) }),
|
|
1240
|
+
italic: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z" }) }),
|
|
1241
|
+
underline: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z" }) }),
|
|
1242
|
+
strikethrough: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z" }) }),
|
|
1243
|
+
alignLeft: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z" }) }),
|
|
1244
|
+
alignCenter: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z" }) }),
|
|
1245
|
+
alignRight: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z" }) }),
|
|
1246
|
+
bulletList: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z" }) }),
|
|
1247
|
+
numberedList: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
|
|
1248
|
+
image: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z" }) }),
|
|
1249
|
+
expandMore: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx3("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }),
|
|
1250
|
+
textColor: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z" }) }),
|
|
1251
|
+
bgColor: /* @__PURE__ */ jsxs3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
|
|
1252
|
+
/* @__PURE__ */ jsx3("path", { d: "M16.56 8.94L7.62 0 6.21 1.41l2.38 2.38-5.15 5.15c-.59.59-.59 1.54 0 2.12l5.5 5.5c.29.29.68.44 1.06.44s.77-.15 1.06-.44l5.5-5.5c.59-.58.59-1.53 0-2.12zM5.21 10L10 5.21 14.79 10H5.21zM19 11.5s-2 2.17-2 3.5c0 1.1.9 2 2 2s2-.9 2-2c0-1.33-2-3.5-2-3.5z" }),
|
|
1253
|
+
/* @__PURE__ */ jsx3("path", { fillOpacity: ".36", d: "M0 20h24v4H0z" })
|
|
1254
|
+
] }),
|
|
1255
|
+
link: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" }) }),
|
|
1256
|
+
chevronRight: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) }),
|
|
1257
|
+
chevronLeft: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) }),
|
|
1258
|
+
table: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M20 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM10 17H5v-2h5v2zm0-4H5v-2h5v2zm0-4H5V7h5v2zm9 8h-7v-2h7v2zm0-4h-7v-2h7v2zm0-4h-7V7h7v2z" }) }),
|
|
1259
|
+
htmlFile: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 2v5h5l-5-5zm-4 14H7v-1h2v1zm0-2H7v-1h2v1zm-2-2h2v1H7v-1zm4 4h-2v-1h2v1zm0-2h-2v-1h2v1zm0-2h-2v-1h2v1zm6 4h-4v-1h4v1zm0-2h-4v-1h4v1zm0-2h-4v-1h4v1z" }) })
|
|
1260
|
+
};
|
|
1261
|
+
var BlockTypeIcons = {
|
|
1262
|
+
paragraph: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M5 5h14v2H5zM5 11h14v2H5zM5 17h10v2H5z" }) }),
|
|
1263
|
+
h1: /* @__PURE__ */ jsx3("span", { className: "lumir-block-icon-text", children: "H1" }),
|
|
1264
|
+
h2: /* @__PURE__ */ jsx3("span", { className: "lumir-block-icon-text", children: "H2" }),
|
|
1265
|
+
h3: /* @__PURE__ */ jsx3("span", { className: "lumir-block-icon-text", children: "H3" }),
|
|
1266
|
+
h4: /* @__PURE__ */ jsx3("span", { className: "lumir-block-icon-text", children: "H4" }),
|
|
1267
|
+
h5: /* @__PURE__ */ jsx3("span", { className: "lumir-block-icon-text", children: "H5" }),
|
|
1268
|
+
h6: /* @__PURE__ */ jsx3("span", { className: "lumir-block-icon-text", children: "H6" }),
|
|
1269
|
+
toggleH1: /* @__PURE__ */ jsxs3("span", { className: "lumir-block-icon-toggle", children: [
|
|
1270
|
+
/* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx3("path", { d: "M8 5v14l11-7z" }) }),
|
|
1271
|
+
/* @__PURE__ */ jsx3("span", { children: "H1" })
|
|
1272
|
+
] }),
|
|
1273
|
+
toggleH2: /* @__PURE__ */ jsxs3("span", { className: "lumir-block-icon-toggle", children: [
|
|
1274
|
+
/* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx3("path", { d: "M8 5v14l11-7z" }) }),
|
|
1275
|
+
/* @__PURE__ */ jsx3("span", { children: "H2" })
|
|
1276
|
+
] }),
|
|
1277
|
+
toggleH3: /* @__PURE__ */ jsxs3("span", { className: "lumir-block-icon-toggle", children: [
|
|
1278
|
+
/* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "8", height: "8", children: /* @__PURE__ */ jsx3("path", { d: "M8 5v14l11-7z" }) }),
|
|
1279
|
+
/* @__PURE__ */ jsx3("span", { children: "H3" })
|
|
1280
|
+
] }),
|
|
1281
|
+
quote: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z" }) }),
|
|
1282
|
+
codeBlock: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" }) }),
|
|
1283
|
+
toggleList: /* @__PURE__ */ jsxs3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
|
|
1284
|
+
/* @__PURE__ */ jsx3("path", { d: "M10 6h10v2H10zM10 11h10v2H10zM10 16h10v2H10z" }),
|
|
1285
|
+
/* @__PURE__ */ jsx3(
|
|
1286
|
+
"path",
|
|
1287
|
+
{
|
|
1288
|
+
d: "M4 8l4 4-4 4",
|
|
1289
|
+
stroke: "currentColor",
|
|
1290
|
+
strokeWidth: "2",
|
|
1291
|
+
fill: "none",
|
|
1292
|
+
strokeLinecap: "round",
|
|
1293
|
+
strokeLinejoin: "round"
|
|
1294
|
+
}
|
|
1295
|
+
)
|
|
1296
|
+
] }),
|
|
1297
|
+
bulletList: /* @__PURE__ */ jsxs3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
|
|
1298
|
+
/* @__PURE__ */ jsx3("circle", { cx: "4", cy: "6", r: "1.5" }),
|
|
1299
|
+
/* @__PURE__ */ jsx3("circle", { cx: "4", cy: "12", r: "1.5" }),
|
|
1300
|
+
/* @__PURE__ */ jsx3("circle", { cx: "4", cy: "18", r: "1.5" }),
|
|
1301
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 5h12v2H8zM8 11h12v2H8zM8 17h12v2H8z" })
|
|
1302
|
+
] }),
|
|
1303
|
+
numberedList: /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx3("path", { d: "M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" }) }),
|
|
1304
|
+
checkList: /* @__PURE__ */ jsxs3("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: [
|
|
1305
|
+
/* @__PURE__ */ jsx3(
|
|
1306
|
+
"rect",
|
|
1307
|
+
{
|
|
1308
|
+
x: "3",
|
|
1309
|
+
y: "4",
|
|
1310
|
+
width: "6",
|
|
1311
|
+
height: "6",
|
|
1312
|
+
rx: "1",
|
|
1313
|
+
fill: "none",
|
|
1314
|
+
stroke: "currentColor",
|
|
1315
|
+
strokeWidth: "1.5"
|
|
1316
|
+
}
|
|
1317
|
+
),
|
|
1318
|
+
/* @__PURE__ */ jsx3(
|
|
1319
|
+
"path",
|
|
1320
|
+
{
|
|
1321
|
+
d: "M4.5 7l1.5 1.5 3-3",
|
|
1322
|
+
stroke: "currentColor",
|
|
1323
|
+
strokeWidth: "1.5",
|
|
1324
|
+
fill: "none",
|
|
1325
|
+
strokeLinecap: "round",
|
|
1326
|
+
strokeLinejoin: "round"
|
|
1327
|
+
}
|
|
1328
|
+
),
|
|
1329
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 6h8v2h-8z" }),
|
|
1330
|
+
/* @__PURE__ */ jsx3(
|
|
1331
|
+
"rect",
|
|
1332
|
+
{
|
|
1333
|
+
x: "3",
|
|
1334
|
+
y: "14",
|
|
1335
|
+
width: "6",
|
|
1336
|
+
height: "6",
|
|
1337
|
+
rx: "1",
|
|
1338
|
+
fill: "none",
|
|
1339
|
+
stroke: "currentColor",
|
|
1340
|
+
strokeWidth: "1.5"
|
|
1341
|
+
}
|
|
1342
|
+
),
|
|
1343
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 16h8v2h-8z" })
|
|
1344
|
+
] })
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
// src/components/FloatingMenu/components/ToolbarDivider.tsx
|
|
1348
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1349
|
+
var ToolbarDivider = () => /* @__PURE__ */ jsx4("div", { className: "lumir-toolbar-divider" });
|
|
1350
|
+
|
|
1351
|
+
// src/components/FloatingMenu/components/UndoRedoButtons.tsx
|
|
1352
|
+
import { useCallback as useCallback3 } from "react";
|
|
1353
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1354
|
+
var UndoRedoButtons = ({ editor }) => {
|
|
1355
|
+
const handleUndo = useCallback3(() => {
|
|
1356
|
+
try {
|
|
1357
|
+
editor?.undo?.();
|
|
1358
|
+
} catch (err) {
|
|
1359
|
+
console.error("Undo failed:", err);
|
|
1360
|
+
}
|
|
1361
|
+
}, [editor]);
|
|
1362
|
+
const handleRedo = useCallback3(() => {
|
|
1363
|
+
try {
|
|
1364
|
+
editor?.redo?.();
|
|
1365
|
+
} catch (err) {
|
|
1366
|
+
console.error("Redo failed:", err);
|
|
1367
|
+
}
|
|
1368
|
+
}, [editor]);
|
|
1369
|
+
const handleMouseDown = useCallback3((e) => {
|
|
1370
|
+
e.preventDefault();
|
|
1371
|
+
}, []);
|
|
1372
|
+
return /* @__PURE__ */ jsxs4("div", { className: "lumir-toolbar-group", children: [
|
|
1373
|
+
/* @__PURE__ */ jsx5(
|
|
1374
|
+
"button",
|
|
1375
|
+
{
|
|
1376
|
+
className: "lumir-toolbar-btn",
|
|
1377
|
+
onClick: handleUndo,
|
|
1378
|
+
onMouseDown: handleMouseDown,
|
|
1379
|
+
title: "\uC2E4\uD589 \uCDE8\uC18C",
|
|
1380
|
+
type: "button",
|
|
1381
|
+
children: Icons.undo
|
|
1382
|
+
}
|
|
1383
|
+
),
|
|
1384
|
+
/* @__PURE__ */ jsx5(
|
|
1385
|
+
"button",
|
|
1386
|
+
{
|
|
1387
|
+
className: "lumir-toolbar-btn",
|
|
1388
|
+
onClick: handleRedo,
|
|
1389
|
+
onMouseDown: handleMouseDown,
|
|
1390
|
+
title: "\uB2E4\uC2DC \uC2E4\uD589",
|
|
1391
|
+
type: "button",
|
|
1392
|
+
children: Icons.redo
|
|
1393
|
+
}
|
|
1394
|
+
)
|
|
1395
|
+
] });
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1398
|
+
// src/components/FloatingMenu/components/TextStyleButton.tsx
|
|
1399
|
+
import { useCallback as useCallback4 } from "react";
|
|
1400
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1401
|
+
var iconMap = {
|
|
1402
|
+
bold: Icons.bold,
|
|
1403
|
+
italic: Icons.italic,
|
|
1404
|
+
underline: Icons.underline,
|
|
1405
|
+
strike: Icons.strikethrough
|
|
1406
|
+
};
|
|
1407
|
+
var titleMap = {
|
|
1408
|
+
bold: "\uAD75\uAC8C",
|
|
1409
|
+
italic: "\uAE30\uC6B8\uC784",
|
|
1410
|
+
underline: "\uBC11\uC904",
|
|
1411
|
+
strike: "\uCDE8\uC18C\uC120"
|
|
1412
|
+
};
|
|
1413
|
+
var TextStyleButton = ({
|
|
1414
|
+
editor,
|
|
1415
|
+
style
|
|
1416
|
+
}) => {
|
|
1417
|
+
const getIsActive = () => {
|
|
1418
|
+
try {
|
|
1419
|
+
const activeStyles = editor?.getActiveStyles?.() || {};
|
|
1420
|
+
return activeStyles[style] === true;
|
|
1421
|
+
} catch {
|
|
1422
|
+
return false;
|
|
1423
|
+
}
|
|
1424
|
+
};
|
|
1425
|
+
const isActive = getIsActive();
|
|
1426
|
+
const handleClick = useCallback4(() => {
|
|
1427
|
+
try {
|
|
1428
|
+
editor?.toggleStyles?.({ [style]: true });
|
|
1429
|
+
} catch (err) {
|
|
1430
|
+
console.error(`Toggle ${style} failed:`, err);
|
|
1431
|
+
}
|
|
1432
|
+
}, [editor, style]);
|
|
1433
|
+
const handleMouseDown = useCallback4((e) => {
|
|
1434
|
+
e.preventDefault();
|
|
1435
|
+
}, []);
|
|
1436
|
+
return /* @__PURE__ */ jsx6(
|
|
1437
|
+
"button",
|
|
1438
|
+
{
|
|
1439
|
+
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
1440
|
+
onClick: handleClick,
|
|
1441
|
+
onMouseDown: handleMouseDown,
|
|
1442
|
+
title: titleMap[style],
|
|
1443
|
+
type: "button",
|
|
1444
|
+
children: iconMap[style]
|
|
1445
|
+
}
|
|
1446
|
+
);
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1449
|
+
// src/components/FloatingMenu/components/AlignButton.tsx
|
|
1450
|
+
import { useCallback as useCallback5 } from "react";
|
|
1451
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1452
|
+
var iconMap2 = {
|
|
1453
|
+
left: Icons.alignLeft,
|
|
1454
|
+
center: Icons.alignCenter,
|
|
1455
|
+
right: Icons.alignRight
|
|
1456
|
+
};
|
|
1457
|
+
var titleMap2 = {
|
|
1458
|
+
left: "\uC67C\uCABD \uC815\uB82C",
|
|
1459
|
+
center: "\uAC00\uC6B4\uB370 \uC815\uB82C",
|
|
1460
|
+
right: "\uC624\uB978\uCABD \uC815\uB82C"
|
|
1461
|
+
};
|
|
1462
|
+
var AlignButton = ({
|
|
1463
|
+
editor,
|
|
1464
|
+
alignment
|
|
1465
|
+
}) => {
|
|
1466
|
+
const getCurrentAlignment = () => {
|
|
1467
|
+
try {
|
|
1468
|
+
const block = editor?.getTextCursorPosition()?.block;
|
|
1469
|
+
return block?.props?.textAlignment || "left";
|
|
1470
|
+
} catch {
|
|
1471
|
+
return "left";
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
const isActive = getCurrentAlignment() === alignment;
|
|
1475
|
+
const handleClick = useCallback5(() => {
|
|
1476
|
+
try {
|
|
1477
|
+
const block = editor?.getTextCursorPosition()?.block;
|
|
1478
|
+
if (block && editor?.updateBlock) {
|
|
1479
|
+
editor.updateBlock(block, { props: { textAlignment: alignment } });
|
|
1480
|
+
}
|
|
1481
|
+
} catch (err) {
|
|
1482
|
+
console.error(`Set alignment ${alignment} failed:`, err);
|
|
1483
|
+
}
|
|
1484
|
+
}, [editor, alignment]);
|
|
1485
|
+
const handleMouseDown = useCallback5((e) => {
|
|
1486
|
+
e.preventDefault();
|
|
1487
|
+
}, []);
|
|
1488
|
+
return /* @__PURE__ */ jsx7(
|
|
1489
|
+
"button",
|
|
1490
|
+
{
|
|
1491
|
+
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
1492
|
+
onClick: handleClick,
|
|
1493
|
+
onMouseDown: handleMouseDown,
|
|
1494
|
+
title: titleMap2[alignment],
|
|
1495
|
+
type: "button",
|
|
1496
|
+
children: iconMap2[alignment]
|
|
1497
|
+
}
|
|
1498
|
+
);
|
|
1499
|
+
};
|
|
1500
|
+
|
|
1501
|
+
// src/components/FloatingMenu/components/ListButton.tsx
|
|
1502
|
+
import { useCallback as useCallback6 } from "react";
|
|
1503
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1504
|
+
var iconMap3 = {
|
|
1505
|
+
bullet: Icons.bulletList,
|
|
1506
|
+
numbered: Icons.numberedList
|
|
1507
|
+
};
|
|
1508
|
+
var titleMap3 = {
|
|
1509
|
+
bullet: "\uAE00\uBA38\uB9AC \uAE30\uD638 \uBAA9\uB85D",
|
|
1510
|
+
numbered: "\uBC88\uD638 \uBAA9\uB85D"
|
|
1511
|
+
};
|
|
1512
|
+
var ListButton = ({ editor, type }) => {
|
|
1513
|
+
const getIsActive = () => {
|
|
1514
|
+
try {
|
|
1515
|
+
const block = editor?.getTextCursorPosition()?.block;
|
|
1516
|
+
const blockType = type === "bullet" ? "bulletListItem" : "numberedListItem";
|
|
1517
|
+
return block?.type === blockType;
|
|
1518
|
+
} catch {
|
|
1519
|
+
return false;
|
|
1520
|
+
}
|
|
1521
|
+
};
|
|
1522
|
+
const isActive = getIsActive();
|
|
1523
|
+
const handleClick = useCallback6(() => {
|
|
1524
|
+
try {
|
|
1525
|
+
const block = editor?.getTextCursorPosition()?.block;
|
|
1526
|
+
if (block && editor?.updateBlock) {
|
|
1527
|
+
const targetType = type === "bullet" ? "bulletListItem" : "numberedListItem";
|
|
1528
|
+
const newType = block.type === targetType ? "paragraph" : targetType;
|
|
1529
|
+
editor.updateBlock(block, { type: newType });
|
|
1530
|
+
}
|
|
1531
|
+
} catch (err) {
|
|
1532
|
+
console.error(`List toggle failed:`, err);
|
|
1533
|
+
}
|
|
1534
|
+
}, [editor, type]);
|
|
1535
|
+
const handleMouseDown = useCallback6((e) => {
|
|
1536
|
+
e.preventDefault();
|
|
1537
|
+
}, []);
|
|
1538
|
+
return /* @__PURE__ */ jsx8(
|
|
1539
|
+
"button",
|
|
1540
|
+
{
|
|
1541
|
+
className: cn("lumir-toolbar-btn", isActive && "is-active"),
|
|
1542
|
+
onClick: handleClick,
|
|
1543
|
+
onMouseDown: handleMouseDown,
|
|
1544
|
+
title: titleMap3[type],
|
|
1545
|
+
type: "button",
|
|
1546
|
+
children: iconMap3[type]
|
|
1547
|
+
}
|
|
1548
|
+
);
|
|
1549
|
+
};
|
|
1550
|
+
|
|
1551
|
+
// src/components/FloatingMenu/components/ImageButton.tsx
|
|
1552
|
+
import { useCallback as useCallback7 } from "react";
|
|
1553
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1554
|
+
var ImageButton = ({
|
|
1555
|
+
editor,
|
|
1556
|
+
onImageUpload
|
|
1557
|
+
}) => {
|
|
1558
|
+
const handleClick = useCallback7(() => {
|
|
1559
|
+
if (onImageUpload) {
|
|
1560
|
+
onImageUpload();
|
|
1561
|
+
} else {
|
|
1562
|
+
const input = document.createElement("input");
|
|
1563
|
+
input.type = "file";
|
|
1564
|
+
input.accept = "image/*";
|
|
1565
|
+
input.onchange = async (e) => {
|
|
1566
|
+
const file = e.target.files?.[0];
|
|
1567
|
+
if (file && editor?.uploadFile) {
|
|
1568
|
+
try {
|
|
1569
|
+
const url = await editor.uploadFile(file);
|
|
1570
|
+
editor.insertBlocks(
|
|
1571
|
+
[{ type: "image", props: { url } }],
|
|
1572
|
+
editor.getTextCursorPosition().block,
|
|
1573
|
+
"after"
|
|
1574
|
+
);
|
|
1575
|
+
} catch (err) {
|
|
1576
|
+
console.error("Image upload failed:", err);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
};
|
|
1580
|
+
input.click();
|
|
1581
|
+
}
|
|
1582
|
+
}, [editor, onImageUpload]);
|
|
1583
|
+
const handleMouseDown = useCallback7((e) => {
|
|
1584
|
+
e.preventDefault();
|
|
1585
|
+
}, []);
|
|
1586
|
+
return /* @__PURE__ */ jsx9(
|
|
1587
|
+
"button",
|
|
1588
|
+
{
|
|
1589
|
+
className: "lumir-toolbar-btn",
|
|
1590
|
+
onClick: handleClick,
|
|
1591
|
+
onMouseDown: handleMouseDown,
|
|
1592
|
+
title: "\uC774\uBBF8\uC9C0 \uC0BD\uC785",
|
|
1593
|
+
type: "button",
|
|
1594
|
+
children: Icons.image
|
|
1595
|
+
}
|
|
1596
|
+
);
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
// src/components/FloatingMenu/components/ColorButton.tsx
|
|
1600
|
+
import { useState as useState3, useEffect as useEffect3, useRef as useRef3, useCallback as useCallback8 } from "react";
|
|
1601
|
+
|
|
1602
|
+
// src/constants/colors.ts
|
|
1603
|
+
var TEXT_COLORS = [
|
|
1604
|
+
{ name: "\uAE30\uBCF8", value: "default", hex: "#3f3f3f" },
|
|
1605
|
+
{ name: "\uD68C\uC0C9", value: "gray", hex: "#9b9a97" },
|
|
1606
|
+
{ name: "\uAC08\uC0C9", value: "brown", hex: "#64473a" },
|
|
1607
|
+
{ name: "\uBE68\uAC04\uC0C9", value: "red", hex: "#e03e3e" },
|
|
1608
|
+
{ name: "\uC8FC\uD669\uC0C9", value: "orange", hex: "#d9730d" },
|
|
1609
|
+
{ name: "\uB178\uB780\uC0C9", value: "yellow", hex: "#dfab01" },
|
|
1610
|
+
{ name: "\uCD08\uB85D\uC0C9", value: "green", hex: "#4d6461" },
|
|
1611
|
+
{ name: "\uD30C\uB780\uC0C9", value: "blue", hex: "#0b6e99" },
|
|
1612
|
+
{ name: "\uBCF4\uB77C\uC0C9", value: "purple", hex: "#6940a5" },
|
|
1613
|
+
{ name: "\uBD84\uD64D\uC0C9", value: "pink", hex: "#ad1a72" }
|
|
1614
|
+
];
|
|
1615
|
+
var BACKGROUND_COLORS = [
|
|
1616
|
+
{ name: "\uAE30\uBCF8", value: "default", hex: "transparent" },
|
|
1617
|
+
{ name: "\uD68C\uC0C9", value: "gray", hex: "#ebeced" },
|
|
1618
|
+
{ name: "\uAC08\uC0C9", value: "brown", hex: "#e9e5e3" },
|
|
1619
|
+
{ name: "\uBE68\uAC04\uC0C9", value: "red", hex: "#fbe4e4" },
|
|
1620
|
+
{ name: "\uC8FC\uD669\uC0C9", value: "orange", hex: "#f6e9d9" },
|
|
1621
|
+
{ name: "\uB178\uB780\uC0C9", value: "yellow", hex: "#fbf3db" },
|
|
1622
|
+
{ name: "\uCD08\uB85D\uC0C9", value: "green", hex: "#ddedea" },
|
|
1623
|
+
{ name: "\uD30C\uB780\uC0C9", value: "blue", hex: "#ddebf1" },
|
|
1624
|
+
{ name: "\uBCF4\uB77C\uC0C9", value: "purple", hex: "#eae4f2" },
|
|
1625
|
+
{ name: "\uBD84\uD64D\uC0C9", value: "pink", hex: "#f4dfeb" }
|
|
1626
|
+
];
|
|
1627
|
+
var getHexFromColorValue = (value, type) => {
|
|
1628
|
+
const colors = type === "text" ? TEXT_COLORS : BACKGROUND_COLORS;
|
|
1629
|
+
const colorItem = colors.find((c) => c.value === value);
|
|
1630
|
+
return colorItem?.hex || (type === "text" ? "#000000" : "transparent");
|
|
1631
|
+
};
|
|
1632
|
+
|
|
1633
|
+
// src/components/FloatingMenu/components/ColorButton.tsx
|
|
1634
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1635
|
+
var ColorButton = ({ editor, type }) => {
|
|
1636
|
+
const [isOpen, setIsOpen] = useState3(false);
|
|
1637
|
+
const [currentColor, setCurrentColor] = useState3("default");
|
|
1638
|
+
const dropdownRef = useRef3(null);
|
|
1639
|
+
const colors = type === "text" ? TEXT_COLORS : BACKGROUND_COLORS;
|
|
1640
|
+
const getCurrentColor = useCallback8(() => {
|
|
1641
|
+
try {
|
|
1642
|
+
const activeStyles = editor?.getActiveStyles?.() || {};
|
|
1643
|
+
if (type === "text" && activeStyles.textColor) {
|
|
1644
|
+
return activeStyles.textColor;
|
|
1645
|
+
} else if (type === "background" && activeStyles.backgroundColor) {
|
|
1646
|
+
return activeStyles.backgroundColor;
|
|
1647
|
+
}
|
|
1648
|
+
} catch {
|
|
1649
|
+
}
|
|
1650
|
+
return "default";
|
|
1651
|
+
}, [editor, type]);
|
|
1652
|
+
useEffect3(() => {
|
|
1653
|
+
if (isOpen) {
|
|
1654
|
+
const color = getCurrentColor();
|
|
1655
|
+
setCurrentColor(color);
|
|
1656
|
+
}
|
|
1657
|
+
}, [isOpen, getCurrentColor]);
|
|
1658
|
+
useEffect3(() => {
|
|
1659
|
+
const handleClickOutside = (e) => {
|
|
1660
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1661
|
+
setIsOpen(false);
|
|
1662
|
+
}
|
|
1663
|
+
};
|
|
1664
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1665
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1666
|
+
}, []);
|
|
1667
|
+
const handleColorSelect = useCallback8(
|
|
1668
|
+
(color) => {
|
|
1669
|
+
try {
|
|
1670
|
+
if (!editor) return;
|
|
1671
|
+
if (type === "text") {
|
|
1672
|
+
editor.toggleStyles({ textColor: color });
|
|
1673
|
+
} else {
|
|
1674
|
+
editor.toggleStyles({ backgroundColor: color });
|
|
1675
|
+
}
|
|
1676
|
+
setCurrentColor(color);
|
|
1677
|
+
setIsOpen(false);
|
|
1678
|
+
} catch (err) {
|
|
1679
|
+
console.error(`Color apply failed:`, err);
|
|
1680
|
+
}
|
|
1681
|
+
},
|
|
1682
|
+
[editor, type]
|
|
1683
|
+
);
|
|
1684
|
+
const handleMouseDown = useCallback8((e) => {
|
|
1685
|
+
e.preventDefault();
|
|
1686
|
+
}, []);
|
|
1687
|
+
return /* @__PURE__ */ jsxs5("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
1688
|
+
/* @__PURE__ */ jsxs5(
|
|
1689
|
+
"button",
|
|
1690
|
+
{
|
|
1691
|
+
className: "lumir-toolbar-btn lumir-color-btn",
|
|
1692
|
+
onClick: () => setIsOpen(!isOpen),
|
|
1693
|
+
onMouseDown: handleMouseDown,
|
|
1694
|
+
title: type === "text" ? "\uD14D\uC2A4\uD2B8 \uC0C9\uC0C1" : "\uBC30\uACBD \uC0C9\uC0C1",
|
|
1695
|
+
type: "button",
|
|
1696
|
+
children: [
|
|
1697
|
+
type === "text" ? Icons.textColor : Icons.bgColor,
|
|
1698
|
+
/* @__PURE__ */ jsx10(
|
|
1699
|
+
"span",
|
|
1700
|
+
{
|
|
1701
|
+
className: "lumir-color-indicator",
|
|
1702
|
+
style: {
|
|
1703
|
+
backgroundColor: getHexFromColorValue(currentColor, type)
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
)
|
|
1707
|
+
]
|
|
1708
|
+
}
|
|
1709
|
+
),
|
|
1710
|
+
isOpen && /* @__PURE__ */ jsx10("div", { className: "lumir-dropdown-menu lumir-color-menu", children: /* @__PURE__ */ jsx10("div", { className: "lumir-color-grid", children: colors.map((color) => /* @__PURE__ */ jsx10(
|
|
1711
|
+
"button",
|
|
1712
|
+
{
|
|
1713
|
+
className: cn(
|
|
1714
|
+
"lumir-color-swatch",
|
|
1715
|
+
currentColor === color.value && "is-active"
|
|
1716
|
+
),
|
|
1717
|
+
onClick: () => handleColorSelect(color.value),
|
|
1718
|
+
onMouseDown: handleMouseDown,
|
|
1719
|
+
title: color.name,
|
|
1720
|
+
style: { backgroundColor: color.hex },
|
|
1721
|
+
type: "button"
|
|
1722
|
+
},
|
|
1723
|
+
color.value
|
|
1724
|
+
)) }) })
|
|
1725
|
+
] });
|
|
1726
|
+
};
|
|
1727
|
+
|
|
1728
|
+
// src/components/FloatingMenu/components/LinkButton.tsx
|
|
1729
|
+
import { useState as useState4, useEffect as useEffect4, useRef as useRef4, useCallback as useCallback9 } from "react";
|
|
1730
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1731
|
+
var isDangerousProtocol = (url) => {
|
|
1732
|
+
const trimmedUrl = url.trim().toLowerCase();
|
|
1733
|
+
const dangerousPatterns = [
|
|
1734
|
+
/^javascript:/i,
|
|
1735
|
+
/^data:/i,
|
|
1736
|
+
/^vbscript:/i,
|
|
1737
|
+
/^file:/i
|
|
1738
|
+
];
|
|
1739
|
+
return dangerousPatterns.some((pattern) => pattern.test(trimmedUrl));
|
|
1740
|
+
};
|
|
1741
|
+
var normalizeUrl = (url) => {
|
|
1742
|
+
const trimmedUrl = url.trim();
|
|
1743
|
+
if (isDangerousProtocol(trimmedUrl)) {
|
|
1744
|
+
console.warn("Blocked dangerous URL protocol:", trimmedUrl);
|
|
1745
|
+
return null;
|
|
1746
|
+
}
|
|
1747
|
+
if (/^https?:\/\//i.test(trimmedUrl)) {
|
|
1748
|
+
return trimmedUrl;
|
|
1749
|
+
}
|
|
1750
|
+
if (/^(mailto:|tel:)/i.test(trimmedUrl)) {
|
|
1751
|
+
return trimmedUrl;
|
|
1752
|
+
}
|
|
1753
|
+
return `https://${trimmedUrl}`;
|
|
1754
|
+
};
|
|
1755
|
+
var LinkButton = ({ editor }) => {
|
|
1756
|
+
const [isOpen, setIsOpen] = useState4(false);
|
|
1757
|
+
const [linkUrl, setLinkUrl] = useState4("");
|
|
1758
|
+
const [errorMsg, setErrorMsg] = useState4(null);
|
|
1759
|
+
const dropdownRef = useRef4(null);
|
|
1760
|
+
const inputRef = useRef4(null);
|
|
1761
|
+
const hasSelectionRef = useRef4(false);
|
|
1762
|
+
useEffect4(() => {
|
|
1763
|
+
const handleClickOutside = (e) => {
|
|
1764
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1765
|
+
setIsOpen(false);
|
|
1766
|
+
setLinkUrl("");
|
|
1767
|
+
setErrorMsg(null);
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1771
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1772
|
+
}, []);
|
|
1773
|
+
useEffect4(() => {
|
|
1774
|
+
if (isOpen && inputRef.current) {
|
|
1775
|
+
try {
|
|
1776
|
+
const selectedText = editor?.getSelectedText?.() || "";
|
|
1777
|
+
hasSelectionRef.current = selectedText.length > 0;
|
|
1778
|
+
} catch {
|
|
1779
|
+
hasSelectionRef.current = false;
|
|
1780
|
+
}
|
|
1781
|
+
setTimeout(() => inputRef.current?.focus(), 0);
|
|
1782
|
+
}
|
|
1783
|
+
}, [isOpen, editor]);
|
|
1784
|
+
const handleSubmit = useCallback9(
|
|
1785
|
+
(e) => {
|
|
1786
|
+
e?.preventDefault();
|
|
1787
|
+
setErrorMsg(null);
|
|
1788
|
+
try {
|
|
1789
|
+
if (linkUrl.trim() && editor?.createLink) {
|
|
1790
|
+
const normalizedUrl = normalizeUrl(linkUrl);
|
|
1791
|
+
if (normalizedUrl === null) {
|
|
1792
|
+
setErrorMsg("\uD5C8\uC6A9\uB418\uC9C0 \uC54A\uB294 URL \uD615\uC2DD\uC785\uB2C8\uB2E4.");
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1795
|
+
editor.focus();
|
|
1796
|
+
if (hasSelectionRef.current) {
|
|
1797
|
+
editor.createLink(normalizedUrl);
|
|
1798
|
+
} else {
|
|
1799
|
+
editor.createLink(normalizedUrl, normalizedUrl);
|
|
1800
|
+
}
|
|
1801
|
+
setIsOpen(false);
|
|
1802
|
+
setLinkUrl("");
|
|
1803
|
+
}
|
|
1804
|
+
} catch (err) {
|
|
1805
|
+
console.error("Create link failed:", err);
|
|
1806
|
+
setErrorMsg("\uB9C1\uD06C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
|
|
1807
|
+
}
|
|
1808
|
+
},
|
|
1809
|
+
[editor, linkUrl]
|
|
1810
|
+
);
|
|
1811
|
+
const handleCancel = useCallback9(() => {
|
|
1812
|
+
setIsOpen(false);
|
|
1813
|
+
setLinkUrl("");
|
|
1814
|
+
setErrorMsg(null);
|
|
1815
|
+
}, []);
|
|
1816
|
+
const handleMouseDown = useCallback9((e) => {
|
|
1817
|
+
e.preventDefault();
|
|
1818
|
+
}, []);
|
|
1819
|
+
const handleKeyDown = useCallback9(
|
|
1820
|
+
(e) => {
|
|
1821
|
+
if (e.key === "Enter") {
|
|
1822
|
+
handleSubmit();
|
|
1823
|
+
} else if (e.key === "Escape") {
|
|
1824
|
+
handleCancel();
|
|
1825
|
+
}
|
|
1826
|
+
},
|
|
1827
|
+
[handleSubmit, handleCancel]
|
|
1828
|
+
);
|
|
1829
|
+
return /* @__PURE__ */ jsxs6("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
1830
|
+
/* @__PURE__ */ jsx11(
|
|
1831
|
+
"button",
|
|
1832
|
+
{
|
|
1833
|
+
className: "lumir-toolbar-btn",
|
|
1834
|
+
onClick: () => setIsOpen(!isOpen),
|
|
1835
|
+
onMouseDown: handleMouseDown,
|
|
1836
|
+
title: "\uB9C1\uD06C \uC0BD\uC785",
|
|
1837
|
+
type: "button",
|
|
1838
|
+
children: Icons.link
|
|
1839
|
+
}
|
|
1840
|
+
),
|
|
1841
|
+
isOpen && /* @__PURE__ */ jsx11("div", { className: "lumir-dropdown-menu lumir-link-menu", children: /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className: "lumir-link-form", children: [
|
|
1842
|
+
/* @__PURE__ */ jsx11(
|
|
1843
|
+
"input",
|
|
1844
|
+
{
|
|
1845
|
+
ref: inputRef,
|
|
1846
|
+
type: "text",
|
|
1847
|
+
className: "lumir-link-input",
|
|
1848
|
+
placeholder: "\uB9C1\uD06C URL\uC744 \uC785\uB825\uD558\uC138\uC694",
|
|
1849
|
+
value: linkUrl,
|
|
1850
|
+
onChange: (e) => {
|
|
1851
|
+
setLinkUrl(e.target.value);
|
|
1852
|
+
setErrorMsg(null);
|
|
1853
|
+
},
|
|
1854
|
+
onKeyDown: handleKeyDown,
|
|
1855
|
+
onMouseDown: handleMouseDown
|
|
1856
|
+
}
|
|
1857
|
+
),
|
|
1858
|
+
errorMsg && /* @__PURE__ */ jsx11(
|
|
1859
|
+
"div",
|
|
1860
|
+
{
|
|
1861
|
+
style: {
|
|
1862
|
+
color: "#dc3545",
|
|
1863
|
+
fontSize: "12px",
|
|
1864
|
+
marginTop: "4px",
|
|
1865
|
+
padding: "0 4px"
|
|
1866
|
+
},
|
|
1867
|
+
children: errorMsg
|
|
1868
|
+
}
|
|
1869
|
+
),
|
|
1870
|
+
/* @__PURE__ */ jsxs6("div", { className: "lumir-link-actions", children: [
|
|
1871
|
+
/* @__PURE__ */ jsx11(
|
|
1872
|
+
"button",
|
|
1873
|
+
{
|
|
1874
|
+
type: "button",
|
|
1875
|
+
className: "lumir-link-btn lumir-link-cancel",
|
|
1876
|
+
onClick: handleCancel,
|
|
1877
|
+
onMouseDown: handleMouseDown,
|
|
1878
|
+
children: "\uCDE8\uC18C"
|
|
1879
|
+
}
|
|
1880
|
+
),
|
|
1881
|
+
/* @__PURE__ */ jsx11(
|
|
1882
|
+
"button",
|
|
1883
|
+
{
|
|
1884
|
+
type: "submit",
|
|
1885
|
+
className: "lumir-link-btn lumir-link-submit",
|
|
1886
|
+
onMouseDown: handleMouseDown,
|
|
1887
|
+
disabled: !linkUrl.trim(),
|
|
1888
|
+
children: "\uD655\uC778"
|
|
1889
|
+
}
|
|
1890
|
+
)
|
|
1891
|
+
] })
|
|
1892
|
+
] }) })
|
|
1893
|
+
] });
|
|
1894
|
+
};
|
|
1895
|
+
|
|
1896
|
+
// src/components/FloatingMenu/components/TableButton.tsx
|
|
1897
|
+
import { useCallback as useCallback10 } from "react";
|
|
1898
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1899
|
+
var TableButton = ({ editor }) => {
|
|
1900
|
+
const handleClick = useCallback10(() => {
|
|
1901
|
+
try {
|
|
1902
|
+
const block = editor?.getTextCursorPosition()?.block;
|
|
1903
|
+
if (!block || !editor?.insertBlocks) return;
|
|
1904
|
+
const defaultCell = [{ type: "text", text: "", styles: {} }];
|
|
1905
|
+
const tableContent = {
|
|
1906
|
+
type: "tableContent",
|
|
1907
|
+
rows: [
|
|
1908
|
+
{ cells: [defaultCell, defaultCell, defaultCell] },
|
|
1909
|
+
{ cells: [defaultCell, defaultCell, defaultCell] },
|
|
1910
|
+
{ cells: [defaultCell, defaultCell, defaultCell] }
|
|
1911
|
+
]
|
|
1912
|
+
};
|
|
1913
|
+
editor.insertBlocks(
|
|
1914
|
+
[{ type: "table", content: tableContent }],
|
|
1915
|
+
block,
|
|
1916
|
+
"after"
|
|
1917
|
+
);
|
|
1918
|
+
} catch (err) {
|
|
1919
|
+
console.error("Table insert failed:", err);
|
|
1920
|
+
}
|
|
1921
|
+
}, [editor]);
|
|
1922
|
+
const handleMouseDown = useCallback10((e) => {
|
|
1923
|
+
e.preventDefault();
|
|
1924
|
+
}, []);
|
|
1925
|
+
return /* @__PURE__ */ jsx12(
|
|
1926
|
+
"button",
|
|
1927
|
+
{
|
|
1928
|
+
className: "lumir-toolbar-btn",
|
|
1929
|
+
onClick: handleClick,
|
|
1930
|
+
onMouseDown: handleMouseDown,
|
|
1931
|
+
title: "\uD14C\uC774\uBE14 \uC0BD\uC785",
|
|
1932
|
+
type: "button",
|
|
1933
|
+
children: Icons.table
|
|
1934
|
+
}
|
|
1935
|
+
);
|
|
1936
|
+
};
|
|
1937
|
+
|
|
1938
|
+
// src/components/FloatingMenu/components/HTMLImportButton.tsx
|
|
1939
|
+
import { useCallback as useCallback11, useRef as useRef5 } from "react";
|
|
1940
|
+
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1941
|
+
var HTMLImportButton = ({
|
|
1942
|
+
editor
|
|
1943
|
+
}) => {
|
|
1944
|
+
const fileInputRef = useRef5(null);
|
|
1945
|
+
const handleFileUpload = useCallback11(
|
|
1946
|
+
(e) => {
|
|
1947
|
+
const file = e.target.files?.[0];
|
|
1948
|
+
if (!file) return;
|
|
1949
|
+
const reader = new FileReader();
|
|
1950
|
+
reader.onload = (event) => {
|
|
1951
|
+
const content = event.target?.result;
|
|
1952
|
+
try {
|
|
1953
|
+
if (!editor || !content.trim()) return;
|
|
1954
|
+
const block = editor?.getTextCursorPosition()?.block;
|
|
1955
|
+
if (!block || !editor?.insertBlocks) return;
|
|
1956
|
+
editor.insertBlocks(
|
|
1957
|
+
[
|
|
1958
|
+
{
|
|
1959
|
+
type: "htmlPreview",
|
|
1960
|
+
props: {
|
|
1961
|
+
htmlContent: content,
|
|
1962
|
+
fileName: file.name,
|
|
1963
|
+
height: "400px"
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
],
|
|
1967
|
+
block,
|
|
1968
|
+
"after"
|
|
1969
|
+
);
|
|
1970
|
+
if (fileInputRef.current) {
|
|
1971
|
+
fileInputRef.current.value = "";
|
|
1972
|
+
}
|
|
1973
|
+
} catch (err) {
|
|
1974
|
+
console.error("HTML insert failed:", err);
|
|
1975
|
+
}
|
|
1976
|
+
};
|
|
1977
|
+
reader.readAsText(file);
|
|
1978
|
+
},
|
|
1979
|
+
[editor]
|
|
1980
|
+
);
|
|
1981
|
+
const handleClick = useCallback11(() => {
|
|
1982
|
+
fileInputRef.current?.click();
|
|
1983
|
+
}, []);
|
|
1984
|
+
const handleMouseDown = useCallback11((e) => {
|
|
1985
|
+
e.preventDefault();
|
|
1986
|
+
}, []);
|
|
1987
|
+
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1988
|
+
/* @__PURE__ */ jsx13(
|
|
1989
|
+
"input",
|
|
1990
|
+
{
|
|
1991
|
+
ref: fileInputRef,
|
|
1992
|
+
type: "file",
|
|
1993
|
+
accept: ".html,.htm",
|
|
1994
|
+
onChange: handleFileUpload,
|
|
1995
|
+
style: { display: "none" }
|
|
1996
|
+
}
|
|
1997
|
+
),
|
|
1998
|
+
/* @__PURE__ */ jsx13(
|
|
1999
|
+
"button",
|
|
2000
|
+
{
|
|
2001
|
+
className: "lumir-toolbar-btn",
|
|
2002
|
+
onClick: handleClick,
|
|
2003
|
+
onMouseDown: handleMouseDown,
|
|
2004
|
+
title: "HTML Import",
|
|
2005
|
+
type: "button",
|
|
2006
|
+
children: Icons.htmlFile
|
|
2007
|
+
}
|
|
2008
|
+
)
|
|
2009
|
+
] });
|
|
2010
|
+
};
|
|
2011
|
+
|
|
2012
|
+
// src/components/FloatingMenu/components/BlockTypeSelect.tsx
|
|
2013
|
+
import { useState as useState5, useEffect as useEffect5, useRef as useRef6, useCallback as useCallback12 } from "react";
|
|
2014
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2015
|
+
var blockTypeCategories = [
|
|
2016
|
+
{
|
|
2017
|
+
category: "Headings",
|
|
2018
|
+
items: [
|
|
2019
|
+
{ type: "heading", label: "Heading 1", level: 1, icon: "h1", isToggle: false },
|
|
2020
|
+
{ type: "heading", label: "Heading 2", level: 2, icon: "h2", isToggle: false },
|
|
2021
|
+
{ type: "heading", label: "Heading 3", level: 3, icon: "h3", isToggle: false },
|
|
2022
|
+
{ type: "heading", label: "Toggle Heading 1", level: 1, icon: "toggleH1", isToggle: true },
|
|
2023
|
+
{ type: "heading", label: "Toggle Heading 2", level: 2, icon: "toggleH2", isToggle: true },
|
|
2024
|
+
{ type: "heading", label: "Toggle Heading 3", level: 3, icon: "toggleH3", isToggle: true }
|
|
2025
|
+
]
|
|
2026
|
+
},
|
|
2027
|
+
{
|
|
2028
|
+
category: "Basic blocks",
|
|
2029
|
+
items: [
|
|
2030
|
+
{ type: "paragraph", label: "Paragraph", icon: "paragraph" },
|
|
2031
|
+
{ type: "quote", label: "Quote", icon: "quote" },
|
|
2032
|
+
{ type: "codeBlock", label: "Code Block", icon: "codeBlock" },
|
|
2033
|
+
{ type: "bulletListItem", label: "Bullet List", icon: "bulletList" },
|
|
2034
|
+
{ type: "numberedListItem", label: "Numbered List", icon: "numberedList" },
|
|
2035
|
+
{ type: "checkListItem", label: "Check List", icon: "checkList" },
|
|
2036
|
+
{ type: "toggleListItem", label: "Toggle List", icon: "toggleList" }
|
|
2037
|
+
]
|
|
2038
|
+
}
|
|
2039
|
+
];
|
|
2040
|
+
var blockTypes = blockTypeCategories.flatMap(
|
|
2041
|
+
(cat) => cat.items
|
|
2042
|
+
);
|
|
2043
|
+
var BlockTypeSelect = ({ editor }) => {
|
|
2044
|
+
const [isOpen, setIsOpen] = useState5(false);
|
|
2045
|
+
const dropdownRef = useRef6(null);
|
|
2046
|
+
const getCurrentBlock = () => {
|
|
2047
|
+
try {
|
|
2048
|
+
return editor?.getTextCursorPosition()?.block;
|
|
2049
|
+
} catch {
|
|
2050
|
+
return null;
|
|
2051
|
+
}
|
|
2052
|
+
};
|
|
2053
|
+
const currentBlock = getCurrentBlock();
|
|
2054
|
+
const currentType = currentBlock?.type || "paragraph";
|
|
2055
|
+
const currentLevel = currentBlock?.props?.level;
|
|
2056
|
+
const isCurrentToggle = currentType === "heading" && currentBlock?.props?.isToggleable === true;
|
|
2057
|
+
useEffect5(() => {
|
|
2058
|
+
const handleClickOutside = (e) => {
|
|
2059
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
2060
|
+
setIsOpen(false);
|
|
2061
|
+
}
|
|
2062
|
+
};
|
|
2063
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2064
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2065
|
+
}, []);
|
|
2066
|
+
const handleTypeChange = (type, level, isToggle) => {
|
|
2067
|
+
try {
|
|
2068
|
+
const block = editor?.getTextCursorPosition()?.block;
|
|
2069
|
+
if (!block || !editor) return;
|
|
2070
|
+
const props = {};
|
|
2071
|
+
if (level) props.level = level;
|
|
2072
|
+
if (type === "heading" && isToggle !== void 0) {
|
|
2073
|
+
props.isToggleable = isToggle;
|
|
2074
|
+
editor.updateBlock(block, {
|
|
2075
|
+
type: "heading",
|
|
2076
|
+
props
|
|
2077
|
+
});
|
|
2078
|
+
} else {
|
|
2079
|
+
editor.updateBlock(block, { type, props });
|
|
2080
|
+
}
|
|
2081
|
+
setIsOpen(false);
|
|
2082
|
+
} catch (err) {
|
|
2083
|
+
console.error("Block type change failed:", err);
|
|
2084
|
+
}
|
|
2085
|
+
};
|
|
2086
|
+
const handleMouseDown = useCallback12((e) => {
|
|
2087
|
+
e.preventDefault();
|
|
2088
|
+
}, []);
|
|
2089
|
+
const getCurrentLabel = () => {
|
|
2090
|
+
if (currentType === "heading" && currentLevel) {
|
|
2091
|
+
const found2 = blockTypes.find(
|
|
2092
|
+
(bt) => bt.type === "heading" && bt.level === currentLevel && bt.isToggle === isCurrentToggle
|
|
2093
|
+
);
|
|
2094
|
+
return found2?.label || "Heading";
|
|
2095
|
+
}
|
|
2096
|
+
const found = blockTypes.find((bt) => bt.type === currentType);
|
|
2097
|
+
return found?.label || "Paragraph";
|
|
2098
|
+
};
|
|
2099
|
+
const getCurrentIcon = () => {
|
|
2100
|
+
if (currentType === "heading" && currentLevel) {
|
|
2101
|
+
const found2 = blockTypes.find(
|
|
2102
|
+
(bt) => bt.type === "heading" && bt.level === currentLevel && bt.isToggle === isCurrentToggle
|
|
2103
|
+
);
|
|
2104
|
+
return found2?.icon || `h${currentLevel}`;
|
|
2105
|
+
}
|
|
2106
|
+
const found = blockTypes.find((bt) => bt.type === currentType);
|
|
2107
|
+
return found?.icon || "paragraph";
|
|
2108
|
+
};
|
|
2109
|
+
const isActiveItem = (bt) => {
|
|
2110
|
+
if (bt.type === "heading" && bt.level) {
|
|
2111
|
+
const isLevelMatch = currentType === "heading" && currentLevel === bt.level;
|
|
2112
|
+
const isToggleMatch = bt.isToggle === isCurrentToggle;
|
|
2113
|
+
return isLevelMatch && isToggleMatch;
|
|
2114
|
+
}
|
|
2115
|
+
return currentType === bt.type;
|
|
2116
|
+
};
|
|
2117
|
+
return /* @__PURE__ */ jsxs8("div", { className: "lumir-dropdown-wrapper", ref: dropdownRef, children: [
|
|
2118
|
+
/* @__PURE__ */ jsxs8(
|
|
2119
|
+
"button",
|
|
2120
|
+
{
|
|
2121
|
+
className: "lumir-dropdown-btn lumir-block-type-btn",
|
|
2122
|
+
onClick: () => setIsOpen(!isOpen),
|
|
2123
|
+
onMouseDown: handleMouseDown,
|
|
2124
|
+
type: "button",
|
|
2125
|
+
children: [
|
|
2126
|
+
/* @__PURE__ */ jsx14("span", { className: "lumir-block-icon", children: BlockTypeIcons[getCurrentIcon()] }),
|
|
2127
|
+
/* @__PURE__ */ jsx14("span", { className: "lumir-block-label", children: getCurrentLabel() }),
|
|
2128
|
+
Icons.expandMore
|
|
2129
|
+
]
|
|
2130
|
+
}
|
|
2131
|
+
),
|
|
2132
|
+
isOpen && /* @__PURE__ */ jsx14("div", { className: "lumir-dropdown-menu lumir-block-menu", children: blockTypeCategories.map((category) => /* @__PURE__ */ jsxs8("div", { className: "lumir-block-category", children: [
|
|
2133
|
+
/* @__PURE__ */ jsx14("div", { className: "lumir-block-category-title", children: category.category }),
|
|
2134
|
+
category.items.map((bt) => /* @__PURE__ */ jsxs8(
|
|
2135
|
+
"button",
|
|
2136
|
+
{
|
|
2137
|
+
className: cn(
|
|
2138
|
+
"lumir-dropdown-item lumir-block-item",
|
|
2139
|
+
isActiveItem(bt) && "is-active"
|
|
2140
|
+
),
|
|
2141
|
+
onClick: () => handleTypeChange(bt.type, bt.level, bt.isToggle),
|
|
2142
|
+
onMouseDown: handleMouseDown,
|
|
2143
|
+
children: [
|
|
2144
|
+
/* @__PURE__ */ jsx14("span", { className: "lumir-block-icon", children: BlockTypeIcons[bt.icon] }),
|
|
2145
|
+
/* @__PURE__ */ jsx14("span", { className: "lumir-block-item-title", children: bt.label })
|
|
2146
|
+
]
|
|
2147
|
+
},
|
|
2148
|
+
bt.icon
|
|
2149
|
+
))
|
|
2150
|
+
] }, category.category)) })
|
|
2151
|
+
] });
|
|
2152
|
+
};
|
|
2153
|
+
|
|
2154
|
+
// src/components/FloatingMenu/index.tsx
|
|
2155
|
+
import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2156
|
+
var COMPACT_BREAKPOINT = 700;
|
|
2157
|
+
var MINIMIZED_BREAKPOINT = 400;
|
|
2158
|
+
var FloatingMenu = ({
|
|
2159
|
+
editor,
|
|
2160
|
+
position = "sticky",
|
|
2161
|
+
className,
|
|
2162
|
+
onImageUpload
|
|
2163
|
+
}) => {
|
|
2164
|
+
const wrapperRef = useRef7(null);
|
|
2165
|
+
const [isCompact, setIsCompact] = useState6(false);
|
|
2166
|
+
const [isMinimizable, setIsMinimizable] = useState6(false);
|
|
2167
|
+
const [isMinimized, setIsMinimized] = useState6(false);
|
|
2168
|
+
const [, setSelectionTick] = useState6(0);
|
|
2169
|
+
useEffect6(() => {
|
|
2170
|
+
if (!editor) return;
|
|
2171
|
+
let debounceTimer = null;
|
|
2172
|
+
const DEBOUNCE_DELAY = 150;
|
|
2173
|
+
const handleSelectionChange = () => {
|
|
2174
|
+
if (debounceTimer) {
|
|
2175
|
+
clearTimeout(debounceTimer);
|
|
2176
|
+
}
|
|
2177
|
+
debounceTimer = setTimeout(() => {
|
|
2178
|
+
setSelectionTick((prev) => prev + 1);
|
|
2179
|
+
}, DEBOUNCE_DELAY);
|
|
2180
|
+
};
|
|
2181
|
+
const unsubscribe = editor.onSelectionChange?.(handleSelectionChange);
|
|
2182
|
+
const unsubscribeContent = editor.onEditorContentChange?.(() => {
|
|
2183
|
+
setSelectionTick((prev) => prev + 1);
|
|
2184
|
+
});
|
|
2185
|
+
return () => {
|
|
2186
|
+
if (debounceTimer) {
|
|
2187
|
+
clearTimeout(debounceTimer);
|
|
2188
|
+
}
|
|
2189
|
+
unsubscribe?.();
|
|
2190
|
+
unsubscribeContent?.();
|
|
2191
|
+
};
|
|
2192
|
+
}, [editor]);
|
|
2193
|
+
useEffect6(() => {
|
|
2194
|
+
const checkWidth = () => {
|
|
2195
|
+
if (wrapperRef.current) {
|
|
2196
|
+
const width = wrapperRef.current.offsetWidth;
|
|
2197
|
+
setIsCompact(width < COMPACT_BREAKPOINT);
|
|
2198
|
+
setIsMinimizable(width < MINIMIZED_BREAKPOINT);
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
checkWidth();
|
|
2202
|
+
const resizeObserver = new ResizeObserver(checkWidth);
|
|
2203
|
+
if (wrapperRef.current) {
|
|
2204
|
+
resizeObserver.observe(wrapperRef.current);
|
|
2205
|
+
}
|
|
2206
|
+
return () => resizeObserver.disconnect();
|
|
2207
|
+
}, []);
|
|
2208
|
+
const MinimizedLayout = () => /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2209
|
+
/* @__PURE__ */ jsx15(
|
|
2210
|
+
"button",
|
|
2211
|
+
{
|
|
2212
|
+
className: "lumir-toolbar-button lumir-toggle-button",
|
|
2213
|
+
onClick: () => setIsMinimized(!isMinimized),
|
|
2214
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
2215
|
+
type: "button",
|
|
2216
|
+
title: isMinimized ? "\uBA54\uB274 \uD3BC\uCE58\uAE30" : "\uBA54\uB274 \uC811\uAE30",
|
|
2217
|
+
children: isMinimized ? Icons.chevronRight : Icons.chevronLeft
|
|
2218
|
+
}
|
|
2219
|
+
),
|
|
2220
|
+
!isMinimized && /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2221
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2222
|
+
/* @__PURE__ */ jsx15(UndoRedoButtons, { editor }),
|
|
2223
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2224
|
+
/* @__PURE__ */ jsx15("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx15(BlockTypeSelect, { editor }) }),
|
|
2225
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2226
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2227
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "bold" }),
|
|
2228
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "italic" }),
|
|
2229
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "underline" }),
|
|
2230
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "strike" })
|
|
2231
|
+
] }),
|
|
2232
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2233
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2234
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "left" }),
|
|
2235
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "center" }),
|
|
2236
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "right" })
|
|
2237
|
+
] }),
|
|
2238
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2239
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2240
|
+
/* @__PURE__ */ jsx15(ListButton, { editor, type: "bullet" }),
|
|
2241
|
+
/* @__PURE__ */ jsx15(ListButton, { editor, type: "numbered" })
|
|
2242
|
+
] }),
|
|
2243
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2244
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2245
|
+
/* @__PURE__ */ jsx15(ColorButton, { editor, type: "text" }),
|
|
2246
|
+
/* @__PURE__ */ jsx15(ColorButton, { editor, type: "background" })
|
|
2247
|
+
] }),
|
|
2248
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2249
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2250
|
+
/* @__PURE__ */ jsx15(ImageButton, { editor, onImageUpload }),
|
|
2251
|
+
/* @__PURE__ */ jsx15(LinkButton, { editor }),
|
|
2252
|
+
/* @__PURE__ */ jsx15(TableButton, { editor }),
|
|
2253
|
+
/* @__PURE__ */ jsx15(HTMLImportButton, { editor })
|
|
2254
|
+
] })
|
|
2255
|
+
] })
|
|
2256
|
+
] });
|
|
2257
|
+
const SingleRowLayout = () => /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2258
|
+
/* @__PURE__ */ jsx15(UndoRedoButtons, { editor }),
|
|
2259
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2260
|
+
/* @__PURE__ */ jsx15("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx15(BlockTypeSelect, { editor }) }),
|
|
2261
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2262
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2263
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "bold" }),
|
|
2264
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "italic" }),
|
|
2265
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "underline" }),
|
|
2266
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "strike" })
|
|
2267
|
+
] }),
|
|
2268
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2269
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2270
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "left" }),
|
|
2271
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "center" }),
|
|
2272
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "right" })
|
|
2273
|
+
] }),
|
|
2274
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2275
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2276
|
+
/* @__PURE__ */ jsx15(ListButton, { editor, type: "bullet" }),
|
|
2277
|
+
/* @__PURE__ */ jsx15(ListButton, { editor, type: "numbered" })
|
|
2278
|
+
] }),
|
|
2279
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2280
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2281
|
+
/* @__PURE__ */ jsx15(ColorButton, { editor, type: "text" }),
|
|
2282
|
+
/* @__PURE__ */ jsx15(ColorButton, { editor, type: "background" })
|
|
2283
|
+
] }),
|
|
2284
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2285
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2286
|
+
/* @__PURE__ */ jsx15(ImageButton, { editor, onImageUpload }),
|
|
2287
|
+
/* @__PURE__ */ jsx15(LinkButton, { editor }),
|
|
2288
|
+
/* @__PURE__ */ jsx15(TableButton, { editor }),
|
|
2289
|
+
/* @__PURE__ */ jsx15(HTMLImportButton, { editor })
|
|
2290
|
+
] })
|
|
2291
|
+
] });
|
|
2292
|
+
const TwoRowLayout = () => /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2293
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-row", children: [
|
|
2294
|
+
/* @__PURE__ */ jsx15(UndoRedoButtons, { editor }),
|
|
2295
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2296
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2297
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "bold" }),
|
|
2298
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "italic" }),
|
|
2299
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "underline" }),
|
|
2300
|
+
/* @__PURE__ */ jsx15(TextStyleButton, { editor, style: "strike" })
|
|
2301
|
+
] }),
|
|
2302
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2303
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2304
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "left" }),
|
|
2305
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "center" }),
|
|
2306
|
+
/* @__PURE__ */ jsx15(AlignButton, { editor, alignment: "right" })
|
|
2307
|
+
] }),
|
|
2308
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2309
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2310
|
+
/* @__PURE__ */ jsx15(ListButton, { editor, type: "bullet" }),
|
|
2311
|
+
/* @__PURE__ */ jsx15(ListButton, { editor, type: "numbered" })
|
|
2312
|
+
] })
|
|
2313
|
+
] }),
|
|
2314
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-row", children: [
|
|
2315
|
+
/* @__PURE__ */ jsx15("div", { className: "lumir-toolbar-group", children: /* @__PURE__ */ jsx15(BlockTypeSelect, { editor }) }),
|
|
2316
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2317
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2318
|
+
/* @__PURE__ */ jsx15(ColorButton, { editor, type: "text" }),
|
|
2319
|
+
/* @__PURE__ */ jsx15(ColorButton, { editor, type: "background" })
|
|
2320
|
+
] }),
|
|
2321
|
+
/* @__PURE__ */ jsx15(ToolbarDivider, {}),
|
|
2322
|
+
/* @__PURE__ */ jsxs9("div", { className: "lumir-toolbar-group", children: [
|
|
2323
|
+
/* @__PURE__ */ jsx15(ImageButton, { editor, onImageUpload }),
|
|
2324
|
+
/* @__PURE__ */ jsx15(LinkButton, { editor }),
|
|
2325
|
+
/* @__PURE__ */ jsx15(TableButton, { editor }),
|
|
2326
|
+
/* @__PURE__ */ jsx15(HTMLImportButton, { editor })
|
|
2327
|
+
] })
|
|
2328
|
+
] })
|
|
2329
|
+
] });
|
|
2330
|
+
return /* @__PURE__ */ jsx15(
|
|
2331
|
+
"div",
|
|
2332
|
+
{
|
|
2333
|
+
ref: wrapperRef,
|
|
2334
|
+
className: cn(
|
|
2335
|
+
"lumir-floating-toolbar-wrapper",
|
|
2336
|
+
isMinimizable && "is-minimizable",
|
|
2337
|
+
className
|
|
2338
|
+
),
|
|
2339
|
+
"data-position": position,
|
|
2340
|
+
children: /* @__PURE__ */ jsx15(
|
|
2341
|
+
"div",
|
|
2342
|
+
{
|
|
2343
|
+
className: cn(
|
|
2344
|
+
"lumir-floating-toolbar",
|
|
2345
|
+
isCompact && "is-compact",
|
|
2346
|
+
isMinimizable && "is-minimizable",
|
|
2347
|
+
isMinimized && "is-minimized"
|
|
2348
|
+
),
|
|
2349
|
+
children: isMinimizable ? /* @__PURE__ */ jsx15(MinimizedLayout, {}) : isCompact ? /* @__PURE__ */ jsx15(TwoRowLayout, {}) : /* @__PURE__ */ jsx15(SingleRowLayout, {})
|
|
2350
|
+
}
|
|
2351
|
+
)
|
|
2352
|
+
}
|
|
2353
|
+
);
|
|
2354
|
+
};
|
|
2355
|
+
|
|
2356
|
+
// src/errors/LumirEditorError.ts
|
|
2357
|
+
var LumirEditorError = class _LumirEditorError extends Error {
|
|
2358
|
+
constructor(message, details = {}) {
|
|
2359
|
+
super(message);
|
|
2360
|
+
this.name = "LumirEditorError";
|
|
2361
|
+
this.code = details.code || "UNKNOWN_ERROR";
|
|
2362
|
+
this.originalError = details.originalError;
|
|
2363
|
+
this.context = details.context;
|
|
2364
|
+
Object.setPrototypeOf(this, _LumirEditorError.prototype);
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* 에러 정보를 JSON 형태로 반환
|
|
2368
|
+
*/
|
|
2369
|
+
toJSON() {
|
|
2370
|
+
return {
|
|
2371
|
+
name: this.name,
|
|
2372
|
+
message: this.message,
|
|
2373
|
+
code: this.code,
|
|
2374
|
+
context: this.context,
|
|
2375
|
+
stack: this.stack
|
|
2376
|
+
};
|
|
2377
|
+
}
|
|
2378
|
+
/**
|
|
2379
|
+
* 사용자 친화적 에러 메시지 반환
|
|
2380
|
+
*/
|
|
2381
|
+
getUserMessage() {
|
|
2382
|
+
switch (this.code) {
|
|
2383
|
+
case "UPLOAD_FAILED":
|
|
2384
|
+
return "\uD30C\uC77C \uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.";
|
|
2385
|
+
case "INVALID_FILE_TYPE":
|
|
2386
|
+
return "\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD30C\uC77C \uD615\uC2DD\uC785\uB2C8\uB2E4. \uC774\uBBF8\uC9C0 \uD30C\uC77C\uB9CC \uC5C5\uB85C\uB4DC \uAC00\uB2A5\uD569\uB2C8\uB2E4.";
|
|
2387
|
+
case "S3_CONFIG_ERROR":
|
|
2388
|
+
return "S3 \uC124\uC815\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758\uD558\uC138\uC694.";
|
|
2389
|
+
case "PRESIGNED_URL_ERROR":
|
|
2390
|
+
return "\uC5C5\uB85C\uB4DC URL \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.";
|
|
2391
|
+
case "NETWORK_ERROR":
|
|
2392
|
+
return "\uB124\uD2B8\uC6CC\uD06C \uC5F0\uACB0\uC744 \uD655\uC778\uD574\uC8FC\uC138\uC694.";
|
|
2393
|
+
case "EDITOR_ERROR":
|
|
2394
|
+
return "\uC5D0\uB514\uD130 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uD398\uC774\uC9C0\uB97C \uC0C8\uB85C\uACE0\uCE68\uD574\uC8FC\uC138\uC694.";
|
|
2395
|
+
default:
|
|
2396
|
+
return "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.";
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* 일반 Error를 LumirEditorError로 변환
|
|
2401
|
+
*/
|
|
2402
|
+
static fromError(error, code = "UNKNOWN_ERROR", context) {
|
|
2403
|
+
return new _LumirEditorError(error.message, {
|
|
2404
|
+
code,
|
|
2405
|
+
originalError: error,
|
|
2406
|
+
context
|
|
2407
|
+
});
|
|
2408
|
+
}
|
|
2409
|
+
/**
|
|
2410
|
+
* 업로드 실패 에러 생성
|
|
2411
|
+
*/
|
|
2412
|
+
static uploadFailed(message, originalError) {
|
|
2413
|
+
return new _LumirEditorError(message, {
|
|
2414
|
+
code: "UPLOAD_FAILED",
|
|
2415
|
+
originalError
|
|
2416
|
+
});
|
|
2417
|
+
}
|
|
2418
|
+
/**
|
|
2419
|
+
* 잘못된 파일 형식 에러 생성
|
|
2420
|
+
*/
|
|
2421
|
+
static invalidFileType(fileName) {
|
|
2422
|
+
return new _LumirEditorError(
|
|
2423
|
+
`Invalid file type: ${fileName}. Only image files are allowed.`,
|
|
2424
|
+
{
|
|
2425
|
+
code: "INVALID_FILE_TYPE",
|
|
2426
|
+
context: { fileName }
|
|
2427
|
+
}
|
|
2428
|
+
);
|
|
2429
|
+
}
|
|
2430
|
+
/**
|
|
2431
|
+
* S3 설정 에러 생성
|
|
2432
|
+
*/
|
|
2433
|
+
static s3ConfigError(message) {
|
|
2434
|
+
return new _LumirEditorError(message, {
|
|
2435
|
+
code: "S3_CONFIG_ERROR"
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
/**
|
|
2439
|
+
* 네트워크 에러 생성
|
|
2440
|
+
*/
|
|
2441
|
+
static networkError(originalError) {
|
|
2442
|
+
return new _LumirEditorError("Network request failed", {
|
|
2443
|
+
code: "NETWORK_ERROR",
|
|
2444
|
+
originalError
|
|
2445
|
+
});
|
|
2446
|
+
}
|
|
2447
|
+
};
|
|
2448
|
+
|
|
2449
|
+
// src/constants/limits.ts
|
|
2450
|
+
var MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
2451
|
+
var BLOCKED_EXTENSIONS = [".svg", ".svgz"];
|
|
2452
|
+
|
|
114
2453
|
// src/components/LumirEditor.tsx
|
|
115
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2454
|
+
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
116
2455
|
var ContentUtils = class {
|
|
117
2456
|
/**
|
|
118
2457
|
* JSON 문자열의 유효성을 검증합니다
|
|
@@ -232,7 +2571,122 @@ var EditorConfig = class {
|
|
|
232
2571
|
}
|
|
233
2572
|
};
|
|
234
2573
|
var isImageFile = (file) => {
|
|
235
|
-
|
|
2574
|
+
if (file.size === 0 || file.size > MAX_FILE_SIZE) {
|
|
2575
|
+
return false;
|
|
2576
|
+
}
|
|
2577
|
+
const fileName = file.name?.toLowerCase() || "";
|
|
2578
|
+
if (file.type === "image/svg+xml" || BLOCKED_EXTENSIONS.some((ext) => fileName.endsWith(ext))) {
|
|
2579
|
+
return false;
|
|
2580
|
+
}
|
|
2581
|
+
return file.type?.startsWith("image/") || !file.type && /\.(png|jpe?g|gif|webp|bmp)$/i.test(fileName);
|
|
2582
|
+
};
|
|
2583
|
+
var isHtmlFile = (file) => {
|
|
2584
|
+
return file.size > 0 && (file.type === "text/html" || file.name?.toLowerCase().endsWith(".html") || file.name?.toLowerCase().endsWith(".htm"));
|
|
2585
|
+
};
|
|
2586
|
+
var escapeHtml = (str) => {
|
|
2587
|
+
const htmlEscapes = {
|
|
2588
|
+
"&": "&",
|
|
2589
|
+
"<": "<",
|
|
2590
|
+
">": ">",
|
|
2591
|
+
'"': """,
|
|
2592
|
+
"'": "'"
|
|
2593
|
+
};
|
|
2594
|
+
return str.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
|
|
2595
|
+
};
|
|
2596
|
+
var extractImageUrls = (blocks) => {
|
|
2597
|
+
const urls = /* @__PURE__ */ new Set();
|
|
2598
|
+
const traverse = (blockList) => {
|
|
2599
|
+
for (const block of blockList) {
|
|
2600
|
+
if (block.type === "image" && block.props?.url) {
|
|
2601
|
+
const url = block.props.url;
|
|
2602
|
+
if (typeof url === "string" && url.trim()) {
|
|
2603
|
+
urls.add(url);
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
if (block.children && Array.isArray(block.children)) {
|
|
2607
|
+
traverse(block.children);
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
};
|
|
2611
|
+
traverse(blocks);
|
|
2612
|
+
return urls;
|
|
2613
|
+
};
|
|
2614
|
+
var findDeletedImageUrls = (previousUrls, currentUrls) => {
|
|
2615
|
+
const deleted = [];
|
|
2616
|
+
previousUrls.forEach((url) => {
|
|
2617
|
+
if (!currentUrls.has(url)) {
|
|
2618
|
+
deleted.push(url);
|
|
2619
|
+
}
|
|
2620
|
+
});
|
|
2621
|
+
return deleted;
|
|
2622
|
+
};
|
|
2623
|
+
var findBlockWithLink = (blocks, targetUrl) => {
|
|
2624
|
+
for (const block of blocks) {
|
|
2625
|
+
if (block.content) {
|
|
2626
|
+
for (const item of block.content) {
|
|
2627
|
+
if (item.type === "link" && item.href === targetUrl) return block;
|
|
2628
|
+
if (item.content) {
|
|
2629
|
+
for (const sub of item.content) {
|
|
2630
|
+
if (sub.type === "link" && sub.href === targetUrl) return block;
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
if (block.children?.length) {
|
|
2636
|
+
const found = findBlockWithLink(block.children, targetUrl);
|
|
2637
|
+
if (found) return found;
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
return null;
|
|
2641
|
+
};
|
|
2642
|
+
var ConvertToPreviewButton = ({ url }) => {
|
|
2643
|
+
const editor = useBlockNoteEditor();
|
|
2644
|
+
const Components = useComponentsContext();
|
|
2645
|
+
return /* @__PURE__ */ jsx16(
|
|
2646
|
+
Components.LinkToolbar.Button,
|
|
2647
|
+
{
|
|
2648
|
+
className: "bn-button",
|
|
2649
|
+
mainTooltip: "\uB9C1\uD06C \uD504\uB9AC\uBDF0\uB85C \uC804\uD658",
|
|
2650
|
+
label: "\uB9C1\uD06C \uD504\uB9AC\uBDF0\uB85C \uC804\uD658",
|
|
2651
|
+
isSelected: false,
|
|
2652
|
+
onClick: () => {
|
|
2653
|
+
try {
|
|
2654
|
+
const allBlocks = editor.document;
|
|
2655
|
+
const targetBlock = findBlockWithLink(allBlocks, url) || editor.getTextCursorPosition().block;
|
|
2656
|
+
editor.replaceBlocks(
|
|
2657
|
+
[targetBlock],
|
|
2658
|
+
[{ type: "linkPreview", props: { url } }]
|
|
2659
|
+
);
|
|
2660
|
+
} catch (err) {
|
|
2661
|
+
console.error("Convert to link preview failed:", err);
|
|
2662
|
+
}
|
|
2663
|
+
},
|
|
2664
|
+
icon: /* @__PURE__ */ jsxs10("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
2665
|
+
/* @__PURE__ */ jsx16("rect", { x: "1", y: "3", width: "14", height: "10", rx: "2", stroke: "currentColor", strokeWidth: "1.5", fill: "none" }),
|
|
2666
|
+
/* @__PURE__ */ jsx16("line", { x1: "1", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2667
|
+
/* @__PURE__ */ jsx16("circle", { cx: "5", cy: "6.5", r: "1.5", stroke: "currentColor", strokeWidth: "1", fill: "none" })
|
|
2668
|
+
] })
|
|
2669
|
+
}
|
|
2670
|
+
);
|
|
2671
|
+
};
|
|
2672
|
+
var CustomLinkToolbar = (props) => {
|
|
2673
|
+
const editor = useBlockNoteEditor();
|
|
2674
|
+
const Components = useComponentsContext();
|
|
2675
|
+
const hasLinkPreview = !!editor?._linkPreviewApiEndpoint;
|
|
2676
|
+
return /* @__PURE__ */ jsxs10(
|
|
2677
|
+
Components.LinkToolbar.Root,
|
|
2678
|
+
{
|
|
2679
|
+
className: "bn-toolbar bn-link-toolbar",
|
|
2680
|
+
onMouseEnter: props.stopHideTimer,
|
|
2681
|
+
onMouseLeave: props.startHideTimer,
|
|
2682
|
+
children: [
|
|
2683
|
+
/* @__PURE__ */ jsx16(EditLinkButton, { url: props.url, text: props.text, editLink: props.editLink }),
|
|
2684
|
+
/* @__PURE__ */ jsx16(OpenLinkButton, { url: props.url }),
|
|
2685
|
+
/* @__PURE__ */ jsx16(DeleteLinkButton, { deleteLink: props.deleteLink }),
|
|
2686
|
+
hasLinkPreview && /* @__PURE__ */ jsx16(ConvertToPreviewButton, { url: props.url })
|
|
2687
|
+
]
|
|
2688
|
+
}
|
|
2689
|
+
);
|
|
236
2690
|
};
|
|
237
2691
|
function LumirEditor({
|
|
238
2692
|
// editor options
|
|
@@ -249,6 +2703,8 @@ function LumirEditor({
|
|
|
249
2703
|
allowVideoUpload = false,
|
|
250
2704
|
allowAudioUpload = false,
|
|
251
2705
|
allowFileUpload = false,
|
|
2706
|
+
// link preview
|
|
2707
|
+
linkPreview,
|
|
252
2708
|
// view options
|
|
253
2709
|
editable = true,
|
|
254
2710
|
theme = "light",
|
|
@@ -260,11 +2716,25 @@ function LumirEditor({
|
|
|
260
2716
|
tableHandles = true,
|
|
261
2717
|
onSelectionChange,
|
|
262
2718
|
className = "",
|
|
2719
|
+
placeholder,
|
|
263
2720
|
sideMenuAddButton = false,
|
|
2721
|
+
floatingMenu = false,
|
|
2722
|
+
floatingMenuPosition = "sticky",
|
|
264
2723
|
// callbacks / refs
|
|
265
|
-
onContentChange
|
|
2724
|
+
onContentChange,
|
|
2725
|
+
onError,
|
|
2726
|
+
onImageDelete
|
|
266
2727
|
}) {
|
|
267
|
-
const [isUploading, setIsUploading] =
|
|
2728
|
+
const [isUploading, setIsUploading] = useState7(false);
|
|
2729
|
+
const [errorMessage, setErrorMessage] = useState7(null);
|
|
2730
|
+
const handleError = useCallback13(
|
|
2731
|
+
(error) => {
|
|
2732
|
+
onError?.(error);
|
|
2733
|
+
setErrorMessage(error.getUserMessage());
|
|
2734
|
+
setTimeout(() => setErrorMessage(null), 3e3);
|
|
2735
|
+
},
|
|
2736
|
+
[onError]
|
|
2737
|
+
);
|
|
268
2738
|
const validatedContent = useMemo(() => {
|
|
269
2739
|
return ContentUtils.validateContent(initialContent, initialEmptyBlocks);
|
|
270
2740
|
}, [initialContent, initialEmptyBlocks]);
|
|
@@ -287,8 +2757,8 @@ function LumirEditor({
|
|
|
287
2757
|
allowFileUpload
|
|
288
2758
|
);
|
|
289
2759
|
}, [disableExtensions, allowVideoUpload, allowAudioUpload, allowFileUpload]);
|
|
290
|
-
const fileNameTransformRef =
|
|
291
|
-
|
|
2760
|
+
const fileNameTransformRef = useRef8(s3Upload?.fileNameTransform);
|
|
2761
|
+
useEffect7(() => {
|
|
292
2762
|
fileNameTransformRef.current = s3Upload?.fileNameTransform;
|
|
293
2763
|
}, [s3Upload?.fileNameTransform]);
|
|
294
2764
|
const memoizedS3Upload = useMemo(() => {
|
|
@@ -313,6 +2783,8 @@ function LumirEditor({
|
|
|
313
2783
|
]);
|
|
314
2784
|
const editor = useCreateBlockNote(
|
|
315
2785
|
{
|
|
2786
|
+
// HTML 미리보기 블록이 포함된 커스텀 스키마 사용
|
|
2787
|
+
schema,
|
|
316
2788
|
initialContent: validatedContent,
|
|
317
2789
|
tables: tableConfig,
|
|
318
2790
|
heading: headingConfig,
|
|
@@ -321,11 +2793,14 @@ function LumirEditor({
|
|
|
321
2793
|
defaultStyles,
|
|
322
2794
|
// 확장 비활성: 비디오/오디오/파일 제어
|
|
323
2795
|
disableExtensions: disabledExtensions,
|
|
2796
|
+
placeholders: placeholder ? { default: placeholder, emptyDocument: placeholder } : void 0,
|
|
324
2797
|
tabBehavior,
|
|
325
2798
|
trailingBlock,
|
|
326
2799
|
uploadFile: async (file) => {
|
|
327
2800
|
if (!isImageFile(file)) {
|
|
328
|
-
|
|
2801
|
+
const error = LumirEditorError.invalidFileType(file.name);
|
|
2802
|
+
handleError(error);
|
|
2803
|
+
throw error;
|
|
329
2804
|
}
|
|
330
2805
|
try {
|
|
331
2806
|
let imageUrl;
|
|
@@ -335,18 +2810,49 @@ function LumirEditor({
|
|
|
335
2810
|
const s3Uploader = createS3Uploader(memoizedS3Upload);
|
|
336
2811
|
imageUrl = await s3Uploader(file);
|
|
337
2812
|
} else {
|
|
338
|
-
|
|
2813
|
+
const error = LumirEditorError.s3ConfigError(
|
|
2814
|
+
"No upload method available. Please provide uploadFile or s3Upload configuration."
|
|
2815
|
+
);
|
|
2816
|
+
handleError(error);
|
|
2817
|
+
throw error;
|
|
339
2818
|
}
|
|
340
2819
|
return imageUrl;
|
|
341
2820
|
} catch (error) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
2821
|
+
if (error instanceof LumirEditorError) {
|
|
2822
|
+
throw error;
|
|
2823
|
+
}
|
|
2824
|
+
const lumirError = LumirEditorError.uploadFailed(
|
|
2825
|
+
error instanceof Error ? error.message : String(error),
|
|
2826
|
+
error instanceof Error ? error : void 0
|
|
345
2827
|
);
|
|
2828
|
+
handleError(lumirError);
|
|
2829
|
+
throw lumirError;
|
|
346
2830
|
}
|
|
347
2831
|
},
|
|
348
2832
|
pasteHandler: (ctx) => {
|
|
349
2833
|
const { event, editor: editor2, defaultPasteHandler } = ctx;
|
|
2834
|
+
if (linkPreview?.apiEndpoint) {
|
|
2835
|
+
const text = event?.clipboardData?.getData?.("text/plain") || "";
|
|
2836
|
+
const trimmed = text.trim();
|
|
2837
|
+
if (trimmed && /^https?:\/\/\S+$/i.test(trimmed) && !event?.clipboardData?.files?.length) {
|
|
2838
|
+
event.preventDefault();
|
|
2839
|
+
const currentBlock = editor2.getTextCursorPosition().block;
|
|
2840
|
+
const blockText = currentBlock.content?.map((c) => c.text || "").join("").trim();
|
|
2841
|
+
if (!blockText && currentBlock.type === "paragraph") {
|
|
2842
|
+
editor2.updateBlock(currentBlock, {
|
|
2843
|
+
type: "linkPreview",
|
|
2844
|
+
props: { url: trimmed }
|
|
2845
|
+
});
|
|
2846
|
+
} else {
|
|
2847
|
+
editor2.insertBlocks(
|
|
2848
|
+
[{ type: "linkPreview", props: { url: trimmed } }],
|
|
2849
|
+
currentBlock,
|
|
2850
|
+
"after"
|
|
2851
|
+
);
|
|
2852
|
+
}
|
|
2853
|
+
return true;
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
350
2856
|
const fileList = event?.clipboardData?.files ?? null;
|
|
351
2857
|
const files = fileList ? Array.from(fileList) : [];
|
|
352
2858
|
const acceptedFiles = files.filter(isImageFile);
|
|
@@ -364,7 +2870,9 @@ function LumirEditor({
|
|
|
364
2870
|
for (const file of acceptedFiles) {
|
|
365
2871
|
try {
|
|
366
2872
|
const url = await editor2.uploadFile(file);
|
|
367
|
-
editor2.pasteHTML(
|
|
2873
|
+
editor2.pasteHTML(
|
|
2874
|
+
`<img src="${escapeHtml(url)}" alt="image" />`
|
|
2875
|
+
);
|
|
368
2876
|
} catch (err) {
|
|
369
2877
|
console.warn(
|
|
370
2878
|
"Image upload failed, skipped:",
|
|
@@ -389,15 +2897,20 @@ function LumirEditor({
|
|
|
389
2897
|
tabBehavior,
|
|
390
2898
|
trailingBlock,
|
|
391
2899
|
uploadFile,
|
|
392
|
-
memoizedS3Upload
|
|
2900
|
+
memoizedS3Upload,
|
|
2901
|
+
linkPreview?.apiEndpoint,
|
|
2902
|
+
placeholder
|
|
393
2903
|
]
|
|
394
2904
|
);
|
|
395
|
-
|
|
2905
|
+
if (editor && linkPreview?.apiEndpoint) {
|
|
2906
|
+
editor._linkPreviewApiEndpoint = linkPreview.apiEndpoint;
|
|
2907
|
+
}
|
|
2908
|
+
useEffect7(() => {
|
|
396
2909
|
if (editor) {
|
|
397
2910
|
editor.isEditable = editable;
|
|
398
2911
|
}
|
|
399
2912
|
}, [editor, editable]);
|
|
400
|
-
|
|
2913
|
+
useEffect7(() => {
|
|
401
2914
|
if (!editor || !onContentChange) return;
|
|
402
2915
|
const handleContentChange = () => {
|
|
403
2916
|
const blocks = editor.topLevelBlocks;
|
|
@@ -405,7 +2918,27 @@ function LumirEditor({
|
|
|
405
2918
|
};
|
|
406
2919
|
return editor.onEditorContentChange(handleContentChange);
|
|
407
2920
|
}, [editor, onContentChange]);
|
|
408
|
-
|
|
2921
|
+
const previousImageUrlsRef = useRef8(/* @__PURE__ */ new Set());
|
|
2922
|
+
useEffect7(() => {
|
|
2923
|
+
if (!editor) return;
|
|
2924
|
+
const initialBlocks = editor.topLevelBlocks;
|
|
2925
|
+
previousImageUrlsRef.current = extractImageUrls(initialBlocks);
|
|
2926
|
+
}, [editor]);
|
|
2927
|
+
useEffect7(() => {
|
|
2928
|
+
if (!editor || !onImageDelete) return;
|
|
2929
|
+
const handleImageDeleteCheck = () => {
|
|
2930
|
+
const currentBlocks = editor.topLevelBlocks;
|
|
2931
|
+
const currentUrls = extractImageUrls(currentBlocks);
|
|
2932
|
+
const previousUrls = previousImageUrlsRef.current;
|
|
2933
|
+
const deletedUrls = findDeletedImageUrls(previousUrls, currentUrls);
|
|
2934
|
+
deletedUrls.forEach((url) => {
|
|
2935
|
+
onImageDelete(url);
|
|
2936
|
+
});
|
|
2937
|
+
previousImageUrlsRef.current = currentUrls;
|
|
2938
|
+
};
|
|
2939
|
+
return editor.onEditorContentChange(handleImageDeleteCheck);
|
|
2940
|
+
}, [editor, onImageDelete]);
|
|
2941
|
+
useEffect7(() => {
|
|
409
2942
|
const el = editor?.domElement;
|
|
410
2943
|
if (!el) return;
|
|
411
2944
|
const handleDragOver = (e) => {
|
|
@@ -424,17 +2957,20 @@ function LumirEditor({
|
|
|
424
2957
|
e.stopPropagation();
|
|
425
2958
|
const items = Array.from(e.dataTransfer.items ?? []);
|
|
426
2959
|
const files = items.filter((it) => it.kind === "file").map((it) => it.getAsFile()).filter((f) => !!f);
|
|
427
|
-
const
|
|
428
|
-
|
|
2960
|
+
const imageFiles = files.filter(isImageFile);
|
|
2961
|
+
const htmlFiles = files.filter(isHtmlFile);
|
|
2962
|
+
if (imageFiles.length === 0 && htmlFiles.length === 0) return;
|
|
429
2963
|
(async () => {
|
|
430
2964
|
setIsUploading(true);
|
|
431
2965
|
try {
|
|
432
|
-
for (const file of
|
|
2966
|
+
for (const file of imageFiles) {
|
|
433
2967
|
try {
|
|
434
2968
|
if (editor?.uploadFile) {
|
|
435
2969
|
const url = await editor.uploadFile(file);
|
|
436
|
-
if (url) {
|
|
437
|
-
editor.pasteHTML(
|
|
2970
|
+
if (url && typeof url === "string") {
|
|
2971
|
+
editor.pasteHTML(
|
|
2972
|
+
`<img src="${escapeHtml(url)}" alt="image" />`
|
|
2973
|
+
);
|
|
438
2974
|
}
|
|
439
2975
|
}
|
|
440
2976
|
} catch (err) {
|
|
@@ -445,6 +2981,32 @@ function LumirEditor({
|
|
|
445
2981
|
);
|
|
446
2982
|
}
|
|
447
2983
|
}
|
|
2984
|
+
for (const file of htmlFiles) {
|
|
2985
|
+
try {
|
|
2986
|
+
const htmlContent = await file.text();
|
|
2987
|
+
const currentBlock = editor.getTextCursorPosition().block;
|
|
2988
|
+
editor.insertBlocks(
|
|
2989
|
+
[
|
|
2990
|
+
{
|
|
2991
|
+
type: "htmlPreview",
|
|
2992
|
+
props: {
|
|
2993
|
+
htmlContent,
|
|
2994
|
+
fileName: file.name,
|
|
2995
|
+
height: "400px"
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
],
|
|
2999
|
+
currentBlock,
|
|
3000
|
+
"after"
|
|
3001
|
+
);
|
|
3002
|
+
} catch (err) {
|
|
3003
|
+
console.warn(
|
|
3004
|
+
"HTML file processing failed, skipped:",
|
|
3005
|
+
file.name || "",
|
|
3006
|
+
err
|
|
3007
|
+
);
|
|
3008
|
+
}
|
|
3009
|
+
}
|
|
448
3010
|
} finally {
|
|
449
3011
|
setIsUploading(false);
|
|
450
3012
|
}
|
|
@@ -463,22 +3025,58 @@ function LumirEditor({
|
|
|
463
3025
|
return sideMenuAddButton ? sideMenu : false;
|
|
464
3026
|
}, [sideMenuAddButton, sideMenu]);
|
|
465
3027
|
const DragHandleOnlySideMenu = useMemo(() => {
|
|
466
|
-
return (props) => /* @__PURE__ */
|
|
3028
|
+
return (props) => /* @__PURE__ */ jsx16(BlockSideMenu, { ...props, children: /* @__PURE__ */ jsx16(DragHandleButton, { ...props }) });
|
|
467
3029
|
}, []);
|
|
468
|
-
return /* @__PURE__ */
|
|
3030
|
+
return /* @__PURE__ */ jsxs10(
|
|
469
3031
|
"div",
|
|
470
3032
|
{
|
|
471
3033
|
className: cn("lumirEditor", className),
|
|
472
|
-
style: { position: "relative" },
|
|
3034
|
+
style: { position: "relative", display: "flex", flexDirection: "column" },
|
|
473
3035
|
children: [
|
|
474
|
-
/* @__PURE__ */
|
|
3036
|
+
floatingMenu && editor && /* @__PURE__ */ jsx16(
|
|
3037
|
+
FloatingMenu,
|
|
3038
|
+
{
|
|
3039
|
+
editor,
|
|
3040
|
+
position: floatingMenuPosition,
|
|
3041
|
+
onImageUpload: async () => {
|
|
3042
|
+
const input = document.createElement("input");
|
|
3043
|
+
input.type = "file";
|
|
3044
|
+
input.accept = "image/*";
|
|
3045
|
+
input.onchange = async (e) => {
|
|
3046
|
+
const file = e.target.files?.[0];
|
|
3047
|
+
if (file && editor.uploadFile) {
|
|
3048
|
+
try {
|
|
3049
|
+
setIsUploading(true);
|
|
3050
|
+
const url = await editor.uploadFile(file);
|
|
3051
|
+
editor.insertBlocks(
|
|
3052
|
+
[
|
|
3053
|
+
{
|
|
3054
|
+
type: "image",
|
|
3055
|
+
props: { url }
|
|
3056
|
+
}
|
|
3057
|
+
],
|
|
3058
|
+
editor.getTextCursorPosition().block,
|
|
3059
|
+
"after"
|
|
3060
|
+
);
|
|
3061
|
+
} catch (err) {
|
|
3062
|
+
console.error("Image upload failed:", err);
|
|
3063
|
+
} finally {
|
|
3064
|
+
setIsUploading(false);
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
};
|
|
3068
|
+
input.click();
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
),
|
|
3072
|
+
/* @__PURE__ */ jsxs10(
|
|
475
3073
|
BlockNoteView,
|
|
476
3074
|
{
|
|
477
3075
|
editor,
|
|
478
3076
|
editable,
|
|
479
3077
|
theme,
|
|
480
3078
|
formattingToolbar,
|
|
481
|
-
linkToolbar,
|
|
3079
|
+
linkToolbar: false,
|
|
482
3080
|
sideMenu: computedSideMenu,
|
|
483
3081
|
slashMenu: false,
|
|
484
3082
|
emojiPicker,
|
|
@@ -486,11 +3084,12 @@ function LumirEditor({
|
|
|
486
3084
|
tableHandles,
|
|
487
3085
|
onSelectionChange,
|
|
488
3086
|
children: [
|
|
489
|
-
/* @__PURE__ */
|
|
3087
|
+
linkToolbar && (linkPreview?.apiEndpoint ? /* @__PURE__ */ jsx16(LinkToolbarController, { linkToolbar: CustomLinkToolbar }) : /* @__PURE__ */ jsx16(LinkToolbarController, {})),
|
|
3088
|
+
/* @__PURE__ */ jsx16(
|
|
490
3089
|
SuggestionMenuController,
|
|
491
3090
|
{
|
|
492
3091
|
triggerCharacter: "/",
|
|
493
|
-
getItems:
|
|
3092
|
+
getItems: useCallback13(
|
|
494
3093
|
async (query) => {
|
|
495
3094
|
const items = getDefaultReactSlashMenuItems(editor);
|
|
496
3095
|
const filtered = items.filter((item) => {
|
|
@@ -501,32 +3100,144 @@ function LumirEditor({
|
|
|
501
3100
|
return false;
|
|
502
3101
|
return true;
|
|
503
3102
|
});
|
|
504
|
-
|
|
3103
|
+
const htmlPreviewItem = {
|
|
3104
|
+
title: "HTML Preview",
|
|
3105
|
+
onItemClick: () => {
|
|
3106
|
+
const input = document.createElement("input");
|
|
3107
|
+
input.type = "file";
|
|
3108
|
+
input.accept = ".html,.htm";
|
|
3109
|
+
input.onchange = async (e) => {
|
|
3110
|
+
const file = e.target.files?.[0];
|
|
3111
|
+
if (file) {
|
|
3112
|
+
const htmlContent = await file.text();
|
|
3113
|
+
const currentBlock = editor.getTextCursorPosition().block;
|
|
3114
|
+
editor.insertBlocks(
|
|
3115
|
+
[
|
|
3116
|
+
{
|
|
3117
|
+
type: "htmlPreview",
|
|
3118
|
+
props: {
|
|
3119
|
+
htmlContent,
|
|
3120
|
+
fileName: file.name,
|
|
3121
|
+
height: "400px"
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
],
|
|
3125
|
+
currentBlock,
|
|
3126
|
+
"after"
|
|
3127
|
+
);
|
|
3128
|
+
}
|
|
3129
|
+
};
|
|
3130
|
+
input.click();
|
|
3131
|
+
},
|
|
3132
|
+
aliases: ["html", "preview", "\uC6F9", "\uC6F9\uD398\uC774\uC9C0"],
|
|
3133
|
+
group: "Embeds",
|
|
3134
|
+
icon: /* @__PURE__ */ jsxs10(
|
|
3135
|
+
"svg",
|
|
3136
|
+
{
|
|
3137
|
+
width: "18",
|
|
3138
|
+
height: "18",
|
|
3139
|
+
viewBox: "0 0 24 24",
|
|
3140
|
+
fill: "none",
|
|
3141
|
+
stroke: "currentColor",
|
|
3142
|
+
strokeWidth: "2",
|
|
3143
|
+
strokeLinecap: "round",
|
|
3144
|
+
strokeLinejoin: "round",
|
|
3145
|
+
children: [
|
|
3146
|
+
/* @__PURE__ */ jsx16("polyline", { points: "16 18 22 12 16 6" }),
|
|
3147
|
+
/* @__PURE__ */ jsx16("polyline", { points: "8 6 2 12 8 18" })
|
|
3148
|
+
]
|
|
3149
|
+
}
|
|
3150
|
+
),
|
|
3151
|
+
subtext: "HTML \uD30C\uC77C\uC744 \uBBF8\uB9AC\uBCF4\uAE30\uB85C \uC0BD\uC785"
|
|
3152
|
+
};
|
|
3153
|
+
const allItems = [...filtered, htmlPreviewItem];
|
|
3154
|
+
if (linkPreview?.apiEndpoint) {
|
|
3155
|
+
allItems.push({
|
|
3156
|
+
title: "Link Preview",
|
|
3157
|
+
onItemClick: () => {
|
|
3158
|
+
insertOrUpdateBlock(editor, {
|
|
3159
|
+
type: "linkPreview",
|
|
3160
|
+
props: { url: "" }
|
|
3161
|
+
});
|
|
3162
|
+
},
|
|
3163
|
+
aliases: [
|
|
3164
|
+
"link",
|
|
3165
|
+
"preview",
|
|
3166
|
+
"url",
|
|
3167
|
+
"\uB9C1\uD06C",
|
|
3168
|
+
"\uBBF8\uB9AC\uBCF4\uAE30",
|
|
3169
|
+
"\uD504\uB9AC\uBDF0"
|
|
3170
|
+
],
|
|
3171
|
+
group: "Embeds",
|
|
3172
|
+
icon: /* @__PURE__ */ jsxs10(
|
|
3173
|
+
"svg",
|
|
3174
|
+
{
|
|
3175
|
+
width: "18",
|
|
3176
|
+
height: "18",
|
|
3177
|
+
viewBox: "0 0 24 24",
|
|
3178
|
+
fill: "none",
|
|
3179
|
+
stroke: "currentColor",
|
|
3180
|
+
strokeWidth: "2",
|
|
3181
|
+
strokeLinecap: "round",
|
|
3182
|
+
strokeLinejoin: "round",
|
|
3183
|
+
children: [
|
|
3184
|
+
/* @__PURE__ */ jsx16("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
|
|
3185
|
+
/* @__PURE__ */ jsx16("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
|
|
3186
|
+
]
|
|
3187
|
+
}
|
|
3188
|
+
),
|
|
3189
|
+
subtext: "URL\uC758 \uBBF8\uB9AC\uBCF4\uAE30 \uCE74\uB4DC\uB97C \uC0BD\uC785"
|
|
3190
|
+
});
|
|
3191
|
+
}
|
|
3192
|
+
if (!query) return allItems;
|
|
505
3193
|
const q = query.toLowerCase();
|
|
506
|
-
return
|
|
3194
|
+
return allItems.filter(
|
|
507
3195
|
(item) => item.title?.toLowerCase().includes(q) || (item.aliases || []).some(
|
|
508
3196
|
(a) => a.toLowerCase().includes(q)
|
|
509
3197
|
)
|
|
510
3198
|
);
|
|
511
3199
|
},
|
|
512
|
-
[editor]
|
|
3200
|
+
[editor, linkPreview?.apiEndpoint]
|
|
513
3201
|
)
|
|
514
3202
|
}
|
|
515
3203
|
),
|
|
516
|
-
!sideMenuAddButton && /* @__PURE__ */
|
|
3204
|
+
!sideMenuAddButton && /* @__PURE__ */ jsx16(SideMenuController, { sideMenu: DragHandleOnlySideMenu })
|
|
517
3205
|
]
|
|
518
3206
|
}
|
|
519
3207
|
),
|
|
520
|
-
isUploading && /* @__PURE__ */
|
|
3208
|
+
isUploading && /* @__PURE__ */ jsx16("div", { className: "lumirEditor-upload-overlay", children: /* @__PURE__ */ jsx16("div", { className: "lumirEditor-spinner" }) }),
|
|
3209
|
+
errorMessage && /* @__PURE__ */ jsxs10("div", { className: "lumirEditor-error-toast", children: [
|
|
3210
|
+
/* @__PURE__ */ jsx16("span", { className: "lumirEditor-error-icon", children: "\u26A0\uFE0F" }),
|
|
3211
|
+
/* @__PURE__ */ jsx16("span", { className: "lumirEditor-error-message", children: errorMessage }),
|
|
3212
|
+
/* @__PURE__ */ jsx16(
|
|
3213
|
+
"button",
|
|
3214
|
+
{
|
|
3215
|
+
className: "lumirEditor-error-close",
|
|
3216
|
+
onClick: () => setErrorMessage(null),
|
|
3217
|
+
type: "button",
|
|
3218
|
+
children: "\u2715"
|
|
3219
|
+
}
|
|
3220
|
+
)
|
|
3221
|
+
] })
|
|
521
3222
|
]
|
|
522
3223
|
}
|
|
523
3224
|
);
|
|
524
3225
|
}
|
|
525
3226
|
export {
|
|
3227
|
+
BACKGROUND_COLORS,
|
|
526
3228
|
ContentUtils,
|
|
527
3229
|
EditorConfig,
|
|
3230
|
+
FloatingMenu,
|
|
3231
|
+
HtmlPreviewBlock,
|
|
3232
|
+
schema as HtmlPreviewSchema,
|
|
3233
|
+
LinkPreviewBlock,
|
|
528
3234
|
LumirEditor,
|
|
3235
|
+
LumirEditorError,
|
|
3236
|
+
TEXT_COLORS,
|
|
3237
|
+
clearMetadataCache,
|
|
529
3238
|
cn,
|
|
530
|
-
createS3Uploader
|
|
3239
|
+
createS3Uploader,
|
|
3240
|
+
fetchLinkMetadata,
|
|
3241
|
+
getHexFromColorValue
|
|
531
3242
|
};
|
|
532
3243
|
//# sourceMappingURL=index.mjs.map
|