@fiestaboard/ui 3.0.1 → 3.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.
Files changed (115) hide show
  1. package/dist/components/containment/json-tree.d.ts +59 -0
  2. package/dist/components/containment/json-tree.js +122 -0
  3. package/dist/components/containment/json-tree.js.map +1 -0
  4. package/dist/components/editor/color-picker-content.d.ts +25 -0
  5. package/dist/components/editor/color-picker-content.js +118 -0
  6. package/dist/components/editor/color-picker-content.js.map +1 -0
  7. package/dist/components/editor/constants.d.ts +87 -0
  8. package/dist/components/editor/constants.js +29 -0
  9. package/dist/components/editor/constants.js.map +1 -0
  10. package/dist/components/editor/draw-char-picker-content.d.ts +22 -0
  11. package/dist/components/editor/draw-char-picker-content.js +79 -0
  12. package/dist/components/editor/draw-char-picker-content.js.map +1 -0
  13. package/dist/components/editor/extensions/color-tile-node.d.ts +10 -0
  14. package/dist/components/editor/extensions/color-tile-node.js +43 -0
  15. package/dist/components/editor/extensions/color-tile-node.js.map +1 -0
  16. package/dist/components/editor/extensions/fill-space-node.d.ts +10 -0
  17. package/dist/components/editor/extensions/fill-space-node.js +40 -0
  18. package/dist/components/editor/extensions/fill-space-node.js.map +1 -0
  19. package/dist/components/editor/extensions/formula-node.d.ts +6 -0
  20. package/dist/components/editor/extensions/formula-node.js +40 -0
  21. package/dist/components/editor/extensions/formula-node.js.map +1 -0
  22. package/dist/components/editor/extensions/line-navigation.d.ts +18 -0
  23. package/dist/components/editor/extensions/line-navigation.js +16 -0
  24. package/dist/components/editor/extensions/line-navigation.js.map +1 -0
  25. package/dist/components/editor/extensions/single-paragraph-doc.d.ts +15 -0
  26. package/dist/components/editor/extensions/single-paragraph-doc.js +11 -0
  27. package/dist/components/editor/extensions/single-paragraph-doc.js.map +1 -0
  28. package/dist/components/editor/extensions/trailing-newline.d.ts +13 -0
  29. package/dist/components/editor/extensions/trailing-newline.js +27 -0
  30. package/dist/components/editor/extensions/trailing-newline.js.map +1 -0
  31. package/dist/components/editor/extensions/variable-node.d.ts +15 -0
  32. package/dist/components/editor/extensions/variable-node.js +56 -0
  33. package/dist/components/editor/extensions/variable-node.js.map +1 -0
  34. package/dist/components/editor/extensions/wrapped-text-node.d.ts +9 -0
  35. package/dist/components/editor/extensions/wrapped-text-node.js +31 -0
  36. package/dist/components/editor/extensions/wrapped-text-node.js.map +1 -0
  37. package/dist/components/editor/filter-picker-content.d.ts +24 -0
  38. package/dist/components/editor/filter-picker-content.js +146 -0
  39. package/dist/components/editor/filter-picker-content.js.map +1 -0
  40. package/dist/components/editor/formatting-picker-content.d.ts +30 -0
  41. package/dist/components/editor/formatting-picker-content.js +154 -0
  42. package/dist/components/editor/formatting-picker-content.js.map +1 -0
  43. package/dist/components/editor/formula/formula-editor-panel.d.ts +102 -0
  44. package/dist/components/editor/formula/formula-editor-panel.js +527 -0
  45. package/dist/components/editor/formula/formula-editor-panel.js.map +1 -0
  46. package/dist/components/editor/node-views/color-tile-node-view.d.ts +21 -0
  47. package/dist/components/editor/node-views/color-tile-node-view.js +66 -0
  48. package/dist/components/editor/node-views/color-tile-node-view.js.map +1 -0
  49. package/dist/components/editor/node-views/fill-space-node-view.d.ts +16 -0
  50. package/dist/components/editor/node-views/fill-space-node-view.js +43 -0
  51. package/dist/components/editor/node-views/fill-space-node-view.js.map +1 -0
  52. package/dist/components/editor/node-views/formula-node-view.d.ts +39 -0
  53. package/dist/components/editor/node-views/formula-node-view.js +109 -0
  54. package/dist/components/editor/node-views/formula-node-view.js.map +1 -0
  55. package/dist/components/editor/node-views/node-view-context.d.ts +58 -0
  56. package/dist/components/editor/node-views/node-view-context.js +22 -0
  57. package/dist/components/editor/node-views/node-view-context.js.map +1 -0
  58. package/dist/components/editor/node-views/variable-node-view.d.ts +16 -0
  59. package/dist/components/editor/node-views/variable-node-view.js +63 -0
  60. package/dist/components/editor/node-views/variable-node-view.js.map +1 -0
  61. package/dist/components/editor/node-views/wrapped-text-view.d.ts +14 -0
  62. package/dist/components/editor/node-views/wrapped-text-view.js +46 -0
  63. package/dist/components/editor/node-views/wrapped-text-view.js.map +1 -0
  64. package/dist/components/editor/template-editor-toolbar.d.ts +146 -0
  65. package/dist/components/editor/template-editor-toolbar.js +434 -0
  66. package/dist/components/editor/template-editor-toolbar.js.map +1 -0
  67. package/dist/components/editor/template-editor.d.ts +109 -0
  68. package/dist/components/editor/template-editor.js +662 -0
  69. package/dist/components/editor/template-editor.js.map +1 -0
  70. package/dist/components/editor/toolbar-dropdown.d.ts +20 -0
  71. package/dist/components/editor/toolbar-dropdown.js +88 -0
  72. package/dist/components/editor/toolbar-dropdown.js.map +1 -0
  73. package/dist/components/editor/utils/draw-mode.d.ts +55 -0
  74. package/dist/components/editor/utils/draw-mode.js +79 -0
  75. package/dist/components/editor/utils/draw-mode.js.map +1 -0
  76. package/dist/components/editor/utils/insertion.d.ts +11 -0
  77. package/dist/components/editor/utils/insertion.js +26 -0
  78. package/dist/components/editor/utils/insertion.js.map +1 -0
  79. package/dist/components/editor/utils/length-calculator.d.ts +36 -0
  80. package/dist/components/editor/utils/length-calculator.js +32 -0
  81. package/dist/components/editor/utils/length-calculator.js.map +1 -0
  82. package/dist/components/editor/utils/serialization.d.ts +34 -0
  83. package/dist/components/editor/utils/serialization.js +184 -0
  84. package/dist/components/editor/utils/serialization.js.map +1 -0
  85. package/dist/components/editor/utils/stroke-transaction.d.ts +36 -0
  86. package/dist/components/editor/utils/stroke-transaction.js +57 -0
  87. package/dist/components/editor/utils/stroke-transaction.js.map +1 -0
  88. package/dist/components/editor/variable-picker-content.d.ts +130 -0
  89. package/dist/components/editor/variable-picker-content.js +422 -0
  90. package/dist/components/editor/variable-picker-content.js.map +1 -0
  91. package/dist/components/feedback/status-dot.d.ts +49 -0
  92. package/dist/components/feedback/status-dot.js +58 -0
  93. package/dist/components/feedback/status-dot.js.map +1 -0
  94. package/dist/components/forms/secret-input.d.ts +38 -0
  95. package/dist/components/forms/secret-input.js +42 -0
  96. package/dist/components/forms/secret-input.js.map +1 -0
  97. package/dist/components/forms/time-picker.d.ts +87 -0
  98. package/dist/components/forms/time-picker.js +260 -0
  99. package/dist/components/forms/time-picker.js.map +1 -0
  100. package/dist/components/forms/toggle-card.d.ts +120 -0
  101. package/dist/components/forms/toggle-card.js +211 -0
  102. package/dist/components/forms/toggle-card.js.map +1 -0
  103. package/dist/components/overlays/popover.d.ts +65 -0
  104. package/dist/components/overlays/popover.js +89 -0
  105. package/dist/components/overlays/popover.js.map +1 -0
  106. package/dist/editor.css +164 -0
  107. package/dist/index.d.ts +34 -0
  108. package/dist/index.js +95 -61
  109. package/dist/lib/board-colors.d.ts +16 -0
  110. package/dist/lib/board-colors.js +14 -14
  111. package/dist/lib/board-colors.js.map +1 -1
  112. package/dist/lib/use-deps-changed.d.ts +33 -0
  113. package/dist/lib/use-deps-changed.js +11 -0
  114. package/dist/lib/use-deps-changed.js.map +1 -0
  115. package/package.json +50 -2
@@ -0,0 +1,662 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/utils.js";
3
+ import { Box as t } from "../layout/box.js";
4
+ import { Flex as n } from "../layout/flex.js";
5
+ import { Skeleton as r } from "../feedback/skeleton.js";
6
+ import { Text as i } from "../typography/text.js";
7
+ import { Stack as a } from "../layout/stack.js";
8
+ import { Tooltip as o, TooltipContent as s, TooltipProvider as c, TooltipTrigger as l } from "../overlays/tooltip.js";
9
+ import { resolveDimensions as ee } from "../../lib/board-dimensions.js";
10
+ import { DEFAULT_BOARD_LINES as te, DEFAULT_BOARD_WIDTH as ne } from "./constants.js";
11
+ import { ColorTileNode as re } from "./extensions/color-tile-node.js";
12
+ import { FillSpaceNode as ie } from "./extensions/fill-space-node.js";
13
+ import { FormulaNode as u } from "./extensions/formula-node.js";
14
+ import { LineNavigation as ae } from "./extensions/line-navigation.js";
15
+ import { SingleParagraphDoc as oe } from "./extensions/single-paragraph-doc.js";
16
+ import { TrailingNewline as se } from "./extensions/trailing-newline.js";
17
+ import { VariableNode as ce } from "./extensions/variable-node.js";
18
+ import { WrappedTextNode as le } from "./extensions/wrapped-text-node.js";
19
+ import { brushToCell as ue } from "./utils/draw-mode.js";
20
+ import { parseLineContent as de, parseTemplateSimple as d, serializeTemplateSimple as f } from "./utils/serialization.js";
21
+ import { TemplateEditorToolbar as fe } from "./template-editor-toolbar.js";
22
+ import { buildStrokeTransaction as pe } from "./utils/stroke-transaction.js";
23
+ import { AlignCenter as me, AlignLeft as he, AlignRight as ge } from "lucide-react";
24
+ import { forwardRef as p, useCallback as m, useEffect as h, useImperativeHandle as _e, useMemo as ve, useRef as g, useState as _ } from "react";
25
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
26
+ import { closeHistory as b, undoDepth as ye } from "@tiptap/pm/history";
27
+ import { TextSelection as x } from "@tiptap/pm/state";
28
+ import { EditorContent as be, useEditor as xe } from "@tiptap/react";
29
+ import Se from "@tiptap/starter-kit";
30
+ //#region src/components/editor/template-editor.tsx
31
+ var S = {
32
+ lineCount: (e, t) => `${e} / ${t} lines`,
33
+ overLineLimit: (e) => ` — exceeds the ${e}-line board limit`,
34
+ currentLine: (e) => `(Line ${e})`,
35
+ alignment: "Alignment:",
36
+ alignLeft: "Align left",
37
+ alignCenter: "Align center",
38
+ alignRight: "Align right",
39
+ editorAriaLabel: "Template editor"
40
+ }, Ce = /* @__PURE__ */ new Set([
41
+ "variable",
42
+ "colorTile",
43
+ "fillSpace",
44
+ "formula",
45
+ "wrappedText"
46
+ ]);
47
+ function C(e) {
48
+ try {
49
+ if (!e || !e.content || e.content.size === 0) return "";
50
+ let t = "";
51
+ return e.content.forEach((e) => {
52
+ if (!(!e || !e.type)) try {
53
+ if (e.type.name === "text") t += e.text || "";
54
+ else if (e.type.name === "variable") {
55
+ let { pluginId: n, field: r, filters: i } = e.attrs || {}, a = i && i.length > 0 ? i.map((e) => `|${e.name}${e.arg ? ":" + e.arg : ""}`).join("") : "";
56
+ t += `{{${n || ""}.${r || ""}${a}}}`;
57
+ } else if (e.type.name === "colorTile") t += `{{${e.attrs?.color || ""}}}`;
58
+ else if (e.type.name === "fillSpace") {
59
+ let n = e.attrs?.repeatChar;
60
+ t += n && n !== " " ? `{{fill_space_repeat:${n}}}` : "{{fill_space}}";
61
+ } else e.type.name === "wrappedText" ? t += `{{${e.attrs?.text || ""}|wrap}}` : e.type.name === "formula" ? t += `{{= ${e.attrs?.expression || ""} }}` : e.type.name === "hardBreak" && (t += "\n");
62
+ } catch (e) {
63
+ console.warn("Error serializing node:", e);
64
+ }
65
+ }), t;
66
+ } catch (e) {
67
+ return console.warn("Error in serializeSliceToTemplate:", e), "";
68
+ }
69
+ }
70
+ var w = p(function({ value: p, onChange: w, onFocus: we, placeholder: Te = "Type text or insert variables...", className: T, showAlignmentControls: Ee = !0, onLineAlignmentChange: E, lineAlignments: De, onLineWrapChange: D, lineWrapEnabled: Oe, showToolbar: O = !0, boardWidth: ke, boardLines: Ae, onLineCountChange: k, deviceType: A, onSyncFromBoard: je, syncFromBoardPending: Me = !1, drawMode: j = !1, onDrawModeToggle: Ne, drawBrush: Pe, onDrawBrushChange: Fe, onDrawHistoryEvent: M, labels: Ie, toolbarProps: Le }, Re) {
71
+ let N = {
72
+ ...S,
73
+ ...Ie
74
+ }, P = A ? ee(A) : null, F = ke ?? P?.cols ?? ne, I = Ae ?? P?.rows ?? te, ze = De || Array.from({ length: I }, () => "left"), L = Oe || Array.from({ length: I }, () => !1), Be = g(!1), R = g(null), z = g(null), [B, V] = _(() => (p || "").split("\n").length), [Ve, He] = _(() => Array.from({ length: I }, () => 24)), H = g(!1), U = g(null), W = xe({
75
+ immediatelyRender: !1,
76
+ extensions: [
77
+ oe,
78
+ Se.configure({
79
+ heading: !1,
80
+ blockquote: !1,
81
+ codeBlock: !1,
82
+ horizontalRule: !1,
83
+ bulletList: !1,
84
+ orderedList: !1,
85
+ listItem: !1,
86
+ code: !1,
87
+ bold: !1,
88
+ italic: !1,
89
+ strike: !1,
90
+ document: !1
91
+ }),
92
+ ce,
93
+ re,
94
+ ie,
95
+ u,
96
+ le,
97
+ ae,
98
+ se
99
+ ],
100
+ content: d(p || "", I),
101
+ editorProps: {
102
+ attributes: {
103
+ class: e("w-full font-mono text-sm", "prose prose-sm max-w-none", "[&_.ProseMirror]:outline-none", "[&_.ProseMirror]:font-mono", "[&_.ProseMirror]:text-sm", "[&_.ProseMirror]:resize-none", "[&_.ProseMirror]:uppercase", "[&_.ProseMirror_p]:my-0 [&_.ProseMirror_p]:leading-tight", "[&_.ProseMirror_p]:min-h-[1.5rem]", T),
104
+ "data-placeholder": Te,
105
+ role: "textbox",
106
+ "aria-label": N.editorAriaLabel,
107
+ "aria-multiline": "true"
108
+ },
109
+ handleKeyDown: (e, t) => {
110
+ if (t.key === "Enter" && !t.ctrlKey && !t.metaKey) {
111
+ if (t.preventDefault(), t.shiftKey) return !0;
112
+ let n = e.state.schema.nodes.hardBreak;
113
+ return n && e.dispatch(e.state.tr.replaceSelectionWith(n.create()).scrollIntoView()), !0;
114
+ }
115
+ if (t.key === "Backspace" && !t.ctrlKey && !t.metaKey && !t.shiftKey) {
116
+ let { state: t } = e, { selection: n } = t;
117
+ if (!n.empty) return !1;
118
+ let r = n.$from.pos, i = n.$from.start();
119
+ if (r <= i || t.doc.textBetween(r - 1, r, void 0, "") !== "​") return !1;
120
+ let a = r - 1;
121
+ for (; a > i && t.doc.textBetween(a - 1, a, void 0, "") === "​";) a--;
122
+ let o = t.doc.resolve(a).nodeBefore;
123
+ if (o?.type.name === "hardBreak") {
124
+ for (a -= o.nodeSize; a > i && t.doc.textBetween(a - 1, a, void 0, "") === "​";) a--;
125
+ let s = r, c = n.$from.end();
126
+ for (; s < c && t.doc.textBetween(s, s + 1, void 0, "") === "​";) s++;
127
+ return e.dispatch(t.tr.delete(a, s).scrollIntoView()), !0;
128
+ }
129
+ return a <= i ? !0 : o?.isAtom ? (e.dispatch(t.tr.delete(a - o.nodeSize, r).scrollIntoView()), !0) : (e.dispatch(t.tr.delete(a - 1, r).scrollIntoView()), !0);
130
+ }
131
+ if (t.key === "Delete" && !t.ctrlKey && !t.metaKey && !t.shiftKey) {
132
+ let { state: t } = e, { selection: n } = t;
133
+ if (!n.empty) return !1;
134
+ let r = n.$from.pos, i = n.$from.end();
135
+ if (r >= i || t.doc.textBetween(r, r + 1, void 0, "") !== "​") return !1;
136
+ let a = r + 1;
137
+ for (; a < i && t.doc.textBetween(a, a + 1, void 0, "") === "​";) a++;
138
+ let o = t.doc.resolve(a).nodeAfter;
139
+ if (o?.type.name === "hardBreak") {
140
+ for (a += o.nodeSize; a < i && t.doc.textBetween(a, a + 1, void 0, "") === "​";) a++;
141
+ let s = r, c = n.$from.start();
142
+ for (; s > c && t.doc.textBetween(s - 1, s, void 0, "") === "​";) s--;
143
+ return e.dispatch(t.tr.delete(s, a).scrollIntoView()), !0;
144
+ }
145
+ return a >= i ? !0 : o?.isAtom ? (e.dispatch(t.tr.delete(r, a + o.nodeSize).scrollIntoView()), !0) : (e.dispatch(t.tr.delete(r, a + 1).scrollIntoView()), !0);
146
+ }
147
+ if ((t.key === "ArrowRight" || t.key === "ArrowLeft") && !t.altKey && !t.ctrlKey && !t.metaKey) {
148
+ let { state: n } = e, { selection: r } = n;
149
+ if (!(r instanceof x)) return !1;
150
+ let i = r.$head.pos, a = r.$head.start(), o = r.$head.end();
151
+ if (t.key === "ArrowRight") {
152
+ if (i >= o) return !1;
153
+ let a = i + 1;
154
+ for (; a < o && n.doc.textBetween(a - 1, a, void 0, "") === "​";) a++;
155
+ if (a === i + 1 && !t.shiftKey) return !1;
156
+ t.preventDefault();
157
+ let s = t.shiftKey ? x.create(n.doc, r.$anchor.pos, a) : x.create(n.doc, a);
158
+ return e.dispatch(n.tr.setSelection(s).scrollIntoView()), !0;
159
+ }
160
+ if (t.key === "ArrowLeft") {
161
+ if (i <= a) return !1;
162
+ let o = i - 1;
163
+ for (; o > a && n.doc.textBetween(o, o + 1, void 0, "") === "​";) o--;
164
+ if (o === i - 1 && !t.shiftKey) return !1;
165
+ t.preventDefault();
166
+ let s = t.shiftKey ? x.create(n.doc, r.$anchor.pos, o) : x.create(n.doc, o);
167
+ return e.dispatch(n.tr.setSelection(s).scrollIntoView()), !0;
168
+ }
169
+ }
170
+ let n = t.key.toLowerCase(), r = t.ctrlKey || t.metaKey;
171
+ if (r && n === "z" && !t.shiftKey) {
172
+ let e = R.current;
173
+ return e?.can().undo() ? (t.preventDefault(), e.chain().focus().undo().run(), !0) : !1;
174
+ }
175
+ if (r && (n === "y" || n === "z" && t.shiftKey)) {
176
+ let e = R.current;
177
+ return e?.can().redo() ? (t.preventDefault(), e.chain().focus().redo().run(), !0) : !1;
178
+ }
179
+ if (!e || !e.state || !e.state.selection || !e.state.doc || !e.state.schema) return !1;
180
+ try {
181
+ let { state: n } = e, { selection: r } = n;
182
+ if (!r) return !1;
183
+ if ((t.ctrlKey || t.metaKey) && t.key === "x" && !r.empty) {
184
+ try {
185
+ let e = r.content();
186
+ if (e) {
187
+ let t = C(e);
188
+ navigator.clipboard && navigator.clipboard.writeText && navigator.clipboard.writeText(t).catch(() => {});
189
+ }
190
+ } catch (e) {
191
+ console.warn("Error in cut handler:", e);
192
+ }
193
+ return !1;
194
+ }
195
+ return !1;
196
+ } catch (e) {
197
+ return console.warn("Error in handleKeyDown:", e), !1;
198
+ }
199
+ },
200
+ handlePaste: (e, t, n) => {
201
+ try {
202
+ let e = t.clipboardData?.getData("text/plain") || "";
203
+ if (e && (e.includes("{{") || e.match(/\{[a-z]+\}/i))) {
204
+ let t = de(e);
205
+ if (t.length > 0 && R.current?.state && R.current?.chain) return R.current.chain().focus().insertContent(t).run(), !0;
206
+ }
207
+ } catch (e) {
208
+ console.warn("Error in handlePaste:", e);
209
+ }
210
+ return !1;
211
+ },
212
+ transformPastedText: (e) => e && (e.includes("{{") || e.match(/\{[a-z]+\}/i)) ? e : e.toUpperCase(),
213
+ handleDOMEvents: {
214
+ mousedown: (e, t) => {
215
+ let n = t.target, r = n.closest("[data-drag-handle]");
216
+ if (r && t.button === 0) {
217
+ if (n.closest("button")) return !1;
218
+ let t = e.posAtDOM(r, 0);
219
+ if (t !== null && t >= 0) try {
220
+ let n = e.state.doc.resolve(t), r = n.nodeAfter, i = n.pos;
221
+ if ((!r || r.type.name !== "variable" && r.type.name !== "colorTile" && r.type.name !== "fillSpace" && r.type.name !== "wrappedText") && (r = n.nodeBefore, r && (i = n.pos - r.nodeSize)), r && (r.type.name === "variable" || r.type.name === "colorTile" || r.type.name === "fillSpace" || r.type.name === "wrappedText")) return z.current = {
222
+ from: i,
223
+ to: i + r.nodeSize
224
+ }, !1;
225
+ } catch (e) {
226
+ console.warn("Error selecting node for drag:", e);
227
+ }
228
+ }
229
+ return !1;
230
+ },
231
+ dragstart: (e, t) => !1,
232
+ click: (e, t) => {
233
+ if (t.target.closest("button")) return !1;
234
+ let n = e.posAtCoords({
235
+ left: t.clientX,
236
+ top: t.clientY
237
+ });
238
+ if (!n) return !1;
239
+ let r = e.state.doc.nodeAt(n.pos);
240
+ if (!r || !Ce.has(r.type.name)) return !1;
241
+ let i = n.pos + r.nodeSize;
242
+ e.dispatch(e.state.tr.setSelection(x.create(e.state.doc, i)));
243
+ let a = e.nodeDOM(n.pos);
244
+ return a instanceof HTMLElement && a.classList.add("selected-inline"), t.preventDefault(), !0;
245
+ }
246
+ },
247
+ handleDrop: (e, t, n, r) => {
248
+ if (z.current) {
249
+ let { from: n, to: r } = z.current, i = e.posAtCoords({
250
+ left: t.clientX,
251
+ top: t.clientY
252
+ });
253
+ if (i && i.pos !== null) try {
254
+ let t = e.state.doc.resolve(i.pos);
255
+ if (i.pos >= n && i.pos <= r) return z.current = null, !0;
256
+ let a = e.state.doc.nodeAt(n);
257
+ if (!a) return z.current = null, !1;
258
+ let o = t.pos;
259
+ t.parentOffset === 0 && t.depth > 0 && (o = t.before(t.depth)), o > r && (o -= r - n);
260
+ let s = e.state.tr;
261
+ s.delete(n, r);
262
+ let c = o > n ? o - (r - n) : o;
263
+ if (c >= 0 && c <= s.doc.content.size) {
264
+ s.insert(c, a);
265
+ let t = c + a.nodeSize;
266
+ return t <= s.doc.content.size && s.setSelection(x.create(s.doc, t)), e.dispatch(s), z.current = null, !0;
267
+ }
268
+ } catch (e) {
269
+ console.warn("Error handling drop:", e);
270
+ }
271
+ z.current = null;
272
+ }
273
+ return !1;
274
+ },
275
+ clipboardTextSerializer: (e) => {
276
+ try {
277
+ return !e || !e.content ? "" : C(e);
278
+ } catch (e) {
279
+ return console.warn("Error in clipboardTextSerializer:", e), "";
280
+ }
281
+ }
282
+ },
283
+ onSelectionUpdate: ({ editor: e }) => {
284
+ e.view.dom.querySelectorAll(".selected-inline").forEach((e) => {
285
+ e.classList.remove("selected-inline");
286
+ });
287
+ let { selection: t } = e.state;
288
+ t.empty || e.state.doc.nodesBetween(t.from, t.to, (t, n) => {
289
+ if (t.isAtom && t.isInline) {
290
+ let t = e.view.nodeDOM(n);
291
+ t instanceof HTMLElement && t.classList.add("selected-inline");
292
+ }
293
+ });
294
+ },
295
+ onUpdate: ({ editor: e }) => {
296
+ if (Be.current || !e || !e.state) return;
297
+ let t = e.getJSON(), n = f(t, I), r = n.split("\n").length;
298
+ w(n), V(r), k && k(r), U.current?.();
299
+ },
300
+ onCreate: ({ editor: e }) => {
301
+ let t = e.getJSON(), n = f(t, I).split("\n").length;
302
+ V(n), k && k(n), U.current?.();
303
+ },
304
+ onFocus: () => {
305
+ we?.();
306
+ }
307
+ });
308
+ h(() => {
309
+ W && (R.current = W);
310
+ }, [W]);
311
+ let Ue = g({
312
+ done: [],
313
+ undone: []
314
+ }), G = g(!1), K = g(M);
315
+ h(() => {
316
+ K.current = M;
317
+ }, [M]), h(() => {
318
+ if (!W) return;
319
+ let e = ({ transaction: e }) => {
320
+ if (!e.docChanged) return;
321
+ let t = Ue.current, n = e.getMeta("history$"), r = ye(W.state);
322
+ if (n && typeof n == "object" && typeof n.redo == "boolean") if (n.redo) {
323
+ for (; t.undone.length > 0 && t.undone[t.undone.length - 1] > r;) t.undone.pop();
324
+ let e = t.undone[t.undone.length - 1] === r;
325
+ e && t.done.push(t.undone.pop()), K.current?.({
326
+ action: "redo",
327
+ stroke: e
328
+ });
329
+ } else {
330
+ let e = r + 1;
331
+ for (; t.done.length > 0 && t.done[t.done.length - 1] > e;) t.done.pop();
332
+ let n = t.done[t.done.length - 1] === e;
333
+ n && t.undone.push(t.done.pop()), K.current?.({
334
+ action: "undo",
335
+ stroke: n
336
+ });
337
+ }
338
+ else {
339
+ for (t.undone.length = 0; t.done.length > 0 && t.done[t.done.length - 1] >= r;) t.done.pop();
340
+ G.current && (G.current = !1, t.done.push(r));
341
+ }
342
+ };
343
+ return W.on("transaction", e), () => {
344
+ W.off("transaction", e);
345
+ };
346
+ }, [W]), _e(Re, () => ({
347
+ applyStroke(e, t) {
348
+ let n = R.current;
349
+ if (!n || n.isDestroyed) return [];
350
+ let r = ue(t), i = f(n.getJSON(), I).split("\n"), a = /* @__PURE__ */ new Map();
351
+ for (let t of e) {
352
+ if (t.row < 0 || t.row >= I || t.col < 0 || t.col >= F) continue;
353
+ let e = a.get(t.row) ?? [];
354
+ e.push({
355
+ col: t.col,
356
+ cell: r
357
+ }), a.set(t.row, e);
358
+ }
359
+ if (a.size === 0) return [];
360
+ let o = pe(n.state, i, a, F);
361
+ if (!o) return [];
362
+ let { view: s } = n;
363
+ return G.current = !0, s.dispatch(b(o)), s.dispatch(b(s.state.tr)), [...a.keys()].sort((e, t) => e - t);
364
+ },
365
+ undo() {
366
+ let e = R.current;
367
+ !e || e.isDestroyed || e.chain().undo().run();
368
+ },
369
+ redo() {
370
+ let e = R.current;
371
+ !e || e.isDestroyed || e.chain().redo().run();
372
+ }
373
+ }), [I, F]);
374
+ let q = m(() => {
375
+ if (!(!W || W.isDestroyed) && !j) try {
376
+ let { state: e, view: t } = W;
377
+ if (!t.dom.isConnected) return;
378
+ let n = [];
379
+ e.doc.descendants((e, t) => {
380
+ e.type.name === "hardBreak" && n.push(t);
381
+ });
382
+ let r = [];
383
+ try {
384
+ r.push(t.coordsAtPos(1).top);
385
+ } catch {
386
+ return;
387
+ }
388
+ for (let e of n) try {
389
+ r.push(t.coordsAtPos(e + 1).top);
390
+ } catch {
391
+ return;
392
+ }
393
+ let i = [];
394
+ for (let e = 0; e < r.length; e++) if (e + 1 < r.length) i.push(Math.max(Math.round(r[e + 1] - r[e]), 24));
395
+ else {
396
+ let n = t.dom.querySelector("p"), a = n ? n.getBoundingClientRect().bottom : r[e] + 24;
397
+ i.push(Math.max(Math.round(a - r[e]), 24));
398
+ }
399
+ for (; i.length < I;) i.push(24);
400
+ He(i);
401
+ } catch {}
402
+ }, [
403
+ W,
404
+ I,
405
+ j
406
+ ]), J = m(() => {
407
+ H.current || (H.current = !0, requestAnimationFrame(() => {
408
+ H.current = !1, q();
409
+ }));
410
+ }, [q]);
411
+ h(() => {
412
+ U.current = J;
413
+ }, [J]), h(() => {
414
+ j || J();
415
+ }, [j, J]), h(() => {
416
+ if (!W) return;
417
+ let e = new ResizeObserver(J);
418
+ return e.observe(W.view.dom), J(), () => e.disconnect();
419
+ }, [W, J]), h(() => {
420
+ if (!W) return;
421
+ let e = W.view.dom, t = (e) => {
422
+ if (!z.current) return;
423
+ e.preventDefault(), e.stopPropagation();
424
+ let { from: t, to: n } = z.current, r = W.view.posAtCoords({
425
+ left: e.clientX,
426
+ top: e.clientY
427
+ });
428
+ if (r && r.pos !== null) try {
429
+ let e = W.state.doc.resolve(r.pos);
430
+ if (r.pos >= t && r.pos <= n) {
431
+ z.current = null;
432
+ return;
433
+ }
434
+ let i = W.state.doc.nodeAt(t);
435
+ if (!i) {
436
+ z.current = null;
437
+ return;
438
+ }
439
+ let a = e.pos;
440
+ e.parentOffset === 0 && e.depth > 0 && (a = e.before(e.depth)), a > n && (a -= n - t);
441
+ let o = W.state.tr;
442
+ o.delete(t, n);
443
+ let s = a > t ? a - (n - t) : a;
444
+ if (s >= 0 && s <= o.doc.content.size) {
445
+ o.insert(s, i);
446
+ let e = s + i.nodeSize;
447
+ e <= o.doc.content.size && o.setSelection(x.create(o.doc, e)), W.view.dispatch(o), z.current = null;
448
+ }
449
+ } catch (e) {
450
+ console.warn("Error handling DOM drop:", e), z.current = null;
451
+ }
452
+ }, n = (e) => {
453
+ z.current && (e.preventDefault(), e.dataTransfer.dropEffect = "move");
454
+ };
455
+ return e.addEventListener("drop", t), e.addEventListener("dragover", n), () => {
456
+ e.removeEventListener("drop", t), e.removeEventListener("dragover", n);
457
+ };
458
+ }, [W]), h(() => {
459
+ if (!W || W.isDestroyed) return;
460
+ W.isFocused || p !== f(W.getJSON(), I) && queueMicrotask(() => {
461
+ !W || W.isDestroyed || W.commands.setContent(d(p || "", I), {
462
+ emitUpdate: !1,
463
+ parseOptions: { preserveWhitespace: !0 }
464
+ });
465
+ });
466
+ let e = (p || "").split("\n").length;
467
+ V(e), k && k(e), U.current?.();
468
+ }, [
469
+ p,
470
+ W,
471
+ I,
472
+ k
473
+ ]);
474
+ let Y = m(() => {
475
+ try {
476
+ if (!W || !W.state || !W.state.selection) return null;
477
+ let { state: e } = W, { selection: t } = e;
478
+ if (!t || !t.$from) return null;
479
+ let { $from: n } = t, r = 0;
480
+ return e.doc && e.doc.nodesBetween(0, n.pos, (e) => {
481
+ e && e.type && e.type.name === "hardBreak" && r++;
482
+ }), r;
483
+ } catch (e) {
484
+ return console.warn("Error in getCurrentLineIndex:", e), null;
485
+ }
486
+ }, [W]), X = m((e) => {
487
+ if (W) try {
488
+ if (!W.state || !W.state.selection) return;
489
+ let { state: t } = W, { selection: n } = t;
490
+ if (!n || !n.$from) return;
491
+ let r = 0;
492
+ t.doc.nodesBetween(0, n.$from.pos, (e) => {
493
+ e && e.type && e.type.name === "hardBreak" && r++;
494
+ });
495
+ let i = r;
496
+ if (n.empty || t.doc.nodesBetween(n.$from.pos, n.$to.pos, (e) => {
497
+ e && e.type && e.type.name === "hardBreak" && i++;
498
+ }), r < 0 || r >= I) return;
499
+ let a = Math.min(i, I - 1);
500
+ if (E) for (let t = r; t <= a; t++) E(t, e);
501
+ } catch (e) {
502
+ console.warn("Error in handleAlignmentClick:", e);
503
+ }
504
+ }, [
505
+ W,
506
+ I,
507
+ E
508
+ ]), We = m(() => {
509
+ if (!W) return;
510
+ let e = Y();
511
+ if (e === null || e < 0 || e >= I) return;
512
+ let t = !L[e];
513
+ D && D(e, t);
514
+ }, [
515
+ W,
516
+ Y,
517
+ D,
518
+ I,
519
+ L
520
+ ]), Z = ve(() => {
521
+ try {
522
+ if (!W?.state?.selection?.$from || !W.state.doc) return null;
523
+ let e = 0;
524
+ return W.state.doc.nodesBetween(0, W.state.selection.$from.pos, (t) => {
525
+ t && t.type && t.type.name === "hardBreak" && e++;
526
+ }), e;
527
+ } catch (e) {
528
+ return console.warn("Error getting current line index:", e), null;
529
+ }
530
+ }, [W, W?.state?.selection?.$from?.pos]), Q = Z !== null && Z >= 0 && Z < I && ze[Z] || "left";
531
+ if (!W) return /* @__PURE__ */ v(t, {
532
+ className: e("min-h-[9rem] border rounded-md p-2 bg-muted/30", T),
533
+ children: /* @__PURE__ */ v(a, {
534
+ gap: "1",
535
+ children: Array.from({ length: I }).map((e, t) => /* @__PURE__ */ v(r, { className: "h-6" }, t))
536
+ })
537
+ });
538
+ let Ge = Z !== null && Z >= 0 && Z < I && L[Z] || !1, $ = B > I;
539
+ return /* @__PURE__ */ y(t, {
540
+ className: e("relative", T),
541
+ children: [O && /* @__PURE__ */ v(fe, {
542
+ ...Le,
543
+ editor: W,
544
+ currentAlignment: Q,
545
+ currentWrapEnabled: Ge,
546
+ onAlignmentChange: (e) => {
547
+ X(e);
548
+ },
549
+ onWrapToggle: () => {
550
+ We();
551
+ },
552
+ deviceType: A,
553
+ onSyncFromBoard: je,
554
+ syncFromBoardPending: Me,
555
+ drawMode: j,
556
+ onDrawModeToggle: Ne,
557
+ drawBrush: Pe,
558
+ onDrawBrushChange: Fe
559
+ }), /* @__PURE__ */ y(t, {
560
+ className: e("flex-1", j && "hidden"),
561
+ children: [
562
+ /* @__PURE__ */ v(t, {
563
+ className: e("border bg-background relative rounded-md", O ? "rounded-t-none" : "", $ && "border-warning"),
564
+ style: {
565
+ padding: "0.75rem",
566
+ minHeight: `${I * 1.5 + 1.5}rem`
567
+ },
568
+ children: /* @__PURE__ */ y(n, {
569
+ gap: "2",
570
+ style: { minHeight: `${I * 1.5}rem` },
571
+ children: [/* @__PURE__ */ v(t, {
572
+ className: "select-none shrink-0 text-right",
573
+ style: {
574
+ fontSize: "0.75rem",
575
+ lineHeight: "1.5rem",
576
+ minWidth: "1.25rem"
577
+ },
578
+ "aria-hidden": "true",
579
+ children: Array.from({ length: Math.max(B, I) }, (e, n) => /* @__PURE__ */ v(t, {
580
+ style: {
581
+ height: `${Ve[n] ?? 24}px`,
582
+ lineHeight: "1.5rem",
583
+ color: n === Z ? "var(--foreground)" : "var(--muted-foreground)",
584
+ opacity: n === Z ? .7 : .4
585
+ },
586
+ children: n + 1
587
+ }, n))
588
+ }), /* @__PURE__ */ v(t, {
589
+ className: "relative flex-1 min-w-0",
590
+ children: /* @__PURE__ */ v(be, { editor: W })
591
+ })]
592
+ })
593
+ }),
594
+ /* @__PURE__ */ y(i, {
595
+ size: "xs",
596
+ tone: $ ? "warning" : "muted",
597
+ weight: $ ? "medium" : "normal",
598
+ className: "mt-1",
599
+ children: [N.lineCount(B, I), $ && N.overLineLimit(I)]
600
+ }),
601
+ !O && Ee && /* @__PURE__ */ v(c, { children: /* @__PURE__ */ y(n, {
602
+ align: "center",
603
+ gap: "2",
604
+ className: "mt-2",
605
+ children: [
606
+ /* @__PURE__ */ v(i, {
607
+ as: "span",
608
+ size: "xs",
609
+ tone: "muted",
610
+ children: N.alignment
611
+ }),
612
+ /* @__PURE__ */ y(n, {
613
+ className: "rounded-md border overflow-hidden",
614
+ children: [
615
+ /* @__PURE__ */ y(o, { children: [/* @__PURE__ */ v(l, {
616
+ asChild: !0,
617
+ children: /* @__PURE__ */ v("button", {
618
+ type: "button",
619
+ onClick: () => X("left"),
620
+ "aria-label": N.alignLeft,
621
+ className: e("px-3 py-1.5 text-xs transition-colors", Q === "left" ? "bg-primary text-primary-foreground" : "hover:bg-muted text-muted-foreground"),
622
+ children: /* @__PURE__ */ v(he, { className: "w-4 h-4" })
623
+ })
624
+ }), /* @__PURE__ */ v(s, { children: N.alignLeft })] }),
625
+ /* @__PURE__ */ y(o, { children: [/* @__PURE__ */ v(l, {
626
+ asChild: !0,
627
+ children: /* @__PURE__ */ v("button", {
628
+ type: "button",
629
+ onClick: () => X("center"),
630
+ "aria-label": N.alignCenter,
631
+ className: e("px-3 py-1.5 text-xs border-x transition-colors", Q === "center" ? "bg-primary text-primary-foreground border-primary" : "hover:bg-muted text-muted-foreground"),
632
+ children: /* @__PURE__ */ v(me, { className: "w-4 h-4" })
633
+ })
634
+ }), /* @__PURE__ */ v(s, { children: N.alignCenter })] }),
635
+ /* @__PURE__ */ y(o, { children: [/* @__PURE__ */ v(l, {
636
+ asChild: !0,
637
+ children: /* @__PURE__ */ v("button", {
638
+ type: "button",
639
+ onClick: () => X("right"),
640
+ "aria-label": N.alignRight,
641
+ className: e("px-3 py-1.5 text-xs transition-colors", Q === "right" ? "bg-primary text-primary-foreground" : "hover:bg-muted text-muted-foreground"),
642
+ children: /* @__PURE__ */ v(ge, { className: "w-4 h-4" })
643
+ })
644
+ }), /* @__PURE__ */ v(s, { children: N.alignRight })] })
645
+ ]
646
+ }),
647
+ Z !== null && /* @__PURE__ */ v(i, {
648
+ as: "span",
649
+ size: "xs",
650
+ tone: "muted",
651
+ children: N.currentLine(Z + 1)
652
+ })
653
+ ]
654
+ }) })
655
+ ]
656
+ })]
657
+ });
658
+ });
659
+ //#endregion
660
+ export { S as DEFAULT_TEMPLATE_EDITOR_LABELS, w as TemplateEditor };
661
+
662
+ //# sourceMappingURL=template-editor.js.map