@windoc/react 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/Editor.tsx
2
- import { useEffect as useEffect4, useRef as useRef4, useState as useState21 } from "react";
2
+ import { useEffect as useEffect4, useRef as useRef16, useState as useState11 } from "react";
3
3
 
4
4
  // src/EditorContext.tsx
5
5
  import { createContext, useContext, useEffect, useState } from "react";
@@ -100,11 +100,11 @@ function RedoTool() {
100
100
  }
101
101
 
102
102
  // src/toolbar/ColumnTool.tsx
103
- import { useState as useState3 } from "react";
103
+ import { useRef, useState as useState3 } from "react";
104
104
  import { Fragment, jsx as jsx5, jsxs } from "react/jsx-runtime";
105
105
  function ColumnTool() {
106
106
  const { editorRef } = useEditor();
107
- const [isOpen, setIsOpen] = useState3(false);
107
+ const optionsRef = useRef(null);
108
108
  const [currentColumns, setCurrentColumns] = useState3(1);
109
109
  const [gap, setGap] = useState3(20);
110
110
  const handleColumn = (col) => {
@@ -116,9 +116,9 @@ function ColumnTool() {
116
116
  setGap(clampedValue);
117
117
  editorRef.current?.command.executeColumnGap(clampedValue);
118
118
  };
119
- return /* @__PURE__ */ jsxs("div", { className: "menu-item__column", onClick: () => setIsOpen(!isOpen), children: [
119
+ return /* @__PURE__ */ jsxs("div", { className: "menu-item__column", onClick: () => optionsRef.current?.classList.toggle("visible"), children: [
120
120
  /* @__PURE__ */ jsx5("span", { className: "select", title: "Column Layout", children: currentColumns === 1 ? "1 Column" : `${currentColumns} Columns` }),
121
- /* @__PURE__ */ jsx5("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsxs("div", { onClick: (e) => e.stopPropagation(), children: [
121
+ /* @__PURE__ */ jsx5("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsxs("div", { onClick: (e) => e.stopPropagation(), children: [
122
122
  /* @__PURE__ */ jsxs("ul", { children: [
123
123
  /* @__PURE__ */ jsx5("li", { onClick: () => handleColumn(1), children: "1 Column" }),
124
124
  /* @__PURE__ */ jsx5("li", { onClick: () => handleColumn(2), children: "2 Columns" })
@@ -145,7 +145,7 @@ function ColumnTool() {
145
145
  }
146
146
 
147
147
  // src/toolbar/TableTool.tsx
148
- import { useState as useState4, useEffect as useEffect2, useRef } from "react";
148
+ import { useState as useState4, useEffect as useEffect2, useRef as useRef2 } from "react";
149
149
  import { Table } from "lucide-react";
150
150
  import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
151
151
  function TableTool() {
@@ -153,7 +153,7 @@ function TableTool() {
153
153
  const [visible, setVisible] = useState4(false);
154
154
  const [hoverRow, setHoverRow] = useState4(0);
155
155
  const [hoverCol, setHoverCol] = useState4(0);
156
- const containerRef = useRef(null);
156
+ const containerRef = useRef2(null);
157
157
  useEffect2(() => {
158
158
  if (!visible) return;
159
159
  const handleClickOutside = (e) => {
@@ -194,7 +194,7 @@ function TableTool() {
194
194
  }
195
195
 
196
196
  // src/toolbar/TitleTool.tsx
197
- import { useState as useState5 } from "react";
197
+ import { useRef as useRef3 } from "react";
198
198
  import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
199
199
  var LEVELS = [
200
200
  { level: null, label: "Body" },
@@ -207,15 +207,15 @@ var LEVELS = [
207
207
  ];
208
208
  function TitleTool() {
209
209
  const { editorRef, rangeStyle } = useEditor();
210
- const [isOpen, setIsOpen] = useState5(false);
210
+ const optionsRef = useRef3(null);
211
211
  const activeLevel = rangeStyle?.level || null;
212
212
  const activeLabel = LEVELS.find((l) => l.level === activeLevel)?.label || "Body";
213
213
  const handleTitle = (level) => {
214
214
  editorRef.current?.command.executeTitle(level);
215
215
  };
216
- return /* @__PURE__ */ jsxs3("div", { className: "menu-item__title", onClick: () => setIsOpen(!isOpen), children: [
216
+ return /* @__PURE__ */ jsxs3("div", { className: "menu-item__title", onClick: () => optionsRef.current?.classList.toggle("visible"), children: [
217
217
  /* @__PURE__ */ jsx7("span", { className: "select", title: "Toggle Heading", children: activeLabel }),
218
- /* @__PURE__ */ jsx7("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsx7("ul", { children: LEVELS.map(({ level, label }) => /* @__PURE__ */ jsx7(
218
+ /* @__PURE__ */ jsx7("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsx7("ul", { children: LEVELS.map(({ level, label }) => /* @__PURE__ */ jsx7(
219
219
  "li",
220
220
  {
221
221
  className: activeLevel === level ? "active" : "",
@@ -229,23 +229,29 @@ function TitleTool() {
229
229
  }
230
230
 
231
231
  // src/toolbar/FontTool.tsx
232
- import { useState as useState6 } from "react";
232
+ import { useRef as useRef4 } from "react";
233
233
  import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
234
234
  var FONTS = [
235
- { family: "Arial", label: "Sans Serif" },
236
- { family: "Times New Roman", label: "Serif" }
235
+ { family: "Arial", label: "Arial" },
236
+ { family: "Times New Roman", label: "Times New Roman" },
237
+ { family: "Georgia", label: "Georgia" },
238
+ { family: "Verdana", label: "Verdana" },
239
+ { family: "Trebuchet MS", label: "Trebuchet MS" },
240
+ { family: "Courier New", label: "Courier New" },
241
+ { family: "Comic Sans MS", label: "Comic Sans MS" },
242
+ { family: "Impact", label: "Impact" }
237
243
  ];
238
244
  function FontTool() {
239
245
  const { editorRef, rangeStyle } = useEditor();
240
- const [isOpen, setIsOpen] = useState6(false);
246
+ const optionsRef = useRef4(null);
241
247
  const activeFont = rangeStyle?.font || "Arial";
242
248
  const activeLabel = FONTS.find((f) => f.family === activeFont)?.label || activeFont;
243
249
  const handleFont = (family) => {
244
250
  editorRef.current?.command.executeFont(family);
245
251
  };
246
- return /* @__PURE__ */ jsxs4("div", { className: "menu-item__font", onClick: () => setIsOpen(!isOpen), children: [
252
+ return /* @__PURE__ */ jsxs4("div", { className: "menu-item__font", onClick: () => optionsRef.current?.classList.toggle("visible"), children: [
247
253
  /* @__PURE__ */ jsx8("span", { className: "select", title: "Font", children: activeLabel }),
248
- /* @__PURE__ */ jsx8("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsx8("ul", { children: FONTS.map(({ family, label }) => /* @__PURE__ */ jsx8(
254
+ /* @__PURE__ */ jsx8("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsx8("ul", { children: FONTS.map(({ family, label }) => /* @__PURE__ */ jsx8(
249
255
  "li",
250
256
  {
251
257
  "data-family": family,
@@ -260,19 +266,19 @@ function FontTool() {
260
266
  }
261
267
 
262
268
  // src/toolbar/FontSizeTool.tsx
263
- import { useState as useState7 } from "react";
269
+ import { useRef as useRef5 } from "react";
264
270
  import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
265
271
  var SIZES = [56, 48, 34, 32, 29, 24, 21, 20, 18, 16, 14, 12, 10, 8];
266
272
  function FontSizeTool() {
267
273
  const { editorRef, rangeStyle } = useEditor();
268
- const [isOpen, setIsOpen] = useState7(false);
274
+ const optionsRef = useRef5(null);
269
275
  const activeSize = rangeStyle?.size ?? 16;
270
276
  const handleSize = (size) => {
271
277
  editorRef.current?.command.executeSize(size);
272
278
  };
273
- return /* @__PURE__ */ jsxs5("div", { className: "menu-item__size", onClick: () => setIsOpen(!isOpen), children: [
279
+ return /* @__PURE__ */ jsxs5("div", { className: "menu-item__size", onClick: () => optionsRef.current?.classList.toggle("visible"), children: [
274
280
  /* @__PURE__ */ jsx9("span", { className: "select", title: "Font Size", children: activeSize }),
275
- /* @__PURE__ */ jsx9("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsx9("ul", { children: SIZES.map((size) => /* @__PURE__ */ jsx9(
281
+ /* @__PURE__ */ jsx9("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsx9("ul", { children: SIZES.map((size) => /* @__PURE__ */ jsx9(
276
282
  "li",
277
283
  {
278
284
  className: activeSize === size ? "active" : "",
@@ -285,20 +291,20 @@ function FontSizeTool() {
285
291
  }
286
292
 
287
293
  // src/toolbar/LineHeightTool.tsx
288
- import { useState as useState8 } from "react";
294
+ import { useRef as useRef6 } from "react";
289
295
  import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
290
296
  var LINE_HEIGHTS = ["1.0", "1.15", "1.5", "2.0", "2.5"];
291
297
  function LineHeightTool() {
292
298
  const { editorRef, rangeStyle } = useEditor();
293
- const [isOpen, setIsOpen] = useState8(false);
299
+ const optionsRef = useRef6(null);
294
300
  const activeMargin = rangeStyle?.rowMargin ?? 1;
295
301
  const activeLabel = Number.isInteger(activeMargin) ? `${activeMargin}.0` : String(activeMargin);
296
302
  const handleLineHeight = (value) => {
297
303
  editorRef.current?.command.executeRowMargin(Number(value));
298
304
  };
299
- return /* @__PURE__ */ jsxs6("div", { className: "menu-item__line-height", onClick: () => setIsOpen(!isOpen), children: [
305
+ return /* @__PURE__ */ jsxs6("div", { className: "menu-item__line-height", onClick: () => optionsRef.current?.classList.toggle("visible"), children: [
300
306
  /* @__PURE__ */ jsx10("span", { className: "select", title: "Line Height", children: activeLabel }),
301
- /* @__PURE__ */ jsx10("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsx10("ul", { children: LINE_HEIGHTS.map((h) => /* @__PURE__ */ jsx10(
307
+ /* @__PURE__ */ jsx10("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsx10("ul", { children: LINE_HEIGHTS.map((h) => /* @__PURE__ */ jsx10(
302
308
  "li",
303
309
  {
304
310
  className: String(activeMargin) === h || activeLabel === h ? "active" : "",
@@ -311,7 +317,7 @@ function LineHeightTool() {
311
317
  }
312
318
 
313
319
  // src/toolbar/ColorTool.tsx
314
- import { useState as useState9 } from "react";
320
+ import { useRef as useRef7 } from "react";
315
321
  import { Baseline, RotateCcw } from "lucide-react";
316
322
  import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
317
323
  var COLOR_PALETTE = [
@@ -326,7 +332,7 @@ var COLOR_PALETTE = [
326
332
  ];
327
333
  function ColorTool() {
328
334
  const { editorRef, rangeStyle } = useEditor();
329
- const [visible, setVisible] = useState9(false);
335
+ const dropdownRef = useRef7(null);
330
336
  const activeColor = rangeStyle?.color || "#000000";
331
337
  const handleColor = (color) => {
332
338
  editorRef.current?.command.executeColor(color);
@@ -334,11 +340,11 @@ function ColorTool() {
334
340
  const handleReset = () => {
335
341
  editorRef.current?.command.executeColor(null);
336
342
  };
337
- return /* @__PURE__ */ jsxs7("div", { className: "menu-item__color", title: "Font Color", onClick: () => setVisible(!visible), children: [
343
+ return /* @__PURE__ */ jsxs7("div", { className: "menu-item__color", title: "Font Color", onClick: () => dropdownRef.current?.classList.toggle("visible"), children: [
338
344
  /* @__PURE__ */ jsx11(Baseline, { size: 16 }),
339
345
  /* @__PURE__ */ jsx11("span", { style: { backgroundColor: activeColor } }),
340
346
  /* @__PURE__ */ jsx11("input", { id: "color", type: "color", readOnly: true, tabIndex: -1 }),
341
- /* @__PURE__ */ jsx11("div", { className: "color-palette-dropdown" + (visible ? " visible" : ""), children: /* @__PURE__ */ jsxs7("div", { onClick: (e) => e.stopPropagation(), children: [
347
+ /* @__PURE__ */ jsx11("div", { className: "color-palette-dropdown", ref: dropdownRef, children: /* @__PURE__ */ jsxs7("div", { onClick: (e) => e.stopPropagation(), children: [
342
348
  /* @__PURE__ */ jsxs7("button", { className: "color-palette-reset", onClick: handleReset, children: [
343
349
  /* @__PURE__ */ jsx11(RotateCcw, { size: 12 }),
344
350
  "Reset"
@@ -358,7 +364,7 @@ function ColorTool() {
358
364
  }
359
365
 
360
366
  // src/toolbar/HighlightTool.tsx
361
- import { useState as useState10 } from "react";
367
+ import { useRef as useRef8 } from "react";
362
368
  import { Highlighter, RotateCcw as RotateCcw2 } from "lucide-react";
363
369
  import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
364
370
  var HIGHLIGHT_PALETTE = [
@@ -373,7 +379,7 @@ var HIGHLIGHT_PALETTE = [
373
379
  ];
374
380
  function HighlightTool() {
375
381
  const { editorRef, rangeStyle } = useEditor();
376
- const [visible, setVisible] = useState10(false);
382
+ const dropdownRef = useRef8(null);
377
383
  const activeColor = rangeStyle?.highlight || "";
378
384
  const handleColor = (color) => {
379
385
  editorRef.current?.command.executeHighlight(color);
@@ -381,11 +387,11 @@ function HighlightTool() {
381
387
  const handleReset = () => {
382
388
  editorRef.current?.command.executeHighlight(null);
383
389
  };
384
- return /* @__PURE__ */ jsxs8("div", { className: "menu-item__highlight", title: "Highlight", onClick: () => setVisible(!visible), children: [
390
+ return /* @__PURE__ */ jsxs8("div", { className: "menu-item__highlight", title: "Highlight", onClick: () => dropdownRef.current?.classList.toggle("visible"), children: [
385
391
  /* @__PURE__ */ jsx12(Highlighter, { size: 16 }),
386
392
  /* @__PURE__ */ jsx12("span", { style: { backgroundColor: activeColor || "#ffff00" } }),
387
393
  /* @__PURE__ */ jsx12("input", { id: "highlight", type: "color", readOnly: true, tabIndex: -1 }),
388
- /* @__PURE__ */ jsx12("div", { className: "color-palette-dropdown" + (visible ? " visible" : ""), children: /* @__PURE__ */ jsxs8("div", { onClick: (e) => e.stopPropagation(), children: [
394
+ /* @__PURE__ */ jsx12("div", { className: "color-palette-dropdown", ref: dropdownRef, children: /* @__PURE__ */ jsxs8("div", { onClick: (e) => e.stopPropagation(), children: [
389
395
  /* @__PURE__ */ jsxs8("button", { className: "color-palette-reset", onClick: handleReset, children: [
390
396
  /* @__PURE__ */ jsx12(RotateCcw2, { size: 12 }),
391
397
  "None"
@@ -423,18 +429,18 @@ function ItalicTool() {
423
429
  }
424
430
 
425
431
  // src/toolbar/UnderlineTool.tsx
426
- import { useState as useState11 } from "react";
432
+ import { useRef as useRef9 } from "react";
427
433
  import { Underline as UnderlineIcon } from "lucide-react";
428
434
  import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
429
435
  var STYLES = ["solid", "double", "dashed", "dotted", "wavy"];
430
436
  function UnderlineTool() {
431
437
  const { editorRef, isApple, rangeStyle } = useEditor();
432
- const [isOpen, setIsOpen] = useState11(false);
438
+ const optionsRef = useRef9(null);
433
439
  const isActive = rangeStyle?.underline === true;
434
440
  return /* @__PURE__ */ jsxs9("div", { className: `menu-item__underline ${isActive ? "active" : ""}`, title: `Underline(${isApple ? "\u2318" : "Ctrl"}+U)`, children: [
435
441
  /* @__PURE__ */ jsx15(UnderlineIcon, { size: 16, onClick: () => editorRef.current?.command.executeUnderline(), style: { cursor: "pointer" } }),
436
- /* @__PURE__ */ jsx15("span", { className: "select", onClick: () => setIsOpen(!isOpen) }),
437
- /* @__PURE__ */ jsx15("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsx15("ul", { children: STYLES.map((style) => /* @__PURE__ */ jsx15("li", { "data-decoration-style": style, onClick: () => {
442
+ /* @__PURE__ */ jsx15("span", { className: "select", onClick: () => optionsRef.current?.classList.toggle("visible") }),
443
+ /* @__PURE__ */ jsx15("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsx15("ul", { children: STYLES.map((style) => /* @__PURE__ */ jsx15("li", { "data-decoration-style": style, onClick: () => {
438
444
  editorRef.current?.command.executeUnderline({ style });
439
445
  }, children: /* @__PURE__ */ jsx15("i", {}) }, style)) }) })
440
446
  ] });
@@ -486,7 +492,7 @@ function JustifyTool() {
486
492
  }
487
493
 
488
494
  // src/toolbar/ListTool.tsx
489
- import { useState as useState12 } from "react";
495
+ import { useRef as useRef10 } from "react";
490
496
  import { List, ListOrdered, Indent, Outdent } from "lucide-react";
491
497
  import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
492
498
  var OL_PRESETS = [
@@ -521,7 +527,7 @@ function PresetCell({ option, onClick }) {
521
527
  }
522
528
  function ListTool() {
523
529
  const { editorRef, isApple, rangeStyle } = useEditor();
524
- const [isOpen, setIsOpen] = useState12(false);
530
+ const optionsRef = useRef10(null);
525
531
  const isActive = !!rangeStyle?.listType;
526
532
  const handleList = (type, style) => {
527
533
  editorRef.current?.command.executeList(type, style);
@@ -539,8 +545,8 @@ function ListTool() {
539
545
  editorRef.current?.command.executeListOutdent();
540
546
  };
541
547
  return /* @__PURE__ */ jsxs10("div", { className: `menu-item__list ${isActive ? "active" : ""}`, title: `List(${isApple ? "\u2318" : "Ctrl"}+Shift+U)`, children: [
542
- /* @__PURE__ */ jsx21(List, { size: 16, onClick: () => setIsOpen(!isOpen), style: { cursor: "pointer" } }),
543
- /* @__PURE__ */ jsx21("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsxs10("div", { style: { padding: "8px", width: "320px" }, children: [
548
+ /* @__PURE__ */ jsx21(List, { size: 16, onClick: () => optionsRef.current?.classList.toggle("visible"), style: { cursor: "pointer" } }),
549
+ /* @__PURE__ */ jsx21("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsxs10("div", { style: { padding: "8px", width: "320px" }, children: [
544
550
  /* @__PURE__ */ jsxs10("div", { style: { display: "flex", gap: "4px", marginBottom: "8px" }, children: [
545
551
  /* @__PURE__ */ jsx21(
546
552
  "button",
@@ -615,7 +621,7 @@ function ImageTool() {
615
621
  }
616
622
 
617
623
  // src/toolbar/SeparatorTool.tsx
618
- import { useState as useState13 } from "react";
624
+ import { useRef as useRef11, useState as useState5 } from "react";
619
625
  import { Minus } from "lucide-react";
620
626
  import { jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
621
627
  var DASH_STYLES = [
@@ -631,15 +637,15 @@ var LINE_WIDTHS = [
631
637
  ];
632
638
  function SeparatorTool() {
633
639
  const { editorRef } = useEditor();
634
- const [isOpen, setIsOpen] = useState13(false);
635
- const [selectedWidth, setSelectedWidth] = useState13(1);
640
+ const optionsRef = useRef11(null);
641
+ const [selectedWidth, setSelectedWidth] = useState5(1);
636
642
  const lineColor = "#344054";
637
643
  const handleSeparator = (dashArray) => {
638
644
  editorRef.current?.command.executeSeparator(dashArray, { lineWidth: selectedWidth });
639
645
  };
640
646
  return /* @__PURE__ */ jsxs12("div", { className: "menu-item__separator", title: "Separator", children: [
641
- /* @__PURE__ */ jsx23(Minus, { size: 16, onClick: () => setIsOpen(!isOpen), style: { cursor: "pointer" } }),
642
- /* @__PURE__ */ jsx23("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsxs12("div", { style: { padding: "8px 10px 10px", width: "200px" }, children: [
647
+ /* @__PURE__ */ jsx23(Minus, { size: 16, onClick: () => optionsRef.current?.classList.toggle("visible"), style: { cursor: "pointer" } }),
648
+ /* @__PURE__ */ jsx23("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsxs12("div", { style: { padding: "8px 10px 10px", width: "200px" }, children: [
643
649
  /* @__PURE__ */ jsx23("ul", { style: { margin: 0, padding: 0, listStyle: "none" }, children: DASH_STYLES.map(({ label, dashArray }) => /* @__PURE__ */ jsxs12(
644
650
  "li",
645
651
  {
@@ -693,11 +699,11 @@ function SeparatorTool() {
693
699
  }
694
700
 
695
701
  // src/toolbar/WatermarkTool.tsx
696
- import { useState as useState14 } from "react";
702
+ import { useRef as useRef12 } from "react";
697
703
  import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
698
704
  function InsertElementTool() {
699
705
  const { editorRef } = useEditor();
700
- const [isOpen, setIsOpen] = useState14(false);
706
+ const optionsRef = useRef12(null);
701
707
  const handleHeader = () => {
702
708
  if (!editorRef.current) return;
703
709
  const options = editorRef.current.command.getOptions();
@@ -707,18 +713,18 @@ function InsertElementTool() {
707
713
  }
708
714
  editorRef.current.command.executeSetZone("header");
709
715
  };
710
- return /* @__PURE__ */ jsxs13("div", { className: "menu-item__insert-element", onClick: () => setIsOpen(!isOpen), children: [
716
+ return /* @__PURE__ */ jsxs13("div", { className: "menu-item__insert-element", onClick: () => optionsRef.current?.classList.toggle("visible"), children: [
711
717
  /* @__PURE__ */ jsx24("i", { title: "Insert Element" }),
712
- /* @__PURE__ */ jsx24("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsx24("ul", { children: /* @__PURE__ */ jsx24("li", { onClick: handleHeader, children: "Add Header" }) }) })
718
+ /* @__PURE__ */ jsx24("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsx24("ul", { children: /* @__PURE__ */ jsx24("li", { onClick: handleHeader, children: "Add Header" }) }) })
713
719
  ] });
714
720
  }
715
721
 
716
722
  // src/toolbar/PageBreakTool.tsx
717
- import { useState as useState15 } from "react";
723
+ import { useRef as useRef13 } from "react";
718
724
  import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
719
725
  function PageBreakTool() {
720
726
  const { editorRef } = useEditor();
721
- const [isOpen, setIsOpen] = useState15(false);
727
+ const optionsRef = useRef13(null);
722
728
  const handlePageBreak = () => {
723
729
  editorRef.current?.command.executePageBreak();
724
730
  };
@@ -729,10 +735,10 @@ function PageBreakTool() {
729
735
  "div",
730
736
  {
731
737
  className: "menu-item__page-break",
732
- onClick: () => setIsOpen(!isOpen),
738
+ onClick: () => optionsRef.current?.classList.toggle("visible"),
733
739
  children: [
734
740
  /* @__PURE__ */ jsx25("i", { title: "Break" }),
735
- /* @__PURE__ */ jsx25("div", { className: "options" + (isOpen ? " visible" : ""), children: /* @__PURE__ */ jsxs14("ul", { children: [
741
+ /* @__PURE__ */ jsx25("div", { className: "options", ref: optionsRef, children: /* @__PURE__ */ jsxs14("ul", { children: [
736
742
  /* @__PURE__ */ jsx25("li", { onClick: handlePageBreak, children: "Page Break" }),
737
743
  /* @__PURE__ */ jsx25("li", { onClick: handleColumnBreak, children: "Column Break" })
738
744
  ] }) })
@@ -797,11 +803,11 @@ function CatalogToggleTool() {
797
803
  }
798
804
 
799
805
  // src/footer/PageModeTool.tsx
800
- import { useState as useState16 } from "react";
806
+ import { useState as useState6 } from "react";
801
807
  import { jsx as jsx28, jsxs as jsxs16 } from "react/jsx-runtime";
802
808
  function PageModeTool() {
803
809
  const { editorRef } = useEditor();
804
- const [visible, setVisible] = useState16(false);
810
+ const [visible, setVisible] = useState6(false);
805
811
  const handlePageMode = (mode) => {
806
812
  editorRef.current?.command.executePageMode(mode);
807
813
  setVisible(false);
@@ -850,7 +856,7 @@ function FooterStatus() {
850
856
  }
851
857
 
852
858
  // src/footer/EditorModeTool.tsx
853
- import { useState as useState17, useRef as useRef2 } from "react";
859
+ import { useState as useState7, useRef as useRef14 } from "react";
854
860
  import { jsx as jsx30 } from "react/jsx-runtime";
855
861
  var MODE_LIST = [
856
862
  { mode: "edit", name: "Edit Mode" },
@@ -863,8 +869,8 @@ var MODE_LIST = [
863
869
  ];
864
870
  function EditorModeTool() {
865
871
  const { editorRef } = useEditor();
866
- const [editorMode, setEditorMode] = useState17("Edit Mode");
867
- const modeIndexRef = useRef2(0);
872
+ const [editorMode, setEditorMode] = useState7("Edit Mode");
873
+ const modeIndexRef = useRef14(0);
868
874
  const handleModeChange = () => {
869
875
  modeIndexRef.current = modeIndexRef.current === MODE_LIST.length - 1 ? 0 : modeIndexRef.current + 1;
870
876
  const { name, mode } = MODE_LIST[modeIndexRef.current];
@@ -910,7 +916,7 @@ function PageScaleAddTool() {
910
916
  }
911
917
 
912
918
  // src/footer/PaperSizeTool.tsx
913
- import { useState as useState18 } from "react";
919
+ import { useState as useState8 } from "react";
914
920
  import { jsx as jsx33, jsxs as jsxs19 } from "react/jsx-runtime";
915
921
  var SIZES2 = [
916
922
  { label: "A4", width: 794, height: 1123, active: true },
@@ -920,7 +926,7 @@ var SIZES2 = [
920
926
  ];
921
927
  function PaperSizeTool() {
922
928
  const { editorRef } = useEditor();
923
- const [visible, setVisible] = useState18(false);
929
+ const [visible, setVisible] = useState8(false);
924
930
  const handlePaperSize = (width, height) => {
925
931
  editorRef.current?.command.executePaperSize(width, height);
926
932
  setVisible(false);
@@ -932,11 +938,11 @@ function PaperSizeTool() {
932
938
  }
933
939
 
934
940
  // src/footer/PaperDirectionTool.tsx
935
- import { useState as useState19 } from "react";
941
+ import { useState as useState9 } from "react";
936
942
  import { jsx as jsx34, jsxs as jsxs20 } from "react/jsx-runtime";
937
943
  function PaperDirectionTool() {
938
944
  const { editorRef } = useEditor();
939
- const [visible, setVisible] = useState19(false);
945
+ const [visible, setVisible] = useState9(false);
940
946
  const handlePaperDirection = (direction) => {
941
947
  editorRef.current?.command.executePaperDirection(direction);
942
948
  setVisible(false);
@@ -951,6 +957,7 @@ function PaperDirectionTool() {
951
957
  }
952
958
 
953
959
  // src/footer/PaperMarginTool.tsx
960
+ import { pxToCm, cmToPx } from "@windoc/core";
954
961
  import { jsx as jsx35 } from "react/jsx-runtime";
955
962
  function PaperMarginTool() {
956
963
  const { editorRef } = useEditor();
@@ -961,10 +968,10 @@ function PaperMarginTool() {
961
968
  new Dialog({
962
969
  title: "Page Margins",
963
970
  data: [
964
- { type: "text", label: "Top Margin", name: "top", required: true, value: `${topMargin}`, placeholder: "Please enter top margin" },
965
- { type: "text", label: "Bottom Margin", name: "bottom", required: true, value: `${bottomMargin}`, placeholder: "Please enter bottom margin" },
966
- { type: "text", label: "Left Margin", name: "left", required: true, value: `${leftMargin}`, placeholder: "Please enter left margin" },
967
- { type: "text", label: "Right Margin", name: "right", required: true, value: `${rightMargin}`, placeholder: "Please enter right margin" }
971
+ { type: "text", label: "Top Margin (cm)", name: "top", required: true, value: `${pxToCm(topMargin)}`, placeholder: "e.g. 2.54" },
972
+ { type: "text", label: "Bottom Margin (cm)", name: "bottom", required: true, value: `${pxToCm(bottomMargin)}`, placeholder: "e.g. 2.54" },
973
+ { type: "text", label: "Left Margin (cm)", name: "left", required: true, value: `${pxToCm(leftMargin)}`, placeholder: "e.g. 2.54" },
974
+ { type: "text", label: "Right Margin (cm)", name: "right", required: true, value: `${pxToCm(rightMargin)}`, placeholder: "e.g. 2.54" }
968
975
  ],
969
976
  onConfirm: (payload) => {
970
977
  const top = payload.find((p) => p.name === "top")?.value;
@@ -976,10 +983,10 @@ function PaperMarginTool() {
976
983
  const right = payload.find((p) => p.name === "right")?.value;
977
984
  if (!right) return;
978
985
  editorRef.current?.command.executeSetPaperMargin([
979
- Number(top),
980
- Number(right),
981
- Number(bottom),
982
- Number(left)
986
+ cmToPx(Number(top)),
987
+ cmToPx(Number(right)),
988
+ cmToPx(Number(bottom)),
989
+ cmToPx(Number(left))
983
990
  ]);
984
991
  }
985
992
  });
@@ -1033,7 +1040,7 @@ function EditorOptionTool() {
1033
1040
  }
1034
1041
 
1035
1042
  // src/footer/WatermarkFooterTool.tsx
1036
- import { useState as useState20, useRef as useRef3, useEffect as useEffect3, useCallback } from "react";
1043
+ import { useState as useState10, useRef as useRef15, useEffect as useEffect3, useCallback } from "react";
1037
1044
  import { Fragment as Fragment3, jsx as jsx38, jsxs as jsxs21 } from "react/jsx-runtime";
1038
1045
  var COLOR_PALETTE2 = [
1039
1046
  ["#000000", "#434343", "#666666", "#999999", "#b7b7b7", "#cccccc"],
@@ -1046,20 +1053,20 @@ var FONTS2 = [
1046
1053
  ];
1047
1054
  function WatermarkFooterTool() {
1048
1055
  const { editorRef } = useEditor();
1049
- const [visible, setVisible] = useState20(false);
1050
- const [tab, setTab] = useState20("text");
1051
- const containerRef = useRef3(null);
1052
- const panelRef = useRef3(null);
1053
- const fileInputRef = useRef3(null);
1054
- const [text, setText] = useState20("WATERMARK");
1055
- const [font, setFont] = useState20("Arial");
1056
- const [color, setColor] = useState20("#AEB5C0");
1057
- const [opacity, setOpacity] = useState20(30);
1058
- const [rotation, setRotation] = useState20(-45);
1059
- const [inFront, setInFront] = useState20(false);
1060
- const [imageData, setImageData] = useState20("");
1061
- const [imgWidth, setImgWidth] = useState20(200);
1062
- const [imgHeight, setImgHeight] = useState20(200);
1056
+ const [visible, setVisible] = useState10(false);
1057
+ const [tab, setTab] = useState10("text");
1058
+ const containerRef = useRef15(null);
1059
+ const panelRef = useRef15(null);
1060
+ const fileInputRef = useRef15(null);
1061
+ const [text, setText] = useState10("WATERMARK");
1062
+ const [font, setFont] = useState10("Arial");
1063
+ const [color, setColor] = useState10("#AEB5C0");
1064
+ const [opacity, setOpacity] = useState10(30);
1065
+ const [rotation, setRotation] = useState10(-45);
1066
+ const [inFront, setInFront] = useState10(false);
1067
+ const [imageData, setImageData] = useState10("");
1068
+ const [imgWidth, setImgWidth] = useState10(200);
1069
+ const [imgHeight, setImgHeight] = useState10(200);
1063
1070
  useEffect3(() => {
1064
1071
  if (!visible) return;
1065
1072
  const handler = (e) => {
@@ -1142,85 +1149,95 @@ function WatermarkFooterTool() {
1142
1149
  };
1143
1150
  return /* @__PURE__ */ jsxs21("div", { className: "watermark-footer", ref: containerRef, onClick: () => setVisible(!visible), children: [
1144
1151
  /* @__PURE__ */ jsx38("i", { title: "Watermark" }),
1145
- visible && /* @__PURE__ */ jsxs21("div", { className: "watermark-footer-panel", ref: panelRef, onClick: (e) => e.stopPropagation(), children: [
1146
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-tabs", children: [
1147
- /* @__PURE__ */ jsx38("button", { className: `wm-panel-tab ${tab === "text" ? "active" : ""}`, onClick: () => setTab("text"), children: "Text" }),
1148
- /* @__PURE__ */ jsx38("button", { className: `wm-panel-tab ${tab === "image" ? "active" : ""}`, onClick: () => setTab("image"), children: "Image" })
1149
- ] }),
1150
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-body", children: [
1151
- tab === "text" ? /* @__PURE__ */ jsxs21(Fragment3, { children: [
1152
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1153
- /* @__PURE__ */ jsx38("label", { children: "Text" }),
1154
- /* @__PURE__ */ jsx38("input", { type: "text", value: text, onChange: (e) => setText(e.target.value), placeholder: "Watermark text" })
1152
+ visible && /* @__PURE__ */ jsxs21(Fragment3, { children: [
1153
+ /* @__PURE__ */ jsx38("div", { className: "wm-panel-mask", onClick: (e) => {
1154
+ e.stopPropagation();
1155
+ setVisible(false);
1156
+ } }),
1157
+ /* @__PURE__ */ jsxs21("div", { className: "watermark-footer-panel", ref: panelRef, onClick: (e) => e.stopPropagation(), children: [
1158
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-title", children: [
1159
+ /* @__PURE__ */ jsx38("span", { children: "Watermark" }),
1160
+ /* @__PURE__ */ jsx38("i", { onClick: () => setVisible(false) })
1161
+ ] }),
1162
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-tabs", children: [
1163
+ /* @__PURE__ */ jsx38("button", { className: `wm-panel-tab ${tab === "text" ? "active" : ""}`, onClick: () => setTab("text"), children: "Text" }),
1164
+ /* @__PURE__ */ jsx38("button", { className: `wm-panel-tab ${tab === "image" ? "active" : ""}`, onClick: () => setTab("image"), children: "Image" })
1165
+ ] }),
1166
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-body", children: [
1167
+ tab === "text" ? /* @__PURE__ */ jsxs21(Fragment3, { children: [
1168
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1169
+ /* @__PURE__ */ jsx38("label", { children: "Text" }),
1170
+ /* @__PURE__ */ jsx38("input", { type: "text", value: text, onChange: (e) => setText(e.target.value), placeholder: "Watermark text" })
1171
+ ] }),
1172
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1173
+ /* @__PURE__ */ jsx38("label", { children: "Font" }),
1174
+ /* @__PURE__ */ jsx38("select", { value: font, onChange: (e) => setFont(e.target.value), children: FONTS2.map((f) => /* @__PURE__ */ jsx38("option", { value: f.family, children: f.label }, f.family)) })
1175
+ ] }),
1176
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1177
+ /* @__PURE__ */ jsx38("label", { children: "Color" }),
1178
+ /* @__PURE__ */ jsx38("div", { className: "wm-panel-colors", children: COLOR_PALETTE2.flat().map((c) => /* @__PURE__ */ jsx38(
1179
+ "div",
1180
+ {
1181
+ className: `wm-panel-color ${color.toLowerCase() === c.toLowerCase() ? "active" : ""}`,
1182
+ style: { backgroundColor: c },
1183
+ onClick: () => setColor(c)
1184
+ },
1185
+ c
1186
+ )) })
1187
+ ] })
1188
+ ] }) : /* @__PURE__ */ jsxs21(Fragment3, { children: [
1189
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1190
+ /* @__PURE__ */ jsx38("label", { children: "Image" }),
1191
+ /* @__PURE__ */ jsxs21("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
1192
+ /* @__PURE__ */ jsx38("button", { className: "wm-panel-upload", onClick: () => fileInputRef.current?.click(), children: "Choose File" }),
1193
+ /* @__PURE__ */ jsx38("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: handleFileUpload }),
1194
+ imageData && /* @__PURE__ */ jsx38("span", { style: { fontSize: "11px", color: "#667085" }, children: "Loaded" })
1195
+ ] })
1196
+ ] }),
1197
+ imageData && /* @__PURE__ */ jsx38("div", { className: "wm-panel-field", children: /* @__PURE__ */ jsx38("div", { className: "wm-panel-preview", children: /* @__PURE__ */ jsx38("img", { src: imageData, alt: "preview", style: { maxWidth: "100%", maxHeight: "48px", objectFit: "contain" } }) }) }),
1198
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field-row", children: [
1199
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field wm-panel-field-half", children: [
1200
+ /* @__PURE__ */ jsx38("label", { children: "W" }),
1201
+ /* @__PURE__ */ jsx38("input", { type: "number", value: imgWidth, min: 10, onChange: (e) => setImgWidth(Number(e.target.value)) })
1202
+ ] }),
1203
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field wm-panel-field-half", children: [
1204
+ /* @__PURE__ */ jsx38("label", { children: "H" }),
1205
+ /* @__PURE__ */ jsx38("input", { type: "number", value: imgHeight, min: 10, onChange: (e) => setImgHeight(Number(e.target.value)) })
1206
+ ] })
1207
+ ] })
1155
1208
  ] }),
1156
1209
  /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1157
- /* @__PURE__ */ jsx38("label", { children: "Font" }),
1158
- /* @__PURE__ */ jsx38("select", { value: font, onChange: (e) => setFont(e.target.value), children: FONTS2.map((f) => /* @__PURE__ */ jsx38("option", { value: f.family, children: f.label }, f.family)) })
1210
+ /* @__PURE__ */ jsxs21("label", { children: [
1211
+ "Opacity ",
1212
+ /* @__PURE__ */ jsxs21("span", { className: "wm-panel-value", children: [
1213
+ opacity,
1214
+ "%"
1215
+ ] })
1216
+ ] }),
1217
+ /* @__PURE__ */ jsx38("input", { type: "range", min: 0, max: 100, value: opacity, onChange: (e) => setOpacity(Number(e.target.value)), className: "wm-panel-slider" })
1159
1218
  ] }),
1160
1219
  /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1161
- /* @__PURE__ */ jsx38("label", { children: "Color" }),
1162
- /* @__PURE__ */ jsx38("div", { className: "wm-panel-colors", children: COLOR_PALETTE2.flat().map((c) => /* @__PURE__ */ jsx38(
1163
- "div",
1164
- {
1165
- className: `wm-panel-color ${color.toLowerCase() === c.toLowerCase() ? "active" : ""}`,
1166
- style: { backgroundColor: c },
1167
- onClick: () => setColor(c)
1168
- },
1169
- c
1170
- )) })
1171
- ] })
1172
- ] }) : /* @__PURE__ */ jsxs21(Fragment3, { children: [
1173
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1174
- /* @__PURE__ */ jsx38("label", { children: "Image" }),
1175
- /* @__PURE__ */ jsxs21("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
1176
- /* @__PURE__ */ jsx38("button", { className: "wm-panel-upload", onClick: () => fileInputRef.current?.click(), children: "Choose File" }),
1177
- /* @__PURE__ */ jsx38("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: handleFileUpload }),
1178
- imageData && /* @__PURE__ */ jsx38("span", { style: { fontSize: "11px", color: "#667085" }, children: "Loaded" })
1179
- ] })
1180
- ] }),
1181
- imageData && /* @__PURE__ */ jsx38("div", { className: "wm-panel-field", children: /* @__PURE__ */ jsx38("div", { className: "wm-panel-preview", children: /* @__PURE__ */ jsx38("img", { src: imageData, alt: "preview", style: { maxWidth: "100%", maxHeight: "48px", objectFit: "contain" } }) }) }),
1182
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field-row", children: [
1183
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field wm-panel-field-half", children: [
1184
- /* @__PURE__ */ jsx38("label", { children: "W" }),
1185
- /* @__PURE__ */ jsx38("input", { type: "number", value: imgWidth, min: 10, onChange: (e) => setImgWidth(Number(e.target.value)) })
1220
+ /* @__PURE__ */ jsxs21("label", { children: [
1221
+ "Rotation ",
1222
+ /* @__PURE__ */ jsxs21("span", { className: "wm-panel-value", children: [
1223
+ rotation,
1224
+ "\xB0"
1225
+ ] })
1186
1226
  ] }),
1187
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field wm-panel-field-half", children: [
1188
- /* @__PURE__ */ jsx38("label", { children: "H" }),
1189
- /* @__PURE__ */ jsx38("input", { type: "number", value: imgHeight, min: 10, onChange: (e) => setImgHeight(Number(e.target.value)) })
1190
- ] })
1191
- ] })
1192
- ] }),
1193
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1194
- /* @__PURE__ */ jsxs21("label", { children: [
1195
- "Opacity ",
1196
- /* @__PURE__ */ jsxs21("span", { className: "wm-panel-value", children: [
1197
- opacity,
1198
- "%"
1199
- ] })
1227
+ /* @__PURE__ */ jsx38("input", { type: "range", min: -90, max: 90, value: rotation, onChange: (e) => setRotation(Number(e.target.value)), className: "wm-panel-slider" })
1200
1228
  ] }),
1201
- /* @__PURE__ */ jsx38("input", { type: "range", min: 0, max: 100, value: opacity, onChange: (e) => setOpacity(Number(e.target.value)), className: "wm-panel-slider" })
1202
- ] }),
1203
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1204
- /* @__PURE__ */ jsxs21("label", { children: [
1205
- "Rotation ",
1206
- /* @__PURE__ */ jsxs21("span", { className: "wm-panel-value", children: [
1207
- rotation,
1208
- "\xB0"
1229
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1230
+ /* @__PURE__ */ jsx38("label", { children: "Position" }),
1231
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-toggle", children: [
1232
+ /* @__PURE__ */ jsx38("button", { className: !inFront ? "active" : "", onClick: () => setInFront(false), children: "Behind" }),
1233
+ /* @__PURE__ */ jsx38("button", { className: inFront ? "active" : "", onClick: () => setInFront(true), children: "In Front" })
1209
1234
  ] })
1210
- ] }),
1211
- /* @__PURE__ */ jsx38("input", { type: "range", min: -90, max: 90, value: rotation, onChange: (e) => setRotation(Number(e.target.value)), className: "wm-panel-slider" })
1212
- ] }),
1213
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1214
- /* @__PURE__ */ jsx38("label", { children: "Position" }),
1215
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-toggle", children: [
1216
- /* @__PURE__ */ jsx38("button", { className: !inFront ? "active" : "", onClick: () => setInFront(false), children: "Behind" }),
1217
- /* @__PURE__ */ jsx38("button", { className: inFront ? "active" : "", onClick: () => setInFront(true), children: "In Front" })
1218
1235
  ] })
1236
+ ] }),
1237
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-actions", children: [
1238
+ /* @__PURE__ */ jsx38("button", { className: "wm-panel-btn-delete", onClick: handleDelete, children: "Remove" }),
1239
+ /* @__PURE__ */ jsx38("button", { className: "wm-panel-btn-apply", onClick: handleApply, children: "Apply" })
1219
1240
  ] })
1220
- ] }),
1221
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-actions", children: [
1222
- /* @__PURE__ */ jsx38("button", { className: "wm-panel-btn-delete", onClick: handleDelete, children: "Remove" }),
1223
- /* @__PURE__ */ jsx38("button", { className: "wm-panel-btn-apply", onClick: handleApply, children: "Apply" })
1224
1241
  ] })
1225
1242
  ] })
1226
1243
  ] });
@@ -1298,9 +1315,9 @@ function EditorInner({
1298
1315
  style,
1299
1316
  onDrop: userOnDrop
1300
1317
  }) {
1301
- const containerRef = useRef4(null);
1302
- const editorRef = useRef4(null);
1303
- const [rangeStyle, setRangeStyle] = useState21(null);
1318
+ const containerRef = useRef16(null);
1319
+ const editorRef = useRef16(null);
1320
+ const [rangeStyle, setRangeStyle] = useState11(null);
1304
1321
  const {
1305
1322
  setPageNoList,
1306
1323
  setPageNo,
@@ -1423,7 +1440,9 @@ function EditorInner({
1423
1440
  ]);
1424
1441
  const closeDropdowns = (evt) => {
1425
1442
  const visibleDom = document.querySelector(".visible");
1426
- if (!visibleDom || visibleDom.contains(evt.target)) return;
1443
+ if (!visibleDom) return;
1444
+ const parent = visibleDom.parentElement;
1445
+ if (parent && parent.contains(evt.target)) return;
1427
1446
  visibleDom.classList.remove("visible");
1428
1447
  };
1429
1448
  window.addEventListener("click", closeDropdowns, { capture: true });