@docmentis/udoc-editor 0.0.0-stage → 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 (207) hide show
  1. package/LICENSE-APACHE +202 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +47 -2
  4. package/dist/arrange.d.ts +37 -0
  5. package/dist/arrange.d.ts.map +1 -0
  6. package/dist/arrange.js +431 -0
  7. package/dist/arrange.js.map +1 -0
  8. package/dist/clipboard.d.ts +12 -0
  9. package/dist/clipboard.d.ts.map +1 -0
  10. package/dist/clipboard.js +101 -0
  11. package/dist/clipboard.js.map +1 -0
  12. package/dist/commands.d.ts +12 -0
  13. package/dist/commands.d.ts.map +1 -0
  14. package/dist/commands.js +225 -0
  15. package/dist/commands.js.map +1 -0
  16. package/dist/components/ComboBox.d.ts +38 -0
  17. package/dist/components/ComboBox.d.ts.map +1 -0
  18. package/dist/components/ComboBox.js +57 -0
  19. package/dist/components/ComboBox.js.map +1 -0
  20. package/dist/components/ModeSwitch.d.ts +15 -0
  21. package/dist/components/ModeSwitch.d.ts.map +1 -0
  22. package/dist/components/ModeSwitch.js +94 -0
  23. package/dist/components/ModeSwitch.js.map +1 -0
  24. package/dist/components/NewSlideModal.d.ts +41 -0
  25. package/dist/components/NewSlideModal.d.ts.map +1 -0
  26. package/dist/components/NewSlideModal.js +136 -0
  27. package/dist/components/NewSlideModal.js.map +1 -0
  28. package/dist/components/PageControls.d.ts +78 -0
  29. package/dist/components/PageControls.d.ts.map +1 -0
  30. package/dist/components/PageControls.js +201 -0
  31. package/dist/components/PageControls.js.map +1 -0
  32. package/dist/components/PageSettingsModal.d.ts +27 -0
  33. package/dist/components/PageSettingsModal.d.ts.map +1 -0
  34. package/dist/components/PageSettingsModal.js +273 -0
  35. package/dist/components/PageSettingsModal.js.map +1 -0
  36. package/dist/components/PaintOptionsModal.d.ts +19 -0
  37. package/dist/components/PaintOptionsModal.d.ts.map +1 -0
  38. package/dist/components/PaintOptionsModal.js +103 -0
  39. package/dist/components/PaintOptionsModal.js.map +1 -0
  40. package/dist/components/TextControls.d.ts +49 -0
  41. package/dist/components/TextControls.d.ts.map +1 -0
  42. package/dist/components/TextControls.js +452 -0
  43. package/dist/components/TextControls.js.map +1 -0
  44. package/dist/context-menu.d.ts +46 -0
  45. package/dist/context-menu.d.ts.map +1 -0
  46. package/dist/context-menu.js +144 -0
  47. package/dist/context-menu.js.map +1 -0
  48. package/dist/edit-client.d.ts +121 -0
  49. package/dist/edit-client.d.ts.map +1 -0
  50. package/dist/edit-client.js +154 -0
  51. package/dist/edit-client.js.map +1 -0
  52. package/dist/edit-command.d.ts +7 -0
  53. package/dist/edit-command.d.ts.map +1 -0
  54. package/dist/edit-command.js +18 -0
  55. package/dist/edit-command.js.map +1 -0
  56. package/dist/edit-mode.d.ts +19 -0
  57. package/dist/edit-mode.d.ts.map +1 -0
  58. package/dist/edit-mode.js +214 -0
  59. package/dist/edit-mode.js.map +1 -0
  60. package/dist/editor.d.ts +101 -0
  61. package/dist/editor.d.ts.map +1 -0
  62. package/dist/editor.js +101 -0
  63. package/dist/editor.js.map +1 -0
  64. package/dist/fonts/faces.d.ts +28 -0
  65. package/dist/fonts/faces.d.ts.map +1 -0
  66. package/dist/fonts/faces.js +38 -0
  67. package/dist/fonts/faces.js.map +1 -0
  68. package/dist/fonts/preview.d.ts +98 -0
  69. package/dist/fonts/preview.d.ts.map +1 -0
  70. package/dist/fonts/preview.js +149 -0
  71. package/dist/fonts/preview.js.map +1 -0
  72. package/dist/formatting-marks.d.ts +23 -0
  73. package/dist/formatting-marks.d.ts.map +1 -0
  74. package/dist/formatting-marks.js +55 -0
  75. package/dist/formatting-marks.js.map +1 -0
  76. package/dist/grips.d.ts +14 -0
  77. package/dist/grips.d.ts.map +1 -0
  78. package/dist/grips.js +459 -0
  79. package/dist/grips.js.map +1 -0
  80. package/dist/i18n/ar.d.ts +4 -0
  81. package/dist/i18n/ar.d.ts.map +1 -0
  82. package/dist/i18n/ar.js +175 -0
  83. package/dist/i18n/ar.js.map +1 -0
  84. package/dist/i18n/de.d.ts +4 -0
  85. package/dist/i18n/de.d.ts.map +1 -0
  86. package/dist/i18n/de.js +175 -0
  87. package/dist/i18n/de.js.map +1 -0
  88. package/dist/i18n/en.d.ts +5 -0
  89. package/dist/i18n/en.d.ts.map +1 -0
  90. package/dist/i18n/en.js +176 -0
  91. package/dist/i18n/en.js.map +1 -0
  92. package/dist/i18n/es.d.ts +4 -0
  93. package/dist/i18n/es.d.ts.map +1 -0
  94. package/dist/i18n/es.js +175 -0
  95. package/dist/i18n/es.js.map +1 -0
  96. package/dist/i18n/fr.d.ts +4 -0
  97. package/dist/i18n/fr.d.ts.map +1 -0
  98. package/dist/i18n/fr.js +175 -0
  99. package/dist/i18n/fr.js.map +1 -0
  100. package/dist/i18n/index.d.ts +21 -0
  101. package/dist/i18n/index.d.ts.map +1 -0
  102. package/dist/i18n/index.js +42 -0
  103. package/dist/i18n/index.js.map +1 -0
  104. package/dist/i18n/ja.d.ts +4 -0
  105. package/dist/i18n/ja.d.ts.map +1 -0
  106. package/dist/i18n/ja.js +175 -0
  107. package/dist/i18n/ja.js.map +1 -0
  108. package/dist/i18n/ko.d.ts +4 -0
  109. package/dist/i18n/ko.d.ts.map +1 -0
  110. package/dist/i18n/ko.js +175 -0
  111. package/dist/i18n/ko.js.map +1 -0
  112. package/dist/i18n/messages.d.ts +316 -0
  113. package/dist/i18n/messages.d.ts.map +1 -0
  114. package/dist/i18n/messages.js +2 -0
  115. package/dist/i18n/messages.js.map +1 -0
  116. package/dist/i18n/pt-BR.d.ts +4 -0
  117. package/dist/i18n/pt-BR.d.ts.map +1 -0
  118. package/dist/i18n/pt-BR.js +175 -0
  119. package/dist/i18n/pt-BR.js.map +1 -0
  120. package/dist/i18n/ru.d.ts +4 -0
  121. package/dist/i18n/ru.d.ts.map +1 -0
  122. package/dist/i18n/ru.js +175 -0
  123. package/dist/i18n/ru.js.map +1 -0
  124. package/dist/i18n/zh-CN.d.ts +4 -0
  125. package/dist/i18n/zh-CN.d.ts.map +1 -0
  126. package/dist/i18n/zh-CN.js +175 -0
  127. package/dist/i18n/zh-CN.js.map +1 -0
  128. package/dist/i18n/zh-TW.d.ts +4 -0
  129. package/dist/i18n/zh-TW.d.ts.map +1 -0
  130. package/dist/i18n/zh-TW.js +175 -0
  131. package/dist/i18n/zh-TW.js.map +1 -0
  132. package/dist/icons.d.ts +97 -0
  133. package/dist/icons.d.ts.map +1 -0
  134. package/dist/icons.js +103 -0
  135. package/dist/icons.js.map +1 -0
  136. package/dist/index.d.ts +9 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +14 -0
  139. package/dist/index.js.map +1 -0
  140. package/dist/insert.d.ts +21 -0
  141. package/dist/insert.d.ts.map +1 -0
  142. package/dist/insert.js +129 -0
  143. package/dist/insert.js.map +1 -0
  144. package/dist/menu-action.d.ts +73 -0
  145. package/dist/menu-action.d.ts.map +1 -0
  146. package/dist/menu-action.js +89 -0
  147. package/dist/menu-action.js.map +1 -0
  148. package/dist/mode.d.ts +21 -0
  149. package/dist/mode.d.ts.map +1 -0
  150. package/dist/mode.js +17 -0
  151. package/dist/mode.js.map +1 -0
  152. package/dist/new-slide.d.ts +21 -0
  153. package/dist/new-slide.d.ts.map +1 -0
  154. package/dist/new-slide.js +63 -0
  155. package/dist/new-slide.js.map +1 -0
  156. package/dist/page-controls.d.ts +20 -0
  157. package/dist/page-controls.d.ts.map +1 -0
  158. package/dist/page-controls.js +99 -0
  159. package/dist/page-controls.js.map +1 -0
  160. package/dist/paint.d.ts +52 -0
  161. package/dist/paint.d.ts.map +1 -0
  162. package/dist/paint.js +262 -0
  163. package/dist/paint.js.map +1 -0
  164. package/dist/ruler.d.ts +10 -0
  165. package/dist/ruler.d.ts.map +1 -0
  166. package/dist/ruler.js +97 -0
  167. package/dist/ruler.js.map +1 -0
  168. package/dist/state.d.ts +85 -0
  169. package/dist/state.d.ts.map +1 -0
  170. package/dist/state.js +28 -0
  171. package/dist/state.js.map +1 -0
  172. package/dist/styles.d.ts +2 -0
  173. package/dist/styles.d.ts.map +1 -0
  174. package/dist/styles.js +758 -0
  175. package/dist/styles.js.map +1 -0
  176. package/dist/tabs.d.ts +11 -0
  177. package/dist/tabs.d.ts.map +1 -0
  178. package/dist/tabs.js +153 -0
  179. package/dist/tabs.js.map +1 -0
  180. package/dist/text-format.d.ts +114 -0
  181. package/dist/text-format.d.ts.map +1 -0
  182. package/dist/text-format.js +315 -0
  183. package/dist/text-format.js.map +1 -0
  184. package/dist/tools.d.ts +35 -0
  185. package/dist/tools.d.ts.map +1 -0
  186. package/dist/tools.js +41 -0
  187. package/dist/tools.js.map +1 -0
  188. package/dist/version.d.ts +2 -0
  189. package/dist/version.d.ts.map +1 -0
  190. package/dist/version.js +7 -0
  191. package/dist/version.js.map +1 -0
  192. package/dist/worker/handlers.d.ts +11 -0
  193. package/dist/worker/handlers.d.ts.map +1 -0
  194. package/dist/worker/handlers.js +127 -0
  195. package/dist/worker/handlers.js.map +1 -0
  196. package/dist/worker/protocol.d.ts +190 -0
  197. package/dist/worker/protocol.d.ts.map +1 -0
  198. package/dist/worker/protocol.js +2 -0
  199. package/dist/worker/protocol.js.map +1 -0
  200. package/dist/worker/worker-source.d.ts +3 -0
  201. package/dist/worker/worker-source.d.ts.map +1 -0
  202. package/dist/worker/worker-source.js +11 -0
  203. package/dist/worker/worker.d.ts +2 -0
  204. package/dist/worker/worker.d.ts.map +1 -0
  205. package/dist/worker/worker.js +6 -0
  206. package/dist/worker/worker.js.map +1 -0
  207. package/package.json +69 -5
package/dist/insert.js ADDED
@@ -0,0 +1,129 @@
1
+ // The Insert tab's commands: Shapes on a PDF, placed by a pointer gesture the
2
+ // canvas carries out, and Image on a slide deck, asked for and inserted at once.
3
+ import { ICON_SUBTOOL_ARROW, ICON_SUBTOOL_ELLIPSE, ICON_SUBTOOL_LINE, ICON_SUBTOOL_RECTANGLE, SHAPE_STROKE, SHAPE_STROKE_WIDTH, segmentsFor, } from "@docmentis/udoc-ui/internal";
4
+ import { EditCommand } from "./edit-command.js";
5
+ import { ICON_IMAGE } from "./icons.js";
6
+ /** A placed shape's fill — translucent blue (filled shapes only). */
7
+ const FILL = { components: [0.26, 0.55, 0.96], colorSpace: "srgb" };
8
+ /** A placed shape's fill opacity. */
9
+ const FILL_ALPHA = 0.18;
10
+ /** The shapes the Insert tab places, as the shell carries their place tools. */
11
+ const SHAPES = new Set(["rectangle", "ellipse", "line", "arrow"]);
12
+ /** Shapes offered by the Insert tab's shape picker (`insertShape`). */
13
+ const SHAPE_OPTIONS = [
14
+ ["rectangle", ICON_SUBTOOL_RECTANGLE, "shape.rectangle"],
15
+ ["ellipse", ICON_SUBTOOL_ELLIPSE, "shape.ellipse"],
16
+ ["line", ICON_SUBTOOL_LINE, "shape.line"],
17
+ ["arrow", ICON_SUBTOOL_ARROW, "shape.arrow"],
18
+ ].map(([shape, icon, label]) => ({ tool: { kind: "extension", tool: shape }, icon, label }));
19
+ /**
20
+ * The model `GraphicsObject` for `shape` spanning the drag from `p0` to `p1`
21
+ * (page-local document points), ready to drop into an `InsertObjects` command's
22
+ * `objects`. The object carries **no `id`** — the `InsertObjects` command mints
23
+ * one on insert, so the host never allocates ids. Rectangle and ellipse use the
24
+ * box of the two points; line and arrow run `p0 → p1`, so the direction is
25
+ * preserved. Filled shapes (rectangle / ellipse) get the translucent fill +
26
+ * solid stroke; open shapes (line / arrow) are stroke only.
27
+ */
28
+ function shapeObject(shape, p0, p1) {
29
+ const filled = shape === "rectangle" || shape === "ellipse";
30
+ const object = {
31
+ transform: { scaleX: 1, skewY: 0, skewX: 0, scaleY: 1, translateX: 0, translateY: 0 },
32
+ clips: [],
33
+ optionalContent: [],
34
+ content: {
35
+ path: {
36
+ path: { segments: segmentsFor(shape, p0, p1) },
37
+ windingRule: "nonZero",
38
+ nonstrokingStyle: { brush: { solid: FILL }, alpha: FILL_ALPHA, overprint: false },
39
+ strokingStyle: {
40
+ brush: { solid: SHAPE_STROKE },
41
+ alpha: 1.0,
42
+ overprint: false,
43
+ line: {
44
+ width: SHAPE_STROKE_WIDTH,
45
+ lineCap: "butt",
46
+ lineJoin: "miter",
47
+ miterLimit: 10.0,
48
+ dashArray: null,
49
+ dashOffset: 0.0,
50
+ },
51
+ },
52
+ fill: filled,
53
+ stroke: true,
54
+ renderStyle: {
55
+ blendMode: "normal",
56
+ alphaIsShape: false,
57
+ overprintMode: "default",
58
+ renderingIntent: "relativeColorimetric",
59
+ },
60
+ softMask: null,
61
+ },
62
+ },
63
+ };
64
+ return object;
65
+ }
66
+ /** The shape the Insert tab's place `tool` drags out. */
67
+ export function placedShape(tool) {
68
+ return SHAPES.has(tool) ? tool : null;
69
+ }
70
+ /** Place the Insert tab's `tool` on page `page`, spanning the page-local points
71
+ * `p0 → p1`: a shape as a page object, on top of the page — the engine mints
72
+ * its id and selects it. A no-op for a page with no id (no document, or not a
73
+ * PDF). */
74
+ export async function place(host, tool, page, p0, p1) {
75
+ const shape = placedShape(tool);
76
+ if (!shape || host.store.getState().status !== "ready")
77
+ return;
78
+ const pageId = await host.client.portable.pageIdByIndex(page);
79
+ if (pageId === undefined)
80
+ return;
81
+ await host.commit(() => host.client.execute(EditCommand.insertObjects(pageId, [shapeObject(shape, p0, p1)])));
82
+ }
83
+ /** Insert the image file `bytes` as a picture on the current slide, centred
84
+ * and scaled down to fit, then selected — a committing edit, so the picture's
85
+ * selection rides back. */
86
+ export function insertImage(host, bytes, contentType) {
87
+ return host.commit(() => host.edit.insertImage(bytes, contentType));
88
+ }
89
+ /** Ask for an image file and {@link insertImage} it. The engine reads the
90
+ * file's size and format from its bytes; the browser's MIME type rides along,
91
+ * empty when it has none. */
92
+ export function pickImage(host) {
93
+ const input = document.createElement("input");
94
+ input.type = "file";
95
+ input.accept = "image/*";
96
+ input.addEventListener("change", () => {
97
+ const file = input.files?.[0];
98
+ if (!file)
99
+ return;
100
+ void file
101
+ .arrayBuffer()
102
+ .then((buffer) => insertImage(host, new Uint8Array(buffer), file.type))
103
+ .catch((error) => console.error("udoc: inserting the image failed", error));
104
+ });
105
+ input.click();
106
+ }
107
+ /** The Insert tab's commands, Image asking for its file with `pickImage`. */
108
+ export function insertCommands(pickImage) {
109
+ return {
110
+ insertImage: {
111
+ id: "insertImage",
112
+ label: "command.insertImage",
113
+ icon: ICON_IMAGE,
114
+ group: "insert",
115
+ labeled: true,
116
+ run: { kind: "action", press: pickImage },
117
+ enabledWhen: (c) => c.ready && c.docType === "presentation",
118
+ },
119
+ insertShape: {
120
+ id: "insertShape",
121
+ label: "command.insertShape",
122
+ icon: ICON_SUBTOOL_RECTANGLE,
123
+ group: "insert",
124
+ run: { kind: "armPicker", options: SHAPE_OPTIONS },
125
+ enabledWhen: (c) => c.ready && c.docType === "portable",
126
+ },
127
+ };
128
+ }
129
+ //# sourceMappingURL=insert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insert.js","sourceRoot":"","sources":["../src/insert.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import type { TableSelectionEdit } from "@docmentis/udoc-wasm";
2
+ import type { AlignEdge, EditAxis, MenuAction, TextParagraphAlign, ZOrder } from "@docmentis/udoc-ui/internal";
3
+ import type { ClipboardOp, TableSelectScope } from "./context-menu.js";
4
+ import type { ParagraphSpaceEdge } from "./text-format.js";
5
+ import type { EditTools } from "./tools.js";
6
+ /**
7
+ * What activating one of edit mode's menu rows does. Each variant carries its
8
+ * full payload, so the handler is a switch on `kind` with no side lookup
9
+ * tables. `reorder` is the Arrange dropdown's z-order; `align` / `distribute`
10
+ * / `flip` / `rotate` the Align and Rotate dropdowns; `alignToPage` the Align
11
+ * dropdown's reference toggle (a UI flag, not a document edit). `clipboard` /
12
+ * `delete` are the context menu's acts on the selection, and `selectTable` /
13
+ * `tableEdit` its rows over a table.
14
+ *
15
+ * The first five are the paragraph menus' rows. `indent` carries a *step*, not
16
+ * a measure: an indent is relative per paragraph — a selection spanning two
17
+ * levels keeps their offset instead of flattening to one — so the engine owns
18
+ * what one step means (the list level of a listed paragraph, the left indent of
19
+ * any other), and the menu only says which way.
20
+ */
21
+ export type EditMenuAction = {
22
+ kind: "widthScale";
23
+ scale: number;
24
+ } | {
25
+ kind: "paragraphAlign";
26
+ align: TextParagraphAlign;
27
+ } | {
28
+ kind: "indent";
29
+ delta: number;
30
+ } | {
31
+ kind: "lineSpacing";
32
+ lines: number;
33
+ } | {
34
+ kind: "paragraphSpace";
35
+ edge: ParagraphSpaceEdge;
36
+ } | {
37
+ kind: "reorder";
38
+ order: ZOrder;
39
+ } | {
40
+ kind: "group";
41
+ } | {
42
+ kind: "ungroup";
43
+ } | {
44
+ kind: "align";
45
+ edge: AlignEdge;
46
+ } | {
47
+ kind: "alignToPage";
48
+ } | {
49
+ kind: "distribute";
50
+ axis: EditAxis;
51
+ } | {
52
+ kind: "flip";
53
+ axis: EditAxis;
54
+ } | {
55
+ kind: "rotate";
56
+ angle: number;
57
+ } | {
58
+ kind: "clipboard";
59
+ op: ClipboardOp;
60
+ } | {
61
+ kind: "delete";
62
+ } | {
63
+ kind: "selectTable";
64
+ scope: TableSelectScope;
65
+ } | {
66
+ kind: "tableEdit";
67
+ edit: TableSelectionEdit;
68
+ };
69
+ /** `action` as a shell {@link MenuAction}: carried as the extension's own. */
70
+ export declare function editAction(action: EditMenuAction): MenuAction;
71
+ /** Run one of edit mode's menu rows' intents on the current selection. */
72
+ export declare function runEditMenuAction(tools: EditTools, action: EditMenuAction): void;
73
+ //# sourceMappingURL=menu-action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu-action.d.ts","sourceRoot":"","sources":["../src/menu-action.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC/G,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GACpB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,WAAW,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAEtD,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,CAE7D;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAiFhF"}
@@ -0,0 +1,89 @@
1
+ import { editState, updateEditState } from "./state.js";
2
+ /** `action` as a shell {@link MenuAction}: carried as the extension's own. */
3
+ export function editAction(action) {
4
+ return { kind: "extension", action };
5
+ }
6
+ /** Run one of edit mode's menu rows' intents on the current selection. */
7
+ export function runEditMenuAction(tools, action) {
8
+ const { arrange, text, clipboard, host } = tools;
9
+ switch (action.kind) {
10
+ case "reorder":
11
+ void arrange.reorderSelection(action.order);
12
+ break;
13
+ case "group":
14
+ void arrange.groupSelection();
15
+ break;
16
+ case "ungroup":
17
+ void arrange.ungroupSelection();
18
+ break;
19
+ case "align":
20
+ void arrange.alignSelection(action.edge);
21
+ break;
22
+ case "distribute":
23
+ void arrange.distributeSelection(action.axis);
24
+ break;
25
+ case "flip":
26
+ void arrange.flipSelection(action.axis);
27
+ break;
28
+ case "rotate":
29
+ void arrange.rotateSelectionEach(action.angle);
30
+ break;
31
+ case "alignToPage":
32
+ updateEditState(host.store, { alignToPage: !editState(host.store.getState()).alignToPage });
33
+ break;
34
+ case "widthScale":
35
+ void text.setCharacterProperties([{ widthScale: action.scale }]);
36
+ break;
37
+ case "paragraphAlign":
38
+ void text.setParagraphProperties([{ align: action.align }]);
39
+ break;
40
+ case "lineSpacing":
41
+ void text.setParagraphProperties([{ lineSpacing: { percent: action.lines } }]);
42
+ break;
43
+ case "paragraphSpace":
44
+ void text.toggleParagraphSpace(action.edge);
45
+ break;
46
+ case "indent":
47
+ void text.indentSelection(action.delta);
48
+ break;
49
+ case "clipboard":
50
+ switch (action.op) {
51
+ case "cut":
52
+ clipboard.cut();
53
+ break;
54
+ case "paste":
55
+ void clipboard.paste();
56
+ break;
57
+ }
58
+ break;
59
+ case "delete":
60
+ void host.deleteSelection();
61
+ break;
62
+ case "selectTable":
63
+ // Presence, not an edit: the three widenings re-state what is
64
+ // picked inside the table and report fresh geometry, so they go
65
+ // straight to the client rather than through the edit path.
66
+ switch (action.scope) {
67
+ case "rows":
68
+ host.client.selectTableRows();
69
+ break;
70
+ case "columns":
71
+ host.client.selectTableColumns();
72
+ break;
73
+ case "table":
74
+ host.client.selectTable();
75
+ break;
76
+ }
77
+ break;
78
+ case "tableEdit": {
79
+ // A structural edit on the table the selection sits in — one
80
+ // committing edit like any other. The engine binds it to the
81
+ // innermost table the selection is in; its kind (`deleteRows`, not
82
+ // `delete`) is what keeps it off the frame around that table.
83
+ const { edit } = action;
84
+ void host.commit(() => host.client.executeOnSelection(edit));
85
+ break;
86
+ }
87
+ }
88
+ }
89
+ //# sourceMappingURL=menu-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu-action.js","sourceRoot":"","sources":["../src/menu-action.ts"],"names":[],"mappings":"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"}
package/dist/mode.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import type { Feature } from "@docmentis/udoc-wasm";
2
+ /**
3
+ * The editor's top-level mode — what the user is doing *to* the document. Mode
4
+ * scopes which commands the toolbar offers and how the pointer behaves; it is
5
+ * usually fixed by the host before the editor is shown.
6
+ *
7
+ * - `view` — reading: navigation, filling in a form, and a PDF's annotations
8
+ * (its Annotate tab).
9
+ * - `edit` — full content authoring (Office "select + insert" model).
10
+ */
11
+ export type EditorMode = "view" | "edit";
12
+ /** Canonical render order for the mode switcher. */
13
+ export declare const ALL_MODES: readonly EditorMode[];
14
+ /** Whether a session entitled to `features` may be in `mode`. */
15
+ export declare function modeEntitled(mode: EditorMode, features: readonly Feature[]): boolean;
16
+ /** Edit mode, as the shell knows it: its id and the feature it needs. */
17
+ export declare const EDIT_MODE: {
18
+ readonly id: "edit";
19
+ readonly feature: Feature;
20
+ };
21
+ //# sourceMappingURL=mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode.d.ts","sourceRoot":"","sources":["../src/mode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,oDAAoD;AACpD,eAAO,MAAM,SAAS,EAAE,SAAS,UAAU,EAAqB,CAAC;AAUjE,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAGpF;AAED,yEAAyE;AACzE,eAAO,MAAM,SAAS;;;CAAwD,CAAC"}
package/dist/mode.js ADDED
@@ -0,0 +1,17 @@
1
+ /** Canonical render order for the mode switcher. */
2
+ export const ALL_MODES = ["view", "edit"];
3
+ /** The feature each mode needs, or null for one every session may use. View's
4
+ * own edits — a form's fields, a PDF's annotations — are gated where they
5
+ * start, not by the mode. */
6
+ const MODE_FEATURES = {
7
+ view: null,
8
+ edit: "editing",
9
+ };
10
+ /** Whether a session entitled to `features` may be in `mode`. */
11
+ export function modeEntitled(mode, features) {
12
+ const feature = MODE_FEATURES[mode];
13
+ return feature === null || features.includes(feature);
14
+ }
15
+ /** Edit mode, as the shell knows it: its id and the feature it needs. */
16
+ export const EDIT_MODE = { id: "edit", feature: MODE_FEATURES.edit };
17
+ //# sourceMappingURL=mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode.js","sourceRoot":"","sources":["../src/mode.ts"],"names":[],"mappings":"AAcA,oDAAoD;AACpD,MAAM,CAAC,MAAM,SAAS,GAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjE;;8BAE8B;AAC9B,MAAM,aAAa,GAAuC;IACtD,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;CAClB,CAAC;AAEF,iEAAiE;AACjE,MAAM,UAAU,YAAY,CAAC,IAAgB,EAAE,QAA4B;IACvE,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAK,EAAW,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { CommandDef } from "@docmentis/udoc-ui/internal";
2
+ import type { EditHost } from "./edit-client.js";
3
+ import type { I18n, MessageKey } from "./i18n/index.js";
4
+ /** The layout picker, mounted into a shell. */
5
+ export interface NewSlide {
6
+ /** Open the picker for a new slide after the current one. */
7
+ open(): Promise<void>;
8
+ destroy(): void;
9
+ }
10
+ /** Mount the layout picker into `host` — once, re-seeded with the current
11
+ * layout roster each open. */
12
+ export declare function mountNewSlide(host: EditHost, i18n: I18n): NewSlide;
13
+ /**
14
+ * The New Slide command, opening the picker with `open` — a document-level
15
+ * action shown only with nothing selected: it sits where the selection's
16
+ * property controls go, so it shows on the empty canvas and yields to those
17
+ * controls the moment a shape or text is selected. Labeled, as its page-add
18
+ * glyph reads "slide" only once you know.
19
+ */
20
+ export declare function newSlideCommand(open: () => void): CommandDef<MessageKey>;
21
+ //# sourceMappingURL=new-slide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-slide.d.ts","sourceRoot":"","sources":["../src/new-slide.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAUxD,+CAA+C;AAC/C,MAAM,WAAW,QAAQ;IACrB,6DAA6D;IAC7D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;CACnB;AAED;+BAC+B;AAC/B,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,QAAQ,CAmClE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,CAUxE"}
@@ -0,0 +1,63 @@
1
+ import { createNewSlideModal } from "./components/NewSlideModal.js";
2
+ import { ICON_PAGE_ADD } from "./icons.js";
3
+ /** Create a slide at `index` (clamped), seeded with its layout's content
4
+ * placeholders. `layout` is the slide-layout id to build on; omit it to copy
5
+ * the neighbor slide's layout. */
6
+ function createSlide(index, layout) {
7
+ return { presentation: { insertSlide: layout == null ? { index } : { index, layout } } };
8
+ }
9
+ /** Mount the layout picker into `host` — once, re-seeded with the current
10
+ * layout roster each open. */
11
+ export function mountNewSlide(host, i18n) {
12
+ const modal = createNewSlideModal(i18n);
13
+ modal.mount(host.root);
14
+ const execute = (command) => host.commit(() => host.client.execute(command));
15
+ return {
16
+ // Pull every slide master's summary, flatten it to pickable options
17
+ // (each slide layout previews on its slide master's plane at page
18
+ // `1 + its index`), and open. Falls back to the copy-neighbor default
19
+ // when no slide layouts are available. The 0-based page index nearest
20
+ // the viewport top is the current slide; +1 lands the new slide right
21
+ // after it, PowerPoint-style.
22
+ async open() {
23
+ const insertIndex = host.store.getState().pageIndex + 1;
24
+ const slideMasters = await host.edit.slideMastersSummary();
25
+ const options = slideMasters.flatMap((slideMaster) => slideMaster.slideLayouts.map((slideLayout, index) => ({
26
+ layout: slideLayout.id,
27
+ plane: slideMaster.plane,
28
+ page: index + 1,
29
+ name: slideLayout.name,
30
+ })));
31
+ if (options.length === 0) {
32
+ void execute(createSlide(insertIndex));
33
+ return;
34
+ }
35
+ modal.open({
36
+ insertIndex,
37
+ options,
38
+ renderPreview: (plane, page, scale) => host.client.renderPagePreview(plane, page, scale),
39
+ onPick: (layout) => void execute(createSlide(insertIndex, layout)),
40
+ });
41
+ },
42
+ destroy: () => modal.destroy(),
43
+ };
44
+ }
45
+ /**
46
+ * The New Slide command, opening the picker with `open` — a document-level
47
+ * action shown only with nothing selected: it sits where the selection's
48
+ * property controls go, so it shows on the empty canvas and yields to those
49
+ * controls the moment a shape or text is selected. Labeled, as its page-add
50
+ * glyph reads "slide" only once you know.
51
+ */
52
+ export function newSlideCommand(open) {
53
+ return {
54
+ id: "createSlide",
55
+ label: "command.createSlide",
56
+ icon: ICON_PAGE_ADD,
57
+ group: "slide",
58
+ labeled: true,
59
+ run: { kind: "action", press: open },
60
+ enabledWhen: (c) => c.ready && c.selection.count === 0,
61
+ };
62
+ }
63
+ //# sourceMappingURL=new-slide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-slide.js","sourceRoot":"","sources":["../src/new-slide.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;mCAEmC;AACnC,SAAS,WAAW,CAAC,KAAa,EAAE,MAAe;IAC/C,OAAO,EAAE,YAAY,EAAE,EAAE,WAAW,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAC7F,CAAC;AASD;+BAC+B;AAC/B,MAAM,UAAU,aAAa,CAAC,IAAc,EAAE,IAAU;IACpD,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACxC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,OAAO,GAAG,CAAC,OAAoB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1F,OAAO;QACH,oEAAoE;QACpE,kEAAkE;QAClE,sEAAsE;QACtE,sEAAsE;QACtE,sEAAsE;QACtE,8BAA8B;QAC9B,KAAK,CAAC,IAAI;YACN,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,SAAS,GAAG,CAAC,CAAC;YACxD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3D,MAAM,OAAO,GAAmB,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CACjE,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBAClD,MAAM,EAAE,WAAW,CAAC,EAAE;gBACtB,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,IAAI,EAAE,KAAK,GAAG,CAAC;gBACf,IAAI,EAAE,WAAW,CAAC,IAAI;aACzB,CAAC,CAAC,CACN,CAAC;YACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,KAAK,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;gBACvC,OAAO;YACX,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACP,WAAW;gBACX,OAAO;gBACP,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;gBACxF,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;aACrE,CAAC,CAAC;QACP,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE;KACjC,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAgB;IAC5C,OAAO;QACH,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE;QACpC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC;KACzD,CAAC;AACN,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { PageSpacing, UIShellHost, UIState } from "@docmentis/udoc-ui/internal";
2
+ import type { I18n } from "./i18n/index.js";
3
+ /**
4
+ * The spacing the page controls show with. The insert strip is sized from the
5
+ * gap × the frame scale, so it fills the gap at every zoom. The paddings are
6
+ * screen-fixed (CSS px), so the rail in the right padding stays a constant size
7
+ * on screen — the side paddings are wide enough that the rail (offset + ~26px)
8
+ * clears the virtual scrollbar at fit-width.
9
+ */
10
+ export declare const PAGE_CONTROLS_SPACING: PageSpacing;
11
+ /**
12
+ * Whether the page controls show in `s`: in edit mode, for a doc type whose
13
+ * pages reorder ({@link PAGE_CONTROLLED}), in the continuous single-page
14
+ * arrangement — where the gaps they live in exist, and no facing page sits
15
+ * where the rail goes.
16
+ */
17
+ export declare function pageControlsShown(s: UIState): boolean;
18
+ /** Mount the page controls into `host`, shown while {@link pageControlsShown}; returns the teardown. */
19
+ export declare function mountPageControls(host: UIShellHost, i18n: I18n): () => void;
20
+ //# sourceMappingURL=page-controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-controls.d.ts","sourceRoot":"","sources":["../src/page-controls.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAGrF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAM5C;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAGnC,CAAC;AAqCF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAQrD;AAED,wGAAwG;AACxG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAyD3E"}
@@ -0,0 +1,99 @@
1
+ import { arrangementFor, subscribeSelector } from "@docmentis/udoc-ui/internal";
2
+ import { pageActions, pageInserts } from "./components/PageControls.js";
3
+ import { createPageSettingsModal } from "./components/PageSettingsModal.js";
4
+ /** The gap between pages, which the insert strip lives in: page-fixed
5
+ * (document points), so it reads as part of the paper. */
6
+ const GAP_PT = 24;
7
+ /**
8
+ * The spacing the page controls show with. The insert strip is sized from the
9
+ * gap × the frame scale, so it fills the gap at every zoom. The paddings are
10
+ * screen-fixed (CSS px), so the rail in the right padding stays a constant size
11
+ * on screen — the side paddings are wide enough that the rail (offset + ~26px)
12
+ * clears the virtual scrollbar at fit-width.
13
+ */
14
+ export const PAGE_CONTROLS_SPACING = {
15
+ padding: { top: { px: 36 }, right: { px: 48 }, bottom: { px: 36 }, left: { px: 48 } },
16
+ gap: { horizontal: GAP_PT, vertical: GAP_PT },
17
+ };
18
+ /** The `UDocCommand` for a page-structure edit. */
19
+ function pageCommand(edit) {
20
+ switch (edit.kind) {
21
+ case "insert":
22
+ return { portable: { insertPage: { index: edit.index } } };
23
+ case "delete":
24
+ return { portable: { deletePage: { index: edit.index } } };
25
+ case "reorder":
26
+ return { portable: { reorderPage: { from: edit.from, to: edit.to } } };
27
+ case "rotate":
28
+ return { portable: { rotatePage: { index: edit.index, clockwise: edit.clockwise } } };
29
+ case "resize":
30
+ return {
31
+ portable: { resizePage: { index: edit.index, size: { width: edit.width, height: edit.height } } },
32
+ };
33
+ }
34
+ }
35
+ /** The doc types whose pages the page controls move, rotate, delete and
36
+ * insert: the paginated, page-reorderable ones — PDF today. */
37
+ const PAGE_CONTROLLED = new Set(["portable"]);
38
+ /**
39
+ * Whether the page controls show in `s`: in edit mode, for a doc type whose
40
+ * pages reorder ({@link PAGE_CONTROLLED}), in the continuous single-page
41
+ * arrangement — where the gaps they live in exist, and no facing page sits
42
+ * where the rail goes.
43
+ */
44
+ export function pageControlsShown(s) {
45
+ return (s.mode === "edit" &&
46
+ s.scrollMode === "continuous" &&
47
+ arrangementFor(s).layoutMode === "singlePage" &&
48
+ s.docType !== null &&
49
+ PAGE_CONTROLLED.has(s.docType));
50
+ }
51
+ /** Mount the page controls into `host`, shown while {@link pageControlsShown}; returns the teardown. */
52
+ export function mountPageControls(host, i18n) {
53
+ // Mounted once and reused for whichever page's "more" button is clicked.
54
+ const settings = createPageSettingsModal(i18n);
55
+ settings.mount(host.root);
56
+ const pageEditAt = (edit) => host.commit(() => host.client.execute(pageCommand(edit)));
57
+ const composedPageCount = () => host.store.getState().composedPageCount;
58
+ function show(shown) {
59
+ if (!shown) {
60
+ host.removeOverlay("udoc:page-insert");
61
+ host.removeOverlay("udoc:page-actions");
62
+ return;
63
+ }
64
+ host.setOverlay("udoc:page-insert", pageInserts({
65
+ i18n,
66
+ gapPt: GAP_PT,
67
+ composedPageCount,
68
+ onInsert: (index) => void pageEditAt({ kind: "insert", index }),
69
+ // Yield the gap where a selection's resize/rotate handles
70
+ // floated into it, so the insert strip never sits under them.
71
+ keepOut: () => host.selectionKeepOut(),
72
+ }));
73
+ // Registered after the insert strips so the rail stacks above them —
74
+ // they share the inter-page gap.
75
+ host.setOverlay("udoc:page-actions", pageActions({
76
+ i18n,
77
+ composedPageCount,
78
+ hoveredPage: () => host.hoveredPage(),
79
+ onMoveUp: (index) => void pageEditAt({ kind: "reorder", from: index, to: index - 1 }),
80
+ onMoveDown: (index) => void pageEditAt({ kind: "reorder", from: index, to: index + 1 }),
81
+ onRotate: (index, clockwise) => void pageEditAt({ kind: "rotate", index, clockwise }),
82
+ onDelete: (index) => void pageEditAt({ kind: "delete", index }),
83
+ onOpenSettings: (index, size) => settings.open({
84
+ index,
85
+ width: size.width,
86
+ height: size.height,
87
+ onResize: (width, height) => void pageEditAt({ kind: "resize", index, width, height }),
88
+ onRotate: (clockwise) => void pageEditAt({ kind: "rotate", index, clockwise }),
89
+ }),
90
+ }));
91
+ }
92
+ show(pageControlsShown(host.store.getState()));
93
+ const unsubscribe = subscribeSelector(host.store, pageControlsShown, show);
94
+ return () => {
95
+ unsubscribe();
96
+ settings.destroy();
97
+ };
98
+ }
99
+ //# sourceMappingURL=page-controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-controls.js","sourceRoot":"","sources":["../src/page-controls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { PaintColor, PaintFill } from "@docmentis/udoc-wasm";
2
+ import type { LineDash, PaintChannel, PaintSpec, RibbonControl, RibbonControlEnv, StrokeStyle, UIShellHost } from "@docmentis/udoc-ui/internal";
3
+ import type { EditTools } from "./tools.js";
4
+ /** A picker paint as a `PaintColor`, or `null` for "no fill": a solid sRGB
5
+ * color, or a theme pick kept as a `schemeClr` reference with its tint/shade
6
+ * transforms so it re-themes. The shared color construction behind
7
+ * {@link paintToDrawingFill} and the text highlight (a bare color). */
8
+ export declare function paintToDrawingColor(paint: PaintSpec): PaintColor | null;
9
+ /** A picker paint as a `PaintFill`: a solid / theme color wrapped as a solid
10
+ * fill, or explicit `"none"` for "no fill". */
11
+ export declare function paintToDrawingFill(paint: PaintSpec): PaintFill;
12
+ /** A composed stroke the Line picker applies: its color plus the weight and
13
+ * dash from the Weight / Dashes fly-outs. The shell lowers it to the doc type's
14
+ * outline model (`DrawingML` `Line` / PDF stroking style). */
15
+ export interface StrokeSpec {
16
+ paint: PaintSpec;
17
+ /** Stroke weight in points. */
18
+ weight: number;
19
+ dash: LineDash;
20
+ }
21
+ /** The Fill / Line edits of the selection, on the shell `host` lends. */
22
+ export declare function createPaintEdits(host: UIShellHost): {
23
+ fillSelection: (paint: PaintSpec) => Promise<void>;
24
+ strokeSelection: (stroke: StrokeSpec) => Promise<void>;
25
+ };
26
+ /** The Fill / Line edits {@link createPaintEdits} makes. */
27
+ export type PaintEdits = ReturnType<typeof createPaintEdits>;
28
+ /**
29
+ * The last picks — edit mode's write-side memory: the color per channel that the
30
+ * composed stroke re-sends when only its weight / dash change (the engine sets
31
+ * the outline as one thing), and the weight / dash the Line panel marks. Not
32
+ * shown on the triggers, which mirror the *selection*.
33
+ */
34
+ export interface PaintMemory {
35
+ readonly lastPaint: Record<PaintChannel, PaintSpec>;
36
+ readonly lastStroke: StrokeStyle;
37
+ }
38
+ /** A {@link PaintMemory} at its defaults. */
39
+ export declare function createPaintMemory(): PaintMemory;
40
+ /**
41
+ * A Fill / Line / Text Color dropdown of `channel`, for command `id` drawn with
42
+ * `icon`: the channel glyph over a color bar reflecting the *selection's* color,
43
+ * the caret opening the color panel (rebuilt on each open). A mirror — clicking
44
+ * always opens the picker (no last-color re-apply); each render keeps the
45
+ * swatch in sync with the selection.
46
+ */
47
+ export declare function paintControl(env: RibbonControlEnv, command: {
48
+ id: string;
49
+ icon: string;
50
+ channel: PaintChannel;
51
+ }, tools: EditTools): RibbonControl;
52
+ //# sourceMappingURL=paint.d.ts.map