@doxi/react 0.11.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -0
  3. package/dist/DoxivaEditor.d.ts +20 -0
  4. package/dist/DoxivaEditor.d.ts.map +1 -0
  5. package/dist/DoxivaEditor.js +448 -0
  6. package/dist/DoxivaEditor.js.map +1 -0
  7. package/dist/Editor.d.ts +21 -0
  8. package/dist/Editor.d.ts.map +1 -0
  9. package/dist/Editor.js +49 -0
  10. package/dist/Editor.js.map +1 -0
  11. package/dist/HeaderFooterPopover.d.ts +49 -0
  12. package/dist/HeaderFooterPopover.d.ts.map +1 -0
  13. package/dist/HeaderFooterPopover.js +139 -0
  14. package/dist/HeaderFooterPopover.js.map +1 -0
  15. package/dist/ImagePopover.d.ts +23 -0
  16. package/dist/ImagePopover.d.ts.map +1 -0
  17. package/dist/ImagePopover.js +59 -0
  18. package/dist/ImagePopover.js.map +1 -0
  19. package/dist/LinkPopover.d.ts +25 -0
  20. package/dist/LinkPopover.d.ts.map +1 -0
  21. package/dist/LinkPopover.js +67 -0
  22. package/dist/LinkPopover.js.map +1 -0
  23. package/dist/PageSettingsPopover.d.ts +33 -0
  24. package/dist/PageSettingsPopover.d.ts.map +1 -0
  25. package/dist/PageSettingsPopover.js +48 -0
  26. package/dist/PageSettingsPopover.js.map +1 -0
  27. package/dist/TablePicker.d.ts +27 -0
  28. package/dist/TablePicker.d.ts.map +1 -0
  29. package/dist/TablePicker.js +38 -0
  30. package/dist/TablePicker.js.map +1 -0
  31. package/dist/Toolbar.d.ts +103 -0
  32. package/dist/Toolbar.d.ts.map +1 -0
  33. package/dist/Toolbar.js +161 -0
  34. package/dist/Toolbar.js.map +1 -0
  35. package/dist/index.d.ts +14 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +14 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/toolbar-builders/alignment.d.ts +4 -0
  40. package/dist/toolbar-builders/alignment.d.ts.map +1 -0
  41. package/dist/toolbar-builders/alignment.js +56 -0
  42. package/dist/toolbar-builders/alignment.js.map +1 -0
  43. package/dist/toolbar-builders/blocks.d.ts +4 -0
  44. package/dist/toolbar-builders/blocks.d.ts.map +1 -0
  45. package/dist/toolbar-builders/blocks.js +39 -0
  46. package/dist/toolbar-builders/blocks.js.map +1 -0
  47. package/dist/toolbar-builders/font-size.d.ts +4 -0
  48. package/dist/toolbar-builders/font-size.d.ts.map +1 -0
  49. package/dist/toolbar-builders/font-size.js +41 -0
  50. package/dist/toolbar-builders/font-size.js.map +1 -0
  51. package/dist/toolbar-builders/headings.d.ts +4 -0
  52. package/dist/toolbar-builders/headings.d.ts.map +1 -0
  53. package/dist/toolbar-builders/headings.js +18 -0
  54. package/dist/toolbar-builders/headings.js.map +1 -0
  55. package/dist/toolbar-builders/history.d.ts +3 -0
  56. package/dist/toolbar-builders/history.d.ts.map +1 -0
  57. package/dist/toolbar-builders/history.js +13 -0
  58. package/dist/toolbar-builders/history.js.map +1 -0
  59. package/dist/toolbar-builders/images.d.ts +4 -0
  60. package/dist/toolbar-builders/images.d.ts.map +1 -0
  61. package/dist/toolbar-builders/images.js +8 -0
  62. package/dist/toolbar-builders/images.js.map +1 -0
  63. package/dist/toolbar-builders/line-height.d.ts +4 -0
  64. package/dist/toolbar-builders/line-height.d.ts.map +1 -0
  65. package/dist/toolbar-builders/line-height.js +46 -0
  66. package/dist/toolbar-builders/line-height.js.map +1 -0
  67. package/dist/toolbar-builders/links.d.ts +4 -0
  68. package/dist/toolbar-builders/links.d.ts.map +1 -0
  69. package/dist/toolbar-builders/links.js +19 -0
  70. package/dist/toolbar-builders/links.js.map +1 -0
  71. package/dist/toolbar-builders/lists.d.ts +4 -0
  72. package/dist/toolbar-builders/lists.d.ts.map +1 -0
  73. package/dist/toolbar-builders/lists.js +38 -0
  74. package/dist/toolbar-builders/lists.js.map +1 -0
  75. package/dist/toolbar-builders/marks.d.ts +4 -0
  76. package/dist/toolbar-builders/marks.d.ts.map +1 -0
  77. package/dist/toolbar-builders/marks.js +41 -0
  78. package/dist/toolbar-builders/marks.js.map +1 -0
  79. package/dist/toolbar-builders/system.d.ts +12 -0
  80. package/dist/toolbar-builders/system.d.ts.map +1 -0
  81. package/dist/toolbar-builders/system.js +28 -0
  82. package/dist/toolbar-builders/system.js.map +1 -0
  83. package/dist/toolbar-builders/tables.d.ts +4 -0
  84. package/dist/toolbar-builders/tables.d.ts.map +1 -0
  85. package/dist/toolbar-builders/tables.js +235 -0
  86. package/dist/toolbar-builders/tables.js.map +1 -0
  87. package/dist/toolbar-builders/typography.d.ts +4 -0
  88. package/dist/toolbar-builders/typography.d.ts.map +1 -0
  89. package/dist/toolbar-builders/typography.js +123 -0
  90. package/dist/toolbar-builders/typography.js.map +1 -0
  91. package/dist/types.d.ts +85 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +28 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/useDoxivaEditor.d.ts +10 -0
  96. package/dist/useDoxivaEditor.d.ts.map +1 -0
  97. package/dist/useDoxivaEditor.js +30 -0
  98. package/dist/useDoxivaEditor.js.map +1 -0
  99. package/package.json +48 -0
