@windoc/react 0.1.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 (73) hide show
  1. package/dist/index.d.mts +393 -0
  2. package/dist/index.d.ts +393 -0
  3. package/dist/index.js +1661 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +1582 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +39 -0
  8. package/src/styles/editor.css +1786 -0
  9. package/src/styles/images/alignment.svg +1 -0
  10. package/src/styles/images/arrow-left.svg +1 -0
  11. package/src/styles/images/arrow-right.svg +1 -0
  12. package/src/styles/images/block.svg +1 -0
  13. package/src/styles/images/bold.svg +1 -0
  14. package/src/styles/images/catalog.svg +1 -0
  15. package/src/styles/images/center.svg +1 -0
  16. package/src/styles/images/checkbox.svg +1 -0
  17. package/src/styles/images/close.svg +1 -0
  18. package/src/styles/images/codeblock.svg +1 -0
  19. package/src/styles/images/color.svg +1 -0
  20. package/src/styles/images/column.svg +4 -0
  21. package/src/styles/images/control.svg +1 -0
  22. package/src/styles/images/date.svg +1 -0
  23. package/src/styles/images/exit-fullscreen.svg +1 -0
  24. package/src/styles/images/format.svg +1 -0
  25. package/src/styles/images/highlight.svg +1 -0
  26. package/src/styles/images/hyperlink.svg +1 -0
  27. package/src/styles/images/image.svg +1 -0
  28. package/src/styles/images/insert-element.svg +5 -0
  29. package/src/styles/images/italic.svg +1 -0
  30. package/src/styles/images/justify.svg +7 -0
  31. package/src/styles/images/latex.svg +1 -0
  32. package/src/styles/images/left.svg +1 -0
  33. package/src/styles/images/line-dash-dot-dot.svg +1 -0
  34. package/src/styles/images/line-dash-dot.svg +1 -0
  35. package/src/styles/images/line-dash-large-gap.svg +1 -0
  36. package/src/styles/images/line-dash-small-gap.svg +1 -0
  37. package/src/styles/images/line-dot.svg +1 -0
  38. package/src/styles/images/line-double.svg +1 -0
  39. package/src/styles/images/line-height.svg +8 -0
  40. package/src/styles/images/line-single.svg +1 -0
  41. package/src/styles/images/line-wavy.svg +1 -0
  42. package/src/styles/images/list.svg +1 -0
  43. package/src/styles/images/option.svg +1 -0
  44. package/src/styles/images/page-break.svg +1 -0
  45. package/src/styles/images/page-mode.svg +1 -0
  46. package/src/styles/images/page-scale-add.svg +1 -0
  47. package/src/styles/images/page-scale-minus.svg +1 -0
  48. package/src/styles/images/painter.svg +1 -0
  49. package/src/styles/images/paper-direction.svg +1 -0
  50. package/src/styles/images/paper-margin.svg +1 -0
  51. package/src/styles/images/paper-size.svg +1 -0
  52. package/src/styles/images/print.svg +1 -0
  53. package/src/styles/images/radio.svg +4 -0
  54. package/src/styles/images/redo.svg +1 -0
  55. package/src/styles/images/request-fullscreen.svg +1 -0
  56. package/src/styles/images/right.svg +1 -0
  57. package/src/styles/images/row-margin.svg +1 -0
  58. package/src/styles/images/search.svg +1 -0
  59. package/src/styles/images/separator.svg +1 -0
  60. package/src/styles/images/signature-undo.svg +1 -0
  61. package/src/styles/images/signature.svg +1 -0
  62. package/src/styles/images/size-add.svg +1 -0
  63. package/src/styles/images/size-minus.svg +1 -0
  64. package/src/styles/images/strikeout.svg +1 -0
  65. package/src/styles/images/subscript.svg +1 -0
  66. package/src/styles/images/superscript.svg +1 -0
  67. package/src/styles/images/table.svg +1 -0
  68. package/src/styles/images/title.svg +1 -0
  69. package/src/styles/images/trash.svg +1 -0
  70. package/src/styles/images/underline.svg +1 -0
  71. package/src/styles/images/undo.svg +1 -0
  72. package/src/styles/images/watermark.svg +1 -0
  73. package/src/styles/images/word-tool.svg +1 -0
