@zuilib/text-editor 0.3.0 → 0.3.1
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/CHANGELOG.md +20 -0
- package/DRAWING_FORMAT.md +7 -2
- package/README.md +31 -2
- package/dist/index.d.ts +37 -2
- package/dist/index.js +544 -324
- package/dist/styles.css +38 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -357,6 +357,9 @@ function parseDrawingData(json) {
|
|
|
357
357
|
return {
|
|
358
358
|
version: 1,
|
|
359
359
|
height: typeof raw.height === "number" && raw.height >= 80 ? raw.height : DEFAULT_DRAWING_HEIGHT,
|
|
360
|
+
// `full` is the default and stays implicit so existing payloads are
|
|
361
|
+
// serialized byte-for-byte unchanged
|
|
362
|
+
width: raw.width === "content" ? "content" : void 0,
|
|
360
363
|
shapes
|
|
361
364
|
};
|
|
362
365
|
} catch {
|
|
@@ -373,6 +376,27 @@ function isValidShape(value) {
|
|
|
373
376
|
));
|
|
374
377
|
}
|
|
375
378
|
|
|
379
|
+
// src/components/blockWidthOptions.tsx
|
|
380
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
381
|
+
var BLOCK_WIDTH_OPTIONS = [
|
|
382
|
+
{
|
|
383
|
+
width: "full",
|
|
384
|
+
label: "Full width",
|
|
385
|
+
icon: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
386
|
+
/* @__PURE__ */ jsx("path", { d: "M3 4v12M17 4v12" }),
|
|
387
|
+
/* @__PURE__ */ jsx("path", { d: "M6 10h8M8.5 7.5L6 10l2.5 2.5M11.5 7.5L14 10l-2.5 2.5" })
|
|
388
|
+
] })
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
width: "content",
|
|
392
|
+
label: "Content width",
|
|
393
|
+
icon: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
394
|
+
/* @__PURE__ */ jsx("path", { d: "M3 4v12M17 4v12" }),
|
|
395
|
+
/* @__PURE__ */ jsx("path", { d: "M5.5 10h3M11.5 10h3M6.5 7.5L9 10l-2.5 2.5M13.5 7.5L11 10l2.5 2.5" })
|
|
396
|
+
] })
|
|
397
|
+
}
|
|
398
|
+
];
|
|
399
|
+
|
|
376
400
|
// src/components/drawingGeometry.ts
|
|
377
401
|
var BINDING_GAP = 6;
|
|
378
402
|
var BINDING_TOLERANCE = 8;
|
|
@@ -615,10 +639,12 @@ function resolveBindings(shapes) {
|
|
|
615
639
|
}
|
|
616
640
|
|
|
617
641
|
// src/components/DrawingCanvas.tsx
|
|
618
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
642
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
619
643
|
import { createElement } from "react";
|
|
620
644
|
var MIN_HEIGHT = 120;
|
|
621
645
|
var MAX_HEIGHT = 900;
|
|
646
|
+
var MIN_CONTENT_WIDTH = 240;
|
|
647
|
+
var CONTENT_WIDTH_PADDING = 40;
|
|
622
648
|
var SELECTION_COLOR = "#6965db";
|
|
623
649
|
var CONNECTOR_FONT_SIZE = 12;
|
|
624
650
|
var CONNECTOR_LABEL_MAX_WIDTH = 160;
|
|
@@ -649,7 +675,7 @@ function BoxTexts({
|
|
|
649
675
|
opacity: 0.35,
|
|
650
676
|
style: { userSelect: "none", pointerEvents: "none" }
|
|
651
677
|
};
|
|
652
|
-
return /* @__PURE__ */
|
|
678
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
653
679
|
hideField !== "label" && (shape.label ? labelLines.map((line, i) => /* @__PURE__ */ createElement(
|
|
654
680
|
"text",
|
|
655
681
|
{
|
|
@@ -662,7 +688,7 @@ function BoxTexts({
|
|
|
662
688
|
opacity: 0.85
|
|
663
689
|
},
|
|
664
690
|
line
|
|
665
|
-
)) : showHints && /* @__PURE__ */
|
|
691
|
+
)) : showHints && /* @__PURE__ */ jsx2("text", { ...hint, x: cx, y: b.y + SMALL_FONT_SIZE + 7, fontSize: SMALL_FONT_SIZE, children: "Label" })),
|
|
666
692
|
hideField !== "text" && (shape.text ? mainLines.map((line, i) => /* @__PURE__ */ createElement(
|
|
667
693
|
"text",
|
|
668
694
|
{
|
|
@@ -673,7 +699,7 @@ function BoxTexts({
|
|
|
673
699
|
fontSize: FONT_SIZE
|
|
674
700
|
},
|
|
675
701
|
line
|
|
676
|
-
)) : showHints && /* @__PURE__ */
|
|
702
|
+
)) : showHints && /* @__PURE__ */ jsx2("text", { ...hint, x: cx, y: mainStart, fontSize: FONT_SIZE, children: "Text" })),
|
|
677
703
|
hideField !== "footer" && (shape.footer ? footerLines.map((line, i) => /* @__PURE__ */ createElement(
|
|
678
704
|
"text",
|
|
679
705
|
{
|
|
@@ -685,7 +711,7 @@ function BoxTexts({
|
|
|
685
711
|
opacity: 0.65
|
|
686
712
|
},
|
|
687
713
|
line
|
|
688
|
-
)) : showHints && /* @__PURE__ */
|
|
714
|
+
)) : showHints && /* @__PURE__ */ jsx2("text", { ...hint, x: cx, y: b.y + b.h - 9, fontSize: SMALL_FONT_SIZE, children: "Footer" }))
|
|
689
715
|
] });
|
|
690
716
|
}
|
|
691
717
|
function ShapeView({
|
|
@@ -702,8 +728,8 @@ function ShapeView({
|
|
|
702
728
|
switch (shape.type) {
|
|
703
729
|
case "rect": {
|
|
704
730
|
const b = bbox(shape);
|
|
705
|
-
return /* @__PURE__ */
|
|
706
|
-
/* @__PURE__ */
|
|
731
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
732
|
+
/* @__PURE__ */ jsx2(
|
|
707
733
|
"rect",
|
|
708
734
|
{
|
|
709
735
|
...common,
|
|
@@ -715,13 +741,13 @@ function ShapeView({
|
|
|
715
741
|
fill: shape.fill
|
|
716
742
|
}
|
|
717
743
|
),
|
|
718
|
-
/* @__PURE__ */
|
|
744
|
+
/* @__PURE__ */ jsx2(BoxTexts, { shape, hideField, showHints })
|
|
719
745
|
] });
|
|
720
746
|
}
|
|
721
747
|
case "ellipse": {
|
|
722
748
|
const b = bbox(shape);
|
|
723
|
-
return /* @__PURE__ */
|
|
724
|
-
/* @__PURE__ */
|
|
749
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
750
|
+
/* @__PURE__ */ jsx2(
|
|
725
751
|
"ellipse",
|
|
726
752
|
{
|
|
727
753
|
...common,
|
|
@@ -732,13 +758,13 @@ function ShapeView({
|
|
|
732
758
|
fill: shape.fill
|
|
733
759
|
}
|
|
734
760
|
),
|
|
735
|
-
/* @__PURE__ */
|
|
761
|
+
/* @__PURE__ */ jsx2(BoxTexts, { shape, hideField, showHints })
|
|
736
762
|
] });
|
|
737
763
|
}
|
|
738
764
|
case "triangle":
|
|
739
765
|
case "pentagon":
|
|
740
|
-
return /* @__PURE__ */
|
|
741
|
-
/* @__PURE__ */
|
|
766
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
767
|
+
/* @__PURE__ */ jsx2(
|
|
742
768
|
"polygon",
|
|
743
769
|
{
|
|
744
770
|
...common,
|
|
@@ -746,12 +772,12 @@ function ShapeView({
|
|
|
746
772
|
fill: shape.fill
|
|
747
773
|
}
|
|
748
774
|
),
|
|
749
|
-
/* @__PURE__ */
|
|
775
|
+
/* @__PURE__ */ jsx2(BoxTexts, { shape, hideField, showHints })
|
|
750
776
|
] });
|
|
751
777
|
case "line":
|
|
752
778
|
case "arrow":
|
|
753
|
-
return /* @__PURE__ */
|
|
754
|
-
/* @__PURE__ */
|
|
779
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
780
|
+
/* @__PURE__ */ jsx2(
|
|
755
781
|
"path",
|
|
756
782
|
{
|
|
757
783
|
...common,
|
|
@@ -759,10 +785,10 @@ function ShapeView({
|
|
|
759
785
|
fill: "none"
|
|
760
786
|
}
|
|
761
787
|
),
|
|
762
|
-
shape.text && hideField !== "text" && /* @__PURE__ */
|
|
788
|
+
shape.text && hideField !== "text" && /* @__PURE__ */ jsx2(ConnectorLabel, { shape })
|
|
763
789
|
] });
|
|
764
790
|
case "text":
|
|
765
|
-
return /* @__PURE__ */
|
|
791
|
+
return /* @__PURE__ */ jsx2(
|
|
766
792
|
"text",
|
|
767
793
|
{
|
|
768
794
|
x: shape.x,
|
|
@@ -771,7 +797,7 @@ function ShapeView({
|
|
|
771
797
|
fontSize: FONT_SIZE,
|
|
772
798
|
fontFamily: "ui-sans-serif, system-ui, sans-serif",
|
|
773
799
|
style: { userSelect: "none", whiteSpace: "pre" },
|
|
774
|
-
children: (shape.text ?? "").split("\n").map((line, i) => /* @__PURE__ */
|
|
800
|
+
children: (shape.text ?? "").split("\n").map((line, i) => /* @__PURE__ */ jsx2("tspan", { x: shape.x, dy: i === 0 ? 0 : FONT_SIZE * 1.35, children: line }, i))
|
|
775
801
|
}
|
|
776
802
|
);
|
|
777
803
|
}
|
|
@@ -783,8 +809,8 @@ function ConnectorLabel({ shape }) {
|
|
|
783
809
|
const { x: midX, y: midY } = connectorMidpoint(shape);
|
|
784
810
|
const lineH = CONNECTOR_FONT_SIZE * LINE_HEIGHT;
|
|
785
811
|
const startY = midY - (lines.length - 1) * lineH / 2 + CONNECTOR_FONT_SIZE * 0.35;
|
|
786
|
-
return /* @__PURE__ */
|
|
787
|
-
/* @__PURE__ */
|
|
812
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
813
|
+
/* @__PURE__ */ jsx2(
|
|
788
814
|
"rect",
|
|
789
815
|
{
|
|
790
816
|
x: midX - size.w / 2 - 5,
|
|
@@ -796,7 +822,7 @@ function ConnectorLabel({ shape }) {
|
|
|
796
822
|
opacity: 0.92
|
|
797
823
|
}
|
|
798
824
|
),
|
|
799
|
-
lines.map((line, i) => /* @__PURE__ */
|
|
825
|
+
lines.map((line, i) => /* @__PURE__ */ jsx2(
|
|
800
826
|
"text",
|
|
801
827
|
{
|
|
802
828
|
x: midX,
|
|
@@ -813,20 +839,20 @@ function ConnectorLabel({ shape }) {
|
|
|
813
839
|
] });
|
|
814
840
|
}
|
|
815
841
|
var TOOL_ICONS = {
|
|
816
|
-
select: /* @__PURE__ */
|
|
817
|
-
rect: /* @__PURE__ */
|
|
818
|
-
ellipse: /* @__PURE__ */
|
|
819
|
-
triangle: /* @__PURE__ */
|
|
820
|
-
pentagon: /* @__PURE__ */
|
|
821
|
-
arrow: /* @__PURE__ */
|
|
822
|
-
/* @__PURE__ */
|
|
823
|
-
/* @__PURE__ */
|
|
842
|
+
select: /* @__PURE__ */ jsx2("path", { d: "M4 2l12 6.5-5.2 1.6L8 16z", fill: "currentColor", stroke: "none" }),
|
|
843
|
+
rect: /* @__PURE__ */ jsx2("rect", { x: "3", y: "4.5", width: "14", height: "11", rx: "2" }),
|
|
844
|
+
ellipse: /* @__PURE__ */ jsx2("ellipse", { cx: "10", cy: "10", rx: "7", ry: "5.5" }),
|
|
845
|
+
triangle: /* @__PURE__ */ jsx2("path", { d: "M10 3.5L17 16.5H3z", strokeLinejoin: "round" }),
|
|
846
|
+
pentagon: /* @__PURE__ */ jsx2("path", { d: "M10 3L16.8 8.1L14.2 16.2H5.8L3.2 8.1z", strokeLinejoin: "round" }),
|
|
847
|
+
arrow: /* @__PURE__ */ jsxs2("g", { children: [
|
|
848
|
+
/* @__PURE__ */ jsx2("path", { d: "M4 16L16 4" }),
|
|
849
|
+
/* @__PURE__ */ jsx2("path", { d: "M9 4h7v7" })
|
|
824
850
|
] }),
|
|
825
|
-
line: /* @__PURE__ */
|
|
826
|
-
text: /* @__PURE__ */
|
|
827
|
-
/* @__PURE__ */
|
|
828
|
-
/* @__PURE__ */
|
|
829
|
-
/* @__PURE__ */
|
|
851
|
+
line: /* @__PURE__ */ jsx2("path", { d: "M4 16L16 4" }),
|
|
852
|
+
text: /* @__PURE__ */ jsxs2("g", { children: [
|
|
853
|
+
/* @__PURE__ */ jsx2("path", { d: "M4 5V3.5h12V5" }),
|
|
854
|
+
/* @__PURE__ */ jsx2("path", { d: "M10 3.5V16.5" }),
|
|
855
|
+
/* @__PURE__ */ jsx2("path", { d: "M7 16.5h6" })
|
|
830
856
|
] })
|
|
831
857
|
};
|
|
832
858
|
function bindEndpoints(shape, shapes) {
|
|
@@ -849,11 +875,24 @@ var TOOLS = [
|
|
|
849
875
|
{ tool: "line", label: "Line" },
|
|
850
876
|
{ tool: "text", label: "Text" }
|
|
851
877
|
];
|
|
878
|
+
function contentWidth(shapes) {
|
|
879
|
+
let right = 0;
|
|
880
|
+
for (const shape of shapes) {
|
|
881
|
+
if (isConnectorType(shape.type)) {
|
|
882
|
+
for (const p of connectorPoints(shape)) right = Math.max(right, p.x);
|
|
883
|
+
} else {
|
|
884
|
+
const b = bbox(shape);
|
|
885
|
+
right = Math.max(right, b.x + b.w);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
return Math.max(MIN_CONTENT_WIDTH, Math.ceil(right + CONTENT_WIDTH_PADDING));
|
|
889
|
+
}
|
|
852
890
|
function DrawingCanvas({ nodeKey, data }) {
|
|
853
891
|
const [editor] = useLexicalComposerContext5();
|
|
854
892
|
const isEditable = useLexicalEditable();
|
|
855
893
|
const [shapes, setShapes] = useState(data.shapes);
|
|
856
894
|
const [height, setHeight] = useState(data.height);
|
|
895
|
+
const [width, setWidth] = useState(data.width ?? "full");
|
|
857
896
|
const [tool, setTool] = useState("select");
|
|
858
897
|
const [selectedId, setSelectedId] = useState(null);
|
|
859
898
|
const [editingText, setEditingText] = useState(null);
|
|
@@ -866,21 +905,25 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
866
905
|
shapesRef.current = shapes;
|
|
867
906
|
const heightRef = useRef2(height);
|
|
868
907
|
heightRef.current = height;
|
|
908
|
+
const widthRef = useRef2(width);
|
|
909
|
+
widthRef.current = width;
|
|
869
910
|
useEffect5(() => {
|
|
870
911
|
const incoming = serializeDrawingData(data);
|
|
871
912
|
if (incoming !== lastCommittedRef.current) {
|
|
872
913
|
lastCommittedRef.current = incoming;
|
|
873
914
|
setShapes(data.shapes);
|
|
874
915
|
setHeight(data.height);
|
|
916
|
+
setWidth(data.width ?? "full");
|
|
875
917
|
setSelectedId(null);
|
|
876
918
|
setEditingText(null);
|
|
877
919
|
}
|
|
878
920
|
}, [data]);
|
|
879
921
|
const commit = useCallback(
|
|
880
|
-
(nextShapes, nextHeight) => {
|
|
922
|
+
(nextShapes, nextHeight, nextWidth) => {
|
|
881
923
|
const payload = {
|
|
882
924
|
version: 1,
|
|
883
925
|
height: nextHeight ?? heightRef.current,
|
|
926
|
+
width: (nextWidth ?? widthRef.current) === "content" ? "content" : void 0,
|
|
884
927
|
shapes: nextShapes
|
|
885
928
|
};
|
|
886
929
|
const json = serializeDrawingData(payload);
|
|
@@ -895,6 +938,13 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
895
938
|
},
|
|
896
939
|
[editor, nodeKey]
|
|
897
940
|
);
|
|
941
|
+
const applyWidth = useCallback(
|
|
942
|
+
(next) => {
|
|
943
|
+
setWidth(next);
|
|
944
|
+
commit(shapesRef.current, void 0, next);
|
|
945
|
+
},
|
|
946
|
+
[commit]
|
|
947
|
+
);
|
|
898
948
|
const updateShapes = useCallback(
|
|
899
949
|
(updater, options) => {
|
|
900
950
|
setShapes((prev) => {
|
|
@@ -1299,15 +1349,15 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1299
1349
|
const editingShape = shapes.find((s) => s.id === editingText?.id) ?? null;
|
|
1300
1350
|
const showFill = selectedShape != null ? isBoxType(selectedShape.type) : tool !== "select" && isBoxType(tool);
|
|
1301
1351
|
const canvasCursor = tool === "select" ? "default" : tool === "text" ? "text" : "crosshair";
|
|
1302
|
-
return /* @__PURE__ */
|
|
1352
|
+
return /* @__PURE__ */ jsxs2(
|
|
1303
1353
|
"div",
|
|
1304
1354
|
{
|
|
1305
|
-
className:
|
|
1355
|
+
className: `zui-drawing-canvas ${width === "content" ? "is-content-width" : ""}`,
|
|
1306
1356
|
tabIndex: isEditable ? 0 : void 0,
|
|
1307
1357
|
onKeyDown: handleKeyDown,
|
|
1308
1358
|
children: [
|
|
1309
|
-
isEditable && /* @__PURE__ */
|
|
1310
|
-
/* @__PURE__ */
|
|
1359
|
+
isEditable && /* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar", onPointerDown: (e) => e.stopPropagation(), children: [
|
|
1360
|
+
/* @__PURE__ */ jsx2("div", { className: "zui-drawing-toolbar-group", children: TOOLS.map(({ tool: t, label }) => /* @__PURE__ */ jsx2(
|
|
1311
1361
|
"button",
|
|
1312
1362
|
{
|
|
1313
1363
|
type: "button",
|
|
@@ -1318,7 +1368,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1318
1368
|
setTool(t);
|
|
1319
1369
|
if (t !== "select") setSelectedId(null);
|
|
1320
1370
|
},
|
|
1321
|
-
children: /* @__PURE__ */
|
|
1371
|
+
children: /* @__PURE__ */ jsx2(
|
|
1322
1372
|
"svg",
|
|
1323
1373
|
{
|
|
1324
1374
|
viewBox: "0 0 20 20",
|
|
@@ -1335,9 +1385,9 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1335
1385
|
},
|
|
1336
1386
|
t
|
|
1337
1387
|
)) }),
|
|
1338
|
-
/* @__PURE__ */
|
|
1339
|
-
/* @__PURE__ */
|
|
1340
|
-
STROKE_COLORS.map((color) => /* @__PURE__ */
|
|
1388
|
+
/* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar-group", children: [
|
|
1389
|
+
/* @__PURE__ */ jsx2("span", { className: "zui-drawing-swatch-label", children: "Stroke" }),
|
|
1390
|
+
STROKE_COLORS.map((color) => /* @__PURE__ */ jsx2(
|
|
1341
1391
|
"button",
|
|
1342
1392
|
{
|
|
1343
1393
|
type: "button",
|
|
@@ -1350,9 +1400,9 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1350
1400
|
color
|
|
1351
1401
|
))
|
|
1352
1402
|
] }),
|
|
1353
|
-
showFill && /* @__PURE__ */
|
|
1354
|
-
/* @__PURE__ */
|
|
1355
|
-
FILL_COLORS.map((color) => /* @__PURE__ */
|
|
1403
|
+
showFill && /* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar-group", children: [
|
|
1404
|
+
/* @__PURE__ */ jsx2("span", { className: "zui-drawing-swatch-label", children: "Fill" }),
|
|
1405
|
+
FILL_COLORS.map((color) => /* @__PURE__ */ jsx2(
|
|
1356
1406
|
"button",
|
|
1357
1407
|
{
|
|
1358
1408
|
type: "button",
|
|
@@ -1365,8 +1415,8 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1365
1415
|
color
|
|
1366
1416
|
))
|
|
1367
1417
|
] }),
|
|
1368
|
-
selectedShape && isConnectorType(selectedShape.type) && /* @__PURE__ */
|
|
1369
|
-
/* @__PURE__ */
|
|
1418
|
+
selectedShape && isConnectorType(selectedShape.type) && /* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar-group", children: [
|
|
1419
|
+
/* @__PURE__ */ jsx2(
|
|
1370
1420
|
"button",
|
|
1371
1421
|
{
|
|
1372
1422
|
type: "button",
|
|
@@ -1374,7 +1424,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1374
1424
|
"aria-label": "Straight connector",
|
|
1375
1425
|
className: `zui-drawing-tool ${selectedShape.routing !== "elbow" ? "is-active" : ""}`,
|
|
1376
1426
|
onClick: () => applyRouting(false),
|
|
1377
|
-
children: /* @__PURE__ */
|
|
1427
|
+
children: /* @__PURE__ */ jsx2(
|
|
1378
1428
|
"svg",
|
|
1379
1429
|
{
|
|
1380
1430
|
viewBox: "0 0 20 20",
|
|
@@ -1384,12 +1434,12 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1384
1434
|
stroke: "currentColor",
|
|
1385
1435
|
strokeWidth: "1.6",
|
|
1386
1436
|
strokeLinecap: "round",
|
|
1387
|
-
children: /* @__PURE__ */
|
|
1437
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M4 16L16 4" })
|
|
1388
1438
|
}
|
|
1389
1439
|
)
|
|
1390
1440
|
}
|
|
1391
1441
|
),
|
|
1392
|
-
/* @__PURE__ */
|
|
1442
|
+
/* @__PURE__ */ jsx2(
|
|
1393
1443
|
"button",
|
|
1394
1444
|
{
|
|
1395
1445
|
type: "button",
|
|
@@ -1397,7 +1447,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1397
1447
|
"aria-label": "Elbow connector",
|
|
1398
1448
|
className: `zui-drawing-tool ${selectedShape.routing === "elbow" ? "is-active" : ""}`,
|
|
1399
1449
|
onClick: () => applyRouting(true),
|
|
1400
|
-
children: /* @__PURE__ */
|
|
1450
|
+
children: /* @__PURE__ */ jsx2(
|
|
1401
1451
|
"svg",
|
|
1402
1452
|
{
|
|
1403
1453
|
viewBox: "0 0 20 20",
|
|
@@ -1408,14 +1458,14 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1408
1458
|
strokeWidth: "1.6",
|
|
1409
1459
|
strokeLinecap: "round",
|
|
1410
1460
|
strokeLinejoin: "round",
|
|
1411
|
-
children: /* @__PURE__ */
|
|
1461
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M4 16v-6h12V4" })
|
|
1412
1462
|
}
|
|
1413
1463
|
)
|
|
1414
1464
|
}
|
|
1415
1465
|
)
|
|
1416
1466
|
] }),
|
|
1417
|
-
selectedShape?.type === "arrow" && /* @__PURE__ */
|
|
1418
|
-
/* @__PURE__ */
|
|
1467
|
+
selectedShape?.type === "arrow" && /* @__PURE__ */ jsxs2("div", { className: "zui-drawing-toolbar-group", children: [
|
|
1468
|
+
/* @__PURE__ */ jsx2(
|
|
1419
1469
|
"button",
|
|
1420
1470
|
{
|
|
1421
1471
|
type: "button",
|
|
@@ -1423,7 +1473,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1423
1473
|
"aria-label": "One-way arrow",
|
|
1424
1474
|
className: `zui-drawing-tool ${!selectedShape.bidirectional ? "is-active" : ""}`,
|
|
1425
1475
|
onClick: () => applyDirection(false),
|
|
1426
|
-
children: /* @__PURE__ */
|
|
1476
|
+
children: /* @__PURE__ */ jsx2(
|
|
1427
1477
|
"svg",
|
|
1428
1478
|
{
|
|
1429
1479
|
viewBox: "0 0 20 20",
|
|
@@ -1434,12 +1484,12 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1434
1484
|
strokeWidth: "1.6",
|
|
1435
1485
|
strokeLinecap: "round",
|
|
1436
1486
|
strokeLinejoin: "round",
|
|
1437
|
-
children: /* @__PURE__ */
|
|
1487
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M3 10h13M12 5.5L16.5 10L12 14.5" })
|
|
1438
1488
|
}
|
|
1439
1489
|
)
|
|
1440
1490
|
}
|
|
1441
1491
|
),
|
|
1442
|
-
/* @__PURE__ */
|
|
1492
|
+
/* @__PURE__ */ jsx2(
|
|
1443
1493
|
"button",
|
|
1444
1494
|
{
|
|
1445
1495
|
type: "button",
|
|
@@ -1447,7 +1497,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1447
1497
|
"aria-label": "Two-way arrow",
|
|
1448
1498
|
className: `zui-drawing-tool ${selectedShape.bidirectional ? "is-active" : ""}`,
|
|
1449
1499
|
onClick: () => applyDirection(true),
|
|
1450
|
-
children: /* @__PURE__ */
|
|
1500
|
+
children: /* @__PURE__ */ jsx2(
|
|
1451
1501
|
"svg",
|
|
1452
1502
|
{
|
|
1453
1503
|
viewBox: "0 0 20 20",
|
|
@@ -1458,13 +1508,13 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1458
1508
|
strokeWidth: "1.6",
|
|
1459
1509
|
strokeLinecap: "round",
|
|
1460
1510
|
strokeLinejoin: "round",
|
|
1461
|
-
children: /* @__PURE__ */
|
|
1511
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M3.5 10h13M8 5.5L3.5 10L8 14.5M12 5.5L16.5 10L12 14.5" })
|
|
1462
1512
|
}
|
|
1463
1513
|
)
|
|
1464
1514
|
}
|
|
1465
1515
|
)
|
|
1466
1516
|
] }),
|
|
1467
|
-
selectedShape && /* @__PURE__ */
|
|
1517
|
+
selectedShape && /* @__PURE__ */ jsx2("div", { className: "zui-drawing-toolbar-group", children: /* @__PURE__ */ jsx2(
|
|
1468
1518
|
"button",
|
|
1469
1519
|
{
|
|
1470
1520
|
type: "button",
|
|
@@ -1472,7 +1522,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1472
1522
|
"aria-label": "Delete shape",
|
|
1473
1523
|
className: "zui-drawing-tool zui-drawing-tool-danger",
|
|
1474
1524
|
onClick: deleteSelected,
|
|
1475
|
-
children: /* @__PURE__ */
|
|
1525
|
+
children: /* @__PURE__ */ jsx2(
|
|
1476
1526
|
"svg",
|
|
1477
1527
|
{
|
|
1478
1528
|
viewBox: "0 0 20 20",
|
|
@@ -1482,18 +1532,48 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1482
1532
|
stroke: "currentColor",
|
|
1483
1533
|
strokeWidth: "1.6",
|
|
1484
1534
|
strokeLinecap: "round",
|
|
1485
|
-
children: /* @__PURE__ */
|
|
1535
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M4 6h12M8 6V4h4v2M6 6l1 10h6l1-10M8.5 9v4M11.5 9v4" })
|
|
1486
1536
|
}
|
|
1487
1537
|
)
|
|
1488
1538
|
}
|
|
1489
|
-
) })
|
|
1539
|
+
) }),
|
|
1540
|
+
/* @__PURE__ */ jsx2("div", { className: "zui-drawing-toolbar-group zui-drawing-toolbar-group-end", children: BLOCK_WIDTH_OPTIONS.map(({ width: option, label, icon }) => /* @__PURE__ */ jsx2(
|
|
1541
|
+
"button",
|
|
1542
|
+
{
|
|
1543
|
+
type: "button",
|
|
1544
|
+
title: label,
|
|
1545
|
+
"aria-label": label,
|
|
1546
|
+
"aria-pressed": width === option,
|
|
1547
|
+
className: `zui-drawing-tool ${width === option ? "is-active" : ""}`,
|
|
1548
|
+
onClick: () => applyWidth(option),
|
|
1549
|
+
children: /* @__PURE__ */ jsx2(
|
|
1550
|
+
"svg",
|
|
1551
|
+
{
|
|
1552
|
+
viewBox: "0 0 20 20",
|
|
1553
|
+
width: "16",
|
|
1554
|
+
height: "16",
|
|
1555
|
+
fill: "none",
|
|
1556
|
+
stroke: "currentColor",
|
|
1557
|
+
strokeWidth: "1.6",
|
|
1558
|
+
strokeLinecap: "round",
|
|
1559
|
+
strokeLinejoin: "round",
|
|
1560
|
+
children: icon
|
|
1561
|
+
}
|
|
1562
|
+
)
|
|
1563
|
+
},
|
|
1564
|
+
option
|
|
1565
|
+
)) })
|
|
1490
1566
|
] }),
|
|
1491
|
-
/* @__PURE__ */
|
|
1567
|
+
/* @__PURE__ */ jsxs2(
|
|
1492
1568
|
"svg",
|
|
1493
1569
|
{
|
|
1494
1570
|
ref: svgRef,
|
|
1495
1571
|
className: "zui-drawing-surface",
|
|
1496
|
-
style: {
|
|
1572
|
+
style: {
|
|
1573
|
+
height,
|
|
1574
|
+
width: width === "content" ? contentWidth(shapes) : void 0,
|
|
1575
|
+
cursor: canvasCursor
|
|
1576
|
+
},
|
|
1497
1577
|
onPointerDown: handleBackgroundPointerDown,
|
|
1498
1578
|
onPointerMove: handlePointerMove,
|
|
1499
1579
|
onPointerUp: handlePointerUp,
|
|
@@ -1515,7 +1595,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1515
1595
|
}
|
|
1516
1596
|
},
|
|
1517
1597
|
children: [
|
|
1518
|
-
shapes.map((shape) => /* @__PURE__ */
|
|
1598
|
+
shapes.map((shape) => /* @__PURE__ */ jsxs2(
|
|
1519
1599
|
"g",
|
|
1520
1600
|
{
|
|
1521
1601
|
"data-shape-id": shape.id,
|
|
@@ -1524,7 +1604,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1524
1604
|
},
|
|
1525
1605
|
onPointerDown: (e) => handleShapePointerDown(e, shape),
|
|
1526
1606
|
children: [
|
|
1527
|
-
isConnectorType(shape.type) && /* @__PURE__ */
|
|
1607
|
+
isConnectorType(shape.type) && /* @__PURE__ */ jsx2(
|
|
1528
1608
|
"path",
|
|
1529
1609
|
{
|
|
1530
1610
|
d: connectorPath(shape),
|
|
@@ -1533,8 +1613,8 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1533
1613
|
strokeWidth: 14
|
|
1534
1614
|
}
|
|
1535
1615
|
),
|
|
1536
|
-
(isBoxType(shape.type) || shape.type === "text") && /* @__PURE__ */
|
|
1537
|
-
shape.id === editingText?.id && shape.type === "text" ? null : /* @__PURE__ */
|
|
1616
|
+
(isBoxType(shape.type) || shape.type === "text") && /* @__PURE__ */ jsx2(HitArea, { shape }),
|
|
1617
|
+
shape.id === editingText?.id && shape.type === "text" ? null : /* @__PURE__ */ jsx2(
|
|
1538
1618
|
ShapeView,
|
|
1539
1619
|
{
|
|
1540
1620
|
shape,
|
|
@@ -1546,7 +1626,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1546
1626
|
},
|
|
1547
1627
|
shape.id
|
|
1548
1628
|
)),
|
|
1549
|
-
selectedShape && isEditable && !editingText && /* @__PURE__ */
|
|
1629
|
+
selectedShape && isEditable && !editingText && /* @__PURE__ */ jsx2(
|
|
1550
1630
|
SelectionOverlay,
|
|
1551
1631
|
{
|
|
1552
1632
|
shape: selectedShape,
|
|
@@ -1558,7 +1638,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1558
1638
|
]
|
|
1559
1639
|
}
|
|
1560
1640
|
),
|
|
1561
|
-
editingShape && editingText && /* @__PURE__ */
|
|
1641
|
+
editingShape && editingText && /* @__PURE__ */ jsx2(
|
|
1562
1642
|
TextEditOverlay,
|
|
1563
1643
|
{
|
|
1564
1644
|
shape: editingShape,
|
|
@@ -1567,7 +1647,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1567
1647
|
},
|
|
1568
1648
|
`${editingShape.id}:${editingText.field}`
|
|
1569
1649
|
),
|
|
1570
|
-
isEditable && /* @__PURE__ */
|
|
1650
|
+
isEditable && /* @__PURE__ */ jsx2(
|
|
1571
1651
|
"div",
|
|
1572
1652
|
{
|
|
1573
1653
|
className: "zui-drawing-resize",
|
|
@@ -1606,7 +1686,7 @@ function DrawingCanvas({ nodeKey, data }) {
|
|
|
1606
1686
|
}
|
|
1607
1687
|
function HitArea({ shape }) {
|
|
1608
1688
|
const b = bbox(shape);
|
|
1609
|
-
return /* @__PURE__ */
|
|
1689
|
+
return /* @__PURE__ */ jsx2(
|
|
1610
1690
|
"rect",
|
|
1611
1691
|
{
|
|
1612
1692
|
x: b.x,
|
|
@@ -1640,8 +1720,8 @@ function SelectionOverlay({
|
|
|
1640
1720
|
if (hasElbowHandle && i === 1) return [];
|
|
1641
1721
|
return [{ index: i, x: (p.x + q.x) / 2, y: (p.y + q.y) / 2 }];
|
|
1642
1722
|
});
|
|
1643
|
-
return /* @__PURE__ */
|
|
1644
|
-
ghosts.map(({ index, x, y }) => /* @__PURE__ */
|
|
1723
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
1724
|
+
ghosts.map(({ index, x, y }) => /* @__PURE__ */ jsx2(
|
|
1645
1725
|
"circle",
|
|
1646
1726
|
{
|
|
1647
1727
|
cx: x,
|
|
@@ -1654,11 +1734,11 @@ function SelectionOverlay({
|
|
|
1654
1734
|
opacity: 0.6,
|
|
1655
1735
|
style: { cursor: "copy" },
|
|
1656
1736
|
onPointerDown: (e) => onWaypointAdd(e, shape.id, index, { x, y }),
|
|
1657
|
-
children: /* @__PURE__ */
|
|
1737
|
+
children: /* @__PURE__ */ jsx2("title", { children: "Drag to add a point" })
|
|
1658
1738
|
},
|
|
1659
1739
|
`ghost-${index}`
|
|
1660
1740
|
)),
|
|
1661
|
-
waypoints.map((p, i) => /* @__PURE__ */
|
|
1741
|
+
waypoints.map((p, i) => /* @__PURE__ */ jsx2(
|
|
1662
1742
|
"rect",
|
|
1663
1743
|
{
|
|
1664
1744
|
x: p.x - 4,
|
|
@@ -1679,11 +1759,11 @@ function SelectionOverlay({
|
|
|
1679
1759
|
e.stopPropagation();
|
|
1680
1760
|
onWaypointRemove(shape.id, i);
|
|
1681
1761
|
},
|
|
1682
|
-
children: /* @__PURE__ */
|
|
1762
|
+
children: /* @__PURE__ */ jsx2("title", { children: "Drag to move, double-click to remove" })
|
|
1683
1763
|
},
|
|
1684
1764
|
`wp-${i}`
|
|
1685
1765
|
)),
|
|
1686
|
-
ends.map(({ end, x, y }) => /* @__PURE__ */
|
|
1766
|
+
ends.map(({ end, x, y }) => /* @__PURE__ */ jsx2(
|
|
1687
1767
|
"circle",
|
|
1688
1768
|
{
|
|
1689
1769
|
cx: x,
|
|
@@ -1702,7 +1782,7 @@ function SelectionOverlay({
|
|
|
1702
1782
|
},
|
|
1703
1783
|
end
|
|
1704
1784
|
)),
|
|
1705
|
-
elbowMid && /* @__PURE__ */
|
|
1785
|
+
elbowMid && /* @__PURE__ */ jsx2(
|
|
1706
1786
|
"rect",
|
|
1707
1787
|
{
|
|
1708
1788
|
x: elbowMid.x - 4,
|
|
@@ -1732,8 +1812,8 @@ function SelectionOverlay({
|
|
|
1732
1812
|
{ corner: "se", x: b.x + b.w + pad, y: b.y + b.h + pad }
|
|
1733
1813
|
];
|
|
1734
1814
|
const resizable = shape.type !== "text";
|
|
1735
|
-
return /* @__PURE__ */
|
|
1736
|
-
/* @__PURE__ */
|
|
1815
|
+
return /* @__PURE__ */ jsxs2("g", { children: [
|
|
1816
|
+
/* @__PURE__ */ jsx2(
|
|
1737
1817
|
"rect",
|
|
1738
1818
|
{
|
|
1739
1819
|
x: b.x - pad,
|
|
@@ -1747,7 +1827,7 @@ function SelectionOverlay({
|
|
|
1747
1827
|
pointerEvents: "none"
|
|
1748
1828
|
}
|
|
1749
1829
|
),
|
|
1750
|
-
resizable && corners.map(({ corner, x, y }) => /* @__PURE__ */
|
|
1830
|
+
resizable && corners.map(({ corner, x, y }) => /* @__PURE__ */ jsx2(
|
|
1751
1831
|
"rect",
|
|
1752
1832
|
{
|
|
1753
1833
|
x: x - 4,
|
|
@@ -1823,7 +1903,7 @@ function TextEditOverlay({
|
|
|
1823
1903
|
});
|
|
1824
1904
|
}
|
|
1825
1905
|
const placeholder = field === "label" ? "Label" : field === "footer" ? "Footer" : "Text";
|
|
1826
|
-
return /* @__PURE__ */
|
|
1906
|
+
return /* @__PURE__ */ jsx2(
|
|
1827
1907
|
"textarea",
|
|
1828
1908
|
{
|
|
1829
1909
|
ref,
|
|
@@ -1849,7 +1929,7 @@ function TextEditOverlay({
|
|
|
1849
1929
|
}
|
|
1850
1930
|
|
|
1851
1931
|
// src/nodes/DrawingNode.tsx
|
|
1852
|
-
import { jsx as
|
|
1932
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1853
1933
|
var DrawingNode = class _DrawingNode extends DecoratorNode {
|
|
1854
1934
|
static getType() {
|
|
1855
1935
|
return "drawing";
|
|
@@ -1913,7 +1993,7 @@ var DrawingNode = class _DrawingNode extends DecoratorNode {
|
|
|
1913
1993
|
return false;
|
|
1914
1994
|
}
|
|
1915
1995
|
decorate(_editor, _config) {
|
|
1916
|
-
return /* @__PURE__ */
|
|
1996
|
+
return /* @__PURE__ */ jsx3(DrawingCanvas, { nodeKey: this.getKey(), data: this.getData() });
|
|
1917
1997
|
}
|
|
1918
1998
|
};
|
|
1919
1999
|
function $createDrawingNode(data = serializeDrawingData(EMPTY_DRAWING)) {
|
|
@@ -1958,15 +2038,54 @@ import {
|
|
|
1958
2038
|
$createTableNode,
|
|
1959
2039
|
$createTableRowNode,
|
|
1960
2040
|
$isTableCellNode,
|
|
1961
|
-
$isTableNode,
|
|
2041
|
+
$isTableNode as $isTableNode2,
|
|
1962
2042
|
$isTableRowNode,
|
|
1963
2043
|
TableCellHeaderStates,
|
|
1964
2044
|
TableCellNode,
|
|
1965
2045
|
TableNode,
|
|
1966
2046
|
TableRowNode
|
|
1967
2047
|
} from "@lexical/table";
|
|
2048
|
+
|
|
2049
|
+
// src/transformers/tableWidth.ts
|
|
2050
|
+
import {
|
|
2051
|
+
$getNodeByKey as $getNodeByKey3,
|
|
2052
|
+
$getSelection as $getSelection2,
|
|
2053
|
+
$isRangeSelection as $isRangeSelection2
|
|
2054
|
+
} from "lexical";
|
|
2055
|
+
import { $findMatchingParent } from "@lexical/utils";
|
|
2056
|
+
import { $isTableNode, $isTableSelection } from "@lexical/table";
|
|
2057
|
+
var TABLE_WIDTH_MARKER = "<!-- width: content -->";
|
|
2058
|
+
var TABLE_WIDTH_MARKER_REG_EXP = /^<!--\s*width:\s*content\s*-->\s*$/;
|
|
2059
|
+
var CONTENT_WIDTH_STYLE = "width: auto; table-layout: auto";
|
|
2060
|
+
var CONTENT_WIDTH_REG_EXP = /(^|;)\s*width:\s*auto\s*(;|$)/;
|
|
2061
|
+
function $getTableWidth(table) {
|
|
2062
|
+
return CONTENT_WIDTH_REG_EXP.test(table.getStyle()) ? "content" : "full";
|
|
2063
|
+
}
|
|
2064
|
+
function $setTableWidth(table, width) {
|
|
2065
|
+
table.setStyle(width === "content" ? CONTENT_WIDTH_STYLE : "");
|
|
2066
|
+
}
|
|
2067
|
+
function $getSelectedTable() {
|
|
2068
|
+
const selection = $getSelection2();
|
|
2069
|
+
if ($isTableSelection(selection)) {
|
|
2070
|
+
const node = $getNodeByKey3(selection.tableKey);
|
|
2071
|
+
return $isTableNode(node) ? node : null;
|
|
2072
|
+
}
|
|
2073
|
+
if (!$isRangeSelection2(selection)) return null;
|
|
2074
|
+
const table = $findMatchingParent(
|
|
2075
|
+
selection.anchor.getNode(),
|
|
2076
|
+
(node) => $isTableNode(node)
|
|
2077
|
+
);
|
|
2078
|
+
return $isTableNode(table) ? table : null;
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
// src/transformers/tableTransformer.ts
|
|
1968
2082
|
var TABLE_ROW_REG_EXP = /^\|(.+)\|\s?$/;
|
|
1969
2083
|
var TABLE_ROW_DIVIDER_REG_EXP = /^(\| ?:?-*:? ?)+\|\s?$/;
|
|
2084
|
+
function $isTableWidthMarker(node) {
|
|
2085
|
+
if (!$isParagraphNode2(node) || node.getChildrenSize() !== 1) return false;
|
|
2086
|
+
const child = node.getFirstChild();
|
|
2087
|
+
return $isTextNode(child) && TABLE_WIDTH_MARKER_REG_EXP.test(child.getTextContent());
|
|
2088
|
+
}
|
|
1970
2089
|
function getTableColumnsSize(table) {
|
|
1971
2090
|
const row = table.getFirstChild();
|
|
1972
2091
|
return $isTableRowNode(row) ? row.getChildrenSize() : 0;
|
|
@@ -1985,8 +2104,9 @@ function mapToTableCells(textContent) {
|
|
|
1985
2104
|
var TABLE = {
|
|
1986
2105
|
dependencies: [TableNode, TableRowNode, TableCellNode],
|
|
1987
2106
|
export: (node) => {
|
|
1988
|
-
if (!$
|
|
2107
|
+
if (!$isTableNode2(node)) return null;
|
|
1989
2108
|
const output = [];
|
|
2109
|
+
if ($getTableWidth(node) === "content") output.push(TABLE_WIDTH_MARKER);
|
|
1990
2110
|
for (const row of node.getChildren()) {
|
|
1991
2111
|
if (!$isTableRowNode(row)) continue;
|
|
1992
2112
|
const rowOutput = [];
|
|
@@ -2011,7 +2131,7 @@ var TABLE = {
|
|
|
2011
2131
|
replace: (parentNode, _children, match) => {
|
|
2012
2132
|
if (TABLE_ROW_DIVIDER_REG_EXP.test(match[0])) {
|
|
2013
2133
|
const table2 = parentNode.getPreviousSibling();
|
|
2014
|
-
if (!table2 || !$
|
|
2134
|
+
if (!table2 || !$isTableNode2(table2)) return;
|
|
2015
2135
|
const lastRow = table2.getLastChild();
|
|
2016
2136
|
if (!lastRow || !$isTableRowNode(lastRow)) return;
|
|
2017
2137
|
lastRow.getChildren().forEach((cell) => {
|
|
@@ -2048,10 +2168,14 @@ var TABLE = {
|
|
|
2048
2168
|
}
|
|
2049
2169
|
}
|
|
2050
2170
|
const previousSibling = parentNode.getPreviousSibling();
|
|
2051
|
-
if ($
|
|
2171
|
+
if ($isTableNode2(previousSibling) && getTableColumnsSize(previousSibling) === maxCells) {
|
|
2052
2172
|
previousSibling.append(...table.getChildren());
|
|
2053
2173
|
parentNode.remove();
|
|
2054
2174
|
} else {
|
|
2175
|
+
if ($isTableWidthMarker(previousSibling)) {
|
|
2176
|
+
$setTableWidth(table, "content");
|
|
2177
|
+
previousSibling?.remove();
|
|
2178
|
+
}
|
|
2055
2179
|
parentNode.replace(table);
|
|
2056
2180
|
}
|
|
2057
2181
|
table.selectEnd();
|
|
@@ -2139,7 +2263,7 @@ var editorTheme = {
|
|
|
2139
2263
|
};
|
|
2140
2264
|
|
|
2141
2265
|
// src/EditorRoot.tsx
|
|
2142
|
-
import { Fragment, jsx as
|
|
2266
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2143
2267
|
var SYNC_TRANSFORMERS = [FRONTMATTER, DRAWING, CHECK_LIST, TABLE, ...TRANSFORMERS2];
|
|
2144
2268
|
var SHORTCUT_TRANSFORMERS = [TABLE, ...TRANSFORMERS2.filter((t) => t !== CODE)];
|
|
2145
2269
|
var EditorContext = createContext(null);
|
|
@@ -2229,10 +2353,10 @@ function EditorRoot({
|
|
|
2229
2353
|
[mode, readOnly, autoFocus, value, handleChange]
|
|
2230
2354
|
);
|
|
2231
2355
|
const isRaw = mode === "edit-raw";
|
|
2232
|
-
return /* @__PURE__ */
|
|
2356
|
+
return /* @__PURE__ */ jsx4(LexicalComposer, { initialConfig, children: /* @__PURE__ */ jsx4(EditorContext.Provider, { value: context, children: /* @__PURE__ */ jsxs3("div", { className: `zui-text-editor ${className ?? ""}`, children: [
|
|
2233
2357
|
children,
|
|
2234
|
-
!isRaw && /* @__PURE__ */
|
|
2235
|
-
/* @__PURE__ */
|
|
2358
|
+
!isRaw && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
2359
|
+
/* @__PURE__ */ jsx4(
|
|
2236
2360
|
MarkdownSyncPlugin,
|
|
2237
2361
|
{
|
|
2238
2362
|
initialMarkdown: mode === "view" ? value ?? "" : capturedMarkdown,
|
|
@@ -2240,17 +2364,17 @@ function EditorRoot({
|
|
|
2240
2364
|
transformers: SYNC_TRANSFORMERS
|
|
2241
2365
|
}
|
|
2242
2366
|
),
|
|
2243
|
-
/* @__PURE__ */
|
|
2244
|
-
/* @__PURE__ */
|
|
2245
|
-
/* @__PURE__ */
|
|
2246
|
-
/* @__PURE__ */
|
|
2247
|
-
/* @__PURE__ */
|
|
2248
|
-
/* @__PURE__ */
|
|
2249
|
-
/* @__PURE__ */
|
|
2250
|
-
/* @__PURE__ */
|
|
2251
|
-
/* @__PURE__ */
|
|
2252
|
-
/* @__PURE__ */
|
|
2253
|
-
autoFocus && /* @__PURE__ */
|
|
2367
|
+
/* @__PURE__ */ jsx4(HistoryPlugin, {}),
|
|
2368
|
+
/* @__PURE__ */ jsx4(ListPlugin, {}),
|
|
2369
|
+
/* @__PURE__ */ jsx4(CheckListPlugin, {}),
|
|
2370
|
+
/* @__PURE__ */ jsx4(ChecklistShortcutPlugin, {}),
|
|
2371
|
+
/* @__PURE__ */ jsx4(CodeBlockShortcutPlugin, {}),
|
|
2372
|
+
/* @__PURE__ */ jsx4(CodeHighlightPlugin, {}),
|
|
2373
|
+
/* @__PURE__ */ jsx4(TablePlugin, {}),
|
|
2374
|
+
/* @__PURE__ */ jsx4(LinkPlugin, {}),
|
|
2375
|
+
/* @__PURE__ */ jsx4(MarkdownShortcutPlugin, { transformers: SHORTCUT_TRANSFORMERS }),
|
|
2376
|
+
/* @__PURE__ */ jsx4(ReadOnlyPlugin, { readOnly: readOnly || mode === "view" }),
|
|
2377
|
+
autoFocus && /* @__PURE__ */ jsx4(AutoFocusPlugin, {})
|
|
2254
2378
|
] })
|
|
2255
2379
|
] }) }) }, mountKey);
|
|
2256
2380
|
}
|
|
@@ -2267,10 +2391,10 @@ import {
|
|
|
2267
2391
|
useRef as useRef4,
|
|
2268
2392
|
useState as useState3
|
|
2269
2393
|
} from "react";
|
|
2270
|
-
import { $getRoot, $getSelection as $
|
|
2394
|
+
import { $getRoot, $getSelection as $getSelection3, $isRangeSelection as $isRangeSelection3 } from "lexical";
|
|
2271
2395
|
import { useLexicalComposerContext as useLexicalComposerContext7 } from "@lexical/react/LexicalComposerContext";
|
|
2272
2396
|
import { $isHeadingNode } from "@lexical/rich-text";
|
|
2273
|
-
import { jsx as
|
|
2397
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
2274
2398
|
var HEADING_LEVELS = {
|
|
2275
2399
|
h1: 1,
|
|
2276
2400
|
h2: 2,
|
|
@@ -2306,8 +2430,8 @@ function FoldingPlugin() {
|
|
|
2306
2430
|
hidden.add(sibling.getKey());
|
|
2307
2431
|
}
|
|
2308
2432
|
}
|
|
2309
|
-
const selection = $
|
|
2310
|
-
if ($
|
|
2433
|
+
const selection = $getSelection3();
|
|
2434
|
+
if ($isRangeSelection3(selection)) {
|
|
2311
2435
|
const topLevel = selection.anchor.getNode().getTopLevelElement();
|
|
2312
2436
|
if (topLevel && hidden.has(topLevel.getKey())) {
|
|
2313
2437
|
let node = topLevel.getPreviousSibling();
|
|
@@ -2368,7 +2492,7 @@ function FoldingPlugin() {
|
|
|
2368
2492
|
return next;
|
|
2369
2493
|
});
|
|
2370
2494
|
}, []);
|
|
2371
|
-
return /* @__PURE__ */
|
|
2495
|
+
return /* @__PURE__ */ jsx5("div", { className: "zui-text-editor-fold-gutter", children: buttons.map(({ key, folded, top, height }) => /* @__PURE__ */ jsx5(
|
|
2372
2496
|
"button",
|
|
2373
2497
|
{
|
|
2374
2498
|
type: "button",
|
|
@@ -2378,7 +2502,7 @@ function FoldingPlugin() {
|
|
|
2378
2502
|
"aria-label": folded ? "Expand section" : "Collapse section",
|
|
2379
2503
|
"aria-expanded": !folded,
|
|
2380
2504
|
onClick: () => toggle(key),
|
|
2381
|
-
children: /* @__PURE__ */
|
|
2505
|
+
children: /* @__PURE__ */ jsx5(
|
|
2382
2506
|
"svg",
|
|
2383
2507
|
{
|
|
2384
2508
|
viewBox: "0 0 20 20",
|
|
@@ -2389,7 +2513,7 @@ function FoldingPlugin() {
|
|
|
2389
2513
|
strokeWidth: "2",
|
|
2390
2514
|
strokeLinecap: "round",
|
|
2391
2515
|
strokeLinejoin: "round",
|
|
2392
|
-
children: /* @__PURE__ */
|
|
2516
|
+
children: /* @__PURE__ */ jsx5("path", { d: "M6 8l4 4 4-4" })
|
|
2393
2517
|
}
|
|
2394
2518
|
)
|
|
2395
2519
|
},
|
|
@@ -2397,168 +2521,16 @@ function FoldingPlugin() {
|
|
|
2397
2521
|
)) });
|
|
2398
2522
|
}
|
|
2399
2523
|
|
|
2400
|
-
// src/
|
|
2401
|
-
import {
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
foldable = true,
|
|
2405
|
-
children
|
|
2406
|
-
}) {
|
|
2407
|
-
const { mode, readOnly, autoFocus, rawValue, onRawChange } = useEditorContext();
|
|
2408
|
-
if (mode === "edit-raw") {
|
|
2409
|
-
return /* @__PURE__ */ jsx5(
|
|
2410
|
-
"textarea",
|
|
2411
|
-
{
|
|
2412
|
-
className: "zui-text-editor-textarea",
|
|
2413
|
-
value: rawValue,
|
|
2414
|
-
onChange: (e) => onRawChange(e.target.value),
|
|
2415
|
-
placeholder,
|
|
2416
|
-
readOnly,
|
|
2417
|
-
autoFocus,
|
|
2418
|
-
spellCheck: false
|
|
2419
|
-
}
|
|
2420
|
-
);
|
|
2421
|
-
}
|
|
2422
|
-
return /* @__PURE__ */ jsxs3("div", { className: "zui-text-editor-body", children: [
|
|
2423
|
-
/* @__PURE__ */ jsxs3("div", { className: "zui-text-editor-main", children: [
|
|
2424
|
-
/* @__PURE__ */ jsx5(
|
|
2425
|
-
RichTextPlugin,
|
|
2426
|
-
{
|
|
2427
|
-
contentEditable: /* @__PURE__ */ jsx5(
|
|
2428
|
-
ContentEditable,
|
|
2429
|
-
{
|
|
2430
|
-
className: "zui-text-editor-content",
|
|
2431
|
-
"aria-placeholder": placeholder,
|
|
2432
|
-
placeholder: /* @__PURE__ */ jsx5("div", { className: "zui-text-editor-placeholder", children: placeholder })
|
|
2433
|
-
}
|
|
2434
|
-
),
|
|
2435
|
-
ErrorBoundary: LexicalErrorBoundary
|
|
2436
|
-
}
|
|
2437
|
-
),
|
|
2438
|
-
foldable && /* @__PURE__ */ jsx5(FoldingPlugin, {})
|
|
2439
|
-
] }),
|
|
2440
|
-
children
|
|
2441
|
-
] });
|
|
2442
|
-
}
|
|
2443
|
-
|
|
2444
|
-
// src/plugins/OutlinePlugin.tsx
|
|
2445
|
-
import { useCallback as useCallback4, useEffect as useEffect8, useState as useState4 } from "react";
|
|
2446
|
-
import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
|
|
2447
|
-
import {
|
|
2448
|
-
TableOfContentsPlugin
|
|
2449
|
-
} from "@lexical/react/LexicalTableOfContentsPlugin";
|
|
2450
|
-
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2451
|
-
var INDENT_PER_LEVEL = {
|
|
2452
|
-
h1: 0,
|
|
2453
|
-
h2: 1,
|
|
2454
|
-
h3: 2,
|
|
2455
|
-
h4: 3,
|
|
2456
|
-
h5: 4,
|
|
2457
|
-
h6: 5
|
|
2458
|
-
};
|
|
2459
|
-
function OutlinePlugin() {
|
|
2460
|
-
const [editor] = useLexicalComposerContext8();
|
|
2461
|
-
const [collapsed, setCollapsed] = useState4(false);
|
|
2462
|
-
const [activeKey, setActiveKey] = useState4(null);
|
|
2463
|
-
useEffect8(() => {
|
|
2464
|
-
const rootElement = editor.getRootElement();
|
|
2465
|
-
const scroller = rootElement?.closest(".zui-text-editor");
|
|
2466
|
-
if (!rootElement || !(scroller instanceof HTMLElement)) return;
|
|
2467
|
-
let frame = 0;
|
|
2468
|
-
const updateActive = () => {
|
|
2469
|
-
cancelAnimationFrame(frame);
|
|
2470
|
-
frame = requestAnimationFrame(() => {
|
|
2471
|
-
const headings = rootElement.querySelectorAll(
|
|
2472
|
-
"h1, h2, h3, h4, h5, h6"
|
|
2473
|
-
);
|
|
2474
|
-
const threshold = scroller.scrollTop + 80;
|
|
2475
|
-
let current = null;
|
|
2476
|
-
for (const el of headings) {
|
|
2477
|
-
if (el.offsetTop <= threshold) {
|
|
2478
|
-
current = el.getAttribute("data-outline-key");
|
|
2479
|
-
}
|
|
2480
|
-
}
|
|
2481
|
-
setActiveKey(current);
|
|
2482
|
-
});
|
|
2483
|
-
};
|
|
2484
|
-
updateActive();
|
|
2485
|
-
scroller.addEventListener("scroll", updateActive, { passive: true });
|
|
2486
|
-
const unregister = editor.registerUpdateListener(updateActive);
|
|
2487
|
-
return () => {
|
|
2488
|
-
cancelAnimationFrame(frame);
|
|
2489
|
-
scroller.removeEventListener("scroll", updateActive);
|
|
2490
|
-
unregister();
|
|
2491
|
-
};
|
|
2492
|
-
}, [editor]);
|
|
2493
|
-
const scrollTo = useCallback4(
|
|
2494
|
-
(key) => {
|
|
2495
|
-
editor.getEditorState().read(() => {
|
|
2496
|
-
const element = editor.getElementByKey(key);
|
|
2497
|
-
element?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
2498
|
-
});
|
|
2499
|
-
},
|
|
2500
|
-
[editor]
|
|
2501
|
-
);
|
|
2502
|
-
return /* @__PURE__ */ jsx6(TableOfContentsPlugin, { children: (entries) => {
|
|
2503
|
-
for (const [key] of entries) {
|
|
2504
|
-
editor.getElementByKey(key)?.setAttribute("data-outline-key", key);
|
|
2505
|
-
}
|
|
2506
|
-
return /* @__PURE__ */ jsxs4(
|
|
2507
|
-
"div",
|
|
2508
|
-
{
|
|
2509
|
-
className: `zui-text-editor-outline ${collapsed ? "is-collapsed" : ""}`,
|
|
2510
|
-
children: [
|
|
2511
|
-
/* @__PURE__ */ jsx6(
|
|
2512
|
-
"button",
|
|
2513
|
-
{
|
|
2514
|
-
type: "button",
|
|
2515
|
-
className: "zui-text-editor-outline-toggle",
|
|
2516
|
-
title: collapsed ? "Show outline" : "Hide outline",
|
|
2517
|
-
"aria-label": collapsed ? "Show outline" : "Hide outline",
|
|
2518
|
-
"aria-expanded": !collapsed,
|
|
2519
|
-
onClick: () => setCollapsed((c) => !c),
|
|
2520
|
-
children: /* @__PURE__ */ jsx6(
|
|
2521
|
-
"svg",
|
|
2522
|
-
{
|
|
2523
|
-
viewBox: "0 0 20 20",
|
|
2524
|
-
width: "14",
|
|
2525
|
-
height: "14",
|
|
2526
|
-
fill: "none",
|
|
2527
|
-
stroke: "currentColor",
|
|
2528
|
-
strokeWidth: "1.8",
|
|
2529
|
-
strokeLinecap: "round",
|
|
2530
|
-
children: /* @__PURE__ */ jsx6("path", { d: "M4 5h12M4 10h8M4 15h10" })
|
|
2531
|
-
}
|
|
2532
|
-
)
|
|
2533
|
-
}
|
|
2534
|
-
),
|
|
2535
|
-
!collapsed && /* @__PURE__ */ jsxs4("nav", { className: "zui-text-editor-outline-list", "aria-label": "Table of contents", children: [
|
|
2536
|
-
entries.length === 0 && /* @__PURE__ */ jsx6("div", { className: "zui-text-editor-outline-empty", children: "No headings" }),
|
|
2537
|
-
entries.map(([key, text, tag]) => /* @__PURE__ */ jsx6(
|
|
2538
|
-
"button",
|
|
2539
|
-
{
|
|
2540
|
-
type: "button",
|
|
2541
|
-
className: `zui-text-editor-outline-item ${key === activeKey ? "is-active" : ""}`,
|
|
2542
|
-
style: {
|
|
2543
|
-
paddingLeft: `${0.5 + INDENT_PER_LEVEL[tag] * 0.75}rem`
|
|
2544
|
-
},
|
|
2545
|
-
onClick: () => scrollTo(key),
|
|
2546
|
-
children: text || "Untitled"
|
|
2547
|
-
},
|
|
2548
|
-
key
|
|
2549
|
-
))
|
|
2550
|
-
] })
|
|
2551
|
-
]
|
|
2552
|
-
}
|
|
2553
|
-
);
|
|
2554
|
-
} });
|
|
2555
|
-
}
|
|
2524
|
+
// src/plugins/TableWidthPlugin.tsx
|
|
2525
|
+
import { useCallback as useCallback5, useEffect as useEffect9, useState as useState5 } from "react";
|
|
2526
|
+
import { useLexicalComposerContext as useLexicalComposerContext9 } from "@lexical/react/LexicalComposerContext";
|
|
2527
|
+
import { useLexicalEditable as useLexicalEditable2 } from "@lexical/react/useLexicalEditable";
|
|
2556
2528
|
|
|
2557
2529
|
// src/useMarkdownEditor.ts
|
|
2558
|
-
import { useCallback as
|
|
2530
|
+
import { useCallback as useCallback4, useEffect as useEffect8, useState as useState4 } from "react";
|
|
2559
2531
|
import {
|
|
2560
|
-
$getSelection as $
|
|
2561
|
-
$isRangeSelection as $
|
|
2532
|
+
$getSelection as $getSelection4,
|
|
2533
|
+
$isRangeSelection as $isRangeSelection4,
|
|
2562
2534
|
CAN_REDO_COMMAND,
|
|
2563
2535
|
CAN_UNDO_COMMAND,
|
|
2564
2536
|
COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW2,
|
|
@@ -2566,7 +2538,7 @@ import {
|
|
|
2566
2538
|
REDO_COMMAND,
|
|
2567
2539
|
UNDO_COMMAND
|
|
2568
2540
|
} from "lexical";
|
|
2569
|
-
import { useLexicalComposerContext as
|
|
2541
|
+
import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
|
|
2570
2542
|
import { INSERT_TABLE_COMMAND } from "@lexical/table";
|
|
2571
2543
|
import { $insertNodeToNearestRoot, mergeRegister } from "@lexical/utils";
|
|
2572
2544
|
var TRACKED_FORMATS = [
|
|
@@ -2577,18 +2549,21 @@ var TRACKED_FORMATS = [
|
|
|
2577
2549
|
"code"
|
|
2578
2550
|
];
|
|
2579
2551
|
function useMarkdownEditor() {
|
|
2580
|
-
const [editor] =
|
|
2581
|
-
const [activeFormats, setActiveFormats] =
|
|
2552
|
+
const [editor] = useLexicalComposerContext8();
|
|
2553
|
+
const [activeFormats, setActiveFormats] = useState4(
|
|
2582
2554
|
/* @__PURE__ */ new Set()
|
|
2583
2555
|
);
|
|
2584
|
-
const [canUndo, setCanUndo] =
|
|
2585
|
-
const [canRedo, setCanRedo] =
|
|
2586
|
-
|
|
2556
|
+
const [canUndo, setCanUndo] = useState4(false);
|
|
2557
|
+
const [canRedo, setCanRedo] = useState4(false);
|
|
2558
|
+
const [tableWidth, setTableWidthState] = useState4(null);
|
|
2559
|
+
useEffect8(
|
|
2587
2560
|
() => mergeRegister(
|
|
2588
2561
|
editor.registerUpdateListener(({ editorState }) => {
|
|
2589
2562
|
editorState.read(() => {
|
|
2590
|
-
const
|
|
2591
|
-
|
|
2563
|
+
const table = $getSelectedTable();
|
|
2564
|
+
setTableWidthState(table ? $getTableWidth(table) : null);
|
|
2565
|
+
const selection = $getSelection4();
|
|
2566
|
+
if (!$isRangeSelection4(selection)) {
|
|
2592
2567
|
setActiveFormats(/* @__PURE__ */ new Set());
|
|
2593
2568
|
return;
|
|
2594
2569
|
}
|
|
@@ -2618,13 +2593,13 @@ function useMarkdownEditor() {
|
|
|
2618
2593
|
),
|
|
2619
2594
|
[editor]
|
|
2620
2595
|
);
|
|
2621
|
-
const toggleFormat =
|
|
2596
|
+
const toggleFormat = useCallback4(
|
|
2622
2597
|
(format) => {
|
|
2623
2598
|
editor.dispatchCommand(FORMAT_TEXT_COMMAND, format);
|
|
2624
2599
|
},
|
|
2625
2600
|
[editor]
|
|
2626
2601
|
);
|
|
2627
|
-
const insertTable =
|
|
2602
|
+
const insertTable = useCallback4(
|
|
2628
2603
|
({ rows = 3, columns = 3 } = {}) => {
|
|
2629
2604
|
editor.dispatchCommand(INSERT_TABLE_COMMAND, {
|
|
2630
2605
|
columns: String(columns),
|
|
@@ -2634,15 +2609,24 @@ function useMarkdownEditor() {
|
|
|
2634
2609
|
},
|
|
2635
2610
|
[editor]
|
|
2636
2611
|
);
|
|
2637
|
-
const insertDrawing =
|
|
2612
|
+
const insertDrawing = useCallback4(() => {
|
|
2638
2613
|
editor.update(() => {
|
|
2639
2614
|
$insertNodeToNearestRoot($createDrawingNode());
|
|
2640
2615
|
});
|
|
2641
2616
|
}, [editor]);
|
|
2642
|
-
const
|
|
2617
|
+
const setTableWidth = useCallback4(
|
|
2618
|
+
(width) => {
|
|
2619
|
+
editor.update(() => {
|
|
2620
|
+
const table = $getSelectedTable();
|
|
2621
|
+
if (table) $setTableWidth(table, width);
|
|
2622
|
+
});
|
|
2623
|
+
},
|
|
2624
|
+
[editor]
|
|
2625
|
+
);
|
|
2626
|
+
const undo = useCallback4(() => {
|
|
2643
2627
|
editor.dispatchCommand(UNDO_COMMAND, void 0);
|
|
2644
2628
|
}, [editor]);
|
|
2645
|
-
const redo =
|
|
2629
|
+
const redo = useCallback4(() => {
|
|
2646
2630
|
editor.dispatchCommand(REDO_COMMAND, void 0);
|
|
2647
2631
|
}, [editor]);
|
|
2648
2632
|
return {
|
|
@@ -2651,6 +2635,8 @@ function useMarkdownEditor() {
|
|
|
2651
2635
|
toggleFormat,
|
|
2652
2636
|
insertTable,
|
|
2653
2637
|
insertDrawing,
|
|
2638
|
+
tableWidth,
|
|
2639
|
+
setTableWidth,
|
|
2654
2640
|
canUndo,
|
|
2655
2641
|
canRedo,
|
|
2656
2642
|
undo,
|
|
@@ -2659,23 +2645,23 @@ function useMarkdownEditor() {
|
|
|
2659
2645
|
}
|
|
2660
2646
|
|
|
2661
2647
|
// src/components/Toolbar.tsx
|
|
2662
|
-
import { Fragment as
|
|
2648
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2663
2649
|
function Toolbar({ children, className }) {
|
|
2664
|
-
return /* @__PURE__ */
|
|
2650
|
+
return /* @__PURE__ */ jsx6(
|
|
2665
2651
|
"div",
|
|
2666
2652
|
{
|
|
2667
2653
|
className: `zui-text-editor-toolbar ${className ?? ""}`,
|
|
2668
2654
|
role: "toolbar",
|
|
2669
|
-
children: children ?? /* @__PURE__ */
|
|
2670
|
-
/* @__PURE__ */
|
|
2671
|
-
/* @__PURE__ */
|
|
2672
|
-
/* @__PURE__ */
|
|
2655
|
+
children: children ?? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
2656
|
+
/* @__PURE__ */ jsx6(FormatButtons, {}),
|
|
2657
|
+
/* @__PURE__ */ jsx6(ToolbarDivider, {}),
|
|
2658
|
+
/* @__PURE__ */ jsx6(InsertButtons, {})
|
|
2673
2659
|
] })
|
|
2674
2660
|
}
|
|
2675
2661
|
);
|
|
2676
2662
|
}
|
|
2677
2663
|
function ToolbarDivider() {
|
|
2678
|
-
return /* @__PURE__ */
|
|
2664
|
+
return /* @__PURE__ */ jsx6("div", { className: "zui-text-editor-toolbar-divider" });
|
|
2679
2665
|
}
|
|
2680
2666
|
function ToolbarButton({
|
|
2681
2667
|
label,
|
|
@@ -2685,7 +2671,7 @@ function ToolbarButton({
|
|
|
2685
2671
|
disabled = false,
|
|
2686
2672
|
className
|
|
2687
2673
|
}) {
|
|
2688
|
-
return /* @__PURE__ */
|
|
2674
|
+
return /* @__PURE__ */ jsx6(
|
|
2689
2675
|
"button",
|
|
2690
2676
|
{
|
|
2691
2677
|
type: "button",
|
|
@@ -2701,7 +2687,7 @@ function ToolbarButton({
|
|
|
2701
2687
|
);
|
|
2702
2688
|
}
|
|
2703
2689
|
function Icon({ children, strokeWidth = 1.5 }) {
|
|
2704
|
-
return /* @__PURE__ */
|
|
2690
|
+
return /* @__PURE__ */ jsx6(
|
|
2705
2691
|
"svg",
|
|
2706
2692
|
{
|
|
2707
2693
|
viewBox: "0 0 20 20",
|
|
@@ -2720,27 +2706,27 @@ var FORMAT_BUTTONS = [
|
|
|
2720
2706
|
{
|
|
2721
2707
|
format: "bold",
|
|
2722
2708
|
label: "Bold",
|
|
2723
|
-
icon: /* @__PURE__ */
|
|
2709
|
+
icon: /* @__PURE__ */ jsx6(Icon, { strokeWidth: 1.8, children: /* @__PURE__ */ jsx6("path", { d: "M6 3.5h5a3 3 0 0 1 0 6H6zm0 6h6a3 3 0 0 1 0 6H6z" }) })
|
|
2724
2710
|
},
|
|
2725
2711
|
{
|
|
2726
2712
|
format: "italic",
|
|
2727
2713
|
label: "Italic",
|
|
2728
|
-
icon: /* @__PURE__ */
|
|
2714
|
+
icon: /* @__PURE__ */ jsx6(Icon, { strokeWidth: 1.6, children: /* @__PURE__ */ jsx6("path", { d: "M8.5 3.5h6M5.5 16.5h6M11.5 3.5l-3 13" }) })
|
|
2729
2715
|
},
|
|
2730
2716
|
{
|
|
2731
2717
|
format: "strikethrough",
|
|
2732
2718
|
label: "Strikethrough",
|
|
2733
|
-
icon: /* @__PURE__ */
|
|
2719
|
+
icon: /* @__PURE__ */ jsx6(Icon, { strokeWidth: 1.6, children: /* @__PURE__ */ jsx6("path", { 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" }) })
|
|
2734
2720
|
},
|
|
2735
2721
|
{
|
|
2736
2722
|
format: "code",
|
|
2737
2723
|
label: "Inline code",
|
|
2738
|
-
icon: /* @__PURE__ */
|
|
2724
|
+
icon: /* @__PURE__ */ jsx6(Icon, { strokeWidth: 1.6, children: /* @__PURE__ */ jsx6("path", { d: "M7.5 6L4 10l3.5 4M12.5 6L16 10l-3.5 4" }) })
|
|
2739
2725
|
}
|
|
2740
2726
|
];
|
|
2741
2727
|
function FormatButtons() {
|
|
2742
2728
|
const { activeFormats, toggleFormat } = useMarkdownEditor();
|
|
2743
|
-
return /* @__PURE__ */
|
|
2729
|
+
return /* @__PURE__ */ jsx6(Fragment3, { children: FORMAT_BUTTONS.map(({ format, label, icon }) => /* @__PURE__ */ jsx6(
|
|
2744
2730
|
ToolbarButton,
|
|
2745
2731
|
{
|
|
2746
2732
|
label,
|
|
@@ -2753,38 +2739,264 @@ function FormatButtons() {
|
|
|
2753
2739
|
}
|
|
2754
2740
|
function InsertButtons() {
|
|
2755
2741
|
const { insertTable, insertDrawing } = useMarkdownEditor();
|
|
2756
|
-
return /* @__PURE__ */
|
|
2757
|
-
/* @__PURE__ */
|
|
2758
|
-
/* @__PURE__ */
|
|
2759
|
-
/* @__PURE__ */
|
|
2742
|
+
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
2743
|
+
/* @__PURE__ */ jsx6(ToolbarButton, { label: "Insert table", onClick: () => insertTable(), children: /* @__PURE__ */ jsxs4(Icon, { children: [
|
|
2744
|
+
/* @__PURE__ */ jsx6("rect", { x: "3", y: "3.5", width: "14", height: "13", rx: "1.5" }),
|
|
2745
|
+
/* @__PURE__ */ jsx6("path", { d: "M3 8h14M8 8v8.5M13 8v8.5" })
|
|
2760
2746
|
] }) }),
|
|
2761
|
-
/* @__PURE__ */
|
|
2762
|
-
/* @__PURE__ */
|
|
2763
|
-
/* @__PURE__ */
|
|
2764
|
-
/* @__PURE__ */
|
|
2747
|
+
/* @__PURE__ */ jsx6(ToolbarButton, { label: "Insert drawing", onClick: insertDrawing, children: /* @__PURE__ */ jsxs4(Icon, { children: [
|
|
2748
|
+
/* @__PURE__ */ jsx6("rect", { x: "3", y: "5", width: "8", height: "6", rx: "1.5" }),
|
|
2749
|
+
/* @__PURE__ */ jsx6("path", { d: "M13.5 8h3M14.5 6.5L17.5 8l-3 1.5" }),
|
|
2750
|
+
/* @__PURE__ */ jsx6("ellipse", { cx: "13", cy: "14.5", rx: "4", ry: "2.8" })
|
|
2765
2751
|
] }) })
|
|
2766
2752
|
] });
|
|
2767
2753
|
}
|
|
2768
2754
|
function HistoryButtons() {
|
|
2769
2755
|
const { canUndo, canRedo, undo, redo } = useMarkdownEditor();
|
|
2770
|
-
return /* @__PURE__ */
|
|
2771
|
-
/* @__PURE__ */
|
|
2772
|
-
/* @__PURE__ */
|
|
2773
|
-
/* @__PURE__ */
|
|
2756
|
+
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
2757
|
+
/* @__PURE__ */ jsx6(ToolbarButton, { label: "Undo", onClick: undo, disabled: !canUndo, children: /* @__PURE__ */ jsxs4(Icon, { children: [
|
|
2758
|
+
/* @__PURE__ */ jsx6("path", { d: "M7 6L3.5 9.5 7 13" }),
|
|
2759
|
+
/* @__PURE__ */ jsx6("path", { d: "M3.5 9.5H12a4 4 0 0 1 0 8h-1" })
|
|
2774
2760
|
] }) }),
|
|
2775
|
-
/* @__PURE__ */
|
|
2776
|
-
/* @__PURE__ */
|
|
2777
|
-
/* @__PURE__ */
|
|
2761
|
+
/* @__PURE__ */ jsx6(ToolbarButton, { label: "Redo", onClick: redo, disabled: !canRedo, children: /* @__PURE__ */ jsxs4(Icon, { children: [
|
|
2762
|
+
/* @__PURE__ */ jsx6("path", { d: "M13 6l3.5 3.5L13 13" }),
|
|
2763
|
+
/* @__PURE__ */ jsx6("path", { d: "M16.5 9.5H8a4 4 0 0 0 0 8h1" })
|
|
2778
2764
|
] }) })
|
|
2779
2765
|
] });
|
|
2780
2766
|
}
|
|
2781
2767
|
|
|
2768
|
+
// src/plugins/TableWidthPlugin.tsx
|
|
2769
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2770
|
+
function TableWidthPlugin() {
|
|
2771
|
+
const [editor] = useLexicalComposerContext9();
|
|
2772
|
+
const isEditable = useLexicalEditable2();
|
|
2773
|
+
const { tableWidth, setTableWidth } = useMarkdownEditor();
|
|
2774
|
+
const [anchor, setAnchor] = useState5(null);
|
|
2775
|
+
const sync = useCallback5(() => {
|
|
2776
|
+
const tableKey = editor.getEditorState().read(() => $getSelectedTable()?.getKey());
|
|
2777
|
+
const element = tableKey ? editor.getElementByKey(tableKey) : null;
|
|
2778
|
+
const main = editor.getRootElement()?.parentElement;
|
|
2779
|
+
if (!element || !main) {
|
|
2780
|
+
setAnchor(null);
|
|
2781
|
+
return;
|
|
2782
|
+
}
|
|
2783
|
+
const rect = element.getBoundingClientRect();
|
|
2784
|
+
const mainRect = main.getBoundingClientRect();
|
|
2785
|
+
setAnchor({
|
|
2786
|
+
top: rect.top - mainRect.top,
|
|
2787
|
+
right: mainRect.right - rect.right + 8
|
|
2788
|
+
});
|
|
2789
|
+
}, [editor]);
|
|
2790
|
+
useEffect9(() => {
|
|
2791
|
+
sync();
|
|
2792
|
+
const unregister = editor.registerUpdateListener(sync);
|
|
2793
|
+
const rootElement = editor.getRootElement();
|
|
2794
|
+
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(sync) : null;
|
|
2795
|
+
if (rootElement && observer) observer.observe(rootElement);
|
|
2796
|
+
return () => {
|
|
2797
|
+
unregister();
|
|
2798
|
+
observer?.disconnect();
|
|
2799
|
+
};
|
|
2800
|
+
}, [editor, sync]);
|
|
2801
|
+
if (!isEditable || !anchor || !tableWidth) return null;
|
|
2802
|
+
return /* @__PURE__ */ jsx7(
|
|
2803
|
+
"div",
|
|
2804
|
+
{
|
|
2805
|
+
className: "zui-table-width",
|
|
2806
|
+
role: "group",
|
|
2807
|
+
"aria-label": "Table width",
|
|
2808
|
+
style: { top: anchor.top, right: anchor.right },
|
|
2809
|
+
children: BLOCK_WIDTH_OPTIONS.map(({ width, label, icon }) => /* @__PURE__ */ jsx7(
|
|
2810
|
+
ToolbarButton,
|
|
2811
|
+
{
|
|
2812
|
+
label,
|
|
2813
|
+
active: tableWidth === width,
|
|
2814
|
+
onClick: () => setTableWidth(width),
|
|
2815
|
+
children: /* @__PURE__ */ jsx7(
|
|
2816
|
+
"svg",
|
|
2817
|
+
{
|
|
2818
|
+
viewBox: "0 0 20 20",
|
|
2819
|
+
width: "16",
|
|
2820
|
+
height: "16",
|
|
2821
|
+
fill: "none",
|
|
2822
|
+
stroke: "currentColor",
|
|
2823
|
+
strokeWidth: "1.6",
|
|
2824
|
+
strokeLinecap: "round",
|
|
2825
|
+
strokeLinejoin: "round",
|
|
2826
|
+
children: icon
|
|
2827
|
+
}
|
|
2828
|
+
)
|
|
2829
|
+
},
|
|
2830
|
+
width
|
|
2831
|
+
))
|
|
2832
|
+
}
|
|
2833
|
+
);
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
// src/EditorContent.tsx
|
|
2837
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2838
|
+
function EditorContent({
|
|
2839
|
+
placeholder = "Start writing...",
|
|
2840
|
+
foldable = true,
|
|
2841
|
+
children
|
|
2842
|
+
}) {
|
|
2843
|
+
const { mode, readOnly, autoFocus, rawValue, onRawChange } = useEditorContext();
|
|
2844
|
+
if (mode === "edit-raw") {
|
|
2845
|
+
return /* @__PURE__ */ jsx8(
|
|
2846
|
+
"textarea",
|
|
2847
|
+
{
|
|
2848
|
+
className: "zui-text-editor-textarea",
|
|
2849
|
+
value: rawValue,
|
|
2850
|
+
onChange: (e) => onRawChange(e.target.value),
|
|
2851
|
+
placeholder,
|
|
2852
|
+
readOnly,
|
|
2853
|
+
autoFocus,
|
|
2854
|
+
spellCheck: false
|
|
2855
|
+
}
|
|
2856
|
+
);
|
|
2857
|
+
}
|
|
2858
|
+
return /* @__PURE__ */ jsxs5("div", { className: "zui-text-editor-body", children: [
|
|
2859
|
+
/* @__PURE__ */ jsxs5("div", { className: "zui-text-editor-main", children: [
|
|
2860
|
+
/* @__PURE__ */ jsx8(
|
|
2861
|
+
RichTextPlugin,
|
|
2862
|
+
{
|
|
2863
|
+
contentEditable: /* @__PURE__ */ jsx8(
|
|
2864
|
+
ContentEditable,
|
|
2865
|
+
{
|
|
2866
|
+
className: "zui-text-editor-content",
|
|
2867
|
+
"aria-placeholder": placeholder,
|
|
2868
|
+
placeholder: /* @__PURE__ */ jsx8("div", { className: "zui-text-editor-placeholder", children: placeholder })
|
|
2869
|
+
}
|
|
2870
|
+
),
|
|
2871
|
+
ErrorBoundary: LexicalErrorBoundary
|
|
2872
|
+
}
|
|
2873
|
+
),
|
|
2874
|
+
foldable && /* @__PURE__ */ jsx8(FoldingPlugin, {}),
|
|
2875
|
+
/* @__PURE__ */ jsx8(TableWidthPlugin, {})
|
|
2876
|
+
] }),
|
|
2877
|
+
children
|
|
2878
|
+
] });
|
|
2879
|
+
}
|
|
2880
|
+
|
|
2881
|
+
// src/plugins/OutlinePlugin.tsx
|
|
2882
|
+
import { useCallback as useCallback6, useEffect as useEffect10, useState as useState6 } from "react";
|
|
2883
|
+
import { useLexicalComposerContext as useLexicalComposerContext10 } from "@lexical/react/LexicalComposerContext";
|
|
2884
|
+
import {
|
|
2885
|
+
TableOfContentsPlugin
|
|
2886
|
+
} from "@lexical/react/LexicalTableOfContentsPlugin";
|
|
2887
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2888
|
+
var INDENT_PER_LEVEL = {
|
|
2889
|
+
h1: 0,
|
|
2890
|
+
h2: 1,
|
|
2891
|
+
h3: 2,
|
|
2892
|
+
h4: 3,
|
|
2893
|
+
h5: 4,
|
|
2894
|
+
h6: 5
|
|
2895
|
+
};
|
|
2896
|
+
function OutlinePlugin() {
|
|
2897
|
+
const [editor] = useLexicalComposerContext10();
|
|
2898
|
+
const [collapsed, setCollapsed] = useState6(false);
|
|
2899
|
+
const [activeKey, setActiveKey] = useState6(null);
|
|
2900
|
+
useEffect10(() => {
|
|
2901
|
+
const rootElement = editor.getRootElement();
|
|
2902
|
+
const scroller = rootElement?.closest(".zui-text-editor");
|
|
2903
|
+
if (!rootElement || !(scroller instanceof HTMLElement)) return;
|
|
2904
|
+
let frame = 0;
|
|
2905
|
+
const updateActive = () => {
|
|
2906
|
+
cancelAnimationFrame(frame);
|
|
2907
|
+
frame = requestAnimationFrame(() => {
|
|
2908
|
+
const headings = rootElement.querySelectorAll(
|
|
2909
|
+
"h1, h2, h3, h4, h5, h6"
|
|
2910
|
+
);
|
|
2911
|
+
const threshold = scroller.scrollTop + 80;
|
|
2912
|
+
let current = null;
|
|
2913
|
+
for (const el of headings) {
|
|
2914
|
+
if (el.offsetTop <= threshold) {
|
|
2915
|
+
current = el.getAttribute("data-outline-key");
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
setActiveKey(current);
|
|
2919
|
+
});
|
|
2920
|
+
};
|
|
2921
|
+
updateActive();
|
|
2922
|
+
scroller.addEventListener("scroll", updateActive, { passive: true });
|
|
2923
|
+
const unregister = editor.registerUpdateListener(updateActive);
|
|
2924
|
+
return () => {
|
|
2925
|
+
cancelAnimationFrame(frame);
|
|
2926
|
+
scroller.removeEventListener("scroll", updateActive);
|
|
2927
|
+
unregister();
|
|
2928
|
+
};
|
|
2929
|
+
}, [editor]);
|
|
2930
|
+
const scrollTo = useCallback6(
|
|
2931
|
+
(key) => {
|
|
2932
|
+
editor.getEditorState().read(() => {
|
|
2933
|
+
const element = editor.getElementByKey(key);
|
|
2934
|
+
element?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
2935
|
+
});
|
|
2936
|
+
},
|
|
2937
|
+
[editor]
|
|
2938
|
+
);
|
|
2939
|
+
return /* @__PURE__ */ jsx9(TableOfContentsPlugin, { children: (entries) => {
|
|
2940
|
+
for (const [key] of entries) {
|
|
2941
|
+
editor.getElementByKey(key)?.setAttribute("data-outline-key", key);
|
|
2942
|
+
}
|
|
2943
|
+
return /* @__PURE__ */ jsxs6(
|
|
2944
|
+
"div",
|
|
2945
|
+
{
|
|
2946
|
+
className: `zui-text-editor-outline ${collapsed ? "is-collapsed" : ""}`,
|
|
2947
|
+
children: [
|
|
2948
|
+
/* @__PURE__ */ jsx9(
|
|
2949
|
+
"button",
|
|
2950
|
+
{
|
|
2951
|
+
type: "button",
|
|
2952
|
+
className: "zui-text-editor-outline-toggle",
|
|
2953
|
+
title: collapsed ? "Show outline" : "Hide outline",
|
|
2954
|
+
"aria-label": collapsed ? "Show outline" : "Hide outline",
|
|
2955
|
+
"aria-expanded": !collapsed,
|
|
2956
|
+
onClick: () => setCollapsed((c) => !c),
|
|
2957
|
+
children: /* @__PURE__ */ jsx9(
|
|
2958
|
+
"svg",
|
|
2959
|
+
{
|
|
2960
|
+
viewBox: "0 0 20 20",
|
|
2961
|
+
width: "14",
|
|
2962
|
+
height: "14",
|
|
2963
|
+
fill: "none",
|
|
2964
|
+
stroke: "currentColor",
|
|
2965
|
+
strokeWidth: "1.8",
|
|
2966
|
+
strokeLinecap: "round",
|
|
2967
|
+
children: /* @__PURE__ */ jsx9("path", { d: "M4 5h12M4 10h8M4 15h10" })
|
|
2968
|
+
}
|
|
2969
|
+
)
|
|
2970
|
+
}
|
|
2971
|
+
),
|
|
2972
|
+
!collapsed && /* @__PURE__ */ jsxs6("nav", { className: "zui-text-editor-outline-list", "aria-label": "Table of contents", children: [
|
|
2973
|
+
entries.length === 0 && /* @__PURE__ */ jsx9("div", { className: "zui-text-editor-outline-empty", children: "No headings" }),
|
|
2974
|
+
entries.map(([key, text, tag]) => /* @__PURE__ */ jsx9(
|
|
2975
|
+
"button",
|
|
2976
|
+
{
|
|
2977
|
+
type: "button",
|
|
2978
|
+
className: `zui-text-editor-outline-item ${key === activeKey ? "is-active" : ""}`,
|
|
2979
|
+
style: {
|
|
2980
|
+
paddingLeft: `${0.5 + INDENT_PER_LEVEL[tag] * 0.75}rem`
|
|
2981
|
+
},
|
|
2982
|
+
onClick: () => scrollTo(key),
|
|
2983
|
+
children: text || "Untitled"
|
|
2984
|
+
},
|
|
2985
|
+
key
|
|
2986
|
+
))
|
|
2987
|
+
] })
|
|
2988
|
+
]
|
|
2989
|
+
}
|
|
2990
|
+
);
|
|
2991
|
+
} });
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2782
2994
|
// src/MarkdownEditor.tsx
|
|
2783
|
-
import { jsx as
|
|
2995
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2784
2996
|
var DEFAULT_ITEMS = {
|
|
2785
|
-
format: /* @__PURE__ */
|
|
2786
|
-
insert: /* @__PURE__ */
|
|
2787
|
-
history: /* @__PURE__ */
|
|
2997
|
+
format: /* @__PURE__ */ jsx10(FormatButtons, {}),
|
|
2998
|
+
insert: /* @__PURE__ */ jsx10(InsertButtons, {}),
|
|
2999
|
+
history: /* @__PURE__ */ jsx10(HistoryButtons, {})
|
|
2788
3000
|
};
|
|
2789
3001
|
function EditorToolbar({
|
|
2790
3002
|
children,
|
|
@@ -2792,7 +3004,7 @@ function EditorToolbar({
|
|
|
2792
3004
|
}) {
|
|
2793
3005
|
const { mode, readOnly } = useEditorContext();
|
|
2794
3006
|
if (mode !== "edit-md" || readOnly) return null;
|
|
2795
|
-
return /* @__PURE__ */
|
|
3007
|
+
return /* @__PURE__ */ jsx10(Toolbar, { className, children });
|
|
2796
3008
|
}
|
|
2797
3009
|
function MarkdownEditor({
|
|
2798
3010
|
placeholder,
|
|
@@ -2801,10 +3013,10 @@ function MarkdownEditor({
|
|
|
2801
3013
|
foldable = true,
|
|
2802
3014
|
...rootProps
|
|
2803
3015
|
}) {
|
|
2804
|
-
return /* @__PURE__ */
|
|
2805
|
-
toolbar === true && /* @__PURE__ */
|
|
3016
|
+
return /* @__PURE__ */ jsxs7(EditorRoot, { ...rootProps, children: [
|
|
3017
|
+
toolbar === true && /* @__PURE__ */ jsx10(EditorToolbar, {}),
|
|
2806
3018
|
typeof toolbar === "function" && toolbar(DEFAULT_ITEMS),
|
|
2807
|
-
/* @__PURE__ */
|
|
3019
|
+
/* @__PURE__ */ jsx10(EditorContent, { placeholder, foldable, children: outline && /* @__PURE__ */ jsx10(OutlinePlugin, {}) })
|
|
2808
3020
|
] });
|
|
2809
3021
|
}
|
|
2810
3022
|
MarkdownEditor.Root = EditorRoot;
|
|
@@ -2832,7 +3044,11 @@ var DRAWING_DATA_JSON_SCHEMA = {
|
|
|
2832
3044
|
height: {
|
|
2833
3045
|
type: "number",
|
|
2834
3046
|
minimum: 80,
|
|
2835
|
-
description: "Canvas height in pixels
|
|
3047
|
+
description: "Canvas height in pixels"
|
|
3048
|
+
},
|
|
3049
|
+
width: {
|
|
3050
|
+
enum: ["full", "content"],
|
|
3051
|
+
description: `Canvas width: "full" (default) spans the editor; "content" fits the shapes' horizontal extent and left-aligns with the text`
|
|
2836
3052
|
},
|
|
2837
3053
|
shapes: {
|
|
2838
3054
|
type: "array",
|
|
@@ -2930,8 +3146,11 @@ var DRAWING_DATA_JSON_SCHEMA = {
|
|
|
2930
3146
|
export {
|
|
2931
3147
|
$createDrawingNode,
|
|
2932
3148
|
$createFrontmatterNode,
|
|
3149
|
+
$getSelectedTable,
|
|
3150
|
+
$getTableWidth,
|
|
2933
3151
|
$isDrawingNode,
|
|
2934
3152
|
$isFrontmatterNode,
|
|
3153
|
+
$setTableWidth,
|
|
2935
3154
|
DRAWING,
|
|
2936
3155
|
DRAWING_DATA_JSON_SCHEMA,
|
|
2937
3156
|
DrawingNode,
|
|
@@ -2942,6 +3161,7 @@ export {
|
|
|
2942
3161
|
InsertButtons,
|
|
2943
3162
|
MarkdownEditor_default as MarkdownEditor,
|
|
2944
3163
|
TABLE,
|
|
3164
|
+
TABLE_WIDTH_MARKER,
|
|
2945
3165
|
Toolbar,
|
|
2946
3166
|
ToolbarButton,
|
|
2947
3167
|
ToolbarDivider,
|