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