package/dist/index.js ADDED
@@ -0,0 +1,1661 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ BoldTool: () => BoldTool,
34
+ CatalogToggleTool: () => CatalogToggleTool,
35
+ CenterAlignTool: () => CenterAlignTool,
36
+ ColorTool: () => ColorTool,
37
+ ColumnTool: () => ColumnTool,
38
+ Editor: () => Editor,
39
+ EditorFooter: () => EditorFooter,
40
+ EditorModeTool: () => EditorModeTool,
41
+ EditorOptionTool: () => EditorOptionTool,
42
+ EditorProvider: () => EditorProvider,
43
+ EditorToolbar: () => EditorToolbar,
44
+ FontSizeTool: () => FontSizeTool,
45
+ FontTool: () => FontTool,
46
+ FooterProvider: () => FooterProvider,
47
+ FooterStatus: () => FooterStatus,
48
+ FullscreenTool: () => FullscreenTool,
49
+ HighlightTool: () => HighlightTool,
50
+ ImageTool: () => ImageTool,
51
+ ItalicTool: () => ItalicTool,
52
+ JustifyTool: () => JustifyTool,
53
+ LeftAlignTool: () => LeftAlignTool,
54
+ LineHeightTool: () => LineHeightTool,
55
+ ListTool: () => ListTool,
56
+ PageBreakTool: () => PageBreakTool,
57
+ PageModeTool: () => PageModeTool,
58
+ PageScaleAddTool: () => PageScaleAddTool,
59
+ PageScaleMinusTool: () => PageScaleMinusTool,
60
+ PageScalePercentageTool: () => PageScalePercentageTool,
61
+ PaperDirectionTool: () => PaperDirectionTool,
62
+ PaperMarginTool: () => PaperMarginTool,
63
+ PaperSizeTool: () => PaperSizeTool,
64
+ RedoTool: () => RedoTool,
65
+ RightAlignTool: () => RightAlignTool,
66
+ SeparatorTool: () => SeparatorTool,
67
+ StrikeoutTool: () => StrikeoutTool,
68
+ TableTool: () => TableTool,
69
+ TitleTool: () => TitleTool,
70
+ UnderlineTool: () => UnderlineTool,
71
+ UndoTool: () => UndoTool,
72
+ WatermarkFooterTool: () => WatermarkFooterTool,
73
+ WatermarkTool: () => InsertElementTool,
74
+ useEditor: () => useEditor,
75
+ useFooter: () => useFooter
76
+ });
77
+ module.exports = __toCommonJS(index_exports);
78
+
79
+ // src/Editor.tsx
80
+ var import_react21 = require("react");
81
+
82
+ // src/EditorContext.tsx
83
+ var import_react = require("react");
84
+ var import_jsx_runtime = require("react/jsx-runtime");
85
+ var EditorContext = (0, import_react.createContext)(null);
86
+ function EditorProvider({
87
+ editorRef,
88
+ rangeStyle,
89
+ children
90
+ }) {
91
+ const [isApple, setIsApple] = (0, import_react.useState)(false);
92
+ (0, import_react.useEffect)(() => {
93
+ setIsApple(/Mac OS X/.test(navigator.userAgent));
94
+ }, []);
95
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorContext.Provider, { value: { editorRef, isApple, rangeStyle }, children });
96
+ }
97
+ function useEditor() {
98
+ const ctx = (0, import_react.useContext)(EditorContext);
99
+ if (!ctx) throw new Error("useEditor must be used within EditorProvider");
100
+ return ctx;
101
+ }
102
+
103
+ // src/FooterContext.tsx
104
+ var import_react2 = require("react");
105
+ var import_jsx_runtime2 = require("react/jsx-runtime");
106
+ var FooterContext = (0, import_react2.createContext)(null);
107
+ function FooterProvider({
108
+ handleToggleCatalogAction,
109
+ children
110
+ }) {
111
+ const [pageNoList, setPageNoList] = (0, import_react2.useState)("1");
112
+ const [pageNo, setPageNo] = (0, import_react2.useState)(1);
113
+ const [pageSize, setPageSize] = (0, import_react2.useState)(1);
114
+ const [wordCount, setWordCount] = (0, import_react2.useState)(0);
115
+ const [rowNo, setRowNo] = (0, import_react2.useState)(0);
116
+ const [colNo, setColNo] = (0, import_react2.useState)(0);
117
+ const [pageScale, setPageScale] = (0, import_react2.useState)(100);
118
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FooterContext.Provider, { value: {
119
+ pageNoList,
120
+ pageNo,
121
+ pageSize,
122
+ wordCount,
123
+ rowNo,
124
+ colNo,
125
+ pageScale,
126
+ setPageNoList,
127
+ setPageNo,
128
+ setPageSize,
129
+ setWordCount,
130
+ setRowNo,
131
+ setColNo,
132
+ setPageScale,
133
+ handleToggleCatalogAction
134
+ }, children });
135
+ }
136
+ function useFooter() {
137
+ const ctx = (0, import_react2.useContext)(FooterContext);
138
+ if (!ctx) throw new Error("useFooter must be used within FooterProvider");
139
+ return ctx;
140
+ }
141
+
142
+ // src/toolbar/UndoTool.tsx
143
+ var import_lucide_react = require("lucide-react");
144
+ var import_jsx_runtime3 = require("react/jsx-runtime");
145
+ function UndoTool() {
146
+ const { editorRef, isApple, rangeStyle } = useEditor();
147
+ const isDisabled = rangeStyle ? !rangeStyle.undo : true;
148
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
149
+ "div",
150
+ {
151
+ className: `menu-item__undo${isDisabled ? " disabled" : ""}`,
152
+ title: `Undo(${isApple ? "\u2318" : "Ctrl"}+Z)`,
153
+ onClick: () => {
154
+ if (!isDisabled) editorRef.current?.command.executeUndo();
155
+ },
156
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Undo, { size: 16 })
157
+ }
158
+ );
159
+ }
160
+
161
+ // src/toolbar/RedoTool.tsx
162
+ var import_lucide_react2 = require("lucide-react");
163
+ var import_jsx_runtime4 = require("react/jsx-runtime");
164
+ function RedoTool() {
165
+ const { editorRef, isApple, rangeStyle } = useEditor();
166
+ const isDisabled = rangeStyle ? !rangeStyle.redo : true;
167
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
168
+ "div",
169
+ {
170
+ className: `menu-item__redo${isDisabled ? " disabled" : ""}`,
171
+ title: `Redo(${isApple ? "\u2318" : "Ctrl"}+Y)`,
172
+ onClick: () => {
173
+ if (!isDisabled) editorRef.current?.command.executeRedo();
174
+ },
175
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Redo, { size: 16 })
176
+ }
177
+ );
178
+ }
179
+
180
+ // src/toolbar/ColumnTool.tsx
181
+ var import_react3 = require("react");
182
+ var import_jsx_runtime5 = require("react/jsx-runtime");
183
+ function ColumnTool() {
184
+ const { editorRef } = useEditor();
185
+ const [visible, setVisible] = (0, import_react3.useState)(false);
186
+ const [currentColumns, setCurrentColumns] = (0, import_react3.useState)(1);
187
+ const [gap, setGap] = (0, import_react3.useState)(20);
188
+ const handleColumn = (col) => {
189
+ editorRef.current?.command.executeColumnCount(col);
190
+ setCurrentColumns(col);
191
+ setVisible(false);
192
+ };
193
+ const handleGapChange = (value) => {
194
+ const clampedValue = Math.max(0, Math.min(100, value));
195
+ setGap(clampedValue);
196
+ editorRef.current?.command.executeColumnGap(clampedValue);
197
+ };
198
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "menu-item__column", onClick: () => setVisible(!visible), children: [
199
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "select", title: "Column Layout", children: currentColumns === 1 ? "1 Column" : `${currentColumns} Columns` }),
200
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
201
+ "div",
202
+ {
203
+ className: `options ${visible ? "visible" : ""}`,
204
+ onClick: (e) => e.stopPropagation(),
205
+ children: [
206
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("ul", { children: [
207
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { onClick: () => handleColumn(1), children: "1 Column" }),
208
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { onClick: () => handleColumn(2), children: "2 Columns" })
209
+ ] }),
210
+ currentColumns > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
211
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "option-divider" }),
212
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "option-row", children: [
213
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { children: "Gap (px)" }),
214
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
215
+ "input",
216
+ {
217
+ type: "number",
218
+ min: 0,
219
+ max: 100,
220
+ value: gap,
221
+ onChange: (e) => handleGapChange(Number(e.target.value)),
222
+ onClick: (e) => e.stopPropagation()
223
+ }
224
+ )
225
+ ] })
226
+ ] })
227
+ ]
228
+ }
229
+ )
230
+ ] });
231
+ }
232
+
233
+ // src/toolbar/TableTool.tsx
234
+ var import_react4 = require("react");
235
+ var import_lucide_react3 = require("lucide-react");
236
+ var import_jsx_runtime6 = require("react/jsx-runtime");
237
+ function TableTool() {
238
+ const { editorRef } = useEditor();
239
+ const [visible, setVisible] = (0, import_react4.useState)(false);
240
+ const [hoverRow, setHoverRow] = (0, import_react4.useState)(0);
241
+ const [hoverCol, setHoverCol] = (0, import_react4.useState)(0);
242
+ const containerRef = (0, import_react4.useRef)(null);
243
+ (0, import_react4.useEffect)(() => {
244
+ if (!visible) return;
245
+ const handleClickOutside = (e) => {
246
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
247
+ setVisible(false);
248
+ setHoverRow(0);
249
+ setHoverCol(0);
250
+ }
251
+ };
252
+ document.addEventListener("mousedown", handleClickOutside);
253
+ return () => document.removeEventListener("mousedown", handleClickOutside);
254
+ }, [visible]);
255
+ const handleInsertTable = () => {
256
+ if (hoverRow > 0 && hoverCol > 0) {
257
+ editorRef.current?.command.executeInsertTable(hoverRow, hoverCol);
258
+ }
259
+ setVisible(false);
260
+ setHoverRow(0);
261
+ setHoverCol(0);
262
+ };
263
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: containerRef, className: "menu-item__table", title: "Table", children: [
264
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Table, { size: 16, onClick: () => setVisible(!visible), style: { cursor: "pointer" } }),
265
+ visible && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "table-dropdown", children: [
266
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "table-dropdown-header", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: hoverRow > 0 ? `${hoverRow} \xD7 ${hoverCol}` : "Insert Table" }) }),
267
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "table-dropdown-grid", onClick: handleInsertTable, children: Array.from({ length: 8 }).map((_, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "table-dropdown-row", children: Array.from({ length: 8 }).map((_2, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
268
+ "div",
269
+ {
270
+ className: `table-dropdown-cell ${rowIdx < hoverRow && colIdx < hoverCol ? "active" : ""}`,
271
+ onMouseEnter: () => {
272
+ setHoverRow(rowIdx + 1);
273
+ setHoverCol(colIdx + 1);
274
+ }
275
+ },
276
+ colIdx
277
+ )) }, rowIdx)) })
278
+ ] })
279
+ ] });
280
+ }
281
+
282
+ // src/toolbar/TitleTool.tsx
283
+ var import_react5 = require("react");
284
+ var import_jsx_runtime7 = require("react/jsx-runtime");
285
+ var LEVELS = [
286
+ { level: null, label: "Body" },
287
+ { level: "first", label: "Heading 1" },
288
+ { level: "second", label: "Heading 2" },
289
+ { level: "third", label: "Heading 3" },
290
+ { level: "fourth", label: "Heading 4" },
291
+ { level: "fifth", label: "Heading 5" },
292
+ { level: "sixth", label: "Heading 6" }
293
+ ];
294
+ function TitleTool() {
295
+ const { editorRef, rangeStyle } = useEditor();
296
+ const [visible, setVisible] = (0, import_react5.useState)(false);
297
+ const activeLevel = rangeStyle?.level || null;
298
+ const activeLabel = LEVELS.find((l) => l.level === activeLevel)?.label || "Body";
299
+ const handleTitle = (level) => {
300
+ editorRef.current?.command.executeTitle(level);
301
+ setVisible(false);
302
+ };
303
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "menu-item__title", onClick: () => setVisible(!visible), children: [
304
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "select", title: "Toggle Heading", children: activeLabel }),
305
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { children: LEVELS.map(({ level, label }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
306
+ "li",
307
+ {
308
+ className: activeLevel === level ? "active" : "",
309
+ ...level ? { "data-level": level } : {},
310
+ onClick: () => handleTitle(level),
311
+ children: label
312
+ },
313
+ label
314
+ )) }) })
315
+ ] });
316
+ }
317
+
318
+ // src/toolbar/FontTool.tsx
319
+ var import_react6 = require("react");
320
+ var import_jsx_runtime8 = require("react/jsx-runtime");
321
+ var FONTS = [
322
+ { family: "Arial", label: "Sans Serif" },
323
+ { family: "Times New Roman", label: "Serif" }
324
+ ];
325
+ function FontTool() {
326
+ const { editorRef, rangeStyle } = useEditor();
327
+ const [visible, setVisible] = (0, import_react6.useState)(false);
328
+ const activeFont = rangeStyle?.font || "Arial";
329
+ const activeLabel = FONTS.find((f) => f.family === activeFont)?.label || activeFont;
330
+ const handleFont = (family) => {
331
+ editorRef.current?.command.executeFont(family);
332
+ setVisible(false);
333
+ };
334
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "menu-item__font", onClick: () => setVisible(!visible), children: [
335
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "select", title: "Font", children: activeLabel }),
336
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { children: FONTS.map(({ family, label }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
337
+ "li",
338
+ {
339
+ "data-family": family,
340
+ className: activeFont === family ? "active" : "",
341
+ style: { fontFamily: family },
342
+ onClick: () => handleFont(family),
343
+ children: label
344
+ },
345
+ family
346
+ )) }) })
347
+ ] });
348
+ }
349
+
350
+ // src/toolbar/FontSizeTool.tsx
351
+ var import_react7 = require("react");
352
+ var import_jsx_runtime9 = require("react/jsx-runtime");
353
+ var SIZES = [56, 48, 34, 32, 29, 24, 21, 20, 18, 16, 14, 12, 10, 8];
354
+ function FontSizeTool() {
355
+ const { editorRef, rangeStyle } = useEditor();
356
+ const [visible, setVisible] = (0, import_react7.useState)(false);
357
+ const activeSize = rangeStyle?.size ?? 16;
358
+ const handleSize = (size) => {
359
+ editorRef.current?.command.executeSize(size);
360
+ setVisible(false);
361
+ };
362
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "menu-item__size", onClick: () => setVisible(!visible), children: [
363
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "select", title: "Font Size", children: activeSize }),
364
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { children: SIZES.map((size) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
365
+ "li",
366
+ {
367
+ className: activeSize === size ? "active" : "",
368
+ onClick: () => handleSize(size),
369
+ children: size
370
+ },
371
+ size
372
+ )) }) })
373
+ ] });
374
+ }
375
+
376
+ // src/toolbar/LineHeightTool.tsx
377
+ var import_react8 = require("react");
378
+ var import_jsx_runtime10 = require("react/jsx-runtime");
379
+ var LINE_HEIGHTS = ["1.0", "1.15", "1.5", "2.0", "2.5"];
380
+ function LineHeightTool() {
381
+ const { editorRef, rangeStyle } = useEditor();
382
+ const [visible, setVisible] = (0, import_react8.useState)(false);
383
+ const activeMargin = rangeStyle?.rowMargin ?? 1;
384
+ const activeLabel = Number.isInteger(activeMargin) ? `${activeMargin}.0` : String(activeMargin);
385
+ const handleLineHeight = (value) => {
386
+ editorRef.current?.command.executeRowMargin(Number(value));
387
+ setVisible(false);
388
+ };
389
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "menu-item__line-height", onClick: () => setVisible(!visible), children: [
390
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "select", title: "Line Height", children: activeLabel }),
391
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { children: LINE_HEIGHTS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
392
+ "li",
393
+ {
394
+ className: String(activeMargin) === h || activeLabel === h ? "active" : "",
395
+ onClick: () => handleLineHeight(h),
396
+ children: h
397
+ },
398
+ h
399
+ )) }) })
400
+ ] });
401
+ }
402
+
403
+ // src/toolbar/ColorTool.tsx
404
+ var import_react9 = require("react");
405
+ var import_lucide_react4 = require("lucide-react");
406
+ var import_jsx_runtime11 = require("react/jsx-runtime");
407
+ var COLOR_PALETTE = [
408
+ ["#000000", "#434343", "#666666", "#999999", "#b7b7b7", "#cccccc", "#d9d9d9", "#efefef", "#f3f3f3", "#ffffff"],
409
+ ["#980000", "#ff0000", "#ff9900", "#ffff00", "#00ff00", "#00ffff", "#4a86e8", "#0000ff", "#9900ff", "#ff00ff"],
410
+ ["#e6b8af", "#f4cccc", "#fce5cd", "#fff2cc", "#d9ead3", "#d0e0e3", "#c9daf8", "#cfe2f3", "#d9d2e9", "#ead1dc"],
411
+ ["#dd7e6b", "#ea9999", "#f9cb9c", "#ffe599", "#b6d7a8", "#a2c4c9", "#a4c2f4", "#9fc5e8", "#b4a7d6", "#d5a6bd"],
412
+ ["#cc4125", "#e06666", "#f6b26b", "#ffd966", "#93c47d", "#76a5af", "#6d9eeb", "#6fa8dc", "#8e7cc3", "#c27ba0"],
413
+ ["#a61c00", "#cc0000", "#e69138", "#f1c232", "#6aa84f", "#45818e", "#3c78d8", "#3d85c6", "#674ea7", "#a64d79"],
414
+ ["#85200c", "#990000", "#b45f06", "#bf9000", "#38761d", "#134f5c", "#1155cc", "#0b5394", "#351c75", "#741b47"],
415
+ ["#5b0f00", "#660000", "#783f04", "#7f6000", "#274e13", "#0c343d", "#1c4587", "#073763", "#20124d", "#4c1130"]
416
+ ];
417
+ function ColorTool() {
418
+ const { editorRef, rangeStyle } = useEditor();
419
+ const [visible, setVisible] = (0, import_react9.useState)(false);
420
+ const containerRef = (0, import_react9.useRef)(null);
421
+ const activeColor = rangeStyle?.color || "#000000";
422
+ (0, import_react9.useEffect)(() => {
423
+ if (!visible) return;
424
+ const handler = (e) => {
425
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
426
+ setVisible(false);
427
+ }
428
+ };
429
+ document.addEventListener("mousedown", handler);
430
+ return () => document.removeEventListener("mousedown", handler);
431
+ }, [visible]);
432
+ const handleColor = (color) => {
433
+ editorRef.current?.command.executeColor(color);
434
+ setVisible(false);
435
+ };
436
+ const handleReset = () => {
437
+ editorRef.current?.command.executeColor(null);
438
+ setVisible(false);
439
+ };
440
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "menu-item__color", ref: containerRef, title: "Font Color", onClick: () => setVisible(!visible), children: [
441
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Baseline, { size: 16 }),
442
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { backgroundColor: activeColor } }),
443
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { id: "color", type: "color", readOnly: true, tabIndex: -1 }),
444
+ visible && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "color-palette-dropdown", onClick: (e) => e.stopPropagation(), children: [
445
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { className: "color-palette-reset", onClick: handleReset, children: [
446
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.RotateCcw, { size: 12 }),
447
+ "Reset"
448
+ ] }),
449
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "color-palette-grid", children: COLOR_PALETTE.map((row, ri) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "color-palette-row", children: row.map((color) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
450
+ "div",
451
+ {
452
+ className: `color-palette-swatch${activeColor.toLowerCase() === color.toLowerCase() ? " active" : ""}`,
453
+ style: { backgroundColor: color },
454
+ onClick: () => handleColor(color),
455
+ title: color
456
+ },
457
+ color
458
+ )) }, ri)) })
459
+ ] })
460
+ ] });
461
+ }
462
+
463
+ // src/toolbar/HighlightTool.tsx
464
+ var import_react10 = require("react");
465
+ var import_lucide_react5 = require("lucide-react");
466
+ var import_jsx_runtime12 = require("react/jsx-runtime");
467
+ var HIGHLIGHT_PALETTE = [
468
+ ["#000000", "#434343", "#666666", "#999999", "#b7b7b7", "#cccccc", "#d9d9d9", "#efefef", "#f3f3f3", "#ffffff"],
469
+ ["#980000", "#ff0000", "#ff9900", "#ffff00", "#00ff00", "#00ffff", "#4a86e8", "#0000ff", "#9900ff", "#ff00ff"],
470
+ ["#e6b8af", "#f4cccc", "#fce5cd", "#fff2cc", "#d9ead3", "#d0e0e3", "#c9daf8", "#cfe2f3", "#d9d2e9", "#ead1dc"],
471
+ ["#dd7e6b", "#ea9999", "#f9cb9c", "#ffe599", "#b6d7a8", "#a2c4c9", "#a4c2f4", "#9fc5e8", "#b4a7d6", "#d5a6bd"],
472
+ ["#cc4125", "#e06666", "#f6b26b", "#ffd966", "#93c47d", "#76a5af", "#6d9eeb", "#6fa8dc", "#8e7cc3", "#c27ba0"],
473
+ ["#a61c00", "#cc0000", "#e69138", "#f1c232", "#6aa84f", "#45818e", "#3c78d8", "#3d85c6", "#674ea7", "#a64d79"],
474
+ ["#85200c", "#990000", "#b45f06", "#bf9000", "#38761d", "#134f5c", "#1155cc", "#0b5394", "#351c75", "#741b47"],
475
+ ["#5b0f00", "#660000", "#783f04", "#7f6000", "#274e13", "#0c343d", "#1c4587", "#073763", "#20124d", "#4c1130"]
476
+ ];
477
+ function HighlightTool() {
478
+ const { editorRef, rangeStyle } = useEditor();
479
+ const [visible, setVisible] = (0, import_react10.useState)(false);
480
+ const containerRef = (0, import_react10.useRef)(null);
481
+ const activeColor = rangeStyle?.highlight || "";
482
+ (0, import_react10.useEffect)(() => {
483
+ if (!visible) return;
484
+ const handler = (e) => {
485
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
486
+ setVisible(false);
487
+ }
488
+ };
489
+ document.addEventListener("mousedown", handler);
490
+ return () => document.removeEventListener("mousedown", handler);
491
+ }, [visible]);
492
+ const handleColor = (color) => {
493
+ editorRef.current?.command.executeHighlight(color);
494
+ setVisible(false);
495
+ };
496
+ const handleReset = () => {
497
+ editorRef.current?.command.executeHighlight(null);
498
+ setVisible(false);
499
+ };
500
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "menu-item__highlight", ref: containerRef, title: "Highlight", onClick: () => setVisible(!visible), children: [
501
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.Highlighter, { size: 16 }),
502
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { backgroundColor: activeColor || "#ffff00" } }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { id: "highlight", type: "color", readOnly: true, tabIndex: -1 }),
504
+ visible && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "color-palette-dropdown", onClick: (e) => e.stopPropagation(), children: [
505
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: "color-palette-reset", onClick: handleReset, children: [
506
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.RotateCcw, { size: 12 }),
507
+ "None"
508
+ ] }),
509
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "color-palette-grid", children: HIGHLIGHT_PALETTE.map((row, ri) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "color-palette-row", children: row.map((color) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
510
+ "div",
511
+ {
512
+ className: `color-palette-swatch${activeColor && activeColor.toLowerCase() === color.toLowerCase() ? " active" : ""}`,
513
+ style: { backgroundColor: color },
514
+ onClick: () => handleColor(color),
515
+ title: color
516
+ },
517
+ color
518
+ )) }, ri)) })
519
+ ] })
520
+ ] });
521
+ }
522
+
523
+ // src/toolbar/BoldTool.tsx
524
+ var import_lucide_react6 = require("lucide-react");
525
+ var import_jsx_runtime13 = require("react/jsx-runtime");
526
+ function BoldTool() {
527
+ const { editorRef, isApple, rangeStyle } = useEditor();
528
+ const isActive = rangeStyle?.bold === true;
529
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: `menu-item__bold ${isActive ? "active" : ""}`, title: `Bold(${isApple ? "\u2318" : "Ctrl"}+B)`, onClick: () => editorRef.current?.command.executeBold(), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Bold, { size: 16 }) });
530
+ }
531
+
532
+ // src/toolbar/ItalicTool.tsx
533
+ var import_lucide_react7 = require("lucide-react");
534
+ var import_jsx_runtime14 = require("react/jsx-runtime");
535
+ function ItalicTool() {
536
+ const { editorRef, isApple, rangeStyle } = useEditor();
537
+ const isActive = rangeStyle?.italic === true;
538
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `menu-item__italic ${isActive ? "active" : ""}`, title: `Italic(${isApple ? "\u2318" : "Ctrl"}+I)`, onClick: () => editorRef.current?.command.executeItalic(), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Italic, { size: 16 }) });
539
+ }
540
+
541
+ // src/toolbar/UnderlineTool.tsx
542
+ var import_react11 = require("react");
543
+ var import_lucide_react8 = require("lucide-react");
544
+ var import_jsx_runtime15 = require("react/jsx-runtime");
545
+ var STYLES = ["solid", "double", "dashed", "dotted", "wavy"];
546
+ function UnderlineTool() {
547
+ const { editorRef, isApple, rangeStyle } = useEditor();
548
+ const [visible, setVisible] = (0, import_react11.useState)(false);
549
+ const isActive = rangeStyle?.underline === true;
550
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `menu-item__underline ${isActive ? "active" : ""}`, title: `Underline(${isApple ? "\u2318" : "Ctrl"}+U)`, children: [
551
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react8.Underline, { size: 16, onClick: () => editorRef.current?.command.executeUnderline(), style: { cursor: "pointer" } }),
552
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "select", onClick: () => setVisible(!visible) }),
553
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { children: STYLES.map((style) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("li", { "data-decoration-style": style, onClick: () => {
554
+ editorRef.current?.command.executeUnderline({ style });
555
+ setVisible(false);
556
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("i", {}) }, style)) }) })
557
+ ] });
558
+ }
559
+
560
+ // src/toolbar/StrikeoutTool.tsx
561
+ var import_lucide_react9 = require("lucide-react");
562
+ var import_jsx_runtime16 = require("react/jsx-runtime");
563
+ function StrikeoutTool() {
564
+ const { editorRef, rangeStyle } = useEditor();
565
+ const isActive = rangeStyle?.strikeout === true;
566
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: `menu-item__strikeout ${isActive ? "active" : ""}`, title: "Strikethrough", onClick: () => editorRef.current?.command.executeStrikeout(), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react9.Strikethrough, { size: 16 }) });
567
+ }
568
+
569
+ // src/toolbar/LeftAlignTool.tsx
570
+ var import_lucide_react10 = require("lucide-react");
571
+ var import_jsx_runtime17 = require("react/jsx-runtime");
572
+ function LeftAlignTool() {
573
+ const { editorRef, isApple, rangeStyle } = useEditor();
574
+ const isActive = !rangeStyle?.rowFlex || rangeStyle.rowFlex === "left";
575
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: `menu-item__left ${isActive ? "active" : ""}`, title: `Left align(${isApple ? "\u2318" : "Ctrl"}+L)`, onClick: () => editorRef.current?.command.executeRowFlex("left"), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react10.AlignLeft, { size: 16 }) });
576
+ }
577
+
578
+ // src/toolbar/CenterAlignTool.tsx
579
+ var import_lucide_react11 = require("lucide-react");
580
+ var import_jsx_runtime18 = require("react/jsx-runtime");
581
+ function CenterAlignTool() {
582
+ const { editorRef, isApple, rangeStyle } = useEditor();
583
+ const isActive = rangeStyle?.rowFlex === "center";
584
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: `menu-item__center ${isActive ? "active" : ""}`, title: `Center align(${isApple ? "\u2318" : "Ctrl"}+E)`, onClick: () => editorRef.current?.command.executeRowFlex("center"), children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react11.AlignCenter, { size: 16 }) });
585
+ }
586
+
587
+ // src/toolbar/RightAlignTool.tsx
588
+ var import_lucide_react12 = require("lucide-react");
589
+ var import_jsx_runtime19 = require("react/jsx-runtime");
590
+ function RightAlignTool() {
591
+ const { editorRef, isApple, rangeStyle } = useEditor();
592
+ const isActive = rangeStyle?.rowFlex === "right";
593
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: `menu-item__right ${isActive ? "active" : ""}`, title: `Right align(${isApple ? "\u2318" : "Ctrl"}+R)`, onClick: () => editorRef.current?.command.executeRowFlex("right"), children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react12.AlignRight, { size: 16 }) });
594
+ }
595
+
596
+ // src/toolbar/JustifyTool.tsx
597
+ var import_lucide_react13 = require("lucide-react");
598
+ var import_jsx_runtime20 = require("react/jsx-runtime");
599
+ function JustifyTool() {
600
+ const { editorRef, isApple, rangeStyle } = useEditor();
601
+ const isActive = rangeStyle?.rowFlex === "justify" || rangeStyle?.rowFlex === "alignment";
602
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: `menu-item__justify ${isActive ? "active" : ""}`, title: `Distribute(${isApple ? "\u2318" : "Ctrl"}+Shift+J)`, onClick: () => editorRef.current?.command.executeRowFlex("justify"), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react13.AlignJustify, { size: 16 }) });
603
+ }
604
+
605
+ // src/toolbar/ListTool.tsx
606
+ var import_react12 = require("react");
607
+ var import_lucide_react14 = require("lucide-react");
608
+ var import_jsx_runtime21 = require("react/jsx-runtime");
609
+ var OL_PRESETS = [
610
+ { preset: "olDefault", label: "Default", preview: ["1.", "a.", "i."] },
611
+ { preset: "olParen", label: "Parenthesis", preview: ["1)", "a)", "i)"] },
612
+ { preset: "olOutline", label: "Outline", preview: ["1.", "1.1.", "1.1.1."] },
613
+ { preset: "olUpperA", label: "Upper Alpha", preview: ["A.", "a.", "i."] },
614
+ { preset: "olRoman", label: "Roman", preview: ["I.", "A.", "1."] },
615
+ { preset: "olZeroPad", label: "Zero Pad", preview: ["01.", "a.", "i."] }
616
+ ];
617
+ var UL_PRESETS = [
618
+ { preset: "ulDefault", label: "Default", preview: ["\u25CF", "\u25CB", "\u25A0"] },
619
+ { preset: "ulDiamond", label: "Diamond", preview: ["\u25C6", "\u27A4", "\u25A0"] },
620
+ { preset: "ulHollowSq", label: "Hollow Square", preview: ["\u25A1", "\u25A1", "\u25A1"] },
621
+ { preset: "ulArrow", label: "Arrow", preview: ["\u2192", "\u25C6", "\u25CF"] },
622
+ { preset: "ulStar", label: "Star", preview: ["\u2605", "\u25CB", "\u25A0"] },
623
+ { preset: "ulCheckArr", label: "Check Arrow", preview: ["\u27A4", "\u25CB", "\u25A0"] }
624
+ ];
625
+ function PresetCell({ option, onClick }) {
626
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
627
+ "div",
628
+ {
629
+ onClick,
630
+ className: "list-preset-cell",
631
+ title: option.label,
632
+ children: option.preview.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "list-preset-line", style: { paddingLeft: `${i * 10}px` }, children: [
633
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "list-preset-marker", children: item }),
634
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "list-preset-text" })
635
+ ] }, i))
636
+ }
637
+ );
638
+ }
639
+ function ListTool() {
640
+ const { editorRef, isApple, rangeStyle } = useEditor();
641
+ const [visible, setVisible] = (0, import_react12.useState)(false);
642
+ const containerRef = (0, import_react12.useRef)(null);
643
+ const optionsRef = (0, import_react12.useRef)(null);
644
+ const isActive = !!rangeStyle?.listType;
645
+ (0, import_react12.useEffect)(() => {
646
+ if (!visible) return;
647
+ const handler = (e) => {
648
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
649
+ setVisible(false);
650
+ }
651
+ };
652
+ document.addEventListener("mousedown", handler);
653
+ return () => document.removeEventListener("mousedown", handler);
654
+ }, [visible]);
655
+ (0, import_react12.useEffect)(() => {
656
+ if (!visible || !optionsRef.current) return;
657
+ const el = optionsRef.current;
658
+ el.style.left = "";
659
+ el.style.right = "";
660
+ const rect = el.getBoundingClientRect();
661
+ if (rect.right > window.innerWidth) {
662
+ const overflow = rect.right - window.innerWidth + 8;
663
+ el.style.left = `-${overflow}px`;
664
+ } else if (rect.left < 0) {
665
+ el.style.left = `${-rect.left + 8}px`;
666
+ }
667
+ }, [visible]);
668
+ const handleList = (type, style) => {
669
+ editorRef.current?.command.executeList(type, style);
670
+ setVisible(false);
671
+ };
672
+ const handlePreset = (type, preset) => {
673
+ const style = type === "ol" ? "decimal" : "disc";
674
+ editorRef.current?.command.executeListWithPreset(type, style, preset);
675
+ setVisible(false);
676
+ };
677
+ const handleIndent = (e) => {
678
+ e.stopPropagation();
679
+ editorRef.current?.command.executeListIndent();
680
+ };
681
+ const handleOutdent = (e) => {
682
+ e.stopPropagation();
683
+ editorRef.current?.command.executeListOutdent();
684
+ };
685
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { ref: containerRef, className: `menu-item__list ${isActive ? "active" : ""}`, title: `List(${isApple ? "\u2318" : "Ctrl"}+Shift+U)`, children: [
686
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.List, { size: 16, onClick: () => setVisible(!visible), style: { cursor: "pointer" } }),
687
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { ref: optionsRef, className: `options ${visible ? "visible" : ""}`, style: { padding: "8px", width: "320px" }, children: [
688
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: "4px", marginBottom: "8px" }, children: [
689
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
690
+ "button",
691
+ {
692
+ onClick: () => handleList("ul", "checkbox"),
693
+ className: "list-quick-btn",
694
+ children: "Checkbox"
695
+ }
696
+ ),
697
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: handleIndent, className: "list-quick-btn", title: "Indent (Tab)", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.Indent, { size: 14 }) }),
698
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: handleOutdent, className: "list-quick-btn", title: "Outdent (Shift+Tab)", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.Outdent, { size: 14 }) })
699
+ ] }),
700
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { marginBottom: "8px" }, children: [
701
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px", fontSize: "11px", color: "#667085", marginBottom: "6px", fontWeight: 500 }, children: [
702
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.ListOrdered, { size: 12 }),
703
+ "Ordered List"
704
+ ] }),
705
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "list-preset-grid", children: OL_PRESETS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
706
+ PresetCell,
707
+ {
708
+ option,
709
+ onClick: () => handlePreset("ol", option.preset)
710
+ },
711
+ option.preset
712
+ )) })
713
+ ] }),
714
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
715
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px", fontSize: "11px", color: "#667085", marginBottom: "6px", fontWeight: 500 }, children: [
716
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react14.List, { size: 12 }),
717
+ "Unordered List"
718
+ ] }),
719
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "list-preset-grid", children: UL_PRESETS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
720
+ PresetCell,
721
+ {
722
+ option,
723
+ onClick: () => handlePreset("ul", option.preset)
724
+ },
725
+ option.preset
726
+ )) })
727
+ ] })
728
+ ] })
729
+ ] });
730
+ }
731
+
732
+ // src/toolbar/ImageTool.tsx
733
+ var import_lucide_react15 = require("lucide-react");
734
+ var import_jsx_runtime22 = require("react/jsx-runtime");
735
+ function ImageTool() {
736
+ const { editorRef } = useEditor();
737
+ const handleImageUpload = (e) => {
738
+ const file = e.target.files?.[0];
739
+ if (!file) return;
740
+ const reader = new FileReader();
741
+ reader.readAsDataURL(file);
742
+ reader.onload = () => {
743
+ const img = new Image();
744
+ img.src = reader.result;
745
+ img.onload = () => {
746
+ editorRef.current?.command.executeImage({
747
+ value: reader.result,
748
+ width: img.width,
749
+ height: img.height
750
+ });
751
+ };
752
+ };
753
+ e.target.value = "";
754
+ };
755
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "menu-item__image", onClick: () => document.getElementById("image")?.click(), children: [
756
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react15.Image, { size: 16 }),
757
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("input", { type: "file", id: "image", accept: ".png, .jpg, .jpeg, .svg, .gif", onChange: handleImageUpload })
758
+ ] });
759
+ }
760
+
761
+ // src/toolbar/SeparatorTool.tsx
762
+ var import_react13 = require("react");
763
+ var import_lucide_react16 = require("lucide-react");
764
+ var import_jsx_runtime23 = require("react/jsx-runtime");
765
+ var DASH_STYLES = [
766
+ { label: "Solid", dashArray: [] },
767
+ { label: "Dotted", dashArray: [1, 1] },
768
+ { label: "Dashed", dashArray: [3, 1] },
769
+ { label: "Long Dash", dashArray: [4, 4] }
770
+ ];
771
+ var LINE_WIDTHS = [
772
+ { label: "Thin", value: 1 },
773
+ { label: "Medium", value: 2 },
774
+ { label: "Thick", value: 4 }
775
+ ];
776
+ function SeparatorTool() {
777
+ const { editorRef } = useEditor();
778
+ const [visible, setVisible] = (0, import_react13.useState)(false);
779
+ const [selectedWidth, setSelectedWidth] = (0, import_react13.useState)(1);
780
+ const lineColor = "#344054";
781
+ const handleSeparator = (dashArray) => {
782
+ editorRef.current?.command.executeSeparator(dashArray, { lineWidth: selectedWidth });
783
+ setVisible(false);
784
+ };
785
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "menu-item__separator", title: "Separator", children: [
786
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react16.Minus, { size: 16, onClick: () => setVisible(!visible), style: { cursor: "pointer" } }),
787
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `options ${visible ? "visible" : ""}`, style: { padding: "8px 10px 10px", width: "200px" }, children: [
788
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { style: { margin: 0, padding: 0, listStyle: "none" }, children: DASH_STYLES.map(({ label, dashArray }) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
789
+ "li",
790
+ {
791
+ onClick: () => handleSeparator(dashArray),
792
+ style: { display: "flex", alignItems: "center", gap: "10px", padding: "5px 6px", cursor: "pointer", borderRadius: "4px" },
793
+ children: [
794
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("svg", { style: { flex: 1, minWidth: 0, overflow: "hidden" }, height: "8", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
795
+ "line",
796
+ {
797
+ x1: "0",
798
+ y1: "4",
799
+ x2: "100%",
800
+ y2: "4",
801
+ stroke: lineColor,
802
+ strokeWidth: selectedWidth,
803
+ strokeDasharray: dashArray.length ? dashArray.join(",") : "none"
804
+ }
805
+ ) }),
806
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: "11px", color: "#475467", whiteSpace: "nowrap", flexShrink: 0 }, children: label })
807
+ ]
808
+ },
809
+ label
810
+ )) }),
811
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { borderTop: "1px solid #e4e7ec", marginTop: "8px", paddingTop: "8px" }, children: [
812
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { fontSize: "11px", color: "#667085", marginBottom: "6px", fontWeight: 500 }, children: "Line Width" }),
813
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: "flex", gap: "4px" }, children: LINE_WIDTHS.map(({ label, value }) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
814
+ "button",
815
+ {
816
+ onClick: (e) => {
817
+ e.stopPropagation();
818
+ setSelectedWidth(value);
819
+ },
820
+ style: {
821
+ flex: 1,
822
+ padding: "3px 6px",
823
+ fontSize: "11px",
824
+ border: `1px solid ${selectedWidth === value ? "#3b82f6" : "#d0d5dd"}`,
825
+ borderRadius: "4px",
826
+ background: selectedWidth === value ? "#eff6ff" : "#fff",
827
+ color: selectedWidth === value ? "#3b82f6" : "#475467",
828
+ cursor: "pointer",
829
+ fontWeight: selectedWidth === value ? 600 : 400
830
+ },
831
+ children: label
832
+ },
833
+ value
834
+ )) })
835
+ ] })
836
+ ] })
837
+ ] });
838
+ }
839
+
840
+ // src/toolbar/WatermarkTool.tsx
841
+ var import_react14 = require("react");
842
+ var import_jsx_runtime24 = require("react/jsx-runtime");
843
+ function InsertElementTool() {
844
+ const { editorRef } = useEditor();
845
+ const [visible, setVisible] = (0, import_react14.useState)(false);
846
+ const handleHeader = () => {
847
+ if (!editorRef.current) return;
848
+ const options = editorRef.current.command.getOptions();
849
+ if (options.header.disabled) {
850
+ options.header.disabled = false;
851
+ editorRef.current.command.executeForceUpdate();
852
+ }
853
+ editorRef.current.command.executeSetZone("header");
854
+ setVisible(false);
855
+ };
856
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "menu-item__insert-element", onClick: () => setVisible(!visible), children: [
857
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("i", { title: "Insert Element" }),
858
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("li", { onClick: handleHeader, children: "Add Header" }) }) })
859
+ ] });
860
+ }
861
+
862
+ // src/toolbar/PageBreakTool.tsx
863
+ var import_react15 = require("react");
864
+ var import_jsx_runtime25 = require("react/jsx-runtime");
865
+ function PageBreakTool() {
866
+ const { editorRef } = useEditor();
867
+ const [visible, setVisible] = (0, import_react15.useState)(false);
868
+ const handlePageBreak = () => {
869
+ editorRef.current?.command.executePageBreak();
870
+ setVisible(false);
871
+ };
872
+ const handleColumnBreak = () => {
873
+ editorRef.current?.command.executeColumnBreak();
874
+ setVisible(false);
875
+ };
876
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
877
+ "div",
878
+ {
879
+ className: "menu-item__page-break",
880
+ onClick: () => setVisible(!visible),
881
+ children: [
882
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("i", { title: "Break" }),
883
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("ul", { children: [
884
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("li", { onClick: handlePageBreak, children: "Page Break" }),
885
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("li", { onClick: handleColumnBreak, children: "Column Break" })
886
+ ] }) })
887
+ ]
888
+ }
889
+ );
890
+ }
891
+
892
+ // src/EditorToolbar.tsx
893
+ var import_jsx_runtime26 = require("react/jsx-runtime");
894
+ function EditorToolbar() {
895
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "menu", "editor-component": "menu", children: [
896
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "menu-item", children: [
897
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(UndoTool, {}),
898
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RedoTool, {})
899
+ ] }),
900
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-divider" }),
901
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-item", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ColumnTool, {}) }),
902
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-divider" }),
903
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "menu-item", children: [
904
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PageBreakTool, {}),
905
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SeparatorTool, {})
906
+ ] }),
907
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-divider" }),
908
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-item", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TableTool, {}) }),
909
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-divider" }),
910
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "menu-item", children: [
911
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TitleTool, {}),
912
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FontTool, {}),
913
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FontSizeTool, {}),
914
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(LineHeightTool, {})
915
+ ] }),
916
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-divider" }),
917
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "menu-item", children: [
918
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ColorTool, {}),
919
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(HighlightTool, {}),
920
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BoldTool, {}),
921
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItalicTool, {}),
922
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(UnderlineTool, {}),
923
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StrikeoutTool, {})
924
+ ] }),
925
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-divider" }),
926
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "menu-item", children: [
927
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(LeftAlignTool, {}),
928
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CenterAlignTool, {}),
929
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RightAlignTool, {}),
930
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(JustifyTool, {})
931
+ ] }),
932
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-divider" }),
933
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-item", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ListTool, {}) }),
934
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-divider" }),
935
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-item", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ImageTool, {}) }),
936
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "menu-item", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(InsertElementTool, {}) })
937
+ ] });
938
+ }
939
+
940
+ // src/footer/CatalogToggleTool.tsx
941
+ var import_jsx_runtime27 = require("react/jsx-runtime");
942
+ function CatalogToggleTool() {
943
+ const { handleToggleCatalogAction } = useFooter();
944
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "catalog-mode", title: "Catalog", onClick: handleToggleCatalogAction, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("i", {}) });
945
+ }
946
+
947
+ // src/footer/PageModeTool.tsx
948
+ var import_react16 = require("react");
949
+ var import_jsx_runtime28 = require("react/jsx-runtime");
950
+ function PageModeTool() {
951
+ const { editorRef } = useEditor();
952
+ const [visible, setVisible] = (0, import_react16.useState)(false);
953
+ const handlePageMode = (mode) => {
954
+ editorRef.current?.command.executePageMode(mode);
955
+ setVisible(false);
956
+ };
957
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "page-mode", onClick: () => setVisible(!visible), children: [
958
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("i", { title: "Page Mode" }),
959
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("ul", { children: [
960
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { onClick: () => handlePageMode("paging"), className: "active", children: "Paging" }),
961
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { onClick: () => handlePageMode("continuity"), children: "Continuity" })
962
+ ] }) })
963
+ ] });
964
+ }
965
+
966
+ // src/footer/FooterStatus.tsx
967
+ var import_jsx_runtime29 = require("react/jsx-runtime");
968
+ function FooterStatus() {
969
+ const { pageNoList, pageNo, pageSize, wordCount, rowNo, colNo } = useFooter();
970
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
971
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
972
+ "Visible Pages: ",
973
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "page-no-list", children: pageNoList })
974
+ ] }),
975
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "footer-divider" }),
976
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
977
+ "Pages: ",
978
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "page-no", children: pageNo }),
979
+ "/",
980
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "page-size", children: pageSize })
981
+ ] }),
982
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "footer-divider" }),
983
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
984
+ "Words: ",
985
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "word-count", children: wordCount })
986
+ ] }),
987
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "footer-divider" }),
988
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
989
+ "Row: ",
990
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "row-no", children: rowNo })
991
+ ] }),
992
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "footer-divider" }),
993
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { children: [
994
+ "Column: ",
995
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "col-no", children: colNo })
996
+ ] })
997
+ ] });
998
+ }
999
+
1000
+ // src/footer/EditorModeTool.tsx
1001
+ var import_react17 = require("react");
1002
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1003
+ var MODE_LIST = [
1004
+ { mode: "edit", name: "Edit Mode" },
1005
+ { mode: "clean", name: "Clean Mode" },
1006
+ { mode: "readonly", name: "Read-only Mode" },
1007
+ { mode: "form", name: "Form Mode" },
1008
+ { mode: "print", name: "Print Mode" },
1009
+ { mode: "design", name: "Design Mode" },
1010
+ { mode: "graffiti", name: "Graffiti Mode" }
1011
+ ];
1012
+ function EditorModeTool() {
1013
+ const { editorRef } = useEditor();
1014
+ const [editorMode, setEditorMode] = (0, import_react17.useState)("Edit Mode");
1015
+ const modeIndexRef = (0, import_react17.useRef)(0);
1016
+ const handleModeChange = () => {
1017
+ modeIndexRef.current = modeIndexRef.current === MODE_LIST.length - 1 ? 0 : modeIndexRef.current + 1;
1018
+ const { name, mode } = MODE_LIST[modeIndexRef.current];
1019
+ setEditorMode(name);
1020
+ editorRef.current?.command.executeMode(mode);
1021
+ const isReadonly = mode === "readonly";
1022
+ const enableMenuList = ["search", "print"];
1023
+ document.querySelectorAll(".menu-item>div").forEach((dom) => {
1024
+ const menu = dom.dataset.menu;
1025
+ if (isReadonly && (!menu || !enableMenuList.includes(menu))) {
1026
+ dom.classList.add("disable");
1027
+ } else {
1028
+ dom.classList.remove("disable");
1029
+ }
1030
+ });
1031
+ };
1032
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "editor-mode", title: "Click to change mode", onClick: handleModeChange, children: editorMode });
1033
+ }
1034
+
1035
+ // src/footer/PageScaleMinusTool.tsx
1036
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1037
+ function PageScaleMinusTool() {
1038
+ const { editorRef } = useEditor();
1039
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "page-scale-minus", title: "Zoom Out (Ctrl+-)", onClick: () => editorRef.current?.command.executePageScaleMinus(), children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("i", {}) });
1040
+ }
1041
+
1042
+ // src/footer/PageScalePercentageTool.tsx
1043
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1044
+ function PageScalePercentageTool() {
1045
+ const { editorRef } = useEditor();
1046
+ const { pageScale } = useFooter();
1047
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "page-scale-percentage", title: "Zoom Level", onClick: () => editorRef.current?.command.executePageScaleRecovery(), children: [
1048
+ pageScale,
1049
+ "%"
1050
+ ] });
1051
+ }
1052
+
1053
+ // src/footer/PageScaleAddTool.tsx
1054
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1055
+ function PageScaleAddTool() {
1056
+ const { editorRef } = useEditor();
1057
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "page-scale-add", title: "Zoom In (Ctrl+=)", onClick: () => editorRef.current?.command.executePageScaleAdd(), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("i", {}) });
1058
+ }
1059
+
1060
+ // src/footer/PaperSizeTool.tsx
1061
+ var import_react18 = require("react");
1062
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1063
+ var SIZES2 = [
1064
+ { label: "A4", width: 794, height: 1123, active: true },
1065
+ { label: "A2", width: 1593, height: 2251 },
1066
+ { label: "A3", width: 1125, height: 1593 },
1067
+ { label: "A5", width: 565, height: 796 }
1068
+ ];
1069
+ function PaperSizeTool() {
1070
+ const { editorRef } = useEditor();
1071
+ const [visible, setVisible] = (0, import_react18.useState)(false);
1072
+ const handlePaperSize = (width, height) => {
1073
+ editorRef.current?.command.executePaperSize(width, height);
1074
+ setVisible(false);
1075
+ };
1076
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "paper-size", onClick: () => setVisible(!visible), children: [
1077
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("i", { title: "Paper Type" }),
1078
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("ul", { children: SIZES2.map(({ label, width, height, active }) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("li", { onClick: () => handlePaperSize(width, height), className: active ? "active" : "", children: label }, label)) }) })
1079
+ ] });
1080
+ }
1081
+
1082
+ // src/footer/PaperDirectionTool.tsx
1083
+ var import_react19 = require("react");
1084
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1085
+ function PaperDirectionTool() {
1086
+ const { editorRef } = useEditor();
1087
+ const [visible, setVisible] = (0, import_react19.useState)(false);
1088
+ const handlePaperDirection = (direction) => {
1089
+ editorRef.current?.command.executePaperDirection(direction);
1090
+ setVisible(false);
1091
+ };
1092
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "paper-direction", onClick: () => setVisible(!visible), children: [
1093
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("i", { title: "Paper Direction" }),
1094
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: `options ${visible ? "visible" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("ul", { children: [
1095
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("li", { onClick: () => handlePaperDirection("vertical"), className: "active", children: "Portrait" }),
1096
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("li", { onClick: () => handlePaperDirection("horizontal"), children: "Landscape" })
1097
+ ] }) })
1098
+ ] });
1099
+ }
1100
+
1101
+ // src/footer/PaperMarginTool.tsx
1102
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1103
+ function PaperMarginTool() {
1104
+ const { editorRef } = useEditor();
1105
+ const handlePaperMargin = async () => {
1106
+ if (!editorRef.current) return;
1107
+ const { Dialog } = await import("@windoc/core");
1108
+ const [topMargin, rightMargin, bottomMargin, leftMargin] = editorRef.current.command.getPaperMargin();
1109
+ new Dialog({
1110
+ title: "Page Margins",
1111
+ data: [
1112
+ { type: "text", label: "Top Margin", name: "top", required: true, value: `${topMargin}`, placeholder: "Please enter top margin" },
1113
+ { type: "text", label: "Bottom Margin", name: "bottom", required: true, value: `${bottomMargin}`, placeholder: "Please enter bottom margin" },
1114
+ { type: "text", label: "Left Margin", name: "left", required: true, value: `${leftMargin}`, placeholder: "Please enter left margin" },
1115
+ { type: "text", label: "Right Margin", name: "right", required: true, value: `${rightMargin}`, placeholder: "Please enter right margin" }
1116
+ ],
1117
+ onConfirm: (payload) => {
1118
+ const top = payload.find((p) => p.name === "top")?.value;
1119
+ if (!top) return;
1120
+ const bottom = payload.find((p) => p.name === "bottom")?.value;
1121
+ if (!bottom) return;
1122
+ const left = payload.find((p) => p.name === "left")?.value;
1123
+ if (!left) return;
1124
+ const right = payload.find((p) => p.name === "right")?.value;
1125
+ if (!right) return;
1126
+ editorRef.current?.command.executeSetPaperMargin([
1127
+ Number(top),
1128
+ Number(right),
1129
+ Number(bottom),
1130
+ Number(left)
1131
+ ]);
1132
+ }
1133
+ });
1134
+ };
1135
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "paper-margin", title: "Page Margins", onClick: handlePaperMargin, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("i", {}) });
1136
+ }
1137
+
1138
+ // src/footer/FullscreenTool.tsx
1139
+ var import_jsx_runtime37 = require("react/jsx-runtime");
1140
+ function FullscreenTool() {
1141
+ const handleFullscreen = () => {
1142
+ if (!document.fullscreenElement) {
1143
+ document.documentElement.requestFullscreen();
1144
+ } else {
1145
+ document.exitFullscreen();
1146
+ }
1147
+ };
1148
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "fullscreen", title: "Fullscreen", onClick: handleFullscreen, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("i", {}) });
1149
+ }
1150
+
1151
+ // src/footer/EditorOptionTool.tsx
1152
+ var import_jsx_runtime38 = require("react/jsx-runtime");
1153
+ function EditorOptionTool() {
1154
+ const { editorRef } = useEditor();
1155
+ const handleEditorOption = async () => {
1156
+ if (!editorRef.current) return;
1157
+ const { Dialog } = await import("@windoc/core");
1158
+ const options = editorRef.current.command.getOptions();
1159
+ new Dialog({
1160
+ title: "Editor Configuration",
1161
+ data: [
1162
+ {
1163
+ type: "textarea",
1164
+ name: "option",
1165
+ width: 350,
1166
+ height: 300,
1167
+ required: true,
1168
+ value: JSON.stringify(options, null, 2),
1169
+ placeholder: "Please enter editor configuration"
1170
+ }
1171
+ ],
1172
+ onConfirm: (payload) => {
1173
+ const newOptionValue = payload.find((p) => p.name === "option")?.value;
1174
+ if (!newOptionValue) return;
1175
+ const newOption = JSON.parse(newOptionValue);
1176
+ editorRef.current?.command.executeUpdateOptions(newOption);
1177
+ }
1178
+ });
1179
+ };
1180
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "editor-option", title: "Editor Settings", onClick: handleEditorOption, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("i", {}) });
1181
+ }
1182
+
1183
+ // src/footer/WatermarkFooterTool.tsx
1184
+ var import_react20 = require("react");
1185
+ var import_jsx_runtime39 = require("react/jsx-runtime");
1186
+ var COLOR_PALETTE2 = [
1187
+ ["#000000", "#434343", "#666666", "#999999", "#b7b7b7", "#cccccc"],
1188
+ ["#980000", "#ff0000", "#ff9900", "#ffff00", "#00ff00", "#00ffff"],
1189
+ ["#4a86e8", "#0000ff", "#9900ff", "#ff00ff", "#e6b8af", "#f4cccc"]
1190
+ ];
1191
+ var FONTS2 = [
1192
+ { family: "Arial", label: "Sans Serif" },
1193
+ { family: "Times New Roman", label: "Serif" }
1194
+ ];
1195
+ function WatermarkFooterTool() {
1196
+ const { editorRef } = useEditor();
1197
+ const [visible, setVisible] = (0, import_react20.useState)(false);
1198
+ const [tab, setTab] = (0, import_react20.useState)("text");
1199
+ const containerRef = (0, import_react20.useRef)(null);
1200
+ const panelRef = (0, import_react20.useRef)(null);
1201
+ const fileInputRef = (0, import_react20.useRef)(null);
1202
+ const [text, setText] = (0, import_react20.useState)("WATERMARK");
1203
+ const [font, setFont] = (0, import_react20.useState)("Arial");
1204
+ const [color, setColor] = (0, import_react20.useState)("#AEB5C0");
1205
+ const [opacity, setOpacity] = (0, import_react20.useState)(30);
1206
+ const [rotation, setRotation] = (0, import_react20.useState)(-45);
1207
+ const [inFront, setInFront] = (0, import_react20.useState)(false);
1208
+ const [imageData, setImageData] = (0, import_react20.useState)("");
1209
+ const [imgWidth, setImgWidth] = (0, import_react20.useState)(200);
1210
+ const [imgHeight, setImgHeight] = (0, import_react20.useState)(200);
1211
+ (0, import_react20.useEffect)(() => {
1212
+ if (!visible) return;
1213
+ const handler = (e) => {
1214
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
1215
+ setVisible(false);
1216
+ }
1217
+ };
1218
+ document.addEventListener("mousedown", handler);
1219
+ return () => document.removeEventListener("mousedown", handler);
1220
+ }, [visible]);
1221
+ (0, import_react20.useEffect)(() => {
1222
+ if (!visible || !panelRef.current) return;
1223
+ const el = panelRef.current;
1224
+ el.style.right = "";
1225
+ el.style.left = "";
1226
+ const rect = el.getBoundingClientRect();
1227
+ if (rect.right > window.innerWidth) {
1228
+ el.style.left = "unset";
1229
+ el.style.right = "0";
1230
+ }
1231
+ if (rect.left < 0) {
1232
+ el.style.left = `${-rect.left + 4}px`;
1233
+ }
1234
+ }, [visible]);
1235
+ const handleFileUpload = (0, import_react20.useCallback)((e) => {
1236
+ const file = e.target.files?.[0];
1237
+ if (!file) return;
1238
+ const reader = new FileReader();
1239
+ reader.onload = () => {
1240
+ const result = reader.result;
1241
+ setImageData(result);
1242
+ const img = new Image();
1243
+ img.onload = () => {
1244
+ const maxDim = 300;
1245
+ let w = img.naturalWidth;
1246
+ let h = img.naturalHeight;
1247
+ if (w > maxDim || h > maxDim) {
1248
+ const ratio = Math.min(maxDim / w, maxDim / h);
1249
+ w = Math.round(w * ratio);
1250
+ h = Math.round(h * ratio);
1251
+ }
1252
+ setImgWidth(w);
1253
+ setImgHeight(h);
1254
+ };
1255
+ img.src = result;
1256
+ };
1257
+ reader.readAsDataURL(file);
1258
+ }, []);
1259
+ const handleApply = () => {
1260
+ if (!editorRef.current) return;
1261
+ if (tab === "text") {
1262
+ if (!text.trim()) return;
1263
+ editorRef.current.command.executeAddWatermark({
1264
+ data: text,
1265
+ type: "text",
1266
+ color,
1267
+ opacity: opacity / 100,
1268
+ size: 120,
1269
+ font,
1270
+ rotation,
1271
+ inFront
1272
+ });
1273
+ } else {
1274
+ if (!imageData) return;
1275
+ editorRef.current.command.executeAddWatermark({
1276
+ data: imageData,
1277
+ type: "image",
1278
+ opacity: opacity / 100,
1279
+ rotation,
1280
+ inFront,
1281
+ width: imgWidth,
1282
+ height: imgHeight
1283
+ });
1284
+ }
1285
+ setVisible(false);
1286
+ };
1287
+ const handleDelete = () => {
1288
+ editorRef.current?.command.executeDeleteWatermark();
1289
+ setVisible(false);
1290
+ };
1291
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "watermark-footer", ref: containerRef, onClick: () => setVisible(!visible), children: [
1292
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("i", { title: "Watermark" }),
1293
+ visible && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "watermark-footer-panel", ref: panelRef, onClick: (e) => e.stopPropagation(), children: [
1294
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-tabs", children: [
1295
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { className: `wm-panel-tab ${tab === "text" ? "active" : ""}`, onClick: () => setTab("text"), children: "Text" }),
1296
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { className: `wm-panel-tab ${tab === "image" ? "active" : ""}`, onClick: () => setTab("image"), children: "Image" })
1297
+ ] }),
1298
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-body", children: [
1299
+ tab === "text" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
1300
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field", children: [
1301
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { children: "Text" }),
1302
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { type: "text", value: text, onChange: (e) => setText(e.target.value), placeholder: "Watermark text" })
1303
+ ] }),
1304
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field", children: [
1305
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { children: "Font" }),
1306
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("select", { value: font, onChange: (e) => setFont(e.target.value), children: FONTS2.map((f) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: f.family, children: f.label }, f.family)) })
1307
+ ] }),
1308
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field", children: [
1309
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { children: "Color" }),
1310
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "wm-panel-colors", children: COLOR_PALETTE2.flat().map((c) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1311
+ "div",
1312
+ {
1313
+ className: `wm-panel-color ${color.toLowerCase() === c.toLowerCase() ? "active" : ""}`,
1314
+ style: { backgroundColor: c },
1315
+ onClick: () => setColor(c)
1316
+ },
1317
+ c
1318
+ )) })
1319
+ ] })
1320
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
1321
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field", children: [
1322
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { children: "Image" }),
1323
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
1324
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { className: "wm-panel-upload", onClick: () => fileInputRef.current?.click(), children: "Choose File" }),
1325
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: handleFileUpload }),
1326
+ imageData && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { style: { fontSize: "11px", color: "#667085" }, children: "Loaded" })
1327
+ ] })
1328
+ ] }),
1329
+ imageData && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "wm-panel-field", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "wm-panel-preview", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("img", { src: imageData, alt: "preview", style: { maxWidth: "100%", maxHeight: "48px", objectFit: "contain" } }) }) }),
1330
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field-row", children: [
1331
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field wm-panel-field-half", children: [
1332
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { children: "W" }),
1333
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { type: "number", value: imgWidth, min: 10, onChange: (e) => setImgWidth(Number(e.target.value)) })
1334
+ ] }),
1335
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field wm-panel-field-half", children: [
1336
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { children: "H" }),
1337
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { type: "number", value: imgHeight, min: 10, onChange: (e) => setImgHeight(Number(e.target.value)) })
1338
+ ] })
1339
+ ] })
1340
+ ] }),
1341
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field", children: [
1342
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { children: [
1343
+ "Opacity ",
1344
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "wm-panel-value", children: [
1345
+ opacity,
1346
+ "%"
1347
+ ] })
1348
+ ] }),
1349
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { type: "range", min: 0, max: 100, value: opacity, onChange: (e) => setOpacity(Number(e.target.value)), className: "wm-panel-slider" })
1350
+ ] }),
1351
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field", children: [
1352
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { children: [
1353
+ "Rotation ",
1354
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "wm-panel-value", children: [
1355
+ rotation,
1356
+ "\xB0"
1357
+ ] })
1358
+ ] }),
1359
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { type: "range", min: -90, max: 90, value: rotation, onChange: (e) => setRotation(Number(e.target.value)), className: "wm-panel-slider" })
1360
+ ] }),
1361
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-field", children: [
1362
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("label", { children: "Position" }),
1363
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-toggle", children: [
1364
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { className: !inFront ? "active" : "", onClick: () => setInFront(false), children: "Behind" }),
1365
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { className: inFront ? "active" : "", onClick: () => setInFront(true), children: "In Front" })
1366
+ ] })
1367
+ ] })
1368
+ ] }),
1369
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "wm-panel-actions", children: [
1370
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { className: "wm-panel-btn-delete", onClick: handleDelete, children: "Remove" }),
1371
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { className: "wm-panel-btn-apply", onClick: handleApply, children: "Apply" })
1372
+ ] })
1373
+ ] })
1374
+ ] });
1375
+ }
1376
+
1377
+ // src/EditorFooter.tsx
1378
+ var import_jsx_runtime40 = require("react/jsx-runtime");
1379
+ function EditorFooter() {
1380
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "footer", "editor-component": "footer", children: [
1381
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { children: [
1382
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(CatalogToggleTool, {}),
1383
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PageModeTool, {}),
1384
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(FooterStatus, {})
1385
+ ] }),
1386
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(EditorModeTool, {}),
1387
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { children: [
1388
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PageScaleMinusTool, {}),
1389
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PageScalePercentageTool, {}),
1390
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PageScaleAddTool, {}),
1391
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PaperSizeTool, {}),
1392
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PaperDirectionTool, {}),
1393
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PaperMarginTool, {}),
1394
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(WatermarkFooterTool, {}),
1395
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(FullscreenTool, {}),
1396
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(EditorOptionTool, {})
1397
+ ] })
1398
+ ] });
1399
+ }
1400
+
1401
+ // src/Editor.tsx
1402
+ var import_jsx_runtime41 = require("react/jsx-runtime");
1403
+ function Editor({
1404
+ defaultValue,
1405
+ options: userOptions,
1406
+ onChange,
1407
+ onReady,
1408
+ toolbar = true,
1409
+ footer = true,
1410
+ renderToolbar,
1411
+ renderFooter,
1412
+ children,
1413
+ className,
1414
+ style,
1415
+ onDrop: userOnDrop
1416
+ }) {
1417
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(FooterProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
1418
+ EditorInner,
1419
+ {
1420
+ defaultValue,
1421
+ options: userOptions,
1422
+ onChange,
1423
+ onReady,
1424
+ toolbar,
1425
+ footer,
1426
+ renderToolbar,
1427
+ renderFooter,
1428
+ className,
1429
+ style,
1430
+ onDrop: userOnDrop,
1431
+ children
1432
+ }
1433
+ ) });
1434
+ }
1435
+ function EditorInner({
1436
+ defaultValue,
1437
+ options: userOptions,
1438
+ onChange,
1439
+ onReady,
1440
+ toolbar = true,
1441
+ footer = true,
1442
+ renderToolbar,
1443
+ renderFooter,
1444
+ children,
1445
+ className,
1446
+ style,
1447
+ onDrop: userOnDrop
1448
+ }) {
1449
+ const containerRef = (0, import_react21.useRef)(null);
1450
+ const editorRef = (0, import_react21.useRef)(null);
1451
+ const [rangeStyle, setRangeStyle] = (0, import_react21.useState)(null);
1452
+ const {
1453
+ setPageNoList,
1454
+ setPageNo,
1455
+ setPageSize,
1456
+ setWordCount,
1457
+ setRowNo,
1458
+ setColNo,
1459
+ setPageScale
1460
+ } = useFooter();
1461
+ (0, import_react21.useEffect)(() => {
1462
+ let instance = null;
1463
+ const initEditor = async () => {
1464
+ if (!containerRef.current) return;
1465
+ const {
1466
+ default: EditorClass,
1467
+ KeyMap,
1468
+ EditorMode,
1469
+ EditorZone,
1470
+ ElementType,
1471
+ Dialog,
1472
+ Signature
1473
+ } = await import("@windoc/core");
1474
+ const data = defaultValue ?? { main: [] };
1475
+ instance = new EditorClass(
1476
+ containerRef.current,
1477
+ data,
1478
+ userOptions ?? {}
1479
+ );
1480
+ editorRef.current = instance;
1481
+ instance.listener.rangeStyleChange = (payload) => {
1482
+ setRangeStyle(payload);
1483
+ const rangeContext = instance?.command.getRangeContext();
1484
+ if (rangeContext) {
1485
+ setRowNo(rangeContext.startRowNo + 1);
1486
+ setColNo(rangeContext.startColNo + 1);
1487
+ }
1488
+ };
1489
+ instance.listener.visiblePageNoListChange = (payload) => {
1490
+ setPageNoList(payload.map((i) => i + 1).join(", "));
1491
+ };
1492
+ instance.listener.pageSizeChange = (payload) => {
1493
+ setPageSize(payload);
1494
+ };
1495
+ instance.listener.intersectionPageNoChange = (payload) => {
1496
+ setPageNo(payload + 1);
1497
+ };
1498
+ instance.listener.pageScaleChange = (payload) => {
1499
+ setPageScale(Math.floor(payload * 10 * 10));
1500
+ };
1501
+ instance.listener.contentChange = async () => {
1502
+ const count2 = await instance?.command.getWordCount();
1503
+ setWordCount(count2 || 0);
1504
+ if (onChange) {
1505
+ const value = instance?.command.getValue();
1506
+ if (value) onChange(value);
1507
+ }
1508
+ };
1509
+ instance.register.shortcutList([
1510
+ {
1511
+ key: KeyMap.P,
1512
+ mod: true,
1513
+ isGlobal: true,
1514
+ callback: (command) => {
1515
+ command.executePrint();
1516
+ }
1517
+ },
1518
+ {
1519
+ key: KeyMap.MINUS,
1520
+ ctrl: true,
1521
+ isGlobal: true,
1522
+ callback: (command) => {
1523
+ command.executePageScaleMinus();
1524
+ }
1525
+ },
1526
+ {
1527
+ key: KeyMap.EQUAL,
1528
+ ctrl: true,
1529
+ isGlobal: true,
1530
+ callback: (command) => {
1531
+ command.executePageScaleAdd();
1532
+ }
1533
+ },
1534
+ {
1535
+ key: KeyMap.ZERO,
1536
+ ctrl: true,
1537
+ isGlobal: true,
1538
+ callback: (command) => {
1539
+ command.executePageScaleRecovery();
1540
+ }
1541
+ }
1542
+ ]);
1543
+ instance.register.contextMenuList([
1544
+ {
1545
+ name: "Signature",
1546
+ icon: "signature",
1547
+ when: (payload) => {
1548
+ return !payload.isReadonly && payload.editorTextFocus;
1549
+ },
1550
+ callback: (command) => {
1551
+ new Signature({
1552
+ onConfirm(payload) {
1553
+ if (!payload) return;
1554
+ const { value, width, height } = payload;
1555
+ if (!value || !width || !height) return;
1556
+ command.executeInsertElementList([
1557
+ { value, width, height, type: ElementType.IMAGE }
1558
+ ]);
1559
+ }
1560
+ });
1561
+ }
1562
+ },
1563
+ {
1564
+ name: "Format Cleanup",
1565
+ icon: "word-tool",
1566
+ when: (payload) => !payload.isReadonly,
1567
+ callback: (command) => {
1568
+ command.executeWordTool();
1569
+ }
1570
+ }
1571
+ ]);
1572
+ const closeDropdowns = (evt) => {
1573
+ const visibleDom = document.querySelector(".visible");
1574
+ if (!visibleDom || visibleDom.contains(evt.target)) return;
1575
+ visibleDom.classList.remove("visible");
1576
+ };
1577
+ window.addEventListener("click", closeDropdowns, { capture: true });
1578
+ const count = await instance.command.getWordCount();
1579
+ setWordCount(count || 0);
1580
+ onReady?.(instance);
1581
+ };
1582
+ initEditor();
1583
+ return () => {
1584
+ instance?.destroy();
1585
+ };
1586
+ }, []);
1587
+ const handleDrop = (e) => {
1588
+ e.preventDefault();
1589
+ if (userOnDrop && editorRef.current) {
1590
+ userOnDrop(e, editorRef.current);
1591
+ }
1592
+ };
1593
+ const handleDragOver = (e) => {
1594
+ e.preventDefault();
1595
+ e.dataTransfer.dropEffect = "copy";
1596
+ };
1597
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(EditorProvider, { editorRef, rangeStyle, children: [
1598
+ toolbar && !renderToolbar && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(EditorToolbar, {}),
1599
+ renderToolbar,
1600
+ children,
1601
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
1602
+ "div",
1603
+ {
1604
+ className: className ?? "editor",
1605
+ style: style ?? { flex: 1, minHeight: 0, overflow: "auto" },
1606
+ ref: containerRef,
1607
+ onDrop: handleDrop,
1608
+ onDragOver: handleDragOver
1609
+ }
1610
+ ),
1611
+ footer && !renderFooter && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(EditorFooter, {}),
1612
+ renderFooter
1613
+ ] });
1614
+ }
1615
+ // Annotate the CommonJS export names for ESM import in node:
1616
+ 0 && (module.exports = {
1617
+ BoldTool,
1618
+ CatalogToggleTool,
1619
+ CenterAlignTool,
1620
+ ColorTool,
1621
+ ColumnTool,
1622
+ Editor,
1623
+ EditorFooter,
1624
+ EditorModeTool,
1625
+ EditorOptionTool,
1626
+ EditorProvider,
1627
+ EditorToolbar,
1628
+ FontSizeTool,
1629
+ FontTool,
1630
+ FooterProvider,
1631
+ FooterStatus,
1632
+ FullscreenTool,
1633
+ HighlightTool,
1634
+ ImageTool,
1635
+ ItalicTool,
1636
+ JustifyTool,
1637
+ LeftAlignTool,
1638
+ LineHeightTool,
1639
+ ListTool,
1640
+ PageBreakTool,
1641
+ PageModeTool,
1642
+ PageScaleAddTool,
1643
+ PageScaleMinusTool,
1644
+ PageScalePercentageTool,
1645
+ PaperDirectionTool,
1646
+ PaperMarginTool,
1647
+ PaperSizeTool,
1648
+ RedoTool,
1649
+ RightAlignTool,
1650
+ SeparatorTool,
1651
+ StrikeoutTool,
1652
+ TableTool,
1653
+ TitleTool,
1654
+ UnderlineTool,
1655
+ UndoTool,
1656
+ WatermarkFooterTool,
1657
+ WatermarkTool,
1658
+ useEditor,
1659
+ useFooter
1660
+ });
1661
+ //# sourceMappingURL=index.js.map