package/dist/Editor.js ADDED
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { EditorView } from '@doxi/core';
3
+ import { useEffect, useRef } from 'react';
4
+ export function Editor(props) {
5
+ const mountRef = useRef(null);
6
+ const viewRef = useRef(null);
7
+ const editorRef = useRef(props.editor);
8
+ editorRef.current = props.editor;
9
+ const onMountRef = useRef(props.onMount);
10
+ onMountRef.current = props.onMount;
11
+ // Mount/unmount effect — runs once per component lifetime.
12
+ useEffect(() => {
13
+ const mount = mountRef.current;
14
+ if (!mount)
15
+ return;
16
+ const view = new EditorView(mount, {
17
+ state: editorRef.current.state,
18
+ renderer: props.renderer,
19
+ ...(props.editable !== undefined ? { editable: props.editable } : {}),
20
+ ...(props.paginated ? { paginated: props.paginated } : {}),
21
+ ...(props.ariaLabel !== undefined ? { ariaLabel: props.ariaLabel } : {}),
22
+ dispatchTransaction(tr) {
23
+ editorRef.current.dispatch(tr);
24
+ },
25
+ });
26
+ viewRef.current = view;
27
+ const cleanupFn = onMountRef.current ? onMountRef.current(view) : undefined;
28
+ return () => {
29
+ if (cleanupFn)
30
+ cleanupFn();
31
+ view.destroy();
32
+ viewRef.current = null;
33
+ };
34
+ // The view's renderer/editable/paginated are captured at mount. To change
35
+ // any of these, the host should remount the component (key prop).
36
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
+ }, []);
38
+ // updateState effect — runs when editor.state changes.
39
+ useEffect(() => {
40
+ const view = viewRef.current;
41
+ if (!view)
42
+ return;
43
+ if (view.state !== props.editor.state) {
44
+ view.updateState(props.editor.state);
45
+ }
46
+ }, [props.editor.state]);
47
+ return _jsx("div", { ref: mountRef, className: "dx-react-editor-mount" });
48
+ }
49
+ //# sourceMappingURL=Editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Editor.js","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAkC,MAAM,YAAY,CAAA;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAqBzC,MAAM,UAAU,MAAM,CAAC,KAAkB;IACvC,MAAM,QAAQ,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAA;IACpD,MAAM,OAAO,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACtC,SAAS,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAA;IAChC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACxC,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAA;IAElC,2DAA2D;IAC3D,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAA;QAC9B,IAAI,CAAC,KAAK;YAAE,OAAM;QAClB,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE;YACjC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK;YAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,mBAAmB,CAAC,EAAE;gBACpB,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YAChC,CAAC;SACF,CAAC,CAAA;QACF,OAAO,CAAC,OAAO,GAAG,IAAI,CAAA;QACtB,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC3E,OAAO,GAAG,EAAE;YACV,IAAI,SAAS;gBAAE,SAAS,EAAE,CAAA;YAC1B,IAAI,CAAC,OAAO,EAAE,CAAA;YACd,OAAO,CAAC,OAAO,GAAG,IAAI,CAAA;QACxB,CAAC,CAAA;QACD,0EAA0E;QAC1E,kEAAkE;QAClE,uDAAuD;IACzD,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,uDAAuD;IACvD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAA;QAC5B,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAExB,OAAO,cAAK,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAC,uBAAuB,GAAG,CAAA;AACjE,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { type EditorState, type Transaction } from '@doxi/core';
2
+ import { type JSX } from 'react';
3
+ /**
4
+ * Header/footer settings popover for the bundled `<DoxivaEditor>` (v0.11).
5
+ * Also exported as a standalone component for power users who roll their
6
+ * own toolbar via `<Toolbar>` + the popover `id` map.
7
+ *
8
+ * The popover lets the user:
9
+ * - Type plain text for the header and/or footer.
10
+ * - Toggle a "Page N of M" stamp that interleaves page_var atoms
11
+ * (kind='pageNumber' + kind='totalPages') with the user-typed text.
12
+ * - Enable/disable the header and footer slots entirely (CSS-only — hides
13
+ * the slot DOM via `.no-header` / `.no-footer` on `.app-editor-wrap`).
14
+ * - Set the slot min-height via host-side CSS custom properties
15
+ * (`--dx-header-height` / `--dx-footer-height`).
16
+ *
17
+ * Apply dispatches two SetPageMetaSteps in a single transaction so the
18
+ * header + footer text are committed atomically and the history can undo
19
+ * them as one entry.
20
+ *
21
+ * Chrome changes (enable / height) commit LIVE on every change — they are
22
+ * pure CSS, not part of the prosemirror document model, so there's no
23
+ * history entry to batch and the preview reflects edits immediately. Apply
24
+ * just closes the popover for the text path.
25
+ *
26
+ * KNOWN UX GAP (v0.10): The core LayoutEngine does not subtract the
27
+ * configured header/footer slot height from the page content area. Setting
28
+ * a height much larger than the default ~24 px will visually overlap the
29
+ * last lines of body content with the footer on long pages. Fixing it
30
+ * requires a core change to LayoutEngine.layout() — tracked for v0.11/v1.0.
31
+ */
32
+ /** Pure-CSS page chrome state owned by the host App and threaded through
33
+ * the popover. Not part of the prosemirror document. */
34
+ export interface PageChromeState {
35
+ readonly headerEnabled: boolean;
36
+ readonly footerEnabled: boolean;
37
+ readonly headerHeightPx: number;
38
+ readonly footerHeightPx: number;
39
+ }
40
+ export declare const DEFAULT_PAGE_CHROME: PageChromeState;
41
+ export interface HeaderFooterPopoverProps {
42
+ state: EditorState;
43
+ dispatch: (tr: Transaction) => void;
44
+ close: () => void;
45
+ chrome: PageChromeState;
46
+ onChromeChange: (next: PageChromeState) => void;
47
+ }
48
+ export declare function HeaderFooterPopover(props: HeaderFooterPopoverProps): JSX.Element;
49
+ //# sourceMappingURL=HeaderFooterPopover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeaderFooterPopover.d.ts","sourceRoot":"","sources":["../src/HeaderFooterPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACzG,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;yDACyD;AACzD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC;AAED,eAAO,MAAM,mBAAmB,EAAE,eAKjC,CAAA;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,WAAW,CAAA;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,MAAM,EAAE,eAAe,CAAA;IACvB,cAAc,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAA;CAChD;AAoFD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,CAqKhF"}
@@ -0,0 +1,139 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment, SetPageMetaStep, defaultSchema } from '@doxi/core';
3
+ import { useState } from 'react';
4
+ export const DEFAULT_PAGE_CHROME = {
5
+ headerEnabled: true,
6
+ footerEnabled: true,
7
+ headerHeightPx: 24,
8
+ footerHeightPx: 24,
9
+ };
10
+ /** Build a single-paragraph fragment from plain text (empty → Fragment.empty). */
11
+ function fragmentFromText(text) {
12
+ if (!text.trim())
13
+ return Fragment.empty;
14
+ return Fragment.from([
15
+ defaultSchema.node('paragraph', null, [defaultSchema.text(text)]),
16
+ ]);
17
+ }
18
+ /**
19
+ * Build a fragment of the shape "{userText} — Page {pageNumber} of {totalPages}"
20
+ * (when userText is non-empty) or "Page {pageNumber} of {totalPages}" (when
21
+ * userText is empty). Mirrors the exact node shape produced by
22
+ * __doxivaDebug.setHeaderWithPageNumber so the per-page substitution rendered
23
+ * by the page-slots view picks them up.
24
+ */
25
+ function fragmentWithPageNumbers(text) {
26
+ const prefix = text.trim();
27
+ const nodes = prefix
28
+ ? [
29
+ defaultSchema.text(prefix + ' — '),
30
+ defaultSchema.text('Page '),
31
+ defaultSchema.node('page_var', { kind: 'pageNumber' }),
32
+ defaultSchema.text(' of '),
33
+ defaultSchema.node('page_var', { kind: 'totalPages' }),
34
+ ]
35
+ : [
36
+ defaultSchema.text('Page '),
37
+ defaultSchema.node('page_var', { kind: 'pageNumber' }),
38
+ defaultSchema.text(' of '),
39
+ defaultSchema.node('page_var', { kind: 'totalPages' }),
40
+ ];
41
+ return Fragment.from([defaultSchema.node('paragraph', null, nodes)]);
42
+ }
43
+ /**
44
+ * Recover the plain-text portion from a header/footer fragment. Concatenates
45
+ * text nodes of the first paragraph; skips page_var atoms (those are
46
+ * controlled by the checkbox state). If the text ends with the " — " marker
47
+ * we use as a separator before "Page N of M", trim it off so re-opening the
48
+ * popover after an Apply doesn't accumulate extra " — " markers each round.
49
+ */
50
+ function textFromFragment(f) {
51
+ if (f.size === 0)
52
+ return '';
53
+ const first = f.children[0];
54
+ if (!first || !first.content)
55
+ return '';
56
+ let out = '';
57
+ for (let i = 0; i < first.content.childCount; i++) {
58
+ const c = first.content.child(i);
59
+ if (c.text)
60
+ out += c.text;
61
+ }
62
+ // Strip the trailing " — Page " bridge text (from a previous round-trip).
63
+ // If we leave it, applying twice grows the prefix unbounded.
64
+ if (out.endsWith(' — Page '))
65
+ out = out.slice(0, -' — Page '.length);
66
+ if (out.endsWith('Page '))
67
+ out = out.slice(0, -'Page '.length);
68
+ return out;
69
+ }
70
+ /** Does this fragment contain at least one page_var atom anywhere? */
71
+ function hasPageVar(f) {
72
+ if (f.size === 0)
73
+ return false;
74
+ for (let pi = 0; pi < f.childCount; pi++) {
75
+ const p = f.child(pi);
76
+ if (!p.content)
77
+ continue;
78
+ for (let i = 0; i < p.content.childCount; i++) {
79
+ if (p.content.child(i).type.name === 'page_var')
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+ /** Clamp a number-input value into the chrome height domain (0..400 px). */
86
+ function clampHeight(n) {
87
+ if (!Number.isFinite(n))
88
+ return 0;
89
+ if (n < 0)
90
+ return 0;
91
+ if (n > 400)
92
+ return 400;
93
+ return Math.round(n);
94
+ }
95
+ export function HeaderFooterPopover(props) {
96
+ const meta = props.state.pageMeta;
97
+ const [headerText, setHeaderText] = useState(textFromFragment(meta.header));
98
+ const [footerText, setFooterText] = useState(textFromFragment(meta.footer));
99
+ const [headerPageNum, setHeaderPageNum] = useState(hasPageVar(meta.header));
100
+ const [footerPageNum, setFooterPageNum] = useState(hasPageVar(meta.footer));
101
+ // Chrome state is owned by the host — read directly from props.chrome,
102
+ // commit changes live via props.onChromeChange. No local mirror.
103
+ const chrome = props.chrome;
104
+ const setHeaderEnabled = (v) => {
105
+ props.onChromeChange({ ...chrome, headerEnabled: v });
106
+ };
107
+ const setFooterEnabled = (v) => {
108
+ props.onChromeChange({ ...chrome, footerEnabled: v });
109
+ };
110
+ const setHeaderHeight = (v) => {
111
+ props.onChromeChange({ ...chrome, headerHeightPx: clampHeight(v) });
112
+ };
113
+ const setFooterHeight = (v) => {
114
+ props.onChromeChange({ ...chrome, footerHeightPx: clampHeight(v) });
115
+ };
116
+ const apply = () => {
117
+ const headerFrag = headerPageNum
118
+ ? fragmentWithPageNumbers(headerText)
119
+ : fragmentFromText(headerText);
120
+ const footerFrag = footerPageNum
121
+ ? fragmentWithPageNumbers(footerText)
122
+ : fragmentFromText(footerText);
123
+ // Both steps in a single transaction → atomic, one history entry.
124
+ const tr = props.state.tr
125
+ .step(new SetPageMetaStep('header', headerFrag))
126
+ .step(new SetPageMetaStep('footer', footerFrag));
127
+ props.dispatch(tr);
128
+ props.close();
129
+ };
130
+ const clear = () => {
131
+ const tr = props.state.tr
132
+ .step(new SetPageMetaStep('header', Fragment.empty))
133
+ .step(new SetPageMetaStep('footer', Fragment.empty));
134
+ props.dispatch(tr);
135
+ props.close();
136
+ };
137
+ return (_jsxs("div", { className: "dx-toolbar-popover dx-header-footer-popover", role: "dialog", "aria-label": "Header and footer settings", onMouseDown: (e) => e.stopPropagation(), children: [_jsxs("label", { children: ["Header:", _jsx("input", { type: "text", "data-testid": "header-text", value: headerText, placeholder: "Header text", onChange: (e) => setHeaderText(e.target.value) })] }), _jsxs("label", { className: "dx-header-footer-checkbox", children: [_jsx("input", { type: "checkbox", "data-testid": "header-pagenum", checked: headerPageNum, onChange: (e) => setHeaderPageNum(e.target.checked) }), "Show \"Page N of M\" in header"] }), _jsxs("fieldset", { className: "dx-header-footer-section", children: [_jsx("legend", { children: "Header" }), _jsxs("label", { className: "dx-header-footer-checkbox", children: [_jsx("input", { type: "checkbox", "data-testid": "header-enabled", checked: chrome.headerEnabled, onChange: (e) => setHeaderEnabled(e.target.checked) }), "Enabled"] }), _jsxs("label", { children: ["Height (px):", _jsx("input", { type: "number", "data-testid": "header-height", min: 0, max: 400, value: chrome.headerHeightPx, onChange: (e) => setHeaderHeight(Number(e.target.value)) })] })] }), _jsxs("label", { children: ["Footer:", _jsx("input", { type: "text", "data-testid": "footer-text", value: footerText, placeholder: "Footer text", onChange: (e) => setFooterText(e.target.value) })] }), _jsxs("label", { className: "dx-header-footer-checkbox", children: [_jsx("input", { type: "checkbox", "data-testid": "footer-pagenum", checked: footerPageNum, onChange: (e) => setFooterPageNum(e.target.checked) }), "Show \"Page N of M\" in footer"] }), _jsxs("fieldset", { className: "dx-header-footer-section", children: [_jsx("legend", { children: "Footer" }), _jsxs("label", { className: "dx-header-footer-checkbox", children: [_jsx("input", { type: "checkbox", "data-testid": "footer-enabled", checked: chrome.footerEnabled, onChange: (e) => setFooterEnabled(e.target.checked) }), "Enabled"] }), _jsxs("label", { children: ["Height (px):", _jsx("input", { type: "number", "data-testid": "footer-height", min: 0, max: 400, value: chrome.footerHeightPx, onChange: (e) => setFooterHeight(Number(e.target.value)) })] })] }), _jsxs("div", { className: "dx-header-footer-actions", children: [_jsx("button", { type: "button", "data-testid": "header-footer-apply", onMouseDown: (e) => e.preventDefault(), onClick: apply, children: "Apply" }), _jsx("button", { type: "button", "data-testid": "header-footer-clear", onMouseDown: (e) => e.preventDefault(), onClick: clear, children: "Clear" }), _jsx("button", { type: "button", "data-testid": "header-footer-cancel", onMouseDown: (e) => e.preventDefault(), onClick: props.close, children: "Cancel" })] })] }));
138
+ }
139
+ //# sourceMappingURL=HeaderFooterPopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeaderFooterPopover.js","sourceRoot":"","sources":["../src/HeaderFooterPopover.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type EditorState, type Transaction } from '@doxi/core';
2
+ import { type JSX } from 'react';
3
+ /**
4
+ * Insert-image popover. Rendered by the {@link Toolbar} when its `image`
5
+ * popover is open. Props supplied by the toolbar:
6
+ * - `state` — current editor state (used to read the schema).
7
+ * - `dispatch` — apply a transaction to the editor.
8
+ * - `close` — close the popover (called after apply / Escape).
9
+ *
10
+ * UX details:
11
+ * - The URL input autofocuses + selects-all on mount.
12
+ * - Enter (inside the URL input) applies; Escape closes.
13
+ * - Apply with an empty or whitespace-only URL is a no-op except
14
+ * that the popover closes. No error UI in v0.3d.
15
+ * - `onMouseDown` is stopped from propagating so clicking inside the
16
+ * popover doesn't trigger the toolbar's click-outside-to-close.
17
+ */
18
+ export declare function ImagePopover(props: {
19
+ state: EditorState;
20
+ dispatch: (tr: Transaction) => void;
21
+ close: () => void;
22
+ }): JSX.Element;
23
+ //# sourceMappingURL=ImagePopover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImagePopover.d.ts","sourceRoot":"","sources":["../src/ImagePopover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,EAA+B,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAE7D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,KAAK,EAAE,WAAW,CAAA;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB,GAAG,GAAG,CAAC,OAAO,CA0Ed"}
@@ -0,0 +1,59 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { insertImage } from '@doxi/core';
3
+ import { useEffect, useRef, useState } from 'react';
4
+ /**
5
+ * Insert-image popover. Rendered by the {@link Toolbar} when its `image`
6
+ * popover is open. Props supplied by the toolbar:
7
+ * - `state` — current editor state (used to read the schema).
8
+ * - `dispatch` — apply a transaction to the editor.
9
+ * - `close` — close the popover (called after apply / Escape).
10
+ *
11
+ * UX details:
12
+ * - The URL input autofocuses + selects-all on mount.
13
+ * - Enter (inside the URL input) applies; Escape closes.
14
+ * - Apply with an empty or whitespace-only URL is a no-op except
15
+ * that the popover closes. No error UI in v0.3d.
16
+ * - `onMouseDown` is stopped from propagating so clicking inside the
17
+ * popover doesn't trigger the toolbar's click-outside-to-close.
18
+ */
19
+ export function ImagePopover(props) {
20
+ const [src, setSrc] = useState('');
21
+ const [alt, setAlt] = useState('');
22
+ const srcRef = useRef(null);
23
+ useEffect(() => {
24
+ const el = srcRef.current;
25
+ if (!el)
26
+ return;
27
+ el.focus();
28
+ el.select();
29
+ }, []);
30
+ const apply = () => {
31
+ const trimmed = src.trim();
32
+ if (trimmed === '') {
33
+ props.close();
34
+ return;
35
+ }
36
+ insertImage(props.state.schema, { src: trimmed, alt })(props.state, props.dispatch);
37
+ props.close();
38
+ };
39
+ return (_jsxs("div", { className: "dx-toolbar-popover dx-toolbar-image-popover", role: "dialog", "aria-label": "Insert image", onMouseDown: (e) => e.stopPropagation(), children: [_jsx("input", { ref: srcRef, type: "url", "data-testid": "image-input-src", placeholder: "https://example.com/image.jpg", value: src, onChange: (e) => setSrc(e.target.value), onKeyDown: (e) => {
40
+ if (e.key === 'Enter') {
41
+ e.preventDefault();
42
+ apply();
43
+ }
44
+ else if (e.key === 'Escape') {
45
+ e.preventDefault();
46
+ props.close();
47
+ }
48
+ } }), _jsx("input", { type: "text", "data-testid": "image-input-alt", placeholder: "Alt text (optional)", value: alt, onChange: (e) => setAlt(e.target.value), onKeyDown: (e) => {
49
+ if (e.key === 'Enter') {
50
+ e.preventDefault();
51
+ apply();
52
+ }
53
+ else if (e.key === 'Escape') {
54
+ e.preventDefault();
55
+ props.close();
56
+ }
57
+ } }), _jsx("div", { className: "dx-toolbar-image-actions", children: _jsx("button", { type: "button", "data-testid": "image-apply", onMouseDown: (e) => e.preventDefault(), onClick: apply, children: "Apply" }) })] }));
58
+ }
59
+ //# sourceMappingURL=ImagePopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImagePopover.js","sourceRoot":"","sources":["../src/ImagePopover.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type EditorState, type Transaction } from '@doxi/core';
2
+ import { type JSX } from 'react';
3
+ /**
4
+ * The link editor popover. Rendered by the {@link Toolbar} when its `link`
5
+ * popover is open. Props supplied by the toolbar:
6
+ * - `state` — current editor state (used to read the existing link).
7
+ * - `dispatch` — apply a transaction to the editor.
8
+ * - `close` — close the popover (called after apply / remove / Escape).
9
+ *
10
+ * UX details:
11
+ * - The URL input autofocuses + selects-all on mount so the user can
12
+ * immediately type / paste.
13
+ * - Enter applies; Escape closes without changes.
14
+ * - Apply with an empty URL removes any existing link (so a user can
15
+ * clear an accidental link without hunting for the Remove button).
16
+ * - Remove only appears when the cursor is on an existing link.
17
+ * - `onMouseDown` is stopped from propagating so clicking inside the
18
+ * popover doesn't trigger the toolbar's click-outside-to-close.
19
+ */
20
+ export declare function LinkPopover(props: {
21
+ state: EditorState;
22
+ dispatch: (tr: Transaction) => void;
23
+ close: () => void;
24
+ }): JSX.Element;
25
+ //# sourceMappingURL=LinkPopover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkPopover.d.ts","sourceRoot":"","sources":["../src/LinkPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAC9F,OAAO,EAA+B,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAE7D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,KAAK,EAAE,WAAW,CAAA;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB,GAAG,GAAG,CAAC,OAAO,CAkFd"}
@@ -0,0 +1,67 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { getLinkAt, setLink, unsetLink } from '@doxi/core';
3
+ import { useEffect, useRef, useState } from 'react';
4
+ /**
5
+ * The link editor popover. Rendered by the {@link Toolbar} when its `link`
6
+ * popover is open. Props supplied by the toolbar:
7
+ * - `state` — current editor state (used to read the existing link).
8
+ * - `dispatch` — apply a transaction to the editor.
9
+ * - `close` — close the popover (called after apply / remove / Escape).
10
+ *
11
+ * UX details:
12
+ * - The URL input autofocuses + selects-all on mount so the user can
13
+ * immediately type / paste.
14
+ * - Enter applies; Escape closes without changes.
15
+ * - Apply with an empty URL removes any existing link (so a user can
16
+ * clear an accidental link without hunting for the Remove button).
17
+ * - Remove only appears when the cursor is on an existing link.
18
+ * - `onMouseDown` is stopped from propagating so clicking inside the
19
+ * popover doesn't trigger the toolbar's click-outside-to-close.
20
+ */
21
+ export function LinkPopover(props) {
22
+ const linkType = props.state.schema.marks.link;
23
+ const initial = linkType ? getLinkAt(props.state, linkType) : null;
24
+ const initialHref = initial ? String(initial.attrs.href ?? '') : '';
25
+ const [href, setHref] = useState(initialHref);
26
+ const inputRef = useRef(null);
27
+ useEffect(() => {
28
+ const el = inputRef.current;
29
+ if (!el)
30
+ return;
31
+ el.focus();
32
+ el.select();
33
+ }, []);
34
+ const apply = () => {
35
+ if (!linkType) {
36
+ props.close();
37
+ return;
38
+ }
39
+ const trimmed = href.trim();
40
+ if (trimmed === '') {
41
+ unsetLink(linkType)(props.state, props.dispatch);
42
+ props.close();
43
+ return;
44
+ }
45
+ setLink(linkType, { href: trimmed })(props.state, props.dispatch);
46
+ props.close();
47
+ };
48
+ const remove = () => {
49
+ if (!linkType) {
50
+ props.close();
51
+ return;
52
+ }
53
+ unsetLink(linkType)(props.state, props.dispatch);
54
+ props.close();
55
+ };
56
+ return (_jsxs("div", { className: "dx-toolbar-popover dx-toolbar-link-popover", role: "dialog", "aria-label": "Insert link", onMouseDown: (e) => e.stopPropagation(), children: [_jsx("input", { ref: inputRef, type: "url", "data-testid": "link-input", placeholder: "https://example.com", value: href, onChange: (e) => setHref(e.target.value), onKeyDown: (e) => {
57
+ if (e.key === 'Enter') {
58
+ e.preventDefault();
59
+ apply();
60
+ }
61
+ else if (e.key === 'Escape') {
62
+ e.preventDefault();
63
+ props.close();
64
+ }
65
+ } }), _jsx("button", { type: "button", "data-testid": "link-apply", onMouseDown: (e) => e.preventDefault(), onClick: apply, children: "Apply" }), initial && (_jsx("button", { type: "button", "data-testid": "link-remove", onMouseDown: (e) => e.preventDefault(), onClick: remove, children: "Remove" }))] }));
66
+ }
67
+ //# sourceMappingURL=LinkPopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkPopover.js","sourceRoot":"","sources":["../src/LinkPopover.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { EditorState, PageConfig, Transaction } from '@doxi/core';
2
+ import { type JSX } from 'react';
3
+ /**
4
+ * Page settings popover for the bundled `<DoxivaEditor>` (v0.11). Also
5
+ * exported as a standalone component for power users who roll their own
6
+ * toolbar via `<Toolbar>` + the popover `id` map.
7
+ *
8
+ * The popover lets the user pick from a small set of size + orientation +
9
+ * margin presets. Custom dimensions are deferred to v1.0.
10
+ */
11
+ export type PageSizeId = 'letter' | 'a4' | 'legal' | 'a5';
12
+ export type Orientation = 'portrait' | 'landscape';
13
+ export type MarginPreset = 'normal' | 'narrow' | 'wide';
14
+ export interface PageSettings {
15
+ readonly size: PageSizeId;
16
+ readonly orientation: Orientation;
17
+ readonly margins: MarginPreset;
18
+ }
19
+ export declare const DEFAULT_PAGE_SETTINGS: PageSettings;
20
+ /**
21
+ * Project the host-app's preset selection onto the PageConfig shape that
22
+ * @doxi/core's layout engine consumes.
23
+ */
24
+ export declare function pageConfigFromSettings(s: PageSettings): PageConfig;
25
+ export interface PageSettingsPopoverProps {
26
+ state: EditorState;
27
+ dispatch: (tr: Transaction) => void;
28
+ close: () => void;
29
+ current: PageSettings;
30
+ onChange: (next: PageSettings) => void;
31
+ }
32
+ export declare function PageSettingsPopover(props: PageSettingsPopoverProps): JSX.Element;
33
+ //# sourceMappingURL=PageSettingsPopover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageSettingsPopover.d.ts","sourceRoot":"","sources":["../src/PageSettingsPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACtE,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAE1C;;;;;;;GAOG;AAEH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAAA;AACzD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,WAAW,CAAA;AAClD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAC/B;AAqBD,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAA;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,YAAY,GAAG,UAAU,CAQlE;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,WAAW,CAAA;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,OAAO,EAAE,YAAY,CAAA;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;CACvC;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,CAyEhF"}
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ /**
4
+ * Concrete pixel dimensions per preset. Letter/A4 line up with what
5
+ * @doxi/core's resolveDimensions returns for its built-in named sizes, so
6
+ * the default ('letter' + 'portrait' + 'normal') is bit-for-bit identical to
7
+ * DEFAULT_PAGE_CONFIG.
8
+ */
9
+ const SIZE_PX = {
10
+ letter: { w: 816, h: 1056 },
11
+ a4: { w: 794, h: 1123 },
12
+ legal: { w: 816, h: 1344 },
13
+ a5: { w: 559, h: 794 },
14
+ };
15
+ const MARGIN_PX = {
16
+ normal: 96,
17
+ narrow: 48,
18
+ wide: 144,
19
+ };
20
+ export const DEFAULT_PAGE_SETTINGS = {
21
+ size: 'letter',
22
+ orientation: 'portrait',
23
+ margins: 'normal',
24
+ };
25
+ /**
26
+ * Project the host-app's preset selection onto the PageConfig shape that
27
+ * @doxi/core's layout engine consumes.
28
+ */
29
+ export function pageConfigFromSettings(s) {
30
+ const base = SIZE_PX[s.size];
31
+ const { w, h } = s.orientation === 'landscape' ? { w: base.h, h: base.w } : base;
32
+ const m = MARGIN_PX[s.margins];
33
+ return {
34
+ size: { widthPx: w, heightPx: h },
35
+ margins: { topPx: m, rightPx: m, bottomPx: m, leftPx: m },
36
+ };
37
+ }
38
+ export function PageSettingsPopover(props) {
39
+ const [size, setSize] = useState(props.current.size);
40
+ const [orientation, setOrientation] = useState(props.current.orientation);
41
+ const [margins, setMargins] = useState(props.current.margins);
42
+ const apply = () => {
43
+ props.onChange({ size, orientation, margins });
44
+ props.close();
45
+ };
46
+ return (_jsxs("div", { className: "dx-toolbar-popover dx-page-settings-popover", role: "dialog", "aria-label": "Page settings", onMouseDown: (e) => e.stopPropagation(), children: [_jsxs("label", { children: ["Size:", _jsxs("select", { value: size, onChange: (e) => setSize(e.target.value), "data-testid": "page-size", children: [_jsx("option", { value: "letter", children: "Letter (8.5 \u00D7 11 in)" }), _jsx("option", { value: "a4", children: "A4 (210 \u00D7 297 mm)" }), _jsx("option", { value: "legal", children: "Legal (8.5 \u00D7 14 in)" }), _jsx("option", { value: "a5", children: "A5 (148 \u00D7 210 mm)" })] })] }), _jsxs("label", { children: ["Orientation:", _jsxs("select", { value: orientation, onChange: (e) => setOrientation(e.target.value), "data-testid": "page-orientation", children: [_jsx("option", { value: "portrait", children: "Portrait" }), _jsx("option", { value: "landscape", children: "Landscape" })] })] }), _jsxs("label", { children: ["Margins:", _jsxs("select", { value: margins, onChange: (e) => setMargins(e.target.value), "data-testid": "page-margins", children: [_jsx("option", { value: "normal", children: "Normal (96 px)" }), _jsx("option", { value: "narrow", children: "Narrow (48 px)" }), _jsx("option", { value: "wide", children: "Wide (144 px)" })] })] }), _jsxs("div", { className: "dx-page-settings-actions", children: [_jsx("button", { type: "button", "data-testid": "page-settings-apply", onMouseDown: (e) => e.preventDefault(), onClick: apply, children: "Apply" }), _jsx("button", { type: "button", "data-testid": "page-settings-cancel", onMouseDown: (e) => e.preventDefault(), onClick: props.close, children: "Cancel" })] })] }));
47
+ }
48
+ //# sourceMappingURL=PageSettingsPopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageSettingsPopover.js","sourceRoot":"","sources":["../src/PageSettingsPopover.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAY,MAAM,OAAO,CAAA;AAqB1C;;;;;GAKG;AACH,MAAM,OAAO,GAAiD;IAC5D,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE;IAC3B,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE;IACvB,KAAK,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE;IAC1B,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;CACvB,CAAA;AAED,MAAM,SAAS,GAAiC;IAC9C,MAAM,EAAE,EAAE;IACV,MAAM,EAAE,EAAE;IACV,IAAI,EAAE,GAAG;CACV,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,UAAU;IACvB,OAAO,EAAE,QAAQ;CAClB,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,CAAe;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAChF,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IAC9B,OAAO;QACL,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;QACjC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;KAC1D,CAAA;AACH,CAAC;AAUD,MAAM,UAAU,mBAAmB,CAAC,KAA+B;IACjE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAa,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAc,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACtF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAe,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAE3E,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;QAC9C,KAAK,CAAC,KAAK,EAAE,CAAA;IACf,CAAC,CAAA;IAED,OAAO,CACL,eACE,SAAS,EAAC,6CAA6C,EACvD,IAAI,EAAC,QAAQ,gBACF,eAAe,EAC1B,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,aAEvC,qCAEE,kBACE,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAmB,CAAC,iBAC1C,WAAW,aAEvB,iBAAQ,KAAK,EAAC,QAAQ,0CAA8B,EACpD,iBAAQ,KAAK,EAAC,IAAI,uCAA2B,EAC7C,iBAAQ,KAAK,EAAC,OAAO,yCAA6B,EAClD,iBAAQ,KAAK,EAAC,IAAI,uCAA2B,IACtC,IACH,EACR,4CAEE,kBACE,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAoB,CAAC,iBAClD,kBAAkB,aAE9B,iBAAQ,KAAK,EAAC,UAAU,yBAAkB,EAC1C,iBAAQ,KAAK,EAAC,WAAW,0BAAmB,IACrC,IACH,EACR,wCAEE,kBACE,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAqB,CAAC,iBAC/C,cAAc,aAE1B,iBAAQ,KAAK,EAAC,QAAQ,+BAAwB,EAC9C,iBAAQ,KAAK,EAAC,QAAQ,+BAAwB,EAC9C,iBAAQ,KAAK,EAAC,MAAM,8BAAuB,IACpC,IACH,EACR,eAAK,SAAS,EAAC,0BAA0B,aACvC,iBACE,IAAI,EAAC,QAAQ,iBACD,qBAAqB,EACjC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,EACtC,OAAO,EAAE,KAAK,sBAGP,EACT,iBACE,IAAI,EAAC,QAAQ,iBACD,sBAAsB,EAClC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,EACtC,OAAO,EAAE,KAAK,CAAC,KAAK,uBAGb,IACL,IACF,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type EditorState, type Transaction } from '@doxi/core';
2
+ import { type JSX } from 'react';
3
+ /**
4
+ * Insert-table popover content. Rendered by the {@link Toolbar} when its
5
+ * `table` popover is open. Props supplied by the toolbar:
6
+ * - `state` — current editor state (read schema, run the command).
7
+ * - `dispatch` — apply a transaction.
8
+ * - `close` — close the popover after committing.
9
+ *
10
+ * UX:
11
+ * - 8×8 grid of hoverable cells. Hover highlights the top-left
12
+ * (r+1) × (c+1) rectangle. Click commits an insertTable command at
13
+ * that size and closes the popover.
14
+ * - Label below the grid mirrors the current hover size, or
15
+ * "Insert table" when nothing is hovered.
16
+ * - `onMouseDown` is stopped from propagating so the toolbar's
17
+ * click-outside-to-close handler doesn't close the popover on
18
+ * a grid click before our `onClick` fires.
19
+ * - Escape close is handled by the Toolbar's popover container (its
20
+ * own keydown listener at the window level), mirroring LinkPopover.
21
+ */
22
+ export declare function TablePicker(props: {
23
+ state: EditorState;
24
+ dispatch: (tr: Transaction) => void;
25
+ close: () => void;
26
+ }): JSX.Element;
27
+ //# sourceMappingURL=TablePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TablePicker.d.ts","sourceRoot":"","sources":["../src/TablePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAK1C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,KAAK,EAAE,WAAW,CAAA;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB,GAAG,GAAG,CAAC,OAAO,CAyCd"}