@portone/docx-editor 0.1.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 (347) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/CONTRIBUTING.md +63 -0
  3. package/LICENSE +203 -0
  4. package/README.md +48 -0
  5. package/assets/editor.png +0 -0
  6. package/dist/DocxEditor.d.ts +123 -0
  7. package/dist/DocxEditor.js +348 -0
  8. package/dist/core.d.ts +36 -0
  9. package/dist/core.js +38 -0
  10. package/dist/docx/comments/constants.d.ts +8 -0
  11. package/dist/docx/comments/constants.js +20 -0
  12. package/dist/docx/comments/model.d.ts +37 -0
  13. package/dist/docx/comments/model.js +104 -0
  14. package/dist/docx/comments/reading.d.ts +36 -0
  15. package/dist/docx/comments/reading.js +149 -0
  16. package/dist/docx/comments/writing.d.ts +11 -0
  17. package/dist/docx/comments/writing.js +327 -0
  18. package/dist/docx/comments.d.ts +3 -0
  19. package/dist/docx/comments.js +4 -0
  20. package/dist/docx/container.d.ts +12 -0
  21. package/dist/docx/container.js +130 -0
  22. package/dist/docx/documentSettings.d.ts +4 -0
  23. package/dist/docx/documentSettings.js +14 -0
  24. package/dist/docx/exportDocx.d.ts +15 -0
  25. package/dist/docx/exportDocx.js +163 -0
  26. package/dist/docx/exportRefs.d.ts +16 -0
  27. package/dist/docx/exportRefs.js +10 -0
  28. package/dist/docx/formatting/direct.d.ts +30 -0
  29. package/dist/docx/formatting/direct.js +201 -0
  30. package/dist/docx/formatting/effectiveParagraph.d.ts +15 -0
  31. package/dist/docx/formatting/effectiveParagraph.js +81 -0
  32. package/dist/docx/formatting/styles.d.ts +67 -0
  33. package/dist/docx/formatting/styles.js +165 -0
  34. package/dist/docx/formatting/tabStops.d.ts +8 -0
  35. package/dist/docx/formatting/tabStops.js +65 -0
  36. package/dist/docx/formatting.d.ts +4 -0
  37. package/dist/docx/formatting.js +4 -0
  38. package/dist/docx/headersFooters.d.ts +36 -0
  39. package/dist/docx/headersFooters.js +218 -0
  40. package/dist/docx/hyperlink.d.ts +75 -0
  41. package/dist/docx/hyperlink.js +71 -0
  42. package/dist/docx/importDocx.d.ts +21 -0
  43. package/dist/docx/importDocx.js +263 -0
  44. package/dist/docx/importParagraph.d.ts +32 -0
  45. package/dist/docx/importParagraph.js +308 -0
  46. package/dist/docx/importTable.d.ts +9 -0
  47. package/dist/docx/importTable.js +275 -0
  48. package/dist/docx/media.d.ts +60 -0
  49. package/dist/docx/media.js +213 -0
  50. package/dist/docx/notes.d.ts +22 -0
  51. package/dist/docx/notes.js +71 -0
  52. package/dist/docx/pageGeometry.d.ts +75 -0
  53. package/dist/docx/pageGeometry.js +88 -0
  54. package/dist/docx/paraProps.d.ts +74 -0
  55. package/dist/docx/paraProps.js +167 -0
  56. package/dist/docx/propsXml.d.ts +49 -0
  57. package/dist/docx/propsXml.js +302 -0
  58. package/dist/docx/relationships.d.ts +42 -0
  59. package/dist/docx/relationships.js +94 -0
  60. package/dist/docx/runProps.d.ts +51 -0
  61. package/dist/docx/runProps.js +207 -0
  62. package/dist/docx/scan.d.ts +20 -0
  63. package/dist/docx/scan.js +110 -0
  64. package/dist/docx/sdt.d.ts +56 -0
  65. package/dist/docx/sdt.js +104 -0
  66. package/dist/docx/sdtProps.d.ts +18 -0
  67. package/dist/docx/sdtProps.js +11 -0
  68. package/dist/docx/serializeBlock.d.ts +4 -0
  69. package/dist/docx/serializeBlock.js +30 -0
  70. package/dist/docx/serializeParagraph.d.ts +15 -0
  71. package/dist/docx/serializeParagraph.js +208 -0
  72. package/dist/docx/serializeTable.d.ts +12 -0
  73. package/dist/docx/serializeTable.js +134 -0
  74. package/dist/docx/session.d.ts +81 -0
  75. package/dist/docx/session.js +79 -0
  76. package/dist/docx/tableFormatting/editing.d.ts +64 -0
  77. package/dist/docx/tableFormatting/editing.js +318 -0
  78. package/dist/docx/tableFormatting/reading.d.ts +96 -0
  79. package/dist/docx/tableFormatting/reading.js +221 -0
  80. package/dist/docx/tableFormatting.d.ts +2 -0
  81. package/dist/docx/tableFormatting.js +3 -0
  82. package/dist/docx/tableTemplate.d.ts +22 -0
  83. package/dist/docx/tableTemplate.js +111 -0
  84. package/dist/docx/theme.d.ts +40 -0
  85. package/dist/docx/theme.js +61 -0
  86. package/dist/docx/uniqueControls.d.ts +14 -0
  87. package/dist/docx/uniqueControls.js +62 -0
  88. package/dist/download.d.ts +57 -0
  89. package/dist/download.js +44 -0
  90. package/dist/editor/clipboard/images.d.ts +14 -0
  91. package/dist/editor/clipboard/images.js +158 -0
  92. package/dist/editor/clipboard/inlineFormatting.d.ts +21 -0
  93. package/dist/editor/clipboard/inlineFormatting.js +232 -0
  94. package/dist/editor/commands/breakCommands.d.ts +8 -0
  95. package/dist/editor/commands/breakCommands.js +19 -0
  96. package/dist/editor/commands/canRunCommand.d.ts +6 -0
  97. package/dist/editor/commands/canRunCommand.js +10 -0
  98. package/dist/editor/commands/commentCommands.d.ts +3 -0
  99. package/dist/editor/commands/commentCommands.js +4 -0
  100. package/dist/editor/commands/comments/editing.d.ts +21 -0
  101. package/dist/editor/commands/comments/editing.js +305 -0
  102. package/dist/editor/commands/comments/model.d.ts +31 -0
  103. package/dist/editor/commands/comments/model.js +0 -0
  104. package/dist/editor/commands/comments/reading.d.ts +8 -0
  105. package/dist/editor/commands/comments/reading.js +58 -0
  106. package/dist/editor/commands/formatting/editing.d.ts +32 -0
  107. package/dist/editor/commands/formatting/editing.js +138 -0
  108. package/dist/editor/commands/formatting/reading.d.ts +57 -0
  109. package/dist/editor/commands/formatting/reading.js +82 -0
  110. package/dist/editor/commands/formatting/shared.d.ts +32 -0
  111. package/dist/editor/commands/formatting/shared.js +53 -0
  112. package/dist/editor/commands/formattingCommands.d.ts +2 -0
  113. package/dist/editor/commands/formattingCommands.js +3 -0
  114. package/dist/editor/commands/historyCommands.d.ts +11 -0
  115. package/dist/editor/commands/historyCommands.js +16 -0
  116. package/dist/editor/commands/indentCommands.d.ts +15 -0
  117. package/dist/editor/commands/indentCommands.js +44 -0
  118. package/dist/editor/commands/index.d.ts +82 -0
  119. package/dist/editor/commands/index.js +171 -0
  120. package/dist/editor/commands/linkCommands.d.ts +56 -0
  121. package/dist/editor/commands/linkCommands.js +146 -0
  122. package/dist/editor/commands/listCommands.d.ts +58 -0
  123. package/dist/editor/commands/listCommands.js +140 -0
  124. package/dist/editor/commands/lockCommands.d.ts +47 -0
  125. package/dist/editor/commands/lockCommands.js +198 -0
  126. package/dist/editor/commands/noteQueries.d.ts +12 -0
  127. package/dist/editor/commands/noteQueries.js +29 -0
  128. package/dist/editor/commands/paragraphCommands.d.ts +59 -0
  129. package/dist/editor/commands/paragraphCommands.js +113 -0
  130. package/dist/editor/commands/spacingCommands.d.ts +23 -0
  131. package/dist/editor/commands/spacingCommands.js +48 -0
  132. package/dist/editor/commands/tabCommands.d.ts +5 -0
  133. package/dist/editor/commands/tabCommands.js +65 -0
  134. package/dist/editor/createEditor.d.ts +59 -0
  135. package/dist/editor/createEditor.js +160 -0
  136. package/dist/editor/documentStyles.d.ts +60 -0
  137. package/dist/editor/documentStyles.js +80 -0
  138. package/dist/editor/externalClipboard.d.ts +11 -0
  139. package/dist/editor/externalClipboard.js +323 -0
  140. package/dist/editor/imageFiles.d.ts +74 -0
  141. package/dist/editor/imageFiles.js +173 -0
  142. package/dist/editor/insertImage.d.ts +31 -0
  143. package/dist/editor/insertImage.js +35 -0
  144. package/dist/editor/insertTable.d.ts +18 -0
  145. package/dist/editor/insertTable.js +44 -0
  146. package/dist/editor/paragraphEdits.d.ts +42 -0
  147. package/dist/editor/paragraphEdits.js +59 -0
  148. package/dist/editor/plainText.d.ts +3 -0
  149. package/dist/editor/plainText.js +50 -0
  150. package/dist/editor/plugins/bookmarkProtection.d.ts +3 -0
  151. package/dist/editor/plugins/bookmarkProtection.js +28 -0
  152. package/dist/editor/plugins/columnResize.d.ts +27 -0
  153. package/dist/editor/plugins/columnResize.js +192 -0
  154. package/dist/editor/plugins/commentDecorations.d.ts +3 -0
  155. package/dist/editor/plugins/commentDecorations.js +23 -0
  156. package/dist/editor/plugins/commentReservations.d.ts +5 -0
  157. package/dist/editor/plugins/commentReservations.js +26 -0
  158. package/dist/editor/plugins/dropCaret.d.ts +10 -0
  159. package/dist/editor/plugins/dropCaret.js +11 -0
  160. package/dist/editor/plugins/imagePaste.d.ts +8 -0
  161. package/dist/editor/plugins/imagePaste.js +265 -0
  162. package/dist/editor/plugins/keymap.d.ts +5 -0
  163. package/dist/editor/plugins/keymap.js +94 -0
  164. package/dist/editor/plugins/linkPanel.d.ts +23 -0
  165. package/dist/editor/plugins/linkPanel.js +39 -0
  166. package/dist/editor/plugins/listInputRules.d.ts +14 -0
  167. package/dist/editor/plugins/listInputRules.js +36 -0
  168. package/dist/editor/plugins/lockedContent.d.ts +6 -0
  169. package/dist/editor/plugins/lockedContent.js +41 -0
  170. package/dist/editor/plugins/noteProtection.d.ts +3 -0
  171. package/dist/editor/plugins/noteProtection.js +25 -0
  172. package/dist/editor/plugins/numberingDecorations.d.ts +42 -0
  173. package/dist/editor/plugins/numberingDecorations.js +110 -0
  174. package/dist/editor/plugins/rowResize.d.ts +15 -0
  175. package/dist/editor/plugins/rowResize.js +196 -0
  176. package/dist/editor/plugins/styledParagraphs.d.ts +15 -0
  177. package/dist/editor/plugins/styledParagraphs.js +65 -0
  178. package/dist/editor/plugins/tabCaret.d.ts +3 -0
  179. package/dist/editor/plugins/tabCaret.js +126 -0
  180. package/dist/editor/plugins/tabDecorations.d.ts +11 -0
  181. package/dist/editor/plugins/tabDecorations.js +87 -0
  182. package/dist/editor/plugins/tabLayout.d.ts +16 -0
  183. package/dist/editor/plugins/tabLayout.js +328 -0
  184. package/dist/editor/plugins/tabPointer.d.ts +7 -0
  185. package/dist/editor/plugins/tabPointer.js +95 -0
  186. package/dist/editor/plugins/tableContextMenu.d.ts +21 -0
  187. package/dist/editor/plugins/tableContextMenu.js +88 -0
  188. package/dist/editor/plugins/textContextMenu.d.ts +15 -0
  189. package/dist/editor/plugins/textContextMenu.js +90 -0
  190. package/dist/editor/views/imageResize.d.ts +53 -0
  191. package/dist/editor/views/imageResize.js +167 -0
  192. package/dist/editor/views/runMarkView.d.ts +15 -0
  193. package/dist/editor/views/runMarkView.js +9 -0
  194. package/dist/editor/views/tableView.d.ts +24 -0
  195. package/dist/editor/views/tableView.js +32 -0
  196. package/dist/index.d.ts +44 -0
  197. package/dist/index.js +38 -0
  198. package/dist/model/format.d.ts +240 -0
  199. package/dist/model/format.js +305 -0
  200. package/dist/model/tabStops.d.ts +17 -0
  201. package/dist/model/tabStops.js +22 -0
  202. package/dist/numbering/listTemplate.d.ts +29 -0
  203. package/dist/numbering/listTemplate.js +83 -0
  204. package/dist/numbering/markers.d.ts +24 -0
  205. package/dist/numbering/markers.js +93 -0
  206. package/dist/numbering/parseNumbering.d.ts +65 -0
  207. package/dist/numbering/parseNumbering.js +116 -0
  208. package/dist/numbering/writeNumbering.d.ts +13 -0
  209. package/dist/numbering/writeNumbering.js +49 -0
  210. package/dist/ooxml/errors.d.ts +39 -0
  211. package/dist/ooxml/errors.js +21 -0
  212. package/dist/ooxml/image.d.ts +88 -0
  213. package/dist/ooxml/image.js +106 -0
  214. package/dist/ooxml/tabStops.d.ts +3 -0
  215. package/dist/ooxml/tabStops.js +51 -0
  216. package/dist/ooxml/units.d.ts +37 -0
  217. package/dist/ooxml/units.js +116 -0
  218. package/dist/ooxml/xml.d.ts +36 -0
  219. package/dist/ooxml/xml.js +89 -0
  220. package/dist/page/PageGuides.d.ts +16 -0
  221. package/dist/page/PageGuides.js +114 -0
  222. package/dist/page/measureBlocks.d.ts +25 -0
  223. package/dist/page/measureBlocks.js +80 -0
  224. package/dist/page/pageDecorations.d.ts +36 -0
  225. package/dist/page/pageDecorations.js +211 -0
  226. package/dist/page/pageLayout.d.ts +176 -0
  227. package/dist/page/pageLayout.js +157 -0
  228. package/dist/page/tableMeasurements.d.ts +10 -0
  229. package/dist/page/tableMeasurements.js +115 -0
  230. package/dist/page/usePageLayout.d.ts +57 -0
  231. package/dist/page/usePageLayout.js +141 -0
  232. package/dist/schema/docxSchema.d.ts +9 -0
  233. package/dist/schema/docxSchema.js +863 -0
  234. package/dist/schema/index.d.ts +2 -0
  235. package/dist/schema/index.js +9 -0
  236. package/dist/schema/locks.d.ts +112 -0
  237. package/dist/schema/locks.js +211 -0
  238. package/dist/schema/rendering.d.ts +6 -0
  239. package/dist/schema/rendering.js +46 -0
  240. package/dist/styles/classNames.d.ts +214 -0
  241. package/dist/styles/classNames.js +208 -0
  242. package/dist/styles/colors.d.ts +11 -0
  243. package/dist/styles/colors.js +14 -0
  244. package/dist/styles/fontSizes.d.ts +6 -0
  245. package/dist/styles/fontSizes.js +20 -0
  246. package/dist/styles/fontStack.d.ts +55 -0
  247. package/dist/styles/fontStack.js +262 -0
  248. package/dist/styles/fonts.d.ts +6 -0
  249. package/dist/styles/fonts.js +11 -0
  250. package/dist/styles/inlineStyle.d.ts +67 -0
  251. package/dist/styles/inlineStyle.js +212 -0
  252. package/dist/styles/lineSpacings.d.ts +11 -0
  253. package/dist/styles/lineSpacings.js +10 -0
  254. package/dist/styles.css +1650 -0
  255. package/dist/table/cellBorders.d.ts +12 -0
  256. package/dist/table/cellBorders.js +9 -0
  257. package/dist/table/cellFormatting.d.ts +57 -0
  258. package/dist/table/cellFormatting.js +173 -0
  259. package/dist/table/columns.d.ts +25 -0
  260. package/dist/table/columns.js +155 -0
  261. package/dist/table/commands.d.ts +19 -0
  262. package/dist/table/commands.js +63 -0
  263. package/dist/table/format.d.ts +35 -0
  264. package/dist/table/format.js +26 -0
  265. package/dist/table/gridBorders.d.ts +42 -0
  266. package/dist/table/gridBorders.js +192 -0
  267. package/dist/table/index.d.ts +16 -0
  268. package/dist/table/index.js +52 -0
  269. package/dist/table/merge.d.ts +36 -0
  270. package/dist/table/merge.js +125 -0
  271. package/dist/table/resize.d.ts +55 -0
  272. package/dist/table/resize.js +66 -0
  273. package/dist/table/rowResize.d.ts +14 -0
  274. package/dist/table/rowResize.js +44 -0
  275. package/dist/table/rows.d.ts +32 -0
  276. package/dist/table/rows.js +89 -0
  277. package/dist/table/widths.d.ts +69 -0
  278. package/dist/table/widths.js +97 -0
  279. package/dist/ui/AlignMenu.d.ts +15 -0
  280. package/dist/ui/AlignMenu.js +64 -0
  281. package/dist/ui/CellStyleGroup.d.ts +15 -0
  282. package/dist/ui/CellStyleGroup.js +232 -0
  283. package/dist/ui/ColorPicker.d.ts +13 -0
  284. package/dist/ui/ColorPicker.js +165 -0
  285. package/dist/ui/CommentsPanel.d.ts +15 -0
  286. package/dist/ui/CommentsPanel.js +348 -0
  287. package/dist/ui/FontFamilySelect.d.ts +14 -0
  288. package/dist/ui/FontFamilySelect.js +59 -0
  289. package/dist/ui/FontSizeSelect.d.ts +11 -0
  290. package/dist/ui/FontSizeSelect.js +49 -0
  291. package/dist/ui/InsertImageButton.d.ts +9 -0
  292. package/dist/ui/InsertImageButton.js +47 -0
  293. package/dist/ui/LinkCard.d.ts +12 -0
  294. package/dist/ui/LinkCard.js +127 -0
  295. package/dist/ui/LinkPanel.d.ts +9 -0
  296. package/dist/ui/LinkPanel.js +121 -0
  297. package/dist/ui/MenuChoice.d.ts +11 -0
  298. package/dist/ui/MenuChoice.js +32 -0
  299. package/dist/ui/NotesPanel.d.ts +6 -0
  300. package/dist/ui/NotesPanel.js +33 -0
  301. package/dist/ui/ParagraphStyleSelect.d.ts +11 -0
  302. package/dist/ui/ParagraphStyleSelect.js +62 -0
  303. package/dist/ui/Popover.d.ts +22 -0
  304. package/dist/ui/Popover.js +74 -0
  305. package/dist/ui/SpacingMenu.d.ts +12 -0
  306. package/dist/ui/SpacingMenu.js +54 -0
  307. package/dist/ui/TableMenu.d.ts +12 -0
  308. package/dist/ui/TableMenu.js +112 -0
  309. package/dist/ui/TableSizePicker.d.ts +9 -0
  310. package/dist/ui/TableSizePicker.js +53 -0
  311. package/dist/ui/TextMenu.d.ts +15 -0
  312. package/dist/ui/TextMenu.js +194 -0
  313. package/dist/ui/Toolbar.d.ts +19 -0
  314. package/dist/ui/Toolbar.js +448 -0
  315. package/dist/ui/ToolbarButton.d.ts +23 -0
  316. package/dist/ui/ToolbarButton.js +56 -0
  317. package/dist/ui/Tooltip.d.ts +19 -0
  318. package/dist/ui/Tooltip.js +47 -0
  319. package/dist/ui/ZoomSelect.d.ts +7 -0
  320. package/dist/ui/ZoomSelect.js +44 -0
  321. package/dist/ui/comments/CommentComposer.d.ts +17 -0
  322. package/dist/ui/comments/CommentComposer.js +59 -0
  323. package/dist/ui/comments/useCommentRailLayout.d.ts +18 -0
  324. package/dist/ui/comments/useCommentRailLayout.js +183 -0
  325. package/dist/ui/keyboardWalk.d.ts +22 -0
  326. package/dist/ui/keyboardWalk.js +70 -0
  327. package/dist/ui/openAddress.d.ts +11 -0
  328. package/dist/ui/openAddress.js +16 -0
  329. package/dist/ui/panelPlacement.d.ts +51 -0
  330. package/dist/ui/panelPlacement.js +71 -0
  331. package/dist/ui/presets.d.ts +11 -0
  332. package/dist/ui/presets.js +0 -0
  333. package/dist/ui/rovingFocus.d.ts +20 -0
  334. package/dist/ui/rovingFocus.js +61 -0
  335. package/dist/ui/runCommand.d.ts +5 -0
  336. package/dist/ui/runCommand.js +13 -0
  337. package/dist/ui/useDismiss.d.ts +6 -0
  338. package/dist/ui/useDismiss.js +31 -0
  339. package/dist/ui/useFitWidthZoom.d.ts +2 -0
  340. package/dist/ui/useFitWidthZoom.js +26 -0
  341. package/dist/ui/useGridKeyboard.d.ts +12 -0
  342. package/dist/ui/useGridKeyboard.js +90 -0
  343. package/dist/ui/useMenuKeyboard.d.ts +12 -0
  344. package/dist/ui/useMenuKeyboard.js +56 -0
  345. package/dist/ui/zoom.d.ts +4 -0
  346. package/dist/ui/zoom.js +21 -0
  347. package/package.json +120 -0
@@ -0,0 +1,59 @@
1
+ // src/ui/comments/CommentComposer.tsx
2
+ import {
3
+ useLayoutEffect,
4
+ useRef,
5
+ useState
6
+ } from "react";
7
+ import { editorClassNames } from "../../styles/classNames.js";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function FocusedTextarea({
10
+ label,
11
+ value,
12
+ onChange
13
+ }) {
14
+ const input = useRef(null);
15
+ useLayoutEffect(() => input.current?.focus(), []);
16
+ return /* @__PURE__ */ jsx(
17
+ "textarea",
18
+ {
19
+ ref: input,
20
+ className: editorClassNames.commentInput,
21
+ "aria-label": label,
22
+ value,
23
+ onChange: (event) => onChange(event.target.value)
24
+ }
25
+ );
26
+ }
27
+ function CommentComposer({
28
+ author,
29
+ label,
30
+ submitLabel,
31
+ onSubmit,
32
+ onClose
33
+ }) {
34
+ const [text, setText] = useState("");
35
+ const submit = (event) => {
36
+ event.preventDefault();
37
+ if (onSubmit(text)) onClose();
38
+ };
39
+ return /* @__PURE__ */ jsxs("form", { className: editorClassNames.commentComposer, onSubmit: submit, children: [
40
+ /* @__PURE__ */ jsx("div", { className: editorClassNames.commentMeta, children: author.name }),
41
+ /* @__PURE__ */ jsx(FocusedTextarea, { label, value: text, onChange: setText }),
42
+ /* @__PURE__ */ jsxs("div", { className: editorClassNames.commentActions, children: [
43
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: onClose, children: "Cancel" }),
44
+ /* @__PURE__ */ jsx(
45
+ "button",
46
+ {
47
+ type: "submit",
48
+ className: editorClassNames.commentPrimaryAction,
49
+ disabled: text.trim().length === 0,
50
+ children: submitLabel
51
+ }
52
+ )
53
+ ] })
54
+ ] });
55
+ }
56
+ export {
57
+ CommentComposer,
58
+ FocusedTextarea
59
+ };
@@ -0,0 +1,18 @@
1
+ import type { EditorView } from "prosemirror-view";
2
+ import { type RefObject } from "react";
3
+ import type { DocumentComment } from "../../editor/commands/commentCommands";
4
+ export declare const COMPOSER_POSITION = "composer";
5
+ interface CommentRailLayoutOptions {
6
+ panel: RefObject<HTMLElement | null>;
7
+ view: EditorView;
8
+ scrollContainer: HTMLElement | null;
9
+ visible: readonly DocumentComment[];
10
+ composerOpen: boolean;
11
+ composerSelectionPos: number;
12
+ allCommentsOpen: boolean;
13
+ }
14
+ export declare function useCommentRailLayout({ panel, view, scrollContainer, visible, composerOpen, composerSelectionPos, allCommentsOpen, }: CommentRailLayoutOptions): {
15
+ positions: ReadonlyMap<string, number>;
16
+ canvasHeight: number;
17
+ };
18
+ export {};
@@ -0,0 +1,183 @@
1
+ // src/ui/comments/useCommentRailLayout.ts
2
+ import { useLayoutEffect, useRef, useState } from "react";
3
+ import { editorClassNames } from "../../styles/classNames.js";
4
+ var COMPOSER_POSITION = "composer";
5
+ var VERTICAL_SCROLLBAR_CLEARANCE = 16;
6
+ function estimatedCardHeight(comment) {
7
+ return 150 + comment.replies.length * 88;
8
+ }
9
+ function topAt(view, pos) {
10
+ try {
11
+ return view.coordsAtPos(pos).top;
12
+ } catch {
13
+ return 0;
14
+ }
15
+ }
16
+ function anchorPositions(comments, view, scrollContainer, rail, composerOpen, selectionPos) {
17
+ const root = scrollContainer.getBoundingClientRect();
18
+ const heights = /* @__PURE__ */ new Map();
19
+ for (const element of rail.querySelectorAll(
20
+ "[data-comment-position]"
21
+ )) {
22
+ const key = element.dataset.commentPosition;
23
+ if (key) heights.set(key, element.getBoundingClientRect().height);
24
+ }
25
+ const items = comments.map((comment) => ({
26
+ key: comment.id,
27
+ anchor: topAt(view, comment.from) - root.top + scrollContainer.scrollTop,
28
+ fallbackHeight: estimatedCardHeight(comment)
29
+ }));
30
+ if (composerOpen) {
31
+ items.push({
32
+ key: COMPOSER_POSITION,
33
+ anchor: topAt(view, selectionPos) - root.top + scrollContainer.scrollTop,
34
+ fallbackHeight: 150
35
+ });
36
+ }
37
+ items.sort((left, right) => left.anchor - right.anchor);
38
+ const positions = /* @__PURE__ */ new Map();
39
+ let next = 64;
40
+ for (const item of items) {
41
+ const top = Math.max(item.anchor, next);
42
+ positions.set(item.key, top);
43
+ next = top + (heights.get(item.key) || item.fallbackHeight) + 12;
44
+ }
45
+ return { positions, bottom: next };
46
+ }
47
+ function useCommentRailLayout({
48
+ panel,
49
+ view,
50
+ scrollContainer,
51
+ visible,
52
+ composerOpen,
53
+ composerSelectionPos,
54
+ allCommentsOpen
55
+ }) {
56
+ const wasAllCommentsOpen = useRef(false);
57
+ const [positions, setPositions] = useState(
58
+ /* @__PURE__ */ new Map()
59
+ );
60
+ const [canvasHeight, setCanvasHeight] = useState(0);
61
+ useLayoutEffect(() => {
62
+ if (allCommentsOpen && !wasAllCommentsOpen.current && panel.current) {
63
+ panel.current.scrollTop = 0;
64
+ }
65
+ wasAllCommentsOpen.current = allCommentsOpen;
66
+ }, [allCommentsOpen, panel]);
67
+ useLayoutEffect(() => {
68
+ const rail = panel.current;
69
+ if (!rail || !scrollContainer) return;
70
+ const frameWindow = scrollContainer.ownerDocument.defaultView;
71
+ const pageLayer = view.dom.closest(
72
+ `.${editorClassNames.pageLayer}`
73
+ );
74
+ if (allCommentsOpen) {
75
+ pageLayer?.style.removeProperty("padding-right");
76
+ rail.style.removeProperty("left");
77
+ setPositions(/* @__PURE__ */ new Map());
78
+ setCanvasHeight(0);
79
+ const wheelAllComments = (event) => {
80
+ event.preventDefault();
81
+ const before = rail.scrollTop;
82
+ const max = Math.max(0, rail.scrollHeight - rail.clientHeight);
83
+ rail.scrollTop = Math.min(max, Math.max(0, before + event.deltaY));
84
+ scrollContainer.scrollTop += event.deltaY - (rail.scrollTop - before);
85
+ scrollContainer.scrollLeft += event.deltaX;
86
+ };
87
+ rail.addEventListener("wheel", wheelAllComments, { passive: false });
88
+ return () => rail.removeEventListener("wheel", wheelAllComments);
89
+ }
90
+ const reserveCommentWidth = () => {
91
+ if (!pageLayer) return;
92
+ const drawnWidth = rail.getBoundingClientRect().width || rail.offsetWidth;
93
+ const computedZoom = Number.parseFloat(
94
+ frameWindow?.getComputedStyle(pageLayer).zoom ?? ""
95
+ );
96
+ const scale = Number.isFinite(computedZoom) && computedZoom > 0 ? computedZoom : 1;
97
+ pageLayer.style.paddingRight = `${(drawnWidth + 16 + VERTICAL_SCROLLBAR_CLEARANCE) / scale}px`;
98
+ };
99
+ const placeBesidePaper = () => {
100
+ reserveCommentWidth();
101
+ const viewport = scrollContainer.getBoundingClientRect();
102
+ const paper = view.dom.getBoundingClientRect();
103
+ const desired = paper.right - viewport.left + scrollContainer.scrollLeft + 16;
104
+ rail.style.left = `${Math.max(16, desired)}px`;
105
+ };
106
+ const update = () => {
107
+ const layout = anchorPositions(
108
+ visible,
109
+ view,
110
+ scrollContainer,
111
+ rail,
112
+ composerOpen,
113
+ composerSelectionPos
114
+ );
115
+ setPositions(layout.positions);
116
+ const bottom = visible.length > 0 || composerOpen ? layout.bottom + 12 : 0;
117
+ setCanvasHeight(Math.max(scrollContainer.scrollHeight, bottom));
118
+ };
119
+ const wheelDocument = (event) => {
120
+ event.preventDefault();
121
+ scrollContainer.scrollTop += event.deltaY;
122
+ scrollContainer.scrollLeft += event.deltaX;
123
+ };
124
+ const placeAndUpdate = () => {
125
+ placeBesidePaper();
126
+ update();
127
+ };
128
+ placeAndUpdate();
129
+ let settledFrame;
130
+ const frame = frameWindow?.requestAnimationFrame(() => {
131
+ placeAndUpdate();
132
+ settledFrame = frameWindow.requestAnimationFrame(() => {
133
+ placeAndUpdate();
134
+ });
135
+ });
136
+ frameWindow?.addEventListener("resize", placeAndUpdate, {
137
+ passive: true
138
+ });
139
+ rail.addEventListener("wheel", wheelDocument, { passive: false });
140
+ const resize = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(placeAndUpdate);
141
+ resize?.observe(scrollContainer);
142
+ resize?.observe(view.dom);
143
+ resize?.observe(rail);
144
+ for (const element of rail.querySelectorAll(
145
+ "[data-comment-position]"
146
+ )) {
147
+ resize?.observe(element);
148
+ }
149
+ const mutations = typeof MutationObserver === "undefined" ? null : new MutationObserver(() => {
150
+ placeAndUpdate();
151
+ for (const element of rail.querySelectorAll(
152
+ "[data-comment-position]"
153
+ )) {
154
+ resize?.observe(element);
155
+ }
156
+ });
157
+ mutations?.observe(rail, { childList: true, subtree: true });
158
+ return () => {
159
+ if (frame !== void 0) frameWindow?.cancelAnimationFrame(frame);
160
+ if (settledFrame !== void 0) {
161
+ frameWindow?.cancelAnimationFrame(settledFrame);
162
+ }
163
+ frameWindow?.removeEventListener("resize", placeAndUpdate);
164
+ rail.removeEventListener("wheel", wheelDocument);
165
+ mutations?.disconnect();
166
+ resize?.disconnect();
167
+ pageLayer?.style.removeProperty("padding-right");
168
+ };
169
+ }, [
170
+ allCommentsOpen,
171
+ composerOpen,
172
+ composerSelectionPos,
173
+ panel,
174
+ scrollContainer,
175
+ view,
176
+ visible
177
+ ]);
178
+ return { positions, canvasHeight };
179
+ }
180
+ export {
181
+ COMPOSER_POSITION,
182
+ useCommentRailLayout
183
+ };
@@ -0,0 +1,22 @@
1
+ /** One-dimensional arrow/Home/End navigation backed by roving focus. */
2
+ import { type KeyboardEvent, type RefObject } from "react";
3
+ /** Prevent these keys from scrolling a screen-anchored panel out of place. */
4
+ export declare const SCROLLING_KEYS: Set<string>;
5
+ export type WalkOrientation = "vertical" | "horizontal";
6
+ export interface LinearWalkOptions {
7
+ container: RefObject<HTMLElement | null>;
8
+ selector: string;
9
+ orientation: WalkOrientation;
10
+ /** Filters which controls the walk may land on; all of them by default. */
11
+ navigable?: (control: HTMLElement) => boolean;
12
+ /** The control to open on; the first by default. */
13
+ start?: (controls: readonly HTMLElement[]) => HTMLElement | undefined;
14
+ takeFocus?: boolean;
15
+ }
16
+ export interface LinearWalk {
17
+ controls: () => HTMLElement[];
18
+ moveTo: (control: HTMLElement | undefined) => void;
19
+ /** Handles one key; returns whether it was the walk's own so the caller can handle the rest. */
20
+ walk: (event: KeyboardEvent) => boolean;
21
+ }
22
+ export declare function useLinearWalk({ container, selector, orientation, navigable, start, takeFocus, }: LinearWalkOptions): LinearWalk;
@@ -0,0 +1,70 @@
1
+ // src/ui/keyboardWalk.ts
2
+ import {
3
+ useCallback,
4
+ useMemo
5
+ } from "react";
6
+ import { useRovingFocus } from "./rovingFocus.js";
7
+ var SCROLLING_KEYS = /* @__PURE__ */ new Set(["PageUp", "PageDown"]);
8
+ var WALK_KEYS = {
9
+ vertical: { previous: "ArrowUp", next: "ArrowDown" },
10
+ horizontal: { previous: "ArrowLeft", next: "ArrowRight" }
11
+ };
12
+ function walkedTo(controls, from, key, orientation) {
13
+ const { previous, next } = WALK_KEYS[orientation];
14
+ switch (key) {
15
+ case next:
16
+ return controls[(from + 1) % controls.length];
17
+ case previous:
18
+ return controls[(from - 1 + controls.length) % controls.length];
19
+ case "Home":
20
+ return controls[0];
21
+ case "End":
22
+ return controls[controls.length - 1];
23
+ default:
24
+ return void 0;
25
+ }
26
+ }
27
+ function useLinearWalk({
28
+ container,
29
+ selector,
30
+ orientation,
31
+ navigable,
32
+ start,
33
+ takeFocus
34
+ }) {
35
+ const roving = useRovingFocus({
36
+ container,
37
+ selector,
38
+ navigable,
39
+ start,
40
+ takeFocus
41
+ });
42
+ const walk = useCallback(
43
+ (event) => {
44
+ const controls = roving.controls();
45
+ if (controls.length === 0) return false;
46
+ const found = controls.findIndex(
47
+ (control) => control === document.activeElement
48
+ );
49
+ const to = walkedTo(
50
+ controls,
51
+ found === -1 ? 0 : found,
52
+ event.key,
53
+ orientation
54
+ );
55
+ if (!to) return false;
56
+ roving.moveTo(to);
57
+ event.preventDefault();
58
+ return true;
59
+ },
60
+ [roving, orientation]
61
+ );
62
+ return useMemo(
63
+ () => ({ controls: roving.controls, moveTo: roving.moveTo, walk }),
64
+ [roving, walk]
65
+ );
66
+ }
67
+ export {
68
+ SCROLLING_KEYS,
69
+ useLinearWalk
70
+ };
@@ -0,0 +1,11 @@
1
+ /** Validates document-provided addresses before the link card hands them to the browser. */
2
+ /**
3
+ * Whether this address is one to hand a browser.
4
+ *
5
+ * A scheme-less address is not, and a leading `www.` does not make it one: nothing in the URI rules
6
+ * says a bare host means https, and a relationship target with no scheme is read as relative to the
7
+ * package, which is to say a file beside the document rather than a site. Guessing here would be
8
+ * guessing what the document meant, which is `setLink`'s policy not to do.
9
+ */
10
+ export declare function openable(address: string): boolean;
11
+ export declare function openAddress(address: string): void;
@@ -0,0 +1,16 @@
1
+ // src/ui/openAddress.ts
2
+ var OPENABLE_SCHEMES = ["http:", "https:", "mailto:"];
3
+ function openable(address) {
4
+ try {
5
+ return OPENABLE_SCHEMES.includes(new URL(address).protocol);
6
+ } catch {
7
+ return false;
8
+ }
9
+ }
10
+ function openAddress(address) {
11
+ window.open(address, "_blank", "noopener,noreferrer");
12
+ }
13
+ export {
14
+ openAddress,
15
+ openable
16
+ };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Positions fixed panels within the viewport so host overflow cannot clip them. Panels that do
3
+ * not remeasure themselves are dismissed on scroll by `useDismiss`.
4
+ */
5
+ import type { EditorView } from "prosemirror-view";
6
+ import { type RefObject } from "react";
7
+ export interface PanelPosition {
8
+ left: number;
9
+ top: number;
10
+ }
11
+ interface Size {
12
+ width: number;
13
+ height: number;
14
+ }
15
+ interface Viewport {
16
+ width: number;
17
+ height: number;
18
+ }
19
+ export interface ControlBox {
20
+ left: number;
21
+ top: number;
22
+ bottom: number;
23
+ }
24
+ export interface ScreenPoint {
25
+ clientX: number;
26
+ clientY: number;
27
+ }
28
+ /**
29
+ * The panel hangs under the control, lined up with its left edge.
30
+ * When it does not fit under the control but does fit over it, it flips above instead;
31
+ * when it fits neither way it slides in from the bottom edge of the screen.
32
+ */
33
+ export declare function positionUnderControl(control: ControlBox, size: Size, viewport: Viewport): PanelPosition;
34
+ export declare function positionAtPoint(point: ScreenPoint, size: Size, viewport: Viewport): PanelPosition;
35
+ /**
36
+ * The bottom left corner of what is drawn at this position in the document, which is where a panel
37
+ * about that spot hangs from.
38
+ *
39
+ * A position the browser has not laid out has no coordinates to ask for, and the panel then hangs
40
+ * against the top of the paper rather than not at all.
41
+ */
42
+ export declare function pointBelowPos(view: EditorView, pos: number): ScreenPoint;
43
+ /**
44
+ * Places a panel under the control it opens from.
45
+ *
46
+ * The panel has to be measured, so this is decided right after it renders, before the
47
+ * browser paints. It is `null` for that one render, which the panel spends invisible.
48
+ */
49
+ export declare function usePanelUnderControl(panel: RefObject<HTMLElement | null>, control: RefObject<HTMLElement | null>, open: boolean): PanelPosition | null;
50
+ export declare function usePanelAtPoint(panel: RefObject<HTMLElement | null>, point: ScreenPoint): PanelPosition | null;
51
+ export {};
@@ -0,0 +1,71 @@
1
+ // src/ui/panelPlacement.ts
2
+ import { useLayoutEffect, useState } from "react";
3
+ var EDGE_GAP = 8;
4
+ var CONTROL_GAP = 4;
5
+ function slideInside(start, length, limit) {
6
+ return Math.max(EDGE_GAP, Math.min(start, limit - EDGE_GAP - length));
7
+ }
8
+ function positionUnderControl(control, size, viewport) {
9
+ const under = control.bottom + CONTROL_GAP;
10
+ const over = control.top - CONTROL_GAP - size.height;
11
+ const fitsUnder = under + size.height + EDGE_GAP <= viewport.height;
12
+ return {
13
+ left: slideInside(control.left, size.width, viewport.width),
14
+ top: fitsUnder || over < EDGE_GAP ? slideInside(under, size.height, viewport.height) : over
15
+ };
16
+ }
17
+ function positionAtPoint(point, size, viewport) {
18
+ return {
19
+ left: slideInside(point.clientX, size.width, viewport.width),
20
+ top: slideInside(point.clientY, size.height, viewport.height)
21
+ };
22
+ }
23
+ function pointBelowPos(view, pos) {
24
+ try {
25
+ const at = view.coordsAtPos(pos);
26
+ return { clientX: at.left, clientY: at.bottom };
27
+ } catch {
28
+ const paper = view.dom.getBoundingClientRect();
29
+ return { clientX: paper.left, clientY: paper.top };
30
+ }
31
+ }
32
+ function measure(panel) {
33
+ return {
34
+ size: { width: panel.offsetWidth, height: panel.offsetHeight },
35
+ viewport: { width: window.innerWidth, height: window.innerHeight }
36
+ };
37
+ }
38
+ function usePanelUnderControl(panel, control, open) {
39
+ const [position, setPosition] = useState(null);
40
+ useLayoutEffect(() => {
41
+ const box = panel.current;
42
+ const from = control.current;
43
+ if (!open || !box || !from) {
44
+ setPosition(null);
45
+ return;
46
+ }
47
+ const { size, viewport } = measure(box);
48
+ setPosition(
49
+ positionUnderControl(from.getBoundingClientRect(), size, viewport)
50
+ );
51
+ }, [panel, control, open]);
52
+ return position;
53
+ }
54
+ function usePanelAtPoint(panel, point) {
55
+ const [position, setPosition] = useState(null);
56
+ const { clientX, clientY } = point;
57
+ useLayoutEffect(() => {
58
+ const box = panel.current;
59
+ if (!box) return;
60
+ const { size, viewport } = measure(box);
61
+ setPosition(positionAtPoint({ clientX, clientY }, size, viewport));
62
+ }, [panel, clientX, clientY]);
63
+ return position;
64
+ }
65
+ export {
66
+ pointBelowPos,
67
+ positionAtPoint,
68
+ positionUnderControl,
69
+ usePanelAtPoint,
70
+ usePanelUnderControl
71
+ };
@@ -0,0 +1,11 @@
1
+ /** Optional picker values; omitted fields use the package's exported defaults. */
2
+ import type { ColorRow } from "../styles/colors";
3
+ import type { LineSpacingOption } from "../styles/lineSpacings";
4
+ import type { CellBorderOption } from "../table/cellBorders";
5
+ export interface DocxEditorPresets {
6
+ fonts?: readonly string[];
7
+ colors?: readonly ColorRow[];
8
+ fontSizes?: readonly number[];
9
+ lineSpacings?: readonly LineSpacingOption[];
10
+ cellBorders?: readonly CellBorderOption[];
11
+ }
File without changes
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Maintains one tab stop in a composite widget. It writes `tabIndex` onto discovered controls and
3
+ * focuses without scrolling because scrolling dismisses floating panels.
4
+ */
5
+ import { type RefObject } from "react";
6
+ export interface RovingFocusOptions {
7
+ container: RefObject<HTMLElement | null>;
8
+ selector: string;
9
+ /** Limits which discovered controls can hold the tab stop. */
10
+ navigable?: (control: HTMLElement) => boolean;
11
+ /** Initial control; defaults to the first navigable control. */
12
+ start?: (controls: readonly HTMLElement[]) => HTMLElement | undefined;
13
+ /** Moves focus to the initial control when the widget appears. */
14
+ takeFocus?: boolean;
15
+ }
16
+ export interface RovingFocus {
17
+ controls: () => HTMLElement[];
18
+ moveTo: (control: HTMLElement | undefined) => void;
19
+ }
20
+ export declare function useRovingFocus({ container, selector, navigable, start, takeFocus, }: RovingFocusOptions): RovingFocus;
@@ -0,0 +1,61 @@
1
+ // src/ui/rovingFocus.ts
2
+ import {
3
+ useCallback,
4
+ useLayoutEffect,
5
+ useMemo,
6
+ useRef
7
+ } from "react";
8
+ function useRovingFocus({
9
+ container,
10
+ selector,
11
+ navigable,
12
+ start,
13
+ takeFocus = false
14
+ }) {
15
+ const stop = useRef(null);
16
+ const took = useRef(false);
17
+ const all = useCallback(
18
+ () => Array.from(
19
+ container.current?.querySelectorAll(selector) ?? []
20
+ ),
21
+ [container, selector]
22
+ );
23
+ const controls = useCallback(
24
+ () => navigable ? all().filter(navigable) : all(),
25
+ [all, navigable]
26
+ );
27
+ const write = useCallback(
28
+ (onto) => {
29
+ for (const control of all()) control.tabIndex = control === onto ? 0 : -1;
30
+ stop.current = onto;
31
+ },
32
+ [all]
33
+ );
34
+ const moveTo = useCallback(
35
+ (control) => {
36
+ if (!control || !controls().includes(control)) return;
37
+ write(control);
38
+ control.focus({ preventScroll: true });
39
+ },
40
+ [controls, write]
41
+ );
42
+ useLayoutEffect(() => {
43
+ const found = controls();
44
+ if (found.length === 0) {
45
+ write(null);
46
+ took.current = false;
47
+ return;
48
+ }
49
+ const focused = found.find((control) => control === document.activeElement);
50
+ const held = stop.current;
51
+ const onto = focused ?? (held && found.includes(held) ? held : start?.(found) ?? found[0]) ?? null;
52
+ write(onto);
53
+ if (!takeFocus || took.current || !onto) return;
54
+ onto.focus({ preventScroll: true });
55
+ took.current = document.activeElement === onto;
56
+ });
57
+ return useMemo(() => ({ controls, moveTo }), [controls, moveTo]);
58
+ }
59
+ export {
60
+ useRovingFocus
61
+ };
@@ -0,0 +1,5 @@
1
+ /** Runs editor commands and restores focus for continued typing. */
2
+ import type { Command } from "prosemirror-state";
3
+ import type { EditorView } from "prosemirror-view";
4
+ export type RunCommand = (command: Command) => void;
5
+ export declare function commandRunner(view: EditorView): RunCommand;
@@ -0,0 +1,13 @@
1
+ // src/ui/runCommand.ts
2
+ function apply(view, command) {
3
+ command(view.state, (tr) => view.dispatch(tr), view);
4
+ }
5
+ function commandRunner(view) {
6
+ return (command) => {
7
+ apply(view, command);
8
+ view.focus();
9
+ };
10
+ }
11
+ export {
12
+ commandRunner
13
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Dismisses a panel on outside press, Escape, scroll, or resize. Scroll uses capture to catch
3
+ * nested containers; events inside the panel are ignored so its own scrolling stays open.
4
+ */
5
+ import { type RefObject } from "react";
6
+ export declare function useDismiss(box: RefObject<HTMLElement | null>, open: boolean, onDismiss: () => void): void;
@@ -0,0 +1,31 @@
1
+ // src/ui/useDismiss.ts
2
+ import { useEffect } from "react";
3
+ function useDismiss(box, open, onDismiss) {
4
+ useEffect(() => {
5
+ if (!open) return;
6
+ const inside = (event) => {
7
+ const target = event.target;
8
+ return target instanceof Node && box.current?.contains(target) === true;
9
+ };
10
+ const onOutside = (event) => {
11
+ if (inside(event)) return;
12
+ onDismiss();
13
+ };
14
+ const onKeyDown = (event) => {
15
+ if (event.key === "Escape") onDismiss();
16
+ };
17
+ document.addEventListener("mousedown", onOutside, true);
18
+ document.addEventListener("keydown", onKeyDown, true);
19
+ document.addEventListener("scroll", onOutside, true);
20
+ window.addEventListener("resize", onDismiss);
21
+ return () => {
22
+ document.removeEventListener("mousedown", onOutside, true);
23
+ document.removeEventListener("keydown", onKeyDown, true);
24
+ document.removeEventListener("scroll", onOutside, true);
25
+ window.removeEventListener("resize", onDismiss);
26
+ };
27
+ }, [box, open, onDismiss]);
28
+ }
29
+ export {
30
+ useDismiss
31
+ };
@@ -0,0 +1,2 @@
1
+ import { type RefObject } from "react";
2
+ export declare function useFitWidthZoom(container: RefObject<HTMLElement | null>, pageWidth: number): number;