@stll/folio-react 0.6.0 → 0.7.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 (30) hide show
  1. package/dist/{CommentsSidebar-_utmEkA9.js → CommentsSidebar-B8X5a8JW.js} +126 -129
  2. package/dist/{FindReplaceDialog-DLdBekSR.js → FindReplaceDialog-Bx7QaFQ_.js} +23 -18
  3. package/dist/FootnotePropertiesDialog-2lmpg9m8.js +646 -0
  4. package/dist/ImagePositionDialog-D3MileYL.js +842 -0
  5. package/dist/ImagePropertiesDialog-CzK8HCaW.js +465 -0
  6. package/dist/InsertSymbolDialog-Df9dyLvn.js +376 -0
  7. package/dist/PageSetupDialog-PSs9YdPb.js +684 -0
  8. package/dist/TablePropertiesDialog-PQxKKM0Y.js +344 -0
  9. package/dist/{TextContextMenu-CG0V37wi.js → TextContextMenu-Ci7-M4oU.js} +199 -79
  10. package/dist/compat/eigenpal.d.ts +1 -1
  11. package/dist/compat/eigenpal.js +89 -17
  12. package/dist/dialogChrome-BoGYPgeu.js +26 -0
  13. package/dist/{dialogs-j7qyw17x.d.ts → dialogs-DK8OVUT_.d.ts} +13 -1
  14. package/dist/{dialogs-CzvXYJyG.js → dialogs-DsHnfN0g.js} +508 -316
  15. package/dist/dialogs.d.ts +2 -2
  16. package/dist/dialogs.js +9 -8
  17. package/dist/editor.css +1 -1
  18. package/dist/folio-ui-C-85DSuK.js +1011 -0
  19. package/dist/index.d.ts +5 -4
  20. package/dist/index.js +12 -11
  21. package/dist/{renderAsync-B7UJsZye.d.ts → renderAsync-ChQI9UJG.d.ts} +11 -3
  22. package/dist/{renderAsync-CwHTsxBN.js → renderAsync-evdyE_GW.js} +5593 -3256
  23. package/dist/standalone.css +1 -1
  24. package/package.json +8 -6
  25. package/dist/FootnotePropertiesDialog-CUjq9c6H.js +0 -267
  26. package/dist/ImagePositionDialog-BMuO9rLT.js +0 -395
  27. package/dist/ImagePropertiesDialog-C8iEgdmN.js +0 -198
  28. package/dist/PageSetupDialog-BKsSMCGb.js +0 -312
  29. package/dist/TablePropertiesDialog-Dw8gvL78.js +0 -159
  30. package/dist/useFindReplace-BPBpMWS9.js +0 -842
@@ -0,0 +1,1011 @@
1
+ import { c } from "react-compiler-runtime";
2
+ import { createContext, useContext, useMemo } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { Checkbox } from "@base-ui/react/checkbox";
5
+ import { Popover } from "@base-ui/react/popover";
6
+ import { Dialog } from "@base-ui/react/dialog";
7
+ import { Input } from "@base-ui/react/input";
8
+ import { Menu } from "@base-ui/react/menu";
9
+ import { Select } from "@base-ui/react/select";
10
+ //#region src/lib/utils.ts
11
+ /** Merge class names, filtering out falsy values. */
12
+ function cn(...inputs) {
13
+ return inputs.filter(Boolean).join(" ");
14
+ }
15
+ //#endregion
16
+ //#region src/ui/defaults/button.tsx
17
+ /**
18
+ * Built-in, dependency-free Button used when a consumer does not inject one.
19
+ *
20
+ * Renders a native, accessible `<button>` honoring the `FolioButtonProps`
21
+ * subset. The minimal default styling lives in `editor.css`
22
+ * (`.folio-default-button*` classes, keyed off folio's `--doc-*` variables with
23
+ * safe fallbacks) rather than inline styles, so a caller's `className` can
24
+ * override the defaults through the normal cascade. Consumers that want
25
+ * polished chrome inject their own design-system Button via `DocxEditor`'s
26
+ * `components` prop.
27
+ */
28
+ function DefaultButton({ variant = "default", size = "sm", className, children, ...props }) {
29
+ return /* @__PURE__ */ jsx("button", {
30
+ type: "button",
31
+ className: cn("folio-default-button", `folio-default-button--${variant}`, `folio-default-button--${size}`, className),
32
+ ...props,
33
+ children
34
+ });
35
+ }
36
+ //#endregion
37
+ //#region src/ui/defaults/checkbox.tsx
38
+ /**
39
+ * Built-in, dependency-light Checkbox used when a consumer does not inject one.
40
+ * Wraps `@base-ui/react`'s accessible Checkbox primitive with a minimal check
41
+ * indicator; consumers inject their own design-system Checkbox for full polish.
42
+ */
43
+ function DefaultCheckbox(t0) {
44
+ const $ = c(9);
45
+ let className;
46
+ let props;
47
+ if ($[0] !== t0) {
48
+ ({className, ...props} = t0);
49
+ $[0] = t0;
50
+ $[1] = className;
51
+ $[2] = props;
52
+ } else {
53
+ className = $[1];
54
+ props = $[2];
55
+ }
56
+ let t1;
57
+ if ($[3] !== className) {
58
+ t1 = cn("folio-default-checkbox", className);
59
+ $[3] = className;
60
+ $[4] = t1;
61
+ } else t1 = $[4];
62
+ let t2;
63
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
64
+ t2 = /* @__PURE__ */ jsx(Checkbox.Indicator, {
65
+ className: "folio-default-checkbox-indicator",
66
+ children: /* @__PURE__ */ jsx("svg", {
67
+ "aria-hidden": "true",
68
+ fill: "none",
69
+ height: "14",
70
+ stroke: "currentColor",
71
+ strokeLinecap: "round",
72
+ strokeLinejoin: "round",
73
+ strokeWidth: "3",
74
+ viewBox: "0 0 24 24",
75
+ width: "14",
76
+ xmlns: "http://www.w3.org/2000/svg",
77
+ children: /* @__PURE__ */ jsx("path", { d: "M5.252 12.7 10.2 18.63 18.748 5.37" })
78
+ })
79
+ });
80
+ $[5] = t2;
81
+ } else t2 = $[5];
82
+ let t3;
83
+ if ($[6] !== props || $[7] !== t1) {
84
+ t3 = /* @__PURE__ */ jsx(Checkbox.Root, {
85
+ className: t1,
86
+ ...props,
87
+ children: t2
88
+ });
89
+ $[6] = props;
90
+ $[7] = t1;
91
+ $[8] = t3;
92
+ } else t3 = $[8];
93
+ return t3;
94
+ }
95
+ //#endregion
96
+ //#region src/ui/defaults/color-picker.tsx
97
+ /**
98
+ * Built-in, dependency-light ColorPicker used when a consumer does not inject
99
+ * one. Wraps `@base-ui/react`'s Popover primitive (focus management,
100
+ * portalling, collision-aware positioning) and renders the `presets` as a row
101
+ * of swatch buttons plus a native `<input type="color">` for a custom color.
102
+ * `onSelect` emits a preset value or a 6-char uppercase hex (no `#`), matching
103
+ * the design-system ColorPicker contract. Consumers inject a polished picker
104
+ * via `DocxEditor`'s `components` prop.
105
+ */
106
+ const swatchColor = (preset) => preset.color ?? `#${preset.value}`;
107
+ const normalizeHex = (hex) => hex.replace(/^#/u, "").toUpperCase();
108
+ const EMPTY_PRESETS = [];
109
+ function DefaultColorPicker({ value, onSelect, onClear, presets = EMPTY_PRESETS, columns = 8, children }) {
110
+ const trigger = useMemo(() => /* @__PURE__ */ jsx("div", { className: "folio-default-color-picker-trigger" }), []);
111
+ return /* @__PURE__ */ jsxs(Popover.Root, { children: [/* @__PURE__ */ jsx(Popover.Trigger, {
112
+ nativeButton: false,
113
+ render: trigger,
114
+ children
115
+ }), /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, {
116
+ align: "start",
117
+ className: "folio-default-popover-positioner folio-root",
118
+ side: "bottom",
119
+ sideOffset: 4,
120
+ children: /* @__PURE__ */ jsxs(Popover.Popup, {
121
+ className: "folio-default-color-picker-popup",
122
+ children: [
123
+ onClear && /* @__PURE__ */ jsx(Popover.Close, {
124
+ className: "folio-default-color-picker-clear",
125
+ onClick: onClear,
126
+ children: "No color"
127
+ }),
128
+ /* @__PURE__ */ jsx("div", {
129
+ className: "folio-default-color-picker-swatches",
130
+ style: { gridTemplateColumns: `repeat(${columns}, 1fr)` },
131
+ children: presets.map((preset) => /* @__PURE__ */ jsx(ColorSwatch, {
132
+ onSelect,
133
+ preset,
134
+ selected: value === preset.value
135
+ }, preset.value))
136
+ }),
137
+ /* @__PURE__ */ jsxs("label", {
138
+ className: "folio-default-color-picker-custom",
139
+ children: ["Custom", /* @__PURE__ */ jsx("input", {
140
+ "aria-label": "Custom color",
141
+ onChange: (event) => onSelect?.(normalizeHex(event.target.value)),
142
+ type: "color",
143
+ value: value ? `#${normalizeHex(value)}` : "#000000"
144
+ })]
145
+ })
146
+ ]
147
+ })
148
+ }) })] });
149
+ }
150
+ function ColorSwatch(t0) {
151
+ const $ = c(14);
152
+ const { onSelect, preset, selected } = t0;
153
+ let t1;
154
+ if ($[0] !== onSelect || $[1] !== preset.value) {
155
+ t1 = () => onSelect?.(preset.value);
156
+ $[0] = onSelect;
157
+ $[1] = preset.value;
158
+ $[2] = t1;
159
+ } else t1 = $[2];
160
+ const handleClick = t1;
161
+ let t2;
162
+ if ($[3] !== preset) {
163
+ t2 = swatchColor(preset);
164
+ $[3] = preset;
165
+ $[4] = t2;
166
+ } else t2 = $[4];
167
+ let t3;
168
+ if ($[5] !== t2) {
169
+ t3 = { backgroundColor: t2 };
170
+ $[5] = t2;
171
+ $[6] = t3;
172
+ } else t3 = $[6];
173
+ const style = t3;
174
+ const t4 = preset.label;
175
+ const t5 = selected && "folio-default-color-picker-swatch--selected";
176
+ let t6;
177
+ if ($[7] !== t5) {
178
+ t6 = cn("folio-default-color-picker-swatch", t5);
179
+ $[7] = t5;
180
+ $[8] = t6;
181
+ } else t6 = $[8];
182
+ let t7;
183
+ if ($[9] !== handleClick || $[10] !== preset.label || $[11] !== style || $[12] !== t6) {
184
+ t7 = /* @__PURE__ */ jsx(Popover.Close, {
185
+ "aria-label": t4,
186
+ className: t6,
187
+ onClick: handleClick,
188
+ style,
189
+ title: preset.label
190
+ });
191
+ $[9] = handleClick;
192
+ $[10] = preset.label;
193
+ $[11] = style;
194
+ $[12] = t6;
195
+ $[13] = t7;
196
+ } else t7 = $[13];
197
+ return t7;
198
+ }
199
+ //#endregion
200
+ //#region src/ui/defaults/date-picker-popover.tsx
201
+ /**
202
+ * Built-in, dependency-light DatePickerPopover used when a consumer does not
203
+ * inject one. Renders a native `<input type="date">` whose value is an ISO
204
+ * `yyyy-mm-dd` string; `onChange` emits that string (or `null` when cleared),
205
+ * matching the design-system picker contract. Consumers inject a polished
206
+ * calendar via `DocxEditor`'s `components` prop.
207
+ */
208
+ const toISODate = (value) => {
209
+ if (value === null) return "";
210
+ if (value instanceof Date) return `${value.getFullYear().toString().padStart(4, "0")}-${(value.getMonth() + 1).toString().padStart(2, "0")}-${value.getDate().toString().padStart(2, "0")}`;
211
+ return value.length >= 10 ? value.slice(0, 10) : value;
212
+ };
213
+ function DefaultDatePickerPopover({ value, onChange, defaultOpen = false }) {
214
+ return /* @__PURE__ */ jsx("input", {
215
+ autoFocus: defaultOpen,
216
+ className: "folio-default-date-input",
217
+ onChange: (event) => onChange(event.target.value || null),
218
+ type: "date",
219
+ value: toISODate(value)
220
+ });
221
+ }
222
+ //#endregion
223
+ //#region src/ui/defaults/dialog.tsx
224
+ /**
225
+ * Built-in, dependency-light Dialog parts used when a consumer does not inject
226
+ * its own. Each part wraps the matching `@base-ui/react` primitive — the same
227
+ * accessible primitive the app design system wraps — with minimal styling.
228
+ * Folio's chrome positions the popup itself via `className`, so the default
229
+ * popup is a bare portalled surface (no viewport grid); consumers inject a
230
+ * polished Dialog through `DocxEditor`'s `components` prop.
231
+ */
232
+ function DefaultDialogRoot(props) {
233
+ const $ = c(2);
234
+ let t0;
235
+ if ($[0] !== props) {
236
+ t0 = /* @__PURE__ */ jsx(Dialog.Root, { ...props });
237
+ $[0] = props;
238
+ $[1] = t0;
239
+ } else t0 = $[1];
240
+ return t0;
241
+ }
242
+ function DefaultDialogPortal(t0) {
243
+ const $ = c(9);
244
+ let children;
245
+ let props;
246
+ if ($[0] !== t0) {
247
+ ({children, ...props} = t0);
248
+ $[0] = t0;
249
+ $[1] = children;
250
+ $[2] = props;
251
+ } else {
252
+ children = $[1];
253
+ props = $[2];
254
+ }
255
+ let t1;
256
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
257
+ t1 = { display: "contents" };
258
+ $[3] = t1;
259
+ } else t1 = $[3];
260
+ let t2;
261
+ if ($[4] !== children) {
262
+ t2 = /* @__PURE__ */ jsx("div", {
263
+ className: "folio-root",
264
+ style: t1,
265
+ children
266
+ });
267
+ $[4] = children;
268
+ $[5] = t2;
269
+ } else t2 = $[5];
270
+ let t3;
271
+ if ($[6] !== props || $[7] !== t2) {
272
+ t3 = /* @__PURE__ */ jsx(Dialog.Portal, {
273
+ ...props,
274
+ children: t2
275
+ });
276
+ $[6] = props;
277
+ $[7] = t2;
278
+ $[8] = t3;
279
+ } else t3 = $[8];
280
+ return t3;
281
+ }
282
+ function DefaultDialogBackdrop(t0) {
283
+ const $ = c(8);
284
+ let className;
285
+ let props;
286
+ if ($[0] !== t0) {
287
+ ({className, ...props} = t0);
288
+ $[0] = t0;
289
+ $[1] = className;
290
+ $[2] = props;
291
+ } else {
292
+ className = $[1];
293
+ props = $[2];
294
+ }
295
+ let t1;
296
+ if ($[3] !== className) {
297
+ t1 = cn("folio-default-dialog-backdrop", className);
298
+ $[3] = className;
299
+ $[4] = t1;
300
+ } else t1 = $[4];
301
+ let t2;
302
+ if ($[5] !== props || $[6] !== t1) {
303
+ t2 = /* @__PURE__ */ jsx(Dialog.Backdrop, {
304
+ className: t1,
305
+ ...props
306
+ });
307
+ $[5] = props;
308
+ $[6] = t1;
309
+ $[7] = t2;
310
+ } else t2 = $[7];
311
+ return t2;
312
+ }
313
+ function DefaultDialogPopup(t0) {
314
+ const $ = c(8);
315
+ let className;
316
+ let props;
317
+ if ($[0] !== t0) {
318
+ ({className, ...props} = t0);
319
+ $[0] = t0;
320
+ $[1] = className;
321
+ $[2] = props;
322
+ } else {
323
+ className = $[1];
324
+ props = $[2];
325
+ }
326
+ let t1;
327
+ if ($[3] !== className) {
328
+ t1 = cn("folio-default-dialog-popup", className);
329
+ $[3] = className;
330
+ $[4] = t1;
331
+ } else t1 = $[4];
332
+ let t2;
333
+ if ($[5] !== props || $[6] !== t1) {
334
+ t2 = /* @__PURE__ */ jsx(Dialog.Popup, {
335
+ className: t1,
336
+ ...props
337
+ });
338
+ $[5] = props;
339
+ $[6] = t1;
340
+ $[7] = t2;
341
+ } else t2 = $[7];
342
+ return t2;
343
+ }
344
+ function DefaultDialogTitle(t0) {
345
+ const $ = c(8);
346
+ let className;
347
+ let props;
348
+ if ($[0] !== t0) {
349
+ ({className, ...props} = t0);
350
+ $[0] = t0;
351
+ $[1] = className;
352
+ $[2] = props;
353
+ } else {
354
+ className = $[1];
355
+ props = $[2];
356
+ }
357
+ let t1;
358
+ if ($[3] !== className) {
359
+ t1 = cn("folio-default-dialog-title", className);
360
+ $[3] = className;
361
+ $[4] = t1;
362
+ } else t1 = $[4];
363
+ let t2;
364
+ if ($[5] !== props || $[6] !== t1) {
365
+ t2 = /* @__PURE__ */ jsx(Dialog.Title, {
366
+ className: t1,
367
+ ...props
368
+ });
369
+ $[5] = props;
370
+ $[6] = t1;
371
+ $[7] = t2;
372
+ } else t2 = $[7];
373
+ return t2;
374
+ }
375
+ function DefaultDialogClose(t0) {
376
+ const $ = c(8);
377
+ let className;
378
+ let props;
379
+ if ($[0] !== t0) {
380
+ ({className, ...props} = t0);
381
+ $[0] = t0;
382
+ $[1] = className;
383
+ $[2] = props;
384
+ } else {
385
+ className = $[1];
386
+ props = $[2];
387
+ }
388
+ let t1;
389
+ if ($[3] !== className) {
390
+ t1 = cn("folio-default-dialog-close", className);
391
+ $[3] = className;
392
+ $[4] = t1;
393
+ } else t1 = $[4];
394
+ let t2;
395
+ if ($[5] !== props || $[6] !== t1) {
396
+ t2 = /* @__PURE__ */ jsx(Dialog.Close, {
397
+ className: t1,
398
+ ...props
399
+ });
400
+ $[5] = props;
401
+ $[6] = t1;
402
+ $[7] = t2;
403
+ } else t2 = $[7];
404
+ return t2;
405
+ }
406
+ const DefaultDialog = {
407
+ Root: DefaultDialogRoot,
408
+ Portal: DefaultDialogPortal,
409
+ Backdrop: DefaultDialogBackdrop,
410
+ Popup: DefaultDialogPopup,
411
+ Title: DefaultDialogTitle,
412
+ Close: DefaultDialogClose
413
+ };
414
+ //#endregion
415
+ //#region src/ui/defaults/input.tsx
416
+ /**
417
+ * Built-in, dependency-light Input used when a consumer does not inject one.
418
+ *
419
+ * Wraps `@base-ui/react`'s Input primitive, honoring the `nativeInput` escape
420
+ * hatch (render a plain `<input>` when the caller needs uncontrolled native
421
+ * behavior) and folio's `size` shorthand. Styling is intentionally minimal;
422
+ * consumers inject their own design-system Input for full polish.
423
+ */
424
+ function DefaultInput({ className, size = "default", nativeInput = false, ...props }) {
425
+ const inputClassName = cn("folio-default-input", className);
426
+ const numericSize = typeof size === "number" ? size : void 0;
427
+ if (nativeInput) return /* @__PURE__ */ jsx("input", {
428
+ className: inputClassName,
429
+ "data-size": typeof size === "string" ? size : void 0,
430
+ size: numericSize,
431
+ ...props
432
+ });
433
+ return /* @__PURE__ */ jsx(Input, {
434
+ className: inputClassName,
435
+ "data-size": typeof size === "string" ? size : void 0,
436
+ size: numericSize,
437
+ ...props
438
+ });
439
+ }
440
+ //#endregion
441
+ //#region src/ui/defaults/menu.tsx
442
+ /**
443
+ * Built-in, dependency-light Menu parts used when a consumer does not inject
444
+ * its own. Each part wraps the matching `@base-ui/react` primitive (real
445
+ * keyboard navigation, portalling, collision-aware positioning) with minimal
446
+ * styling. Consumers inject a polished Menu via `DocxEditor`'s `components`
447
+ * prop.
448
+ */
449
+ function DefaultMenuRoot(props) {
450
+ const $ = c(2);
451
+ let t0;
452
+ if ($[0] !== props) {
453
+ t0 = /* @__PURE__ */ jsx(Menu.Root, { ...props });
454
+ $[0] = props;
455
+ $[1] = t0;
456
+ } else t0 = $[1];
457
+ return t0;
458
+ }
459
+ function DefaultMenuTrigger({ nativeButton = true, ...props }) {
460
+ return /* @__PURE__ */ jsx(Menu.Trigger, {
461
+ nativeButton,
462
+ ...props
463
+ });
464
+ }
465
+ function DefaultMenuPopup({ className, children, align = "center", side = "bottom", sideOffset = 4, alignOffset, ...props }) {
466
+ return /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
467
+ align,
468
+ alignOffset,
469
+ className: "folio-default-menu-positioner folio-root",
470
+ side,
471
+ sideOffset,
472
+ children: /* @__PURE__ */ jsx(Menu.Popup, {
473
+ className: cn("folio-default-menu-popup", className),
474
+ ...props,
475
+ children
476
+ })
477
+ }) });
478
+ }
479
+ function DefaultMenuItem(t0) {
480
+ const $ = c(8);
481
+ let className;
482
+ let props;
483
+ if ($[0] !== t0) {
484
+ ({className, ...props} = t0);
485
+ $[0] = t0;
486
+ $[1] = className;
487
+ $[2] = props;
488
+ } else {
489
+ className = $[1];
490
+ props = $[2];
491
+ }
492
+ let t1;
493
+ if ($[3] !== className) {
494
+ t1 = cn("folio-default-menu-item", className);
495
+ $[3] = className;
496
+ $[4] = t1;
497
+ } else t1 = $[4];
498
+ let t2;
499
+ if ($[5] !== props || $[6] !== t1) {
500
+ t2 = /* @__PURE__ */ jsx(Menu.Item, {
501
+ className: t1,
502
+ ...props
503
+ });
504
+ $[5] = props;
505
+ $[6] = t1;
506
+ $[7] = t2;
507
+ } else t2 = $[7];
508
+ return t2;
509
+ }
510
+ function DefaultMenuCheckboxItem(t0) {
511
+ const $ = c(13);
512
+ let children;
513
+ let className;
514
+ let props;
515
+ if ($[0] !== t0) {
516
+ ({className, children, ...props} = t0);
517
+ $[0] = t0;
518
+ $[1] = children;
519
+ $[2] = className;
520
+ $[3] = props;
521
+ } else {
522
+ children = $[1];
523
+ className = $[2];
524
+ props = $[3];
525
+ }
526
+ let t1;
527
+ if ($[4] !== className) {
528
+ t1 = cn("folio-default-menu-checkbox-item", className);
529
+ $[4] = className;
530
+ $[5] = t1;
531
+ } else t1 = $[5];
532
+ let t2;
533
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
534
+ t2 = /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, {
535
+ className: "folio-default-menu-checkbox-indicator",
536
+ children: /* @__PURE__ */ jsx("svg", {
537
+ "aria-hidden": "true",
538
+ fill: "none",
539
+ height: "14",
540
+ stroke: "currentColor",
541
+ strokeLinecap: "round",
542
+ strokeLinejoin: "round",
543
+ strokeWidth: "3",
544
+ viewBox: "0 0 24 24",
545
+ width: "14",
546
+ xmlns: "http://www.w3.org/2000/svg",
547
+ children: /* @__PURE__ */ jsx("path", { d: "M5.252 12.7 10.2 18.63 18.748 5.37" })
548
+ })
549
+ });
550
+ $[6] = t2;
551
+ } else t2 = $[6];
552
+ let t3;
553
+ if ($[7] !== children) {
554
+ t3 = /* @__PURE__ */ jsx("span", { children });
555
+ $[7] = children;
556
+ $[8] = t3;
557
+ } else t3 = $[8];
558
+ let t4;
559
+ if ($[9] !== props || $[10] !== t1 || $[11] !== t3) {
560
+ t4 = /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
561
+ className: t1,
562
+ ...props,
563
+ children: [t2, t3]
564
+ });
565
+ $[9] = props;
566
+ $[10] = t1;
567
+ $[11] = t3;
568
+ $[12] = t4;
569
+ } else t4 = $[12];
570
+ return t4;
571
+ }
572
+ function DefaultMenuGroup(props) {
573
+ const $ = c(2);
574
+ let t0;
575
+ if ($[0] !== props) {
576
+ t0 = /* @__PURE__ */ jsx(Menu.Group, { ...props });
577
+ $[0] = props;
578
+ $[1] = t0;
579
+ } else t0 = $[1];
580
+ return t0;
581
+ }
582
+ function DefaultMenuGroupLabel(t0) {
583
+ const $ = c(8);
584
+ let className;
585
+ let props;
586
+ if ($[0] !== t0) {
587
+ ({className, ...props} = t0);
588
+ $[0] = t0;
589
+ $[1] = className;
590
+ $[2] = props;
591
+ } else {
592
+ className = $[1];
593
+ props = $[2];
594
+ }
595
+ let t1;
596
+ if ($[3] !== className) {
597
+ t1 = cn("folio-default-menu-group-label", className);
598
+ $[3] = className;
599
+ $[4] = t1;
600
+ } else t1 = $[4];
601
+ let t2;
602
+ if ($[5] !== props || $[6] !== t1) {
603
+ t2 = /* @__PURE__ */ jsx(Menu.GroupLabel, {
604
+ className: t1,
605
+ ...props
606
+ });
607
+ $[5] = props;
608
+ $[6] = t1;
609
+ $[7] = t2;
610
+ } else t2 = $[7];
611
+ return t2;
612
+ }
613
+ function DefaultMenuSeparator(t0) {
614
+ const $ = c(8);
615
+ let className;
616
+ let props;
617
+ if ($[0] !== t0) {
618
+ ({className, ...props} = t0);
619
+ $[0] = t0;
620
+ $[1] = className;
621
+ $[2] = props;
622
+ } else {
623
+ className = $[1];
624
+ props = $[2];
625
+ }
626
+ let t1;
627
+ if ($[3] !== className) {
628
+ t1 = cn("folio-default-menu-separator", className);
629
+ $[3] = className;
630
+ $[4] = t1;
631
+ } else t1 = $[4];
632
+ let t2;
633
+ if ($[5] !== props || $[6] !== t1) {
634
+ t2 = /* @__PURE__ */ jsx(Menu.Separator, {
635
+ className: t1,
636
+ ...props
637
+ });
638
+ $[5] = props;
639
+ $[6] = t1;
640
+ $[7] = t2;
641
+ } else t2 = $[7];
642
+ return t2;
643
+ }
644
+ const DefaultMenu = {
645
+ Root: DefaultMenuRoot,
646
+ Trigger: DefaultMenuTrigger,
647
+ Popup: DefaultMenuPopup,
648
+ Item: DefaultMenuItem,
649
+ CheckboxItem: DefaultMenuCheckboxItem,
650
+ Group: DefaultMenuGroup,
651
+ GroupLabel: DefaultMenuGroupLabel,
652
+ Separator: DefaultMenuSeparator
653
+ };
654
+ //#endregion
655
+ //#region src/ui/defaults/outline-rail.tsx
656
+ /**
657
+ * Built-in, dependency-light OutlineRail used when a consumer does not inject
658
+ * one. Renders the outline as a plain semantic `<nav>` list of clickable
659
+ * entries indented by level; clicking an entry calls `onJump` with the resolved
660
+ * scroll container. Consumers inject the polished tick-rail + hover panel via
661
+ * `DocxEditor`'s `components` prop.
662
+ */
663
+ function DefaultOutlineRail({ items, scrollContainerRef, onJump, activeId, topOffset = 0, panelWidth = 300, ariaLabel = "Outline" }) {
664
+ if (items.length < 2) return null;
665
+ return /* @__PURE__ */ jsx("nav", {
666
+ "aria-label": ariaLabel,
667
+ className: "folio-default-outline-rail",
668
+ style: {
669
+ top: topOffset,
670
+ width: panelWidth
671
+ },
672
+ children: /* @__PURE__ */ jsx("ul", {
673
+ className: "folio-default-outline-list",
674
+ children: items.map((item) => {
675
+ const isActive = item.id === activeId;
676
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", {
677
+ "aria-current": isActive ? "true" : void 0,
678
+ className: cn("folio-default-outline-item", isActive && "folio-default-outline-item--active"),
679
+ onClick: () => {
680
+ const container = scrollContainerRef.current;
681
+ if (container) onJump(item.id, container);
682
+ },
683
+ style: { paddingInlineStart: `${item.level * 12 + 8}px` },
684
+ title: item.label,
685
+ type: "button",
686
+ children: item.label
687
+ }) }, item.id);
688
+ })
689
+ })
690
+ });
691
+ }
692
+ //#endregion
693
+ //#region src/ui/defaults/popover.tsx
694
+ /**
695
+ * Built-in, dependency-light Popover parts used when a consumer does not inject
696
+ * its own. Each part wraps the matching `@base-ui/react` primitive (real focus
697
+ * management, portalling, and collision-aware positioning) with minimal
698
+ * styling. Consumers inject a polished Popover via `DocxEditor`'s `components`
699
+ * prop.
700
+ */
701
+ function DefaultPopoverRoot(props) {
702
+ const $ = c(2);
703
+ let t0;
704
+ if ($[0] !== props) {
705
+ t0 = /* @__PURE__ */ jsx(Popover.Root, { ...props });
706
+ $[0] = props;
707
+ $[1] = t0;
708
+ } else t0 = $[1];
709
+ return t0;
710
+ }
711
+ function DefaultPopoverTrigger(props) {
712
+ const $ = c(2);
713
+ let t0;
714
+ if ($[0] !== props) {
715
+ t0 = /* @__PURE__ */ jsx(Popover.Trigger, { ...props });
716
+ $[0] = props;
717
+ $[1] = t0;
718
+ } else t0 = $[1];
719
+ return t0;
720
+ }
721
+ function DefaultPopoverPopup({ className, children, side = "bottom", align = "center", sideOffset = 4, alignOffset = 0, ...props }) {
722
+ return /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, {
723
+ align,
724
+ alignOffset,
725
+ className: "folio-default-popover-positioner folio-root",
726
+ side,
727
+ sideOffset,
728
+ children: /* @__PURE__ */ jsx(Popover.Popup, {
729
+ className: cn("folio-default-popover-popup", className),
730
+ ...props,
731
+ children
732
+ })
733
+ }) });
734
+ }
735
+ function DefaultPopoverClose(props) {
736
+ const $ = c(2);
737
+ let t0;
738
+ if ($[0] !== props) {
739
+ t0 = /* @__PURE__ */ jsx(Popover.Close, { ...props });
740
+ $[0] = props;
741
+ $[1] = t0;
742
+ } else t0 = $[1];
743
+ return t0;
744
+ }
745
+ const DefaultPopover = {
746
+ Root: DefaultPopoverRoot,
747
+ Trigger: DefaultPopoverTrigger,
748
+ Popup: DefaultPopoverPopup,
749
+ Close: DefaultPopoverClose
750
+ };
751
+ //#endregion
752
+ //#region src/ui/defaults/select.tsx
753
+ /**
754
+ * Built-in, dependency-light Select parts used when a consumer does not inject
755
+ * its own. Each part wraps the matching `@base-ui/react` primitive (real
756
+ * listbox semantics, keyboard navigation, portalled positioning) with minimal
757
+ * styling. The default popup omits the scroll arrows and item-aligned
758
+ * positioning of a fully styled design-system Select; consumers inject their
759
+ * own Select via `DocxEditor`'s `components` prop for that polish.
760
+ */
761
+ function DefaultSelectRoot(props) {
762
+ const $ = c(2);
763
+ let t0;
764
+ if ($[0] !== props) {
765
+ t0 = /* @__PURE__ */ jsx(Select.Root, { ...props });
766
+ $[0] = props;
767
+ $[1] = t0;
768
+ } else t0 = $[1];
769
+ return t0;
770
+ }
771
+ function DefaultSelectTrigger(t0) {
772
+ const $ = c(13);
773
+ let children;
774
+ let className;
775
+ let props;
776
+ let size;
777
+ if ($[0] !== t0) {
778
+ ({className, children, size, ...props} = t0);
779
+ $[0] = t0;
780
+ $[1] = children;
781
+ $[2] = className;
782
+ $[3] = props;
783
+ $[4] = size;
784
+ } else {
785
+ children = $[1];
786
+ className = $[2];
787
+ props = $[3];
788
+ size = $[4];
789
+ }
790
+ let t1;
791
+ if ($[5] !== className) {
792
+ t1 = cn("folio-default-select-trigger", className);
793
+ $[5] = className;
794
+ $[6] = t1;
795
+ } else t1 = $[6];
796
+ let t2;
797
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
798
+ t2 = /* @__PURE__ */ jsx(Select.Icon, {
799
+ className: "folio-default-select-icon",
800
+ children: /* @__PURE__ */ jsx("svg", {
801
+ "aria-hidden": "true",
802
+ fill: "none",
803
+ height: "16",
804
+ stroke: "currentColor",
805
+ strokeLinecap: "round",
806
+ strokeLinejoin: "round",
807
+ strokeWidth: "2",
808
+ viewBox: "0 0 24 24",
809
+ width: "16",
810
+ xmlns: "http://www.w3.org/2000/svg",
811
+ children: /* @__PURE__ */ jsx("path", { d: "m7 15 5 5 5-5M7 9l5-5 5 5" })
812
+ })
813
+ });
814
+ $[7] = t2;
815
+ } else t2 = $[7];
816
+ let t3;
817
+ if ($[8] !== children || $[9] !== props || $[10] !== size || $[11] !== t1) {
818
+ t3 = /* @__PURE__ */ jsxs(Select.Trigger, {
819
+ className: t1,
820
+ "data-size": size,
821
+ ...props,
822
+ children: [children, t2]
823
+ });
824
+ $[8] = children;
825
+ $[9] = props;
826
+ $[10] = size;
827
+ $[11] = t1;
828
+ $[12] = t3;
829
+ } else t3 = $[12];
830
+ return t3;
831
+ }
832
+ function DefaultSelectValue(t0) {
833
+ const $ = c(8);
834
+ let className;
835
+ let props;
836
+ if ($[0] !== t0) {
837
+ ({className, ...props} = t0);
838
+ $[0] = t0;
839
+ $[1] = className;
840
+ $[2] = props;
841
+ } else {
842
+ className = $[1];
843
+ props = $[2];
844
+ }
845
+ let t1;
846
+ if ($[3] !== className) {
847
+ t1 = cn("folio-default-select-value", className);
848
+ $[3] = className;
849
+ $[4] = t1;
850
+ } else t1 = $[4];
851
+ let t2;
852
+ if ($[5] !== props || $[6] !== t1) {
853
+ t2 = /* @__PURE__ */ jsx(Select.Value, {
854
+ className: t1,
855
+ ...props
856
+ });
857
+ $[5] = props;
858
+ $[6] = t1;
859
+ $[7] = t2;
860
+ } else t2 = $[7];
861
+ return t2;
862
+ }
863
+ function DefaultSelectPopup(t0) {
864
+ const $ = c(12);
865
+ let children;
866
+ let className;
867
+ let props;
868
+ if ($[0] !== t0) {
869
+ ({className, children, ...props} = t0);
870
+ $[0] = t0;
871
+ $[1] = children;
872
+ $[2] = className;
873
+ $[3] = props;
874
+ } else {
875
+ children = $[1];
876
+ className = $[2];
877
+ props = $[3];
878
+ }
879
+ let t1;
880
+ if ($[4] !== className) {
881
+ t1 = cn("folio-default-select-popup", className);
882
+ $[4] = className;
883
+ $[5] = t1;
884
+ } else t1 = $[5];
885
+ let t2;
886
+ if ($[6] !== children) {
887
+ t2 = /* @__PURE__ */ jsx(Select.List, { children });
888
+ $[6] = children;
889
+ $[7] = t2;
890
+ } else t2 = $[7];
891
+ let t3;
892
+ if ($[8] !== props || $[9] !== t1 || $[10] !== t2) {
893
+ t3 = /* @__PURE__ */ jsx(Select.Portal, { children: /* @__PURE__ */ jsx(Select.Positioner, {
894
+ align: "start",
895
+ className: "folio-default-select-positioner folio-root",
896
+ side: "bottom",
897
+ sideOffset: 4,
898
+ children: /* @__PURE__ */ jsx(Select.Popup, {
899
+ className: t1,
900
+ ...props,
901
+ children: t2
902
+ })
903
+ }) });
904
+ $[8] = props;
905
+ $[9] = t1;
906
+ $[10] = t2;
907
+ $[11] = t3;
908
+ } else t3 = $[11];
909
+ return t3;
910
+ }
911
+ function DefaultSelectItem(t0) {
912
+ const $ = c(12);
913
+ let children;
914
+ let className;
915
+ let props;
916
+ if ($[0] !== t0) {
917
+ ({className, children, ...props} = t0);
918
+ $[0] = t0;
919
+ $[1] = children;
920
+ $[2] = className;
921
+ $[3] = props;
922
+ } else {
923
+ children = $[1];
924
+ className = $[2];
925
+ props = $[3];
926
+ }
927
+ let t1;
928
+ if ($[4] !== className) {
929
+ t1 = cn("folio-default-select-item", className);
930
+ $[4] = className;
931
+ $[5] = t1;
932
+ } else t1 = $[5];
933
+ let t2;
934
+ if ($[6] !== children) {
935
+ t2 = /* @__PURE__ */ jsx(Select.ItemText, { children });
936
+ $[6] = children;
937
+ $[7] = t2;
938
+ } else t2 = $[7];
939
+ let t3;
940
+ if ($[8] !== props || $[9] !== t1 || $[10] !== t2) {
941
+ t3 = /* @__PURE__ */ jsx(Select.Item, {
942
+ className: t1,
943
+ ...props,
944
+ children: t2
945
+ });
946
+ $[8] = props;
947
+ $[9] = t1;
948
+ $[10] = t2;
949
+ $[11] = t3;
950
+ } else t3 = $[11];
951
+ return t3;
952
+ }
953
+ //#endregion
954
+ //#region src/ui/folio-ui.tsx
955
+ const DEFAULT_COMPONENTS = {
956
+ Button: DefaultButton,
957
+ Dialog: DefaultDialog,
958
+ Select: {
959
+ Root: DefaultSelectRoot,
960
+ Trigger: DefaultSelectTrigger,
961
+ Value: DefaultSelectValue,
962
+ Popup: DefaultSelectPopup,
963
+ Item: DefaultSelectItem
964
+ },
965
+ Menu: DefaultMenu,
966
+ Popover: DefaultPopover,
967
+ Input: DefaultInput,
968
+ Checkbox: DefaultCheckbox,
969
+ ColorPicker: DefaultColorPicker,
970
+ DatePickerPopover: DefaultDatePickerPopover,
971
+ OutlineRail: DefaultOutlineRail
972
+ };
973
+ const FolioUIContext = createContext(DEFAULT_COMPONENTS);
974
+ /**
975
+ * Merge a consumer's partial overrides over the built-in defaults: every key is
976
+ * present (defaults fill the gaps), and each provided override wins. Pure, so
977
+ * the resolution contract is unit-tested independently of React.
978
+ */
979
+ function resolveFolioComponents(components) {
980
+ return components ? {
981
+ ...DEFAULT_COMPONENTS,
982
+ ...components
983
+ } : DEFAULT_COMPONENTS;
984
+ }
985
+ function FolioUIProvider(t0) {
986
+ const $ = c(5);
987
+ const { components, children } = t0;
988
+ let t1;
989
+ if ($[0] !== components) {
990
+ t1 = resolveFolioComponents(components);
991
+ $[0] = components;
992
+ $[1] = t1;
993
+ } else t1 = $[1];
994
+ const value = t1;
995
+ let t2;
996
+ if ($[2] !== children || $[3] !== value) {
997
+ t2 = /* @__PURE__ */ jsx(FolioUIContext.Provider, {
998
+ value,
999
+ children
1000
+ });
1001
+ $[2] = children;
1002
+ $[3] = value;
1003
+ $[4] = t2;
1004
+ } else t2 = $[4];
1005
+ return t2;
1006
+ }
1007
+ function useFolioUI() {
1008
+ return useContext(FolioUIContext);
1009
+ }
1010
+ //#endregion
1011
+ export { cn as i, FolioUIProvider as n, useFolioUI as r, DEFAULT_COMPONENTS as t };