@zuilib/text-editor 0.1.0 → 0.2.0
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 +8 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +458 -200
- package/dist/styles.css +141 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/MarkdownEditor.tsx
|
|
2
|
-
import { useCallback as
|
|
2
|
+
import { useCallback as useCallback5, useEffect as useEffect9, useMemo, useRef as useRef4, useState as useState5 } from "react";
|
|
3
3
|
import { LexicalComposer } from "@lexical/react/LexicalComposer";
|
|
4
4
|
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
|
5
5
|
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
|
|
@@ -12,7 +12,7 @@ import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPl
|
|
|
12
12
|
import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
|
|
13
13
|
import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
|
|
14
14
|
import { CHECK_LIST, CODE, TRANSFORMERS as TRANSFORMERS2 } from "@lexical/markdown";
|
|
15
|
-
import { useLexicalComposerContext as
|
|
15
|
+
import { useLexicalComposerContext as useLexicalComposerContext9 } from "@lexical/react/LexicalComposerContext";
|
|
16
16
|
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
|
|
17
17
|
import { ListItemNode, ListNode as ListNode2 } from "@lexical/list";
|
|
18
18
|
import { CodeHighlightNode, CodeNode } from "@lexical/code";
|
|
@@ -166,9 +166,146 @@ function CodeHighlightPlugin() {
|
|
|
166
166
|
return null;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
// src/plugins/
|
|
170
|
-
import {
|
|
169
|
+
// src/plugins/FoldingPlugin.tsx
|
|
170
|
+
import {
|
|
171
|
+
useCallback,
|
|
172
|
+
useEffect as useEffect4,
|
|
173
|
+
useRef,
|
|
174
|
+
useState
|
|
175
|
+
} from "react";
|
|
176
|
+
import { $getRoot, $getSelection as $getSelection2, $isRangeSelection as $isRangeSelection2 } from "lexical";
|
|
171
177
|
import { useLexicalComposerContext as useLexicalComposerContext4 } from "@lexical/react/LexicalComposerContext";
|
|
178
|
+
import { $isHeadingNode } from "@lexical/rich-text";
|
|
179
|
+
import { jsx } from "react/jsx-runtime";
|
|
180
|
+
var HEADING_LEVELS = {
|
|
181
|
+
h1: 1,
|
|
182
|
+
h2: 2,
|
|
183
|
+
h3: 3,
|
|
184
|
+
h4: 4,
|
|
185
|
+
h5: 5,
|
|
186
|
+
h6: 6
|
|
187
|
+
};
|
|
188
|
+
function FoldingPlugin() {
|
|
189
|
+
const [editor] = useLexicalComposerContext4();
|
|
190
|
+
const [foldedKeys, setFoldedKeys] = useState(/* @__PURE__ */ new Set());
|
|
191
|
+
const [buttons, setButtons] = useState([]);
|
|
192
|
+
const foldedRef = useRef(foldedKeys);
|
|
193
|
+
foldedRef.current = foldedKeys;
|
|
194
|
+
const sync = useCallback(() => {
|
|
195
|
+
editor.getEditorState().read(() => {
|
|
196
|
+
const children = $getRoot().getChildren();
|
|
197
|
+
const folded = foldedRef.current;
|
|
198
|
+
const hidden = /* @__PURE__ */ new Set();
|
|
199
|
+
const headings = [];
|
|
200
|
+
for (let i = 0; i < children.length; i++) {
|
|
201
|
+
const node = children[i];
|
|
202
|
+
if (!$isHeadingNode(node)) continue;
|
|
203
|
+
const level = HEADING_LEVELS[node.getTag()] ?? 6;
|
|
204
|
+
const isFolded = folded.has(node.getKey());
|
|
205
|
+
headings.push({ key: node.getKey(), folded: isFolded });
|
|
206
|
+
if (!isFolded) continue;
|
|
207
|
+
for (let j = i + 1; j < children.length; j++) {
|
|
208
|
+
const sibling = children[j];
|
|
209
|
+
if ($isHeadingNode(sibling) && (HEADING_LEVELS[sibling.getTag()] ?? 6) <= level) {
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
hidden.add(sibling.getKey());
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const selection = $getSelection2();
|
|
216
|
+
if ($isRangeSelection2(selection)) {
|
|
217
|
+
const topLevel = selection.anchor.getNode().getTopLevelElement();
|
|
218
|
+
if (topLevel && hidden.has(topLevel.getKey())) {
|
|
219
|
+
let node = topLevel.getPreviousSibling();
|
|
220
|
+
while (node) {
|
|
221
|
+
if ($isHeadingNode(node) && folded.has(node.getKey())) {
|
|
222
|
+
const unfoldKey = node.getKey();
|
|
223
|
+
setFoldedKeys((prev) => {
|
|
224
|
+
const next = new Set(prev);
|
|
225
|
+
next.delete(unfoldKey);
|
|
226
|
+
return next;
|
|
227
|
+
});
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
node = node.getPreviousSibling();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
for (const child of children) {
|
|
235
|
+
const element = editor.getElementByKey(child.getKey());
|
|
236
|
+
if (!element) continue;
|
|
237
|
+
const shouldHide = hidden.has(child.getKey());
|
|
238
|
+
if (shouldHide) {
|
|
239
|
+
element.style.display = "none";
|
|
240
|
+
} else if (element.style.display === "none") {
|
|
241
|
+
element.style.display = "";
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
setButtons(
|
|
245
|
+
headings.map(({ key, folded: isFolded }) => {
|
|
246
|
+
const element = editor.getElementByKey(key);
|
|
247
|
+
element?.classList.toggle("zui-heading-folded", isFolded);
|
|
248
|
+
return {
|
|
249
|
+
key,
|
|
250
|
+
folded: isFolded,
|
|
251
|
+
top: element?.offsetTop ?? 0,
|
|
252
|
+
height: element?.offsetHeight ?? 0
|
|
253
|
+
};
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
});
|
|
257
|
+
}, [editor]);
|
|
258
|
+
useEffect4(() => {
|
|
259
|
+
sync();
|
|
260
|
+
const unregister = editor.registerUpdateListener(sync);
|
|
261
|
+
const rootElement = editor.getRootElement();
|
|
262
|
+
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(sync) : null;
|
|
263
|
+
if (rootElement && observer) observer.observe(rootElement);
|
|
264
|
+
return () => {
|
|
265
|
+
unregister();
|
|
266
|
+
observer?.disconnect();
|
|
267
|
+
};
|
|
268
|
+
}, [editor, sync, foldedKeys]);
|
|
269
|
+
const toggle = useCallback((key) => {
|
|
270
|
+
setFoldedKeys((prev) => {
|
|
271
|
+
const next = new Set(prev);
|
|
272
|
+
if (next.has(key)) next.delete(key);
|
|
273
|
+
else next.add(key);
|
|
274
|
+
return next;
|
|
275
|
+
});
|
|
276
|
+
}, []);
|
|
277
|
+
return /* @__PURE__ */ jsx("div", { className: "zui-text-editor-fold-gutter", children: buttons.map(({ key, folded, top, height }) => /* @__PURE__ */ jsx(
|
|
278
|
+
"button",
|
|
279
|
+
{
|
|
280
|
+
type: "button",
|
|
281
|
+
className: `zui-text-editor-fold ${folded ? "is-folded" : ""}`,
|
|
282
|
+
style: { top: top + Math.max(0, (Math.min(height, 44) - 18) / 2) },
|
|
283
|
+
title: folded ? "Expand section" : "Collapse section",
|
|
284
|
+
"aria-label": folded ? "Expand section" : "Collapse section",
|
|
285
|
+
"aria-expanded": !folded,
|
|
286
|
+
onClick: () => toggle(key),
|
|
287
|
+
children: /* @__PURE__ */ jsx(
|
|
288
|
+
"svg",
|
|
289
|
+
{
|
|
290
|
+
viewBox: "0 0 20 20",
|
|
291
|
+
width: "12",
|
|
292
|
+
height: "12",
|
|
293
|
+
fill: "none",
|
|
294
|
+
stroke: "currentColor",
|
|
295
|
+
strokeWidth: "2",
|
|
296
|
+
strokeLinecap: "round",
|
|
297
|
+
strokeLinejoin: "round",
|
|
298
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 8l4 4 4-4" })
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
},
|
|
302
|
+
key
|
|
303
|
+
)) });
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// src/plugins/MarkdownSyncPlugin.tsx
|
|
307
|
+
import { useEffect as useEffect5, useRef as useRef2 } from "react";
|
|
308
|
+
import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
|
|
172
309
|
import {
|
|
173
310
|
$convertFromMarkdownString,
|
|
174
311
|
$convertToMarkdownString
|
|
@@ -178,11 +315,11 @@ function MarkdownSyncPlugin({
|
|
|
178
315
|
onChange,
|
|
179
316
|
transformers
|
|
180
317
|
}) {
|
|
181
|
-
const [editor] =
|
|
182
|
-
const lastMarkdownRef =
|
|
183
|
-
const onChangeRef =
|
|
318
|
+
const [editor] = useLexicalComposerContext5();
|
|
319
|
+
const lastMarkdownRef = useRef2("");
|
|
320
|
+
const onChangeRef = useRef2(onChange);
|
|
184
321
|
onChangeRef.current = onChange;
|
|
185
|
-
|
|
322
|
+
useEffect5(() => {
|
|
186
323
|
if (initialMarkdown && initialMarkdown !== lastMarkdownRef.current) {
|
|
187
324
|
lastMarkdownRef.current = initialMarkdown;
|
|
188
325
|
editor.update(() => {
|
|
@@ -190,7 +327,7 @@ function MarkdownSyncPlugin({
|
|
|
190
327
|
}, { tag: "initial-load" });
|
|
191
328
|
}
|
|
192
329
|
}, [editor, initialMarkdown]);
|
|
193
|
-
|
|
330
|
+
useEffect5(() => {
|
|
194
331
|
return editor.registerUpdateListener(
|
|
195
332
|
({ editorState, dirtyElements, dirtyLeaves, tags }) => {
|
|
196
333
|
if (dirtyElements.size === 0 && dirtyLeaves.size === 0) return;
|
|
@@ -205,14 +342,127 @@ function MarkdownSyncPlugin({
|
|
|
205
342
|
return null;
|
|
206
343
|
}
|
|
207
344
|
|
|
208
|
-
// src/plugins/
|
|
345
|
+
// src/plugins/OutlinePlugin.tsx
|
|
209
346
|
import { useCallback as useCallback2, useEffect as useEffect6, useState as useState2 } from "react";
|
|
347
|
+
import { useLexicalComposerContext as useLexicalComposerContext6 } from "@lexical/react/LexicalComposerContext";
|
|
348
|
+
import {
|
|
349
|
+
TableOfContentsPlugin
|
|
350
|
+
} from "@lexical/react/LexicalTableOfContentsPlugin";
|
|
351
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
352
|
+
var INDENT_PER_LEVEL = {
|
|
353
|
+
h1: 0,
|
|
354
|
+
h2: 1,
|
|
355
|
+
h3: 2,
|
|
356
|
+
h4: 3,
|
|
357
|
+
h5: 4,
|
|
358
|
+
h6: 5
|
|
359
|
+
};
|
|
360
|
+
function OutlinePlugin() {
|
|
361
|
+
const [editor] = useLexicalComposerContext6();
|
|
362
|
+
const [collapsed, setCollapsed] = useState2(false);
|
|
363
|
+
const [activeKey, setActiveKey] = useState2(null);
|
|
364
|
+
useEffect6(() => {
|
|
365
|
+
const rootElement = editor.getRootElement();
|
|
366
|
+
const scroller = rootElement?.closest(".zui-text-editor");
|
|
367
|
+
if (!rootElement || !(scroller instanceof HTMLElement)) return;
|
|
368
|
+
let frame = 0;
|
|
369
|
+
const updateActive = () => {
|
|
370
|
+
cancelAnimationFrame(frame);
|
|
371
|
+
frame = requestAnimationFrame(() => {
|
|
372
|
+
const headings = rootElement.querySelectorAll(
|
|
373
|
+
"h1, h2, h3, h4, h5, h6"
|
|
374
|
+
);
|
|
375
|
+
const threshold = scroller.scrollTop + 80;
|
|
376
|
+
let current = null;
|
|
377
|
+
for (const el of headings) {
|
|
378
|
+
if (el.offsetTop <= threshold) {
|
|
379
|
+
current = el.getAttribute("data-outline-key");
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
setActiveKey(current);
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
updateActive();
|
|
386
|
+
scroller.addEventListener("scroll", updateActive, { passive: true });
|
|
387
|
+
const unregister = editor.registerUpdateListener(updateActive);
|
|
388
|
+
return () => {
|
|
389
|
+
cancelAnimationFrame(frame);
|
|
390
|
+
scroller.removeEventListener("scroll", updateActive);
|
|
391
|
+
unregister();
|
|
392
|
+
};
|
|
393
|
+
}, [editor]);
|
|
394
|
+
const scrollTo = useCallback2(
|
|
395
|
+
(key) => {
|
|
396
|
+
editor.getEditorState().read(() => {
|
|
397
|
+
const element = editor.getElementByKey(key);
|
|
398
|
+
element?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
399
|
+
});
|
|
400
|
+
},
|
|
401
|
+
[editor]
|
|
402
|
+
);
|
|
403
|
+
return /* @__PURE__ */ jsx2(TableOfContentsPlugin, { children: (entries) => {
|
|
404
|
+
for (const [key] of entries) {
|
|
405
|
+
editor.getElementByKey(key)?.setAttribute("data-outline-key", key);
|
|
406
|
+
}
|
|
407
|
+
return /* @__PURE__ */ jsxs(
|
|
408
|
+
"div",
|
|
409
|
+
{
|
|
410
|
+
className: `zui-text-editor-outline ${collapsed ? "is-collapsed" : ""}`,
|
|
411
|
+
children: [
|
|
412
|
+
/* @__PURE__ */ jsx2(
|
|
413
|
+
"button",
|
|
414
|
+
{
|
|
415
|
+
type: "button",
|
|
416
|
+
className: "zui-text-editor-outline-toggle",
|
|
417
|
+
title: collapsed ? "Show outline" : "Hide outline",
|
|
418
|
+
"aria-label": collapsed ? "Show outline" : "Hide outline",
|
|
419
|
+
"aria-expanded": !collapsed,
|
|
420
|
+
onClick: () => setCollapsed((c) => !c),
|
|
421
|
+
children: /* @__PURE__ */ jsx2(
|
|
422
|
+
"svg",
|
|
423
|
+
{
|
|
424
|
+
viewBox: "0 0 20 20",
|
|
425
|
+
width: "14",
|
|
426
|
+
height: "14",
|
|
427
|
+
fill: "none",
|
|
428
|
+
stroke: "currentColor",
|
|
429
|
+
strokeWidth: "1.8",
|
|
430
|
+
strokeLinecap: "round",
|
|
431
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M4 5h12M4 10h8M4 15h10" })
|
|
432
|
+
}
|
|
433
|
+
)
|
|
434
|
+
}
|
|
435
|
+
),
|
|
436
|
+
!collapsed && /* @__PURE__ */ jsxs("nav", { className: "zui-text-editor-outline-list", "aria-label": "Table of contents", children: [
|
|
437
|
+
entries.length === 0 && /* @__PURE__ */ jsx2("div", { className: "zui-text-editor-outline-empty", children: "No headings" }),
|
|
438
|
+
entries.map(([key, text, tag]) => /* @__PURE__ */ jsx2(
|
|
439
|
+
"button",
|
|
440
|
+
{
|
|
441
|
+
type: "button",
|
|
442
|
+
className: `zui-text-editor-outline-item ${key === activeKey ? "is-active" : ""}`,
|
|
443
|
+
style: {
|
|
444
|
+
paddingLeft: `${0.5 + INDENT_PER_LEVEL[tag] * 0.75}rem`
|
|
445
|
+
},
|
|
446
|
+
onClick: () => scrollTo(key),
|
|
447
|
+
children: text || "Untitled"
|
|
448
|
+
},
|
|
449
|
+
key
|
|
450
|
+
))
|
|
451
|
+
] })
|
|
452
|
+
]
|
|
453
|
+
}
|
|
454
|
+
);
|
|
455
|
+
} });
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// src/plugins/ToolbarPlugin.tsx
|
|
459
|
+
import { useCallback as useCallback4, useEffect as useEffect8, useState as useState4 } from "react";
|
|
210
460
|
import {
|
|
211
|
-
$getSelection as $
|
|
212
|
-
$isRangeSelection as $
|
|
461
|
+
$getSelection as $getSelection3,
|
|
462
|
+
$isRangeSelection as $isRangeSelection3,
|
|
213
463
|
FORMAT_TEXT_COMMAND
|
|
214
464
|
} from "lexical";
|
|
215
|
-
import { useLexicalComposerContext as
|
|
465
|
+
import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
|
|
216
466
|
import { INSERT_TABLE_COMMAND } from "@lexical/table";
|
|
217
467
|
import { $insertNodeToNearestRoot } from "@lexical/utils";
|
|
218
468
|
|
|
@@ -224,13 +474,13 @@ import {
|
|
|
224
474
|
|
|
225
475
|
// src/components/DrawingCanvas.tsx
|
|
226
476
|
import {
|
|
227
|
-
useCallback,
|
|
228
|
-
useEffect as
|
|
229
|
-
useRef as
|
|
230
|
-
useState
|
|
477
|
+
useCallback as useCallback3,
|
|
478
|
+
useEffect as useEffect7,
|
|
479
|
+
useRef as useRef3,
|
|
480
|
+
useState as useState3
|
|
231
481
|
} from "react";
|
|
232
482
|
import { $getNodeByKey as $getNodeByKey2 } from "lexical";
|
|
233
|
-
import { useLexicalComposerContext as
|
|
483
|
+
import { useLexicalComposerContext as useLexicalComposerContext7 } from "@lexical/react/LexicalComposerContext";
|
|
234
484
|
import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
|
|
235
485
|
|
|
236
486
|
// src/components/drawingTypes.ts
|
|
@@ -541,7 +791,7 @@ function resolveBindings(shapes) {
|
|
|
541
791
|
}
|
|
542
792
|
|
|
543
793
|
// src/components/DrawingCanvas.tsx
|
|
544
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
794
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
545
795
|
import { createElement } from "react";
|
|
546
796
|
var MIN_HEIGHT = 120;
|
|
547
797
|
var MAX_HEIGHT = 900;
|
|
@@ -575,7 +825,7 @@ function BoxTexts({
|
|
|
575
825
|
opacity: 0.35,
|
|
576
826
|
style: { userSelect: "none", pointerEvents: "none" }
|
|
577
827
|
};
|
|
578
|
-
return /* @__PURE__ */
|
|
828
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
579
829
|
hideField !== "label" && (shape.label ? labelLines.map((line, i) => /* @__PURE__ */ createElement(
|
|
580
830
|
"text",
|
|
581
831
|
{
|
|
@@ -588,7 +838,7 @@ function BoxTexts({
|
|
|
588
838
|
opacity: 0.85
|
|
589
839
|
},
|
|
590
840
|
line
|
|
591
|
-
)) : showHints && /* @__PURE__ */
|
|
841
|
+
)) : showHints && /* @__PURE__ */ jsx3("text", { ...hint, x: cx, y: b.y + SMALL_FONT_SIZE + 7, fontSize: SMALL_FONT_SIZE, children: "Label" })),
|
|
592
842
|
hideField !== "text" && (shape.text ? mainLines.map((line, i) => /* @__PURE__ */ createElement(
|
|
593
843
|
"text",
|
|
594
844
|
{
|
|
@@ -599,7 +849,7 @@ function BoxTexts({
|
|
|
599
849
|
fontSize: FONT_SIZE
|
|
600
850
|
},
|
|
601
851
|
line
|
|
602
|
-
)) : showHints && /* @__PURE__ */
|
|
852
|
+
)) : showHints && /* @__PURE__ */ jsx3("text", { ...hint, x: cx, y: mainStart, fontSize: FONT_SIZE, children: "Text" })),
|
|
603
853
|
hideField !== "footer" && (shape.footer ? footerLines.map((line, i) => /* @__PURE__ */ createElement(
|
|
604
854
|
"text",
|
|
605
855
|
{
|
|
@@ -611,7 +861,7 @@ function BoxTexts({
|
|
|
611
861
|
opacity: 0.65
|
|
612
862
|
},
|
|
613
863
|
line
|
|
614
|
-
)) : showHints && /* @__PURE__ */
|
|
864
|
+
)) : showHints && /* @__PURE__ */ jsx3("text", { ...hint, x: cx, y: b.y + b.h - 9, fontSize: SMALL_FONT_SIZE, children: "Footer" }))
|
|
615
865
|
] });
|
|
616
866
|
}
|
|
617
867
|
function ShapeView({
|
|
@@ -628,8 +878,8 @@ function ShapeView({
|
|
|
628
878
|
switch (shape.type) {
|
|
629
879
|
case "rect": {
|
|
630
880
|
const b = bbox(shape);
|
|
631
|
-
return /* @__PURE__ */
|
|
632
|
-
/* @__PURE__ */
|
|
881
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
882
|
+
/* @__PURE__ */ jsx3(
|
|
633
883
|
"rect",
|
|
634
884
|
{
|
|
635
885
|
...common,
|
|
@@ -641,13 +891,13 @@ function ShapeView({
|
|
|
641
891
|
fill: shape.fill
|
|
642
892
|
}
|
|
643
893
|
),
|
|
644
|
-
/* @__PURE__ */
|
|
894
|
+
/* @__PURE__ */ jsx3(BoxTexts, { shape, hideField, showHints })
|
|
645
895
|
] });
|
|
646
896
|
}
|
|
647
897
|
case "ellipse": {
|
|
648
898
|
const b = bbox(shape);
|
|
649
|
-
return /* @__PURE__ */
|
|
650
|
-
/* @__PURE__ */
|
|
899
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
900
|
+
/* @__PURE__ */ jsx3(
|
|
651
901
|
"ellipse",
|
|
652
902
|
{
|
|
653
903
|
...common,
|
|
@@ -658,13 +908,13 @@ function ShapeView({
|
|
|
658
908
|
fill: shape.fill
|
|
659
909
|
}
|
|
660
910
|
),
|
|
661
|
-
/* @__PURE__ */
|
|
911
|
+
/* @__PURE__ */ jsx3(BoxTexts, { shape, hideField, showHints })
|
|
662
912
|
] });
|
|
663
913
|
}
|
|
664
914
|
case "triangle":
|
|
665
915
|
case "pentagon":
|
|
666
|
-
return /* @__PURE__ */
|
|
667
|
-
/* @__PURE__ */
|
|
916
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
917
|
+
/* @__PURE__ */ jsx3(
|
|
668
918
|
"polygon",
|
|
669
919
|
{
|
|
670
920
|
...common,
|
|
@@ -672,12 +922,12 @@ function ShapeView({
|
|
|
672
922
|
fill: shape.fill
|
|
673
923
|
}
|
|
674
924
|
),
|
|
675
|
-
/* @__PURE__ */
|
|
925
|
+
/* @__PURE__ */ jsx3(BoxTexts, { shape, hideField, showHints })
|
|
676
926
|
] });
|
|
677
927
|
case "line":
|
|
678
928
|
case "arrow":
|
|
679
|
-
return /* @__PURE__ */
|
|
680
|
-
/* @__PURE__ */
|
|
929
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
930
|
+
/* @__PURE__ */ jsx3(
|
|
681
931
|
"path",
|
|
682
932
|
{
|
|
683
933
|
...common,
|
|
@@ -685,10 +935,10 @@ function ShapeView({
|
|
|
685
935
|
fill: "none"
|
|
686
936
|
}
|
|
687
937
|
),
|
|
688
|
-
shape.text && hideField !== "text" && /* @__PURE__ */
|
|
938
|
+
shape.text && hideField !== "text" && /* @__PURE__ */ jsx3(ConnectorLabel, { shape })
|
|
689
939
|
] });
|
|
690
940
|
case "text":
|
|
691
|
-
return /* @__PURE__ */
|
|
941
|
+
return /* @__PURE__ */ jsx3(
|
|
692
942
|
"text",
|
|
693
943
|
{
|
|
694
944
|
x: shape.x,
|
|
@@ -697,7 +947,7 @@ function ShapeView({
|
|
|
697
947
|
fontSize: FONT_SIZE,
|
|
698
948
|
fontFamily: "ui-sans-serif, system-ui, sans-serif",
|
|
699
949
|
style: { userSelect: "none", whiteSpace: "pre" },
|
|
700
|
-
children: (shape.text ?? "").split("\n").map((line, i) => /* @__PURE__ */
|
|
950
|
+
children: (shape.text ?? "").split("\n").map((line, i) => /* @__PURE__ */ jsx3("tspan", { x: shape.x, dy: i === 0 ? 0 : FONT_SIZE * 1.35, children: line }, i))
|
|
701
951
|
}
|
|
702
952
|
);
|
|
703
953
|
}
|
|
@@ -709,8 +959,8 @@ function ConnectorLabel({ shape }) {
|
|
|
709
959
|
const { x: midX, y: midY } = connectorMidpoint(shape);
|
|
710
960
|
const lineH = CONNECTOR_FONT_SIZE * LINE_HEIGHT;
|
|
711
961
|
const startY = midY - (lines.length - 1) * lineH / 2 + CONNECTOR_FONT_SIZE * 0.35;
|
|
712
|
-
return /* @__PURE__ */
|
|
713
|
-
/* @__PURE__ */
|
|
962
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
963
|
+
/* @__PURE__ */ jsx3(
|
|
714
964
|
"rect",
|
|
715
965
|
{
|
|
716
966
|
x: midX - size.w / 2 - 5,
|
|
@@ -722,7 +972,7 @@ function ConnectorLabel({ shape }) {
|
|
|
722
972
|
opacity: 0.92
|
|
723
973
|
}
|
|
724
974
|
),
|
|
725
|
-
lines.map((line, i) => /* @__PURE__ */
|
|
975
|
+
lines.map((line, i) => /* @__PURE__ */ jsx3(
|
|
726
976
|
"text",
|
|
727
977
|
{
|
|
728
978
|
x: midX,
|
|
@@ -739,20 +989,20 @@ function ConnectorLabel({ shape }) {
|
|
|
739
989
|
] });
|
|
740
990
|
}
|
|
741
991
|
var TOOL_ICONS = {
|
|
742
|
-
select: /* @__PURE__ */
|
|
743
|
-
rect: /* @__PURE__ */
|
|
744
|
-
ellipse: /* @__PURE__ */
|
|
745
|
-
triangle: /* @__PURE__ */
|
|
746
|
-
pentagon: /* @__PURE__ */
|
|
747
|
-
arrow: /* @__PURE__ */
|
|
748
|
-
/* @__PURE__ */
|
|
749
|
-
/* @__PURE__ */
|
|
992
|
+
select: /* @__PURE__ */ jsx3("path", { d: "M4 2l12 6.5-5.2 1.6L8 16z", fill: "currentColor", stroke: "none" }),
|
|
993
|
+
rect: /* @__PURE__ */ jsx3("rect", { x: "3", y: "4.5", width: "14", height: "11", rx: "2" }),
|
|
994
|
+
ellipse: /* @__PURE__ */ jsx3("ellipse", { cx: "10", cy: "10", rx: "7", ry: "5.5" }),
|
|
995
|
+
triangle: /* @__PURE__ */ jsx3("path", { d: "M10 3.5L17 16.5H3z", strokeLinejoin: "round" }),
|
|
996
|
+
pentagon: /* @__PURE__ */ jsx3("path", { d: "M10 3L16.8 8.1L14.2 16.2H5.8L3.2 8.1z", strokeLinejoin: "round" }),
|
|
997
|
+
arrow: /* @__PURE__ */ jsxs2("g", { children: [
|
|
998
|
+
/* @__PURE__ */ jsx3("path", { d: "M4 16L16 4" }),
|
|
999
|
+
/* @__PURE__ */ jsx3("path", { d: "M9 4h7v7" })
|
|
750
1000
|
] }),
|
|
751
|
-
line: /* @__PURE__ */
|
|
752
|
-
text: /* @__PURE__ */
|
|
753
|
-
/* @__PURE__ */
|
|
754
|
-
/* @__PURE__ */
|
|
755
|
-
/* @__PURE__ */
|
|
1001
|
+
line: /* @__PURE__ */ jsx3("path", { d: "M4 16L16 4" }),
|
|
1002
|
+
text: /* @__PURE__ */ jsxs2("g", { children: [
|
|
1003
|
+
/* @__PURE__ */ jsx3("path", { d: "M4 5V3.5h12V5" }),
|
|
1004
|
+
/* @__PURE__ */ jsx3("path", { d: "M10 3.5V16.5" }),
|
|
1005
|
+
/* @__PURE__ */ jsx3("path", { d: "M7 16.5h6" })
|
|
756
1006
|
] })
|
|
757
1007
|
};
|
|
758
1008
|
function bindEndpoints(shape, shapes) {
|
|
@@ -776,23 +1026,23 @@ var TOOLS = [
|
|
|
776
1026
|
{ tool: "text", label: "Text" }
|
|
777
1027
|
];
|
|
778
1028
|
function DrawingCanvas({ nodeKey, data }) {
|
|
779
|
-
const [editor] =
|
|
1029
|
+
const [editor] = useLexicalComposerContext7();
|
|
780
1030
|
const isEditable = useLexicalEditable();
|
|
781
|
-
const [shapes, setShapes] =
|
|
782
|
-
const [height, setHeight] =
|
|
783
|
-
const [tool, setTool] =
|
|
784
|
-
const [selectedId, setSelectedId] =
|
|
785
|
-
const [editingText, setEditingText] =
|
|
786
|
-
const [stroke, setStroke] =
|
|
787
|
-
const [fill, setFill] =
|
|
788
|
-
const svgRef =
|
|
789
|
-
const dragRef =
|
|
790
|
-
const lastCommittedRef =
|
|
791
|
-
const shapesRef =
|
|
1031
|
+
const [shapes, setShapes] = useState3(data.shapes);
|
|
1032
|
+
const [height, setHeight] = useState3(data.height);
|
|
1033
|
+
const [tool, setTool] = useState3("select");
|
|
1034
|
+
const [selectedId, setSelectedId] = useState3(null);
|
|
1035
|
+
const [editingText, setEditingText] = useState3(null);
|
|
1036
|
+
const [stroke, setStroke] = useState3(STROKE_COLORS[0]);
|
|
1037
|
+
const [fill, setFill] = useState3(FILL_COLORS[0]);
|
|
1038
|
+
const svgRef = useRef3(null);
|
|
1039
|
+
const dragRef = useRef3(null);
|
|
1040
|
+
const lastCommittedRef = useRef3(serializeDrawingData(data));
|
|
1041
|
+
const shapesRef = useRef3(shapes);
|
|
792
1042
|
shapesRef.current = shapes;
|
|
793
|
-
const heightRef =
|
|
1043
|
+
const heightRef = useRef3(height);
|
|
794
1044
|
heightRef.current = height;
|
|
795
|
-
|
|
1045
|
+
useEffect7(() => {
|
|
796
1046
|
const incoming = serializeDrawingData(data);
|
|
797
1047
|
if (incoming !== lastCommittedRef.current) {
|
|
798
1048
|
lastCommittedRef.current = incoming;
|
|
@@ -802,7 +1052,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
802
1052
|
setEditingText(null);
|
|
803
1053
|
}
|
|
804
1054
|
}, [data]);
|
|
805
|
-
const commit =
|
|
1055
|
+
const commit = useCallback3(
|
|
806
1056
|
(nextShapes, nextHeight) => {
|
|
807
1057
|
const payload = {
|
|
808
1058
|
version: 1,
|
|
@@ -821,7 +1071,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
821
1071
|
},
|
|
822
1072
|
[editor, nodeKey]
|
|
823
1073
|
);
|
|
824
|
-
const updateShapes =
|
|
1074
|
+
const updateShapes = useCallback3(
|
|
825
1075
|
(updater, options) => {
|
|
826
1076
|
setShapes((prev) => {
|
|
827
1077
|
const next = resolveBindings(updater(prev));
|
|
@@ -831,17 +1081,17 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
831
1081
|
},
|
|
832
1082
|
[commit]
|
|
833
1083
|
);
|
|
834
|
-
const getPoint =
|
|
1084
|
+
const getPoint = useCallback3((e) => {
|
|
835
1085
|
const rect = svgRef.current?.getBoundingClientRect();
|
|
836
1086
|
if (!rect) return { x: 0, y: 0 };
|
|
837
1087
|
return { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
|
838
1088
|
}, []);
|
|
839
1089
|
const selectedShape = shapes.find((s) => s.id === selectedId) ?? null;
|
|
840
|
-
const startTextEditing =
|
|
1090
|
+
const startTextEditing = useCallback3((id, field) => {
|
|
841
1091
|
setEditingText({ id, field });
|
|
842
1092
|
setSelectedId(id);
|
|
843
1093
|
}, []);
|
|
844
|
-
const handleBackgroundPointerDown =
|
|
1094
|
+
const handleBackgroundPointerDown = useCallback3(
|
|
845
1095
|
(e) => {
|
|
846
1096
|
if (!isEditable || editingText) return;
|
|
847
1097
|
if (e.button !== 0) return;
|
|
@@ -901,7 +1151,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
901
1151
|
startTextEditing
|
|
902
1152
|
]
|
|
903
1153
|
);
|
|
904
|
-
const handleShapePointerDown =
|
|
1154
|
+
const handleShapePointerDown = useCallback3(
|
|
905
1155
|
(e, shape) => {
|
|
906
1156
|
if (!isEditable || tool !== "select" || editingText) return;
|
|
907
1157
|
if (e.button !== 0) return;
|
|
@@ -920,7 +1170,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
920
1170
|
},
|
|
921
1171
|
[isEditable, tool, editingText, getPoint, selectedId]
|
|
922
1172
|
);
|
|
923
|
-
const handleHandlePointerDown =
|
|
1173
|
+
const handleHandlePointerDown = useCallback3(
|
|
924
1174
|
(e, drag) => {
|
|
925
1175
|
if (!isEditable) return;
|
|
926
1176
|
if (e.button !== 0) return;
|
|
@@ -936,7 +1186,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
936
1186
|
},
|
|
937
1187
|
[isEditable, updateShapes]
|
|
938
1188
|
);
|
|
939
|
-
const handlePointerMove =
|
|
1189
|
+
const handlePointerMove = useCallback3(
|
|
940
1190
|
(e) => {
|
|
941
1191
|
const drag = dragRef.current;
|
|
942
1192
|
if (!drag) return;
|
|
@@ -1027,7 +1277,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1027
1277
|
},
|
|
1028
1278
|
[getPoint, updateShapes]
|
|
1029
1279
|
);
|
|
1030
|
-
const handlePointerUp =
|
|
1280
|
+
const handlePointerUp = useCallback3(() => {
|
|
1031
1281
|
const drag = dragRef.current;
|
|
1032
1282
|
dragRef.current = null;
|
|
1033
1283
|
if (!drag) return;
|
|
@@ -1080,7 +1330,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1080
1330
|
}
|
|
1081
1331
|
updateShapes((prev) => prev.map(normalize), { commit: true });
|
|
1082
1332
|
}, [commit, updateShapes, startTextEditing]);
|
|
1083
|
-
const deleteSelected =
|
|
1333
|
+
const deleteSelected = useCallback3(() => {
|
|
1084
1334
|
if (!selectedId) return;
|
|
1085
1335
|
setEditingText(null);
|
|
1086
1336
|
setSelectedId(null);
|
|
@@ -1088,7 +1338,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1088
1338
|
commit: true
|
|
1089
1339
|
});
|
|
1090
1340
|
}, [selectedId, updateShapes]);
|
|
1091
|
-
const handleKeyDown =
|
|
1341
|
+
const handleKeyDown = useCallback3(
|
|
1092
1342
|
(e) => {
|
|
1093
1343
|
if (!isEditable || editingText) return;
|
|
1094
1344
|
if ((e.key === "Delete" || e.key === "Backspace") && selectedId) {
|
|
@@ -1116,7 +1366,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1116
1366
|
startTextEditing
|
|
1117
1367
|
]
|
|
1118
1368
|
);
|
|
1119
|
-
const applyStroke =
|
|
1369
|
+
const applyStroke = useCallback3(
|
|
1120
1370
|
(color) => {
|
|
1121
1371
|
setStroke(color);
|
|
1122
1372
|
if (selectedId) {
|
|
@@ -1128,7 +1378,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1128
1378
|
},
|
|
1129
1379
|
[selectedId, updateShapes]
|
|
1130
1380
|
);
|
|
1131
|
-
const applyFill =
|
|
1381
|
+
const applyFill = useCallback3(
|
|
1132
1382
|
(color) => {
|
|
1133
1383
|
setFill(color);
|
|
1134
1384
|
if (selectedId) {
|
|
@@ -1140,7 +1390,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1140
1390
|
},
|
|
1141
1391
|
[selectedId, updateShapes]
|
|
1142
1392
|
);
|
|
1143
|
-
const applyRouting =
|
|
1393
|
+
const applyRouting = useCallback3(
|
|
1144
1394
|
(elbow) => {
|
|
1145
1395
|
if (!selectedId) return;
|
|
1146
1396
|
updateShapes(
|
|
@@ -1157,7 +1407,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1157
1407
|
},
|
|
1158
1408
|
[selectedId, updateShapes]
|
|
1159
1409
|
);
|
|
1160
|
-
const addWaypoint =
|
|
1410
|
+
const addWaypoint = useCallback3(
|
|
1161
1411
|
(e, shapeId, segmentIndex, point) => {
|
|
1162
1412
|
if (!isEditable) return;
|
|
1163
1413
|
if (e.button !== 0) return;
|
|
@@ -1179,7 +1429,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1179
1429
|
},
|
|
1180
1430
|
[isEditable, updateShapes]
|
|
1181
1431
|
);
|
|
1182
|
-
const removeWaypoint =
|
|
1432
|
+
const removeWaypoint = useCallback3(
|
|
1183
1433
|
(shapeId, index) => {
|
|
1184
1434
|
updateShapes(
|
|
1185
1435
|
(prev) => prev.map((s) => {
|
|
@@ -1192,7 +1442,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1192
1442
|
},
|
|
1193
1443
|
[updateShapes]
|
|
1194
1444
|
);
|
|
1195
|
-
const applyDirection =
|
|
1445
|
+
const applyDirection = useCallback3(
|
|
1196
1446
|
(bidirectional) => {
|
|
1197
1447
|
if (!selectedId) return;
|
|
1198
1448
|
updateShapes(
|
|
@@ -1204,7 +1454,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1204
1454
|
},
|
|
1205
1455
|
[selectedId, updateShapes]
|
|
1206
1456
|
);
|
|
1207
|
-
const commitText =
|
|
1457
|
+
const commitText = useCallback3(
|
|
1208
1458
|
(id, field, value) => {
|
|
1209
1459
|
setEditingText(null);
|
|
1210
1460
|
updateShapes(
|
|
@@ -1225,15 +1475,15 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1225
1475
|
const editingShape = shapes.find((s) => s.id === editingText?.id) ?? null;
|
|
1226
1476
|
const showFill = selectedShape != null ? isBoxType(selectedShape.type) : tool !== "select" && isBoxType(tool);
|
|
1227
1477
|
const canvasCursor = tool === "select" ? "default" : tool === "text" ? "text" : "crosshair";
|
|
1228
|
-
return /* @__PURE__ */
|
|
1478
|
+
return /* @__PURE__ */ jsxs2(
|
|
1229
1479
|
"div",
|
|
1230
1480
|
{
|
|
1231
1481
|
className: "zui-drawing-canvas",
|
|
1232
1482
|
tabIndex: isEditable ? 0 : void 0,
|
|
1233
1483
|
onKeyDown: handleKeyDown,
|
|
1234
1484
|
children: [
|
|
1235
|
-
isEditable && /* @__PURE__ */
|
|
1236
|
-
/* @__PURE__ */
|
|
1485
|
+
isEditable && /* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar", onPointerDown: (e) => e.stopPropagation(), children: [
|
|
1486
|
+
/* @__PURE__ */ jsx3("div", { className: "zui-drawing-toolbar-group", children: TOOLS.map(({ tool: t, label }) => /* @__PURE__ */ jsx3(
|
|
1237
1487
|
"button",
|
|
1238
1488
|
{
|
|
1239
1489
|
type: "button",
|
|
@@ -1244,7 +1494,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1244
1494
|
setTool(t);
|
|
1245
1495
|
if (t !== "select") setSelectedId(null);
|
|
1246
1496
|
},
|
|
1247
|
-
children: /* @__PURE__ */
|
|
1497
|
+
children: /* @__PURE__ */ jsx3(
|
|
1248
1498
|
"svg",
|
|
1249
1499
|
{
|
|
1250
1500
|
viewBox: "0 0 20 20",
|
|
@@ -1261,9 +1511,9 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1261
1511
|
},
|
|
1262
1512
|
t
|
|
1263
1513
|
)) }),
|
|
1264
|
-
/* @__PURE__ */
|
|
1265
|
-
/* @__PURE__ */
|
|
1266
|
-
STROKE_COLORS.map((color) => /* @__PURE__ */
|
|
1514
|
+
/* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar-group", children: [
|
|
1515
|
+
/* @__PURE__ */ jsx3("span", { className: "zui-drawing-swatch-label", children: "Stroke" }),
|
|
1516
|
+
STROKE_COLORS.map((color) => /* @__PURE__ */ jsx3(
|
|
1267
1517
|
"button",
|
|
1268
1518
|
{
|
|
1269
1519
|
type: "button",
|
|
@@ -1276,9 +1526,9 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1276
1526
|
color
|
|
1277
1527
|
))
|
|
1278
1528
|
] }),
|
|
1279
|
-
showFill && /* @__PURE__ */
|
|
1280
|
-
/* @__PURE__ */
|
|
1281
|
-
FILL_COLORS.map((color) => /* @__PURE__ */
|
|
1529
|
+
showFill && /* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar-group", children: [
|
|
1530
|
+
/* @__PURE__ */ jsx3("span", { className: "zui-drawing-swatch-label", children: "Fill" }),
|
|
1531
|
+
FILL_COLORS.map((color) => /* @__PURE__ */ jsx3(
|
|
1282
1532
|
"button",
|
|
1283
1533
|
{
|
|
1284
1534
|
type: "button",
|
|
@@ -1291,8 +1541,8 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1291
1541
|
color
|
|
1292
1542
|
))
|
|
1293
1543
|
] }),
|
|
1294
|
-
selectedShape && isConnectorType(selectedShape.type) && /* @__PURE__ */
|
|
1295
|
-
/* @__PURE__ */
|
|
1544
|
+
selectedShape && isConnectorType(selectedShape.type) && /* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar-group", children: [
|
|
1545
|
+
/* @__PURE__ */ jsx3(
|
|
1296
1546
|
"button",
|
|
1297
1547
|
{
|
|
1298
1548
|
type: "button",
|
|
@@ -1300,7 +1550,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1300
1550
|
"aria-label": "Straight connector",
|
|
1301
1551
|
className: `zui-drawing-tool ${selectedShape.routing !== "elbow" ? "is-active" : ""}`,
|
|
1302
1552
|
onClick: () => applyRouting(false),
|
|
1303
|
-
children: /* @__PURE__ */
|
|
1553
|
+
children: /* @__PURE__ */ jsx3(
|
|
1304
1554
|
"svg",
|
|
1305
1555
|
{
|
|
1306
1556
|
viewBox: "0 0 20 20",
|
|
@@ -1310,12 +1560,12 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1310
1560
|
stroke: "currentColor",
|
|
1311
1561
|
strokeWidth: "1.6",
|
|
1312
1562
|
strokeLinecap: "round",
|
|
1313
|
-
children: /* @__PURE__ */
|
|
1563
|
+
children: /* @__PURE__ */ jsx3("path", { d: "M4 16L16 4" })
|
|
1314
1564
|
}
|
|
1315
1565
|
)
|
|
1316
1566
|
}
|
|
1317
1567
|
),
|
|
1318
|
-
/* @__PURE__ */
|
|
1568
|
+
/* @__PURE__ */ jsx3(
|
|
1319
1569
|
"button",
|
|
1320
1570
|
{
|
|
1321
1571
|
type: "button",
|
|
@@ -1323,7 +1573,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1323
1573
|
"aria-label": "Elbow connector",
|
|
1324
1574
|
className: `zui-drawing-tool ${selectedShape.routing === "elbow" ? "is-active" : ""}`,
|
|
1325
1575
|
onClick: () => applyRouting(true),
|
|
1326
|
-
children: /* @__PURE__ */
|
|
1576
|
+
children: /* @__PURE__ */ jsx3(
|
|
1327
1577
|
"svg",
|
|
1328
1578
|
{
|
|
1329
1579
|
viewBox: "0 0 20 20",
|
|
@@ -1334,14 +1584,14 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1334
1584
|
strokeWidth: "1.6",
|
|
1335
1585
|
strokeLinecap: "round",
|
|
1336
1586
|
strokeLinejoin: "round",
|
|
1337
|
-
children: /* @__PURE__ */
|
|
1587
|
+
children: /* @__PURE__ */ jsx3("path", { d: "M4 16v-6h12V4" })
|
|
1338
1588
|
}
|
|
1339
1589
|
)
|
|
1340
1590
|
}
|
|
1341
1591
|
)
|
|
1342
1592
|
] }),
|
|
1343
|
-
selectedShape?.type === "arrow" && /* @__PURE__ */
|
|
1344
|
-
/* @__PURE__ */
|
|
1593
|
+
selectedShape?.type === "arrow" && /* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar-group", children: [
|
|
1594
|
+
/* @__PURE__ */ jsx3(
|
|
1345
1595
|
"button",
|
|
1346
1596
|
{
|
|
1347
1597
|
type: "button",
|
|
@@ -1349,7 +1599,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1349
1599
|
"aria-label": "One-way arrow",
|
|
1350
1600
|
className: `zui-drawing-tool ${!selectedShape.bidirectional ? "is-active" : ""}`,
|
|
1351
1601
|
onClick: () => applyDirection(false),
|
|
1352
|
-
children: /* @__PURE__ */
|
|
1602
|
+
children: /* @__PURE__ */ jsx3(
|
|
1353
1603
|
"svg",
|
|
1354
1604
|
{
|
|
1355
1605
|
viewBox: "0 0 20 20",
|
|
@@ -1360,12 +1610,12 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1360
1610
|
strokeWidth: "1.6",
|
|
1361
1611
|
strokeLinecap: "round",
|
|
1362
1612
|
strokeLinejoin: "round",
|
|
1363
|
-
children: /* @__PURE__ */
|
|
1613
|
+
children: /* @__PURE__ */ jsx3("path", { d: "M3 10h13M12 5.5L16.5 10L12 14.5" })
|
|
1364
1614
|
}
|
|
1365
1615
|
)
|
|
1366
1616
|
}
|
|
1367
1617
|
),
|
|
1368
|
-
/* @__PURE__ */
|
|
1618
|
+
/* @__PURE__ */ jsx3(
|
|
1369
1619
|
"button",
|
|
1370
1620
|
{
|
|
1371
1621
|
type: "button",
|
|
@@ -1373,7 +1623,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1373
1623
|
"aria-label": "Two-way arrow",
|
|
1374
1624
|
className: `zui-drawing-tool ${selectedShape.bidirectional ? "is-active" : ""}`,
|
|
1375
1625
|
onClick: () => applyDirection(true),
|
|
1376
|
-
children: /* @__PURE__ */
|
|
1626
|
+
children: /* @__PURE__ */ jsx3(
|
|
1377
1627
|
"svg",
|
|
1378
1628
|
{
|
|
1379
1629
|
viewBox: "0 0 20 20",
|
|
@@ -1384,13 +1634,13 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1384
1634
|
strokeWidth: "1.6",
|
|
1385
1635
|
strokeLinecap: "round",
|
|
1386
1636
|
strokeLinejoin: "round",
|
|
1387
|
-
children: /* @__PURE__ */
|
|
1637
|
+
children: /* @__PURE__ */ jsx3("path", { d: "M3.5 10h13M8 5.5L3.5 10L8 14.5M12 5.5L16.5 10L12 14.5" })
|
|
1388
1638
|
}
|
|
1389
1639
|
)
|
|
1390
1640
|
}
|
|
1391
1641
|
)
|
|
1392
1642
|
] }),
|
|
1393
|
-
selectedShape && /* @__PURE__ */
|
|
1643
|
+
selectedShape && /* @__PURE__ */ jsx3("div", { className: "zui-drawing-toolbar-group", children: /* @__PURE__ */ jsx3(
|
|
1394
1644
|
"button",
|
|
1395
1645
|
{
|
|
1396
1646
|
type: "button",
|
|
@@ -1398,7 +1648,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1398
1648
|
"aria-label": "Delete shape",
|
|
1399
1649
|
className: "zui-drawing-tool zui-drawing-tool-danger",
|
|
1400
1650
|
onClick: deleteSelected,
|
|
1401
|
-
children: /* @__PURE__ */
|
|
1651
|
+
children: /* @__PURE__ */ jsx3(
|
|
1402
1652
|
"svg",
|
|
1403
1653
|
{
|
|
1404
1654
|
viewBox: "0 0 20 20",
|
|
@@ -1408,13 +1658,13 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1408
1658
|
stroke: "currentColor",
|
|
1409
1659
|
strokeWidth: "1.6",
|
|
1410
1660
|
strokeLinecap: "round",
|
|
1411
|
-
children: /* @__PURE__ */
|
|
1661
|
+
children: /* @__PURE__ */ jsx3("path", { d: "M4 6h12M8 6V4h4v2M6 6l1 10h6l1-10M8.5 9v4M11.5 9v4" })
|
|
1412
1662
|
}
|
|
1413
1663
|
)
|
|
1414
1664
|
}
|
|
1415
1665
|
) })
|
|
1416
1666
|
] }),
|
|
1417
|
-
/* @__PURE__ */
|
|
1667
|
+
/* @__PURE__ */ jsxs2(
|
|
1418
1668
|
"svg",
|
|
1419
1669
|
{
|
|
1420
1670
|
ref: svgRef,
|
|
@@ -1441,7 +1691,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1441
1691
|
}
|
|
1442
1692
|
},
|
|
1443
1693
|
children: [
|
|
1444
|
-
shapes.map((shape) => /* @__PURE__ */
|
|
1694
|
+
shapes.map((shape) => /* @__PURE__ */ jsxs2(
|
|
1445
1695
|
"g",
|
|
1446
1696
|
{
|
|
1447
1697
|
"data-shape-id": shape.id,
|
|
@@ -1450,7 +1700,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1450
1700
|
},
|
|
1451
1701
|
onPointerDown: (e) => handleShapePointerDown(e, shape),
|
|
1452
1702
|
children: [
|
|
1453
|
-
isConnectorType(shape.type) && /* @__PURE__ */
|
|
1703
|
+
isConnectorType(shape.type) && /* @__PURE__ */ jsx3(
|
|
1454
1704
|
"path",
|
|
1455
1705
|
{
|
|
1456
1706
|
d: connectorPath(shape),
|
|
@@ -1459,8 +1709,8 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1459
1709
|
strokeWidth: 14
|
|
1460
1710
|
}
|
|
1461
1711
|
),
|
|
1462
|
-
(isBoxType(shape.type) || shape.type === "text") && /* @__PURE__ */
|
|
1463
|
-
shape.id === editingText?.id && shape.type === "text" ? null : /* @__PURE__ */
|
|
1712
|
+
(isBoxType(shape.type) || shape.type === "text") && /* @__PURE__ */ jsx3(HitArea, { shape }),
|
|
1713
|
+
shape.id === editingText?.id && shape.type === "text" ? null : /* @__PURE__ */ jsx3(
|
|
1464
1714
|
ShapeView,
|
|
1465
1715
|
{
|
|
1466
1716
|
shape,
|
|
@@ -1472,7 +1722,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1472
1722
|
},
|
|
1473
1723
|
shape.id
|
|
1474
1724
|
)),
|
|
1475
|
-
selectedShape && isEditable && !editingText && /* @__PURE__ */
|
|
1725
|
+
selectedShape && isEditable && !editingText && /* @__PURE__ */ jsx3(
|
|
1476
1726
|
SelectionOverlay,
|
|
1477
1727
|
{
|
|
1478
1728
|
shape: selectedShape,
|
|
@@ -1484,7 +1734,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1484
1734
|
]
|
|
1485
1735
|
}
|
|
1486
1736
|
),
|
|
1487
|
-
editingShape && editingText && /* @__PURE__ */
|
|
1737
|
+
editingShape && editingText && /* @__PURE__ */ jsx3(
|
|
1488
1738
|
TextEditOverlay,
|
|
1489
1739
|
{
|
|
1490
1740
|
shape: editingShape,
|
|
@@ -1493,7 +1743,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1493
1743
|
},
|
|
1494
1744
|
`${editingShape.id}:${editingText.field}`
|
|
1495
1745
|
),
|
|
1496
|
-
isEditable && /* @__PURE__ */
|
|
1746
|
+
isEditable && /* @__PURE__ */ jsx3(
|
|
1497
1747
|
"div",
|
|
1498
1748
|
{
|
|
1499
1749
|
className: "zui-drawing-resize",
|
|
@@ -1532,7 +1782,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1532
1782
|
}
|
|
1533
1783
|
function HitArea({ shape }) {
|
|
1534
1784
|
const b = bbox(shape);
|
|
1535
|
-
return /* @__PURE__ */
|
|
1785
|
+
return /* @__PURE__ */ jsx3(
|
|
1536
1786
|
"rect",
|
|
1537
1787
|
{
|
|
1538
1788
|
x: b.x,
|
|
@@ -1566,8 +1816,8 @@ function SelectionOverlay({
|
|
|
1566
1816
|
if (hasElbowHandle && i === 1) return [];
|
|
1567
1817
|
return [{ index: i, x: (p.x + q.x) / 2, y: (p.y + q.y) / 2 }];
|
|
1568
1818
|
});
|
|
1569
|
-
return /* @__PURE__ */
|
|
1570
|
-
ghosts.map(({ index, x, y }) => /* @__PURE__ */
|
|
1819
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
1820
|
+
ghosts.map(({ index, x, y }) => /* @__PURE__ */ jsx3(
|
|
1571
1821
|
"circle",
|
|
1572
1822
|
{
|
|
1573
1823
|
cx: x,
|
|
@@ -1580,11 +1830,11 @@ function SelectionOverlay({
|
|
|
1580
1830
|
opacity: 0.6,
|
|
1581
1831
|
style: { cursor: "copy" },
|
|
1582
1832
|
onPointerDown: (e) => onWaypointAdd(e, shape.id, index, { x, y }),
|
|
1583
|
-
children: /* @__PURE__ */
|
|
1833
|
+
children: /* @__PURE__ */ jsx3("title", { children: "Drag to add a point" })
|
|
1584
1834
|
},
|
|
1585
1835
|
`ghost-${index}`
|
|
1586
1836
|
)),
|
|
1587
|
-
waypoints.map((p, i) => /* @__PURE__ */
|
|
1837
|
+
waypoints.map((p, i) => /* @__PURE__ */ jsx3(
|
|
1588
1838
|
"rect",
|
|
1589
1839
|
{
|
|
1590
1840
|
x: p.x - 4,
|
|
@@ -1605,11 +1855,11 @@ function SelectionOverlay({
|
|
|
1605
1855
|
e.stopPropagation();
|
|
1606
1856
|
onWaypointRemove(shape.id, i);
|
|
1607
1857
|
},
|
|
1608
|
-
children: /* @__PURE__ */
|
|
1858
|
+
children: /* @__PURE__ */ jsx3("title", { children: "Drag to move, double-click to remove" })
|
|
1609
1859
|
},
|
|
1610
1860
|
`wp-${i}`
|
|
1611
1861
|
)),
|
|
1612
|
-
ends.map(({ end, x, y }) => /* @__PURE__ */
|
|
1862
|
+
ends.map(({ end, x, y }) => /* @__PURE__ */ jsx3(
|
|
1613
1863
|
"circle",
|
|
1614
1864
|
{
|
|
1615
1865
|
cx: x,
|
|
@@ -1628,7 +1878,7 @@ function SelectionOverlay({
|
|
|
1628
1878
|
},
|
|
1629
1879
|
end
|
|
1630
1880
|
)),
|
|
1631
|
-
elbowMid && /* @__PURE__ */
|
|
1881
|
+
elbowMid && /* @__PURE__ */ jsx3(
|
|
1632
1882
|
"rect",
|
|
1633
1883
|
{
|
|
1634
1884
|
x: elbowMid.x - 4,
|
|
@@ -1658,8 +1908,8 @@ function SelectionOverlay({
|
|
|
1658
1908
|
{ corner: "se", x: b.x + b.w + pad, y: b.y + b.h + pad }
|
|
1659
1909
|
];
|
|
1660
1910
|
const resizable = shape.type !== "text";
|
|
1661
|
-
return /* @__PURE__ */
|
|
1662
|
-
/* @__PURE__ */
|
|
1911
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
1912
|
+
/* @__PURE__ */ jsx3(
|
|
1663
1913
|
"rect",
|
|
1664
1914
|
{
|
|
1665
1915
|
x: b.x - pad,
|
|
@@ -1673,7 +1923,7 @@ function SelectionOverlay({
|
|
|
1673
1923
|
pointerEvents: "none"
|
|
1674
1924
|
}
|
|
1675
1925
|
),
|
|
1676
|
-
resizable && corners.map(({ corner, x, y }) => /* @__PURE__ */
|
|
1926
|
+
resizable && corners.map(({ corner, x, y }) => /* @__PURE__ */ jsx3(
|
|
1677
1927
|
"rect",
|
|
1678
1928
|
{
|
|
1679
1929
|
x: x - 4,
|
|
@@ -1699,9 +1949,9 @@ function TextEditOverlay({
|
|
|
1699
1949
|
onCommit
|
|
1700
1950
|
}) {
|
|
1701
1951
|
const original = shape[field] ?? "";
|
|
1702
|
-
const [value, setValue] =
|
|
1703
|
-
const ref =
|
|
1704
|
-
|
|
1952
|
+
const [value, setValue] = useState3(original);
|
|
1953
|
+
const ref = useRef3(null);
|
|
1954
|
+
useEffect7(() => {
|
|
1705
1955
|
ref.current?.focus();
|
|
1706
1956
|
ref.current?.select();
|
|
1707
1957
|
}, []);
|
|
@@ -1749,7 +1999,7 @@ function TextEditOverlay({
|
|
|
1749
1999
|
});
|
|
1750
2000
|
}
|
|
1751
2001
|
const placeholder = field === "label" ? "Label" : field === "footer" ? "Footer" : "Text";
|
|
1752
|
-
return /* @__PURE__ */
|
|
2002
|
+
return /* @__PURE__ */ jsx3(
|
|
1753
2003
|
"textarea",
|
|
1754
2004
|
{
|
|
1755
2005
|
ref,
|
|
@@ -1775,7 +2025,7 @@ function TextEditOverlay({
|
|
|
1775
2025
|
}
|
|
1776
2026
|
|
|
1777
2027
|
// src/nodes/DrawingNode.tsx
|
|
1778
|
-
import { jsx as
|
|
2028
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1779
2029
|
var DrawingNode = class _DrawingNode extends DecoratorNode {
|
|
1780
2030
|
static getType() {
|
|
1781
2031
|
return "drawing";
|
|
@@ -1839,7 +2089,7 @@ var DrawingNode = class _DrawingNode extends DecoratorNode {
|
|
|
1839
2089
|
return false;
|
|
1840
2090
|
}
|
|
1841
2091
|
decorate(_editor, _config) {
|
|
1842
|
-
return /* @__PURE__ */
|
|
2092
|
+
return /* @__PURE__ */ jsx4(DrawingCanvas, { nodeKey: this.getKey(), data: this.getData() });
|
|
1843
2093
|
}
|
|
1844
2094
|
};
|
|
1845
2095
|
function $createDrawingNode(data = serializeDrawingData(EMPTY_DRAWING)) {
|
|
@@ -1870,12 +2120,12 @@ ${node.getLatest().__data}
|
|
|
1870
2120
|
};
|
|
1871
2121
|
|
|
1872
2122
|
// src/plugins/ToolbarPlugin.tsx
|
|
1873
|
-
import { jsx as
|
|
2123
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1874
2124
|
var FORMAT_BUTTONS = [
|
|
1875
2125
|
{
|
|
1876
2126
|
format: "bold",
|
|
1877
2127
|
label: "Bold",
|
|
1878
|
-
icon: /* @__PURE__ */
|
|
2128
|
+
icon: /* @__PURE__ */ jsx5(
|
|
1879
2129
|
"path",
|
|
1880
2130
|
{
|
|
1881
2131
|
d: "M6 3.5h5a3 3 0 0 1 0 6H6zm0 6h6a3 3 0 0 1 0 6H6z",
|
|
@@ -1886,12 +2136,12 @@ var FORMAT_BUTTONS = [
|
|
|
1886
2136
|
{
|
|
1887
2137
|
format: "italic",
|
|
1888
2138
|
label: "Italic",
|
|
1889
|
-
icon: /* @__PURE__ */
|
|
2139
|
+
icon: /* @__PURE__ */ jsx5("path", { d: "M8.5 3.5h6M5.5 16.5h6M11.5 3.5l-3 13", strokeWidth: "1.6" })
|
|
1890
2140
|
},
|
|
1891
2141
|
{
|
|
1892
2142
|
format: "strikethrough",
|
|
1893
2143
|
label: "Strikethrough",
|
|
1894
|
-
icon: /* @__PURE__ */
|
|
2144
|
+
icon: /* @__PURE__ */ jsx5(
|
|
1895
2145
|
"path",
|
|
1896
2146
|
{
|
|
1897
2147
|
d: "M4 10h12M13.5 5.5c-.6-1.2-2-2-3.5-2-2 0-3.5 1.2-3.5 2.8 0 .5.1.9.4 1.3m-.4 5c.5 1.6 2 2.9 3.9 2.9 2 0 3.6-1.2 3.6-2.9 0-.4-.1-.8-.2-1.1",
|
|
@@ -1902,19 +2152,19 @@ var FORMAT_BUTTONS = [
|
|
|
1902
2152
|
{
|
|
1903
2153
|
format: "code",
|
|
1904
2154
|
label: "Inline code",
|
|
1905
|
-
icon: /* @__PURE__ */
|
|
2155
|
+
icon: /* @__PURE__ */ jsx5("path", { d: "M7.5 6L4 10l3.5 4M12.5 6L16 10l-3.5 4", strokeWidth: "1.6" })
|
|
1906
2156
|
}
|
|
1907
2157
|
];
|
|
1908
2158
|
function ToolbarPlugin() {
|
|
1909
|
-
const [editor] =
|
|
1910
|
-
const [activeFormats, setActiveFormats] =
|
|
2159
|
+
const [editor] = useLexicalComposerContext8();
|
|
2160
|
+
const [activeFormats, setActiveFormats] = useState4(
|
|
1911
2161
|
/* @__PURE__ */ new Set()
|
|
1912
2162
|
);
|
|
1913
|
-
|
|
2163
|
+
useEffect8(() => {
|
|
1914
2164
|
return editor.registerUpdateListener(({ editorState }) => {
|
|
1915
2165
|
editorState.read(() => {
|
|
1916
|
-
const selection = $
|
|
1917
|
-
if (!$
|
|
2166
|
+
const selection = $getSelection3();
|
|
2167
|
+
if (!$isRangeSelection3(selection)) {
|
|
1918
2168
|
setActiveFormats(/* @__PURE__ */ new Set());
|
|
1919
2169
|
return;
|
|
1920
2170
|
}
|
|
@@ -1926,21 +2176,21 @@ function ToolbarPlugin() {
|
|
|
1926
2176
|
});
|
|
1927
2177
|
});
|
|
1928
2178
|
}, [editor]);
|
|
1929
|
-
const insertTable =
|
|
2179
|
+
const insertTable = useCallback4(() => {
|
|
1930
2180
|
editor.dispatchCommand(INSERT_TABLE_COMMAND, {
|
|
1931
2181
|
columns: "3",
|
|
1932
2182
|
rows: "3",
|
|
1933
2183
|
includeHeaders: { rows: true, columns: false }
|
|
1934
2184
|
});
|
|
1935
2185
|
}, [editor]);
|
|
1936
|
-
const insertDrawing =
|
|
2186
|
+
const insertDrawing = useCallback4(() => {
|
|
1937
2187
|
editor.update(() => {
|
|
1938
2188
|
const drawing = $createDrawingNode();
|
|
1939
2189
|
$insertNodeToNearestRoot(drawing);
|
|
1940
2190
|
});
|
|
1941
2191
|
}, [editor]);
|
|
1942
|
-
return /* @__PURE__ */
|
|
1943
|
-
FORMAT_BUTTONS.map(({ format, label, icon }) => /* @__PURE__ */
|
|
2192
|
+
return /* @__PURE__ */ jsxs3("div", { className: "zui-text-editor-toolbar", children: [
|
|
2193
|
+
FORMAT_BUTTONS.map(({ format, label, icon }) => /* @__PURE__ */ jsx5(
|
|
1944
2194
|
"button",
|
|
1945
2195
|
{
|
|
1946
2196
|
type: "button",
|
|
@@ -1950,7 +2200,7 @@ function ToolbarPlugin() {
|
|
|
1950
2200
|
className: `zui-text-editor-toolbar-button ${activeFormats.has(format) ? "is-active" : ""}`,
|
|
1951
2201
|
onMouseDown: (e) => e.preventDefault(),
|
|
1952
2202
|
onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, format),
|
|
1953
|
-
children: /* @__PURE__ */
|
|
2203
|
+
children: /* @__PURE__ */ jsx5(
|
|
1954
2204
|
"svg",
|
|
1955
2205
|
{
|
|
1956
2206
|
viewBox: "0 0 20 20",
|
|
@@ -1966,8 +2216,8 @@ function ToolbarPlugin() {
|
|
|
1966
2216
|
},
|
|
1967
2217
|
format
|
|
1968
2218
|
)),
|
|
1969
|
-
/* @__PURE__ */
|
|
1970
|
-
/* @__PURE__ */
|
|
2219
|
+
/* @__PURE__ */ jsx5("div", { className: "zui-text-editor-toolbar-divider" }),
|
|
2220
|
+
/* @__PURE__ */ jsx5(
|
|
1971
2221
|
"button",
|
|
1972
2222
|
{
|
|
1973
2223
|
type: "button",
|
|
@@ -1976,7 +2226,7 @@ function ToolbarPlugin() {
|
|
|
1976
2226
|
className: "zui-text-editor-toolbar-button",
|
|
1977
2227
|
onMouseDown: (e) => e.preventDefault(),
|
|
1978
2228
|
onClick: insertTable,
|
|
1979
|
-
children: /* @__PURE__ */
|
|
2229
|
+
children: /* @__PURE__ */ jsxs3(
|
|
1980
2230
|
"svg",
|
|
1981
2231
|
{
|
|
1982
2232
|
viewBox: "0 0 20 20",
|
|
@@ -1987,14 +2237,14 @@ function ToolbarPlugin() {
|
|
|
1987
2237
|
strokeWidth: "1.5",
|
|
1988
2238
|
strokeLinecap: "round",
|
|
1989
2239
|
children: [
|
|
1990
|
-
/* @__PURE__ */
|
|
1991
|
-
/* @__PURE__ */
|
|
2240
|
+
/* @__PURE__ */ jsx5("rect", { x: "3", y: "3.5", width: "14", height: "13", rx: "1.5" }),
|
|
2241
|
+
/* @__PURE__ */ jsx5("path", { d: "M3 8h14M8 8v8.5M13 8v8.5" })
|
|
1992
2242
|
]
|
|
1993
2243
|
}
|
|
1994
2244
|
)
|
|
1995
2245
|
}
|
|
1996
2246
|
),
|
|
1997
|
-
/* @__PURE__ */
|
|
2247
|
+
/* @__PURE__ */ jsx5(
|
|
1998
2248
|
"button",
|
|
1999
2249
|
{
|
|
2000
2250
|
type: "button",
|
|
@@ -2003,7 +2253,7 @@ function ToolbarPlugin() {
|
|
|
2003
2253
|
className: "zui-text-editor-toolbar-button",
|
|
2004
2254
|
onMouseDown: (e) => e.preventDefault(),
|
|
2005
2255
|
onClick: insertDrawing,
|
|
2006
|
-
children: /* @__PURE__ */
|
|
2256
|
+
children: /* @__PURE__ */ jsxs3(
|
|
2007
2257
|
"svg",
|
|
2008
2258
|
{
|
|
2009
2259
|
viewBox: "0 0 20 20",
|
|
@@ -2015,9 +2265,9 @@ function ToolbarPlugin() {
|
|
|
2015
2265
|
strokeLinecap: "round",
|
|
2016
2266
|
strokeLinejoin: "round",
|
|
2017
2267
|
children: [
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
/* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2268
|
+
/* @__PURE__ */ jsx5("rect", { x: "3", y: "5", width: "8", height: "6", rx: "1.5" }),
|
|
2269
|
+
/* @__PURE__ */ jsx5("path", { d: "M13.5 8h3M14.5 6.5L17.5 8l-3 1.5" }),
|
|
2270
|
+
/* @__PURE__ */ jsx5("ellipse", { cx: "13", cy: "14.5", rx: "4", ry: "2.8" })
|
|
2021
2271
|
]
|
|
2022
2272
|
}
|
|
2023
2273
|
)
|
|
@@ -2302,7 +2552,7 @@ var editorTheme = {
|
|
|
2302
2552
|
};
|
|
2303
2553
|
|
|
2304
2554
|
// src/MarkdownEditor.tsx
|
|
2305
|
-
import { jsx as
|
|
2555
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2306
2556
|
var SYNC_TRANSFORMERS = [FRONTMATTER, DRAWING, CHECK_LIST, TABLE, ...TRANSFORMERS2];
|
|
2307
2557
|
var SHORTCUT_TRANSFORMERS = [TABLE, ...TRANSFORMERS2.filter((t) => t !== CODE)];
|
|
2308
2558
|
function onError(error) {
|
|
@@ -2324,8 +2574,8 @@ var editorNodes = [
|
|
|
2324
2574
|
DrawingNode
|
|
2325
2575
|
];
|
|
2326
2576
|
function ReadOnlyPlugin({ readOnly }) {
|
|
2327
|
-
const [editor] =
|
|
2328
|
-
|
|
2577
|
+
const [editor] = useLexicalComposerContext9();
|
|
2578
|
+
useEffect9(() => {
|
|
2329
2579
|
editor.setEditable(!readOnly);
|
|
2330
2580
|
}, [editor, readOnly]);
|
|
2331
2581
|
return null;
|
|
@@ -2338,17 +2588,19 @@ function MarkdownEditor({
|
|
|
2338
2588
|
className,
|
|
2339
2589
|
mode = "edit-md",
|
|
2340
2590
|
autoFocus = false,
|
|
2341
|
-
toolbar = true
|
|
2591
|
+
toolbar = true,
|
|
2592
|
+
outline = false,
|
|
2593
|
+
foldable = true
|
|
2342
2594
|
}) {
|
|
2343
|
-
const latestValueRef =
|
|
2344
|
-
const [mountKey, setMountKey] =
|
|
2345
|
-
const [capturedMarkdown, setCapturedMarkdown] =
|
|
2346
|
-
|
|
2595
|
+
const latestValueRef = useRef4(value ?? "");
|
|
2596
|
+
const [mountKey, setMountKey] = useState5(0);
|
|
2597
|
+
const [capturedMarkdown, setCapturedMarkdown] = useState5(value ?? "");
|
|
2598
|
+
useEffect9(() => {
|
|
2347
2599
|
if (value !== void 0) {
|
|
2348
2600
|
latestValueRef.current = value;
|
|
2349
2601
|
}
|
|
2350
2602
|
}, [value]);
|
|
2351
|
-
const handleTextChange =
|
|
2603
|
+
const handleTextChange = useCallback5(
|
|
2352
2604
|
(e) => {
|
|
2353
2605
|
const newValue = e.target.value;
|
|
2354
2606
|
latestValueRef.current = newValue;
|
|
@@ -2356,15 +2608,15 @@ function MarkdownEditor({
|
|
|
2356
2608
|
},
|
|
2357
2609
|
[onChange]
|
|
2358
2610
|
);
|
|
2359
|
-
const handleLexicalChange =
|
|
2611
|
+
const handleLexicalChange = useCallback5(
|
|
2360
2612
|
(newValue) => {
|
|
2361
2613
|
latestValueRef.current = newValue;
|
|
2362
2614
|
onChange?.(newValue);
|
|
2363
2615
|
},
|
|
2364
2616
|
[onChange]
|
|
2365
2617
|
);
|
|
2366
|
-
const prevModeRef =
|
|
2367
|
-
|
|
2618
|
+
const prevModeRef = useRef4(mode);
|
|
2619
|
+
useEffect9(() => {
|
|
2368
2620
|
if (prevModeRef.current === "edit-raw" && mode !== "edit-raw") {
|
|
2369
2621
|
setCapturedMarkdown(latestValueRef.current);
|
|
2370
2622
|
setMountKey((k) => k + 1);
|
|
@@ -2381,7 +2633,7 @@ function MarkdownEditor({
|
|
|
2381
2633
|
[]
|
|
2382
2634
|
);
|
|
2383
2635
|
if (mode === "edit-raw") {
|
|
2384
|
-
return /* @__PURE__ */
|
|
2636
|
+
return /* @__PURE__ */ jsx6("div", { className: `zui-text-editor ${className ?? ""}`, children: /* @__PURE__ */ jsx6(
|
|
2385
2637
|
"textarea",
|
|
2386
2638
|
{
|
|
2387
2639
|
className: "zui-text-editor-textarea",
|
|
@@ -2394,23 +2646,29 @@ function MarkdownEditor({
|
|
|
2394
2646
|
}
|
|
2395
2647
|
) });
|
|
2396
2648
|
}
|
|
2397
|
-
return /* @__PURE__ */
|
|
2398
|
-
toolbar && mode === "edit-md" && !readOnly && /* @__PURE__ */
|
|
2399
|
-
/* @__PURE__ */
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
ContentEditable,
|
|
2649
|
+
return /* @__PURE__ */ jsx6(LexicalComposer, { initialConfig, children: /* @__PURE__ */ jsxs4("div", { className: `zui-text-editor ${className ?? ""}`, children: [
|
|
2650
|
+
toolbar && mode === "edit-md" && !readOnly && /* @__PURE__ */ jsx6(ToolbarPlugin, {}),
|
|
2651
|
+
/* @__PURE__ */ jsxs4("div", { className: "zui-text-editor-body", children: [
|
|
2652
|
+
/* @__PURE__ */ jsxs4("div", { className: "zui-text-editor-main", children: [
|
|
2653
|
+
/* @__PURE__ */ jsx6(
|
|
2654
|
+
RichTextPlugin,
|
|
2404
2655
|
{
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2656
|
+
contentEditable: /* @__PURE__ */ jsx6(
|
|
2657
|
+
ContentEditable,
|
|
2658
|
+
{
|
|
2659
|
+
className: "zui-text-editor-content",
|
|
2660
|
+
"aria-placeholder": placeholder,
|
|
2661
|
+
placeholder: /* @__PURE__ */ jsx6("div", { className: "zui-text-editor-placeholder", children: placeholder })
|
|
2662
|
+
}
|
|
2663
|
+
),
|
|
2664
|
+
ErrorBoundary: LexicalErrorBoundary
|
|
2408
2665
|
}
|
|
2409
2666
|
),
|
|
2410
|
-
|
|
2411
|
-
}
|
|
2412
|
-
|
|
2413
|
-
|
|
2667
|
+
foldable && /* @__PURE__ */ jsx6(FoldingPlugin, {})
|
|
2668
|
+
] }),
|
|
2669
|
+
outline && /* @__PURE__ */ jsx6(OutlinePlugin, {})
|
|
2670
|
+
] }),
|
|
2671
|
+
/* @__PURE__ */ jsx6(
|
|
2414
2672
|
MarkdownSyncPlugin,
|
|
2415
2673
|
{
|
|
2416
2674
|
initialMarkdown: mode === "view" ? value ?? "" : capturedMarkdown,
|
|
@@ -2418,17 +2676,17 @@ function MarkdownEditor({
|
|
|
2418
2676
|
transformers: SYNC_TRANSFORMERS
|
|
2419
2677
|
}
|
|
2420
2678
|
),
|
|
2421
|
-
/* @__PURE__ */
|
|
2422
|
-
/* @__PURE__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2424
|
-
/* @__PURE__ */
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
/* @__PURE__ */
|
|
2428
|
-
/* @__PURE__ */
|
|
2429
|
-
/* @__PURE__ */
|
|
2430
|
-
/* @__PURE__ */
|
|
2431
|
-
autoFocus && /* @__PURE__ */
|
|
2679
|
+
/* @__PURE__ */ jsx6(HistoryPlugin, {}),
|
|
2680
|
+
/* @__PURE__ */ jsx6(ListPlugin, {}),
|
|
2681
|
+
/* @__PURE__ */ jsx6(CheckListPlugin, {}),
|
|
2682
|
+
/* @__PURE__ */ jsx6(ChecklistShortcutPlugin, {}),
|
|
2683
|
+
/* @__PURE__ */ jsx6(CodeBlockShortcutPlugin, {}),
|
|
2684
|
+
/* @__PURE__ */ jsx6(CodeHighlightPlugin, {}),
|
|
2685
|
+
/* @__PURE__ */ jsx6(TablePlugin, {}),
|
|
2686
|
+
/* @__PURE__ */ jsx6(LinkPlugin, {}),
|
|
2687
|
+
/* @__PURE__ */ jsx6(MarkdownShortcutPlugin, { transformers: SHORTCUT_TRANSFORMERS }),
|
|
2688
|
+
/* @__PURE__ */ jsx6(ReadOnlyPlugin, { readOnly: readOnly || mode === "view" }),
|
|
2689
|
+
autoFocus && /* @__PURE__ */ jsx6(AutoFocusPlugin, {})
|
|
2432
2690
|
] }) }, mountKey);
|
|
2433
2691
|
}
|
|
2434
2692
|
export {
|