ooxml-ui 1.1.0 → 1.3.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 (203) hide show
  1. package/README.md +38 -36
  2. package/custom-elements.json +372 -4
  3. package/dist/chrome/ruler.d.ts +60 -2
  4. package/dist/chrome/ruler.d.ts.map +1 -1
  5. package/dist/chrome/status-bar.d.ts +3 -1
  6. package/dist/chrome/status-bar.d.ts.map +1 -1
  7. package/dist/{chunk-JFJXBYRD.js → chunk-2WLRFPMW.js} +9 -0
  8. package/dist/{chunk-X7RINDJQ.js → chunk-56A2JK63.js} +1 -1
  9. package/dist/{chunk-KVKKXRL7.js → chunk-5OFAJDMQ.js} +93 -14
  10. package/dist/{chunk-M5DTJSOV.js → chunk-723JC3OC.js} +461 -16
  11. package/dist/{chunk-USDLALB5.js → chunk-IY7QJLQG.js} +1 -1
  12. package/dist/{chunk-BOX43CZD.js → chunk-M6GF5ED2.js} +2 -1
  13. package/dist/{chunk-BEN3453I.js → chunk-NYRRH2MD.js} +1 -1
  14. package/dist/{chunk-3FPW7M6U.js → chunk-TWQ45BFL.js} +1 -1
  15. package/dist/{chunk-ZU7GX4SY.js → chunk-V6P6KZCO.js} +7 -5
  16. package/dist/comments/comments-pane.d.ts +116 -0
  17. package/dist/comments/comments-pane.d.ts.map +1 -0
  18. package/dist/comments/types.d.ts +80 -0
  19. package/dist/comments/types.d.ts.map +1 -0
  20. package/dist/controls.d.ts +6 -2
  21. package/dist/controls.d.ts.map +1 -1
  22. package/dist/controls.js +5 -5
  23. package/dist/docx/comments-panel.d.ts +8 -1
  24. package/dist/docx/editor-chrome.d.ts +8 -1
  25. package/dist/docx/file-commands.d.ts +1 -1
  26. package/dist/docx/image-media.d.ts +1 -1
  27. package/dist/docx/locales/en-app.d.ts +1 -0
  28. package/dist/docx/locales/en-ribbon.d.ts +1 -0
  29. package/dist/docx/locales/en.d.ts +2 -0
  30. package/dist/docx/localization-strings.d.ts +2 -0
  31. package/dist/docx/localization.d.ts +7 -0
  32. package/dist/docx/print-layout.d.ts +2 -2
  33. package/dist/docx/print-picture.d.ts +12 -0
  34. package/dist/docx/review-controller.d.ts +2 -0
  35. package/dist/docx/ribbon-actions.d.ts +22 -0
  36. package/dist/docx/ruler.d.ts +7 -10
  37. package/dist/docx/title-bar.d.ts +3 -5
  38. package/dist/docx.js +342 -362
  39. package/dist/form/gradient-preset-gallery.d.ts +2 -2
  40. package/dist/icons.d.ts.map +1 -1
  41. package/dist/icons.js +1 -1
  42. package/dist/index.d.ts +1 -1
  43. package/dist/index.js +9 -9
  44. package/dist/pptx/{chart-3d-view-scene-2KRQ5667.mjs → chart-3d-view-scene-OYJ4CDCO.mjs} +4 -5
  45. package/dist/pptx/{chart-3d-view-scene-36DMZWZ3.cjs → chart-3d-view-scene-SE2Y6QRE.cjs} +38 -39
  46. package/dist/pptx/{chunk-YOGDIDPB.mjs → chunk-CIVA3MLN.mjs} +8 -2
  47. package/dist/pptx/{chunk-KPZWYF44.cjs → chunk-FPE5PZMI.cjs} +789 -491
  48. package/dist/pptx/{chunk-AIL3BNZS.cjs → chunk-IURZJAWP.cjs} +529 -387
  49. package/dist/pptx/{chunk-YHA6XAB3.cjs → chunk-KRMMJUCO.cjs} +83 -1
  50. package/dist/pptx/{chunk-Y2W4SZER.mjs → chunk-MWHGUEIJ.mjs} +637 -348
  51. package/dist/pptx/{chunk-YARCML7O.mjs → chunk-STLXPKJJ.mjs} +519 -388
  52. package/dist/pptx/{chunk-ADOC5JLI.mjs → chunk-TC7HCF5M.mjs} +76 -2
  53. package/dist/pptx/{chunk-CJU4P5FT.cjs → chunk-WKLHJEPD.cjs} +18 -12
  54. package/dist/pptx/dom/element-styles.d.ts.map +1 -1
  55. package/dist/pptx/dom/elements/chart.d.ts +2 -3
  56. package/dist/pptx/dom/elements/chart.d.ts.map +1 -1
  57. package/dist/pptx/dom/elements/connector.d.ts.map +1 -1
  58. package/dist/pptx/dom/elements/shape-filter-defs.d.ts.map +1 -1
  59. package/dist/pptx/dom/elements/table.d.ts.map +1 -1
  60. package/dist/pptx/dom/index.cjs +272 -261
  61. package/dist/pptx/dom/index.mjs +46 -35
  62. package/dist/pptx/dom/slide-stage.d.ts.map +1 -1
  63. package/dist/pptx/export/html2canvas-clone.cjs +2 -2
  64. package/dist/pptx/export/html2canvas-clone.mjs +1 -1
  65. package/dist/pptx/index.cjs +3065 -2993
  66. package/dist/pptx/index.mjs +4 -4
  67. package/dist/pptx/render/chart-3d-oblique-layout.d.ts.map +1 -1
  68. package/dist/pptx/render/chart-3d-persp-bars.d.ts.map +1 -1
  69. package/dist/pptx/render/chart-3d-persp-layout.d.ts.map +1 -1
  70. package/dist/pptx/render/chart-axis-range.d.ts +7 -0
  71. package/dist/pptx/render/chart-axis-range.d.ts.map +1 -1
  72. package/dist/pptx/render/chart-axis-render.d.ts +3 -1
  73. package/dist/pptx/render/chart-axis-render.d.ts.map +1 -1
  74. package/dist/pptx/render/chart-axis-style.d.ts +5 -0
  75. package/dist/pptx/render/chart-axis-style.d.ts.map +1 -1
  76. package/dist/pptx/render/chart-axis.d.ts +1 -1
  77. package/dist/pptx/render/chart-axis.d.ts.map +1 -1
  78. package/dist/pptx/render/chart-bar-cluster-geometry.d.ts +1 -1
  79. package/dist/pptx/render/chart-bar-cluster-geometry.d.ts.map +1 -1
  80. package/dist/pptx/render/chart-cartesian-area.d.ts.map +1 -1
  81. package/dist/pptx/render/chart-cartesian-axes.d.ts.map +1 -1
  82. package/dist/pptx/render/chart-cartesian-bars.d.ts +3 -3
  83. package/dist/pptx/render/chart-cartesian-line-area.d.ts.map +1 -1
  84. package/dist/pptx/render/chart-cartesian-percent-stacked.d.ts.map +1 -1
  85. package/dist/pptx/render/chart-cartesian-stacked-labels.d.ts +11 -7
  86. package/dist/pptx/render/chart-cartesian-stacked-labels.d.ts.map +1 -1
  87. package/dist/pptx/render/chart-cartesian.d.ts.map +1 -1
  88. package/dist/pptx/render/chart-combo-stock.cjs +3 -3
  89. package/dist/pptx/render/chart-combo-stock.mjs +1 -1
  90. package/dist/pptx/render/chart-combo.d.ts.map +1 -1
  91. package/dist/pptx/render/chart-data-label-anchor.d.ts +4 -1
  92. package/dist/pptx/render/chart-data-label-anchor.d.ts.map +1 -1
  93. package/dist/pptx/render/chart-gridlines-toggle.d.ts +13 -1
  94. package/dist/pptx/render/chart-gridlines-toggle.d.ts.map +1 -1
  95. package/dist/pptx/render/chart-helpers.d.ts +13 -13
  96. package/dist/pptx/render/chart-helpers.d.ts.map +1 -1
  97. package/dist/pptx/render/chart-horizontal-bars-helpers.d.ts +7 -3
  98. package/dist/pptx/render/chart-horizontal-bars-helpers.d.ts.map +1 -1
  99. package/dist/pptx/render/chart-horizontal-bars.d.ts.map +1 -1
  100. package/dist/pptx/render/chart-interaction-stacked.d.ts.map +1 -1
  101. package/dist/pptx/render/chart-line-path.d.ts +9 -0
  102. package/dist/pptx/render/chart-line-path.d.ts.map +1 -1
  103. package/dist/pptx/render/chart-overlays.cjs +7 -7
  104. package/dist/pptx/render/chart-overlays.mjs +1 -1
  105. package/dist/pptx/render/chart-palette.d.ts +5 -14
  106. package/dist/pptx/render/chart-palette.d.ts.map +1 -1
  107. package/dist/pptx/render/chart-plot-clip.d.ts +37 -0
  108. package/dist/pptx/render/chart-plot-clip.d.ts.map +1 -0
  109. package/dist/pptx/render/chart-quick-action-styles.d.ts +5 -3
  110. package/dist/pptx/render/chart-quick-action-styles.d.ts.map +1 -1
  111. package/dist/pptx/render/chart-scatter-x-axis.d.ts.map +1 -1
  112. package/dist/pptx/render/chart-style-palette.d.ts +52 -0
  113. package/dist/pptx/render/chart-style-palette.d.ts.map +1 -0
  114. package/dist/pptx/render/chart-surface-treemap.cjs +4 -4
  115. package/dist/pptx/render/chart-surface-treemap.mjs +1 -1
  116. package/dist/pptx/render/chart-view-model-bars.d.ts +32 -1
  117. package/dist/pptx/render/chart-view-model-bars.d.ts.map +1 -1
  118. package/dist/pptx/render/chart-view-model-build.d.ts.map +1 -1
  119. package/dist/pptx/render/chart-view-model.cjs +53 -41
  120. package/dist/pptx/render/chart-view-model.mjs +1 -1
  121. package/dist/pptx/render/chart-waterfall-map.cjs +6 -6
  122. package/dist/pptx/render/chart-waterfall-map.mjs +1 -1
  123. package/dist/pptx/render/device-pixel-stroke.d.ts +101 -0
  124. package/dist/pptx/render/device-pixel-stroke.d.ts.map +1 -0
  125. package/dist/pptx/render/export-clone.d.ts +4 -0
  126. package/dist/pptx/render/export-clone.d.ts.map +1 -1
  127. package/dist/pptx/render/foreign-object-svg-document.d.ts +12 -0
  128. package/dist/pptx/render/foreign-object-svg-document.d.ts.map +1 -1
  129. package/dist/pptx/render/index.d.ts +3 -0
  130. package/dist/pptx/render/index.d.ts.map +1 -1
  131. package/dist/pptx/render/stroke-outline.d.ts +6 -0
  132. package/dist/pptx/render/stroke-outline.d.ts.map +1 -1
  133. package/dist/pptx/render/stroke-style.d.ts +8 -2
  134. package/dist/pptx/render/stroke-style.d.ts.map +1 -1
  135. package/dist/pptx/render/tab-row-actions.d.ts +40 -0
  136. package/dist/pptx/render/tab-row-actions.d.ts.map +1 -0
  137. package/dist/pptx/render/table-cell-css.d.ts +3 -2
  138. package/dist/pptx/render/table-cell-css.d.ts.map +1 -1
  139. package/dist/pptx/render/table-cell-edit.d.ts +1 -1
  140. package/dist/pptx/render/table-cell-edit.d.ts.map +1 -1
  141. package/dist/pptx/render/table-cell-paragraphs.d.ts +29 -0
  142. package/dist/pptx/render/table-cell-paragraphs.d.ts.map +1 -0
  143. package/dist/pptx/render/table-style-borders.d.ts.map +1 -1
  144. package/dist/pptx/render/table-style.d.ts +2 -0
  145. package/dist/pptx/render/table-style.d.ts.map +1 -1
  146. package/dist/pptx/render/title-bar.d.ts +5 -0
  147. package/dist/pptx/render/title-bar.d.ts.map +1 -1
  148. package/dist/pptx/render/viewer-root-options.d.ts +11 -3
  149. package/dist/pptx/render/viewer-root-options.d.ts.map +1 -1
  150. package/dist/pptx/web-components/index.d.ts.map +1 -1
  151. package/dist/pptx/web-components/office-token-bridge.d.ts +1 -1
  152. package/dist/pptx/web-components/office-token-bridge.d.ts.map +1 -1
  153. package/dist/pptx/web-components/ribbon-actions.d.ts +8 -0
  154. package/dist/pptx/web-components/ribbon-actions.d.ts.map +1 -0
  155. package/dist/presence.js +3 -3
  156. package/dist/ribbon/ribbon-actions.d.ts +119 -0
  157. package/dist/ribbon/ribbon-actions.d.ts.map +1 -0
  158. package/dist/ribbon/ribbon-tabs.d.ts +2 -1
  159. package/dist/ribbon/ribbon-tabs.d.ts.map +1 -1
  160. package/dist/smartart/smartart-svg.d.ts +3 -2
  161. package/dist/smartart.js +3 -3
  162. package/dist/suite/attachment-store.d.ts +13 -0
  163. package/dist/suite/document-store.d.ts +31 -0
  164. package/dist/suite/index.d.ts +2 -0
  165. package/dist/suite.js +132 -1
  166. package/dist/teams/app/channel-tab.d.ts +5 -0
  167. package/dist/teams/chat-composer.d.ts +3 -0
  168. package/dist/teams.js +7 -7
  169. package/dist/theme.js +2 -2
  170. package/dist/tokens.d.ts +9 -0
  171. package/dist/tokens.d.ts.map +1 -1
  172. package/dist/visio/styles/index.d.ts +2 -0
  173. package/dist/visio/styles/theme.d.ts +11 -0
  174. package/dist/visio/styles.d.ts +2 -2
  175. package/dist/visio.js +66 -21
  176. package/dist/xlsx/backstage/index.d.ts +4 -1
  177. package/dist/xlsx/backstage/pages-share.d.ts +19 -0
  178. package/dist/xlsx/backstage/parts.d.ts +3 -0
  179. package/dist/xlsx/calc-preparation.d.ts +44 -0
  180. package/dist/xlsx/chart-fill-binding.d.ts +2 -2
  181. package/dist/xlsx/chart-series-gradient-type.d.ts +3 -2
  182. package/dist/xlsx/collaboration-session.d.ts +9 -0
  183. package/dist/xlsx/collaboration-types.d.ts +41 -0
  184. package/dist/xlsx/collaboration.d.ts +56 -0
  185. package/dist/xlsx/component.d.ts +8 -0
  186. package/dist/xlsx/dialogs/comments-list.d.ts +4 -0
  187. package/dist/xlsx/dialogs/help-dialogs.d.ts +1 -1
  188. package/dist/xlsx/editor-core.d.ts +6 -0
  189. package/dist/xlsx/element-api.d.ts +19 -1
  190. package/dist/xlsx/events.d.ts +4 -1
  191. package/dist/xlsx/grid/remote-layer.d.ts +3 -0
  192. package/dist/xlsx/grid/sparkline.d.ts +3 -0
  193. package/dist/xlsx/grid/styles.d.ts +1 -1
  194. package/dist/xlsx/index.d.ts +1 -0
  195. package/dist/xlsx/ribbon-actions.d.ts +22 -0
  196. package/dist/xlsx/shell-commands.d.ts +1 -1
  197. package/dist/xlsx/title-bar.d.ts +4 -2
  198. package/dist/xlsx.js +801 -92
  199. package/package.json +2 -2
  200. package/dist/pptx/web-components/status-bar-styles.d.ts +0 -3
  201. package/dist/pptx/web-components/status-bar-styles.d.ts.map +0 -1
  202. package/dist/pptx/web-components/title-bar-styles.d.ts +0 -7
  203. package/dist/pptx/web-components/title-bar-styles.d.ts.map +0 -1
@@ -1,7 +1,7 @@
1
- import { createIconSvg, paintIcon, getIcon } from './chunk-BOX43CZD.js';
2
- import { initialsOf } from './chunk-3FPW7M6U.js';
3
- import { OfficeElement, controlStyles, definer, valueOn, flag, present, triState, withTokens } from './chunk-USDLALB5.js';
4
- import { tok, OFFICE_TOKENS } from './chunk-JFJXBYRD.js';
1
+ import { createIconSvg, paintIcon, getIcon } from './chunk-M6GF5ED2.js';
2
+ import { initialsOf } from './chunk-TWQ45BFL.js';
3
+ import { OfficeElement, controlStyles, definer, valueOn, flag, present, triState, withTokens } from './chunk-IY7QJLQG.js';
4
+ import { tok, OFFICE_TOKENS } from './chunk-2WLRFPMW.js';
5
5
  import { html, LitElement, nothing, render, svg } from 'lit';
6
6
  import { ifDefined } from 'lit/directives/if-defined.js';
7
7
  import { repeat } from 'lit/directives/repeat.js';
@@ -1009,6 +1009,299 @@ var OfficeUiFindBar = class extends OfficeElement {
1009
1009
  };
1010
1010
  var defineFindBar = definer("office-ui-find-bar", () => OfficeUiFindBar);
1011
1011
 
1012
+ // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/comments/comments-pane.css?raw
1013
+ var comments_pane_default = ":host {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: var(--office-space-2);\n width: var(--office-comments-pane-width);\n padding: var(--office-space-2-5) var(--office-space-3);\n overflow-y: auto;\n border-inline-start: var(--office-border-width) solid var(--office-border);\n background: var(--office-surface);\n color: var(--office-foreground);\n font: var(--office-font-size-sm) / var(--office-line-height) var(--office-font);\n}\n:host([hidden]) {\n display: none;\n}\n:host([list-only]) {\n width: auto;\n padding: 0;\n border: 0;\n background: transparent;\n}\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--office-space-2);\n}\nh2 {\n margin: 0;\n font-size: var(--office-font-size);\n font-weight: var(--office-font-weight-bold);\n}\n.composer,\n.reply,\n.edit {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--office-space-1);\n}\ntextarea {\n box-sizing: border-box;\n width: 100%;\n min-height: var(--office-control-height-lg);\n resize: vertical;\n padding: var(--office-space-1) var(--office-space-1-5);\n font: inherit;\n color: inherit;\n border: var(--office-border-width) solid var(--office-border);\n border-radius: var(--office-radius-sm);\n background: var(--office-background);\n}\nbutton {\n min-height: var(--office-input-height);\n padding: var(--office-space-0) var(--office-space-2);\n font: inherit;\n color: inherit;\n cursor: pointer;\n border: var(--office-border-width) solid var(--office-border);\n border-radius: var(--office-radius-sm);\n background: var(--office-background);\n}\nbutton:disabled,\ntextarea:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.threads {\n display: flex;\n flex-direction: column;\n gap: var(--office-space-2);\n}\n.thread {\n display: flex;\n flex-direction: column;\n gap: var(--office-space-1-5);\n padding: var(--office-space-2);\n border: var(--office-border-width) solid var(--office-border);\n border-radius: var(--office-radius);\n background: var(--office-background);\n cursor: pointer;\n}\n.thread[aria-current='true'] {\n border-color: var(--office-accent);\n box-shadow: inset var(--office-border-width-thick) 0 0 var(--office-accent);\n}\n.thread[data-resolved='true'] {\n opacity: 0.65;\n}\n.anchor {\n display: flex;\n align-items: center;\n gap: var(--office-space-1-5);\n color: var(--office-muted-foreground);\n font-size: var(--office-font-size-xs);\n}\n.anchor-label {\n font-weight: var(--office-font-weight-medium);\n}\n.badge {\n padding: 0 var(--office-space-1);\n border-radius: var(--office-radius-full);\n background: var(--office-selected);\n}\n.comment {\n display: flex;\n flex-direction: column;\n gap: var(--office-space-1);\n cursor: auto;\n}\n.comment.reply {\n margin-inline-start: var(--office-space-3);\n padding-inline-start: var(--office-space-2);\n border-inline-start: var(--office-border-width) solid var(--office-border);\n}\n.meta {\n display: flex;\n align-items: center;\n gap: var(--office-space-1-5);\n min-width: 0;\n color: var(--office-muted-foreground);\n font-size: var(--office-font-size-xs);\n}\n.avatar {\n display: inline-grid;\n flex: none;\n place-items: center;\n width: var(--office-comment-avatar-size);\n height: var(--office-comment-avatar-size);\n border-radius: 50%;\n background: var(--office-accent);\n color: var(--office-accent-foreground);\n font-size: var(--office-font-size-2xs);\n font-weight: var(--office-font-weight-bold);\n}\n.author {\n overflow: hidden;\n color: var(--office-foreground);\n font-weight: var(--office-font-weight-medium);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\ntime {\n margin-inline-start: auto;\n white-space: nowrap;\n}\n.text {\n margin: 0;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--office-space-1);\n}\n.empty {\n margin: 0;\n color: var(--office-muted-foreground);\n}\n.thread:focus-visible,\ntextarea:focus-visible,\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: calc(var(--office-focus-offset) / 2);\n}\n@media (forced-colors: active) {\n .thread[aria-current='true'] {\n border-color: Highlight;\n }\n .avatar {\n border: var(--office-border-width) solid CanvasText;\n }\n}\n";
1014
+
1015
+ // src/comments/types.ts
1016
+ var DEFAULT_COMMENTS_LABELS = {
1017
+ heading: "Comments",
1018
+ list: "Comments",
1019
+ close: "Close comments",
1020
+ newComment: "New comment",
1021
+ add: "Add comment",
1022
+ reply: "Reply",
1023
+ resolve: "Resolve",
1024
+ reopen: "Reopen",
1025
+ resolved: "Resolved",
1026
+ edit: "Edit",
1027
+ save: "Save",
1028
+ cancel: "Cancel",
1029
+ delete: "Delete",
1030
+ edited: "Edited",
1031
+ empty: "No comments"
1032
+ };
1033
+ function commentInitials(author) {
1034
+ const words = author.trim().split(/\s+/).filter(Boolean);
1035
+ const letters = words.length > 1 ? [words[0], words.at(-1)] : words;
1036
+ return letters.map((word) => [...word][0] ?? "").join("").toLocaleUpperCase();
1037
+ }
1038
+ function formatCommentTime(created, locale) {
1039
+ if (!created) return "";
1040
+ if (!/^\d{4}-\d{2}-\d{2}/.test(created)) return created;
1041
+ const date = new Date(created);
1042
+ if (Number.isNaN(date.getTime())) return created;
1043
+ try {
1044
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short" }).format(
1045
+ date
1046
+ );
1047
+ } catch {
1048
+ return created;
1049
+ }
1050
+ }
1051
+
1052
+ // src/comments/comments-pane.ts
1053
+ var INTERACTIVE = /* @__PURE__ */ new Set(["BUTTON", "TEXTAREA", "INPUT", "A", "SELECT"]);
1054
+ var OfficeUiCommentsPane = class extends OfficeElement {
1055
+ static styles = controlStyles(comments_pane_default);
1056
+ static properties = {
1057
+ threads: { attribute: false },
1058
+ activeThreadId: { attribute: "active-thread-id", type: String },
1059
+ readOnly: { attribute: "read-only", ...flag },
1060
+ listOnly: { attribute: "list-only", ...flag },
1061
+ closable: flag,
1062
+ addDisabled: { attribute: "add-disabled", ...flag },
1063
+ currentAuthor: { attribute: "current-author", type: String },
1064
+ labels: { attribute: false },
1065
+ classNames: { attribute: false },
1066
+ locale: { type: String }
1067
+ };
1068
+ focusedId;
1069
+ editingId;
1070
+ constructor() {
1071
+ super();
1072
+ this.threads = [];
1073
+ this.activeThreadId = null;
1074
+ this.readOnly = false;
1075
+ this.listOnly = false;
1076
+ this.closable = false;
1077
+ this.addDisabled = false;
1078
+ this.currentAuthor = null;
1079
+ this.labels = {};
1080
+ this.classNames = {};
1081
+ this.locale = null;
1082
+ }
1083
+ get text() {
1084
+ return { ...DEFAULT_COMMENTS_LABELS, ...this.labels };
1085
+ }
1086
+ get locked() {
1087
+ return present(this.readOnly);
1088
+ }
1089
+ /** The thread that takes Tab focus: the last one focused, else the active one, else the first. */
1090
+ get rovingId() {
1091
+ const ids = this.threads.map((thread) => thread.id);
1092
+ if (this.focusedId && ids.includes(this.focusedId)) return this.focusedId;
1093
+ if (this.activeThreadId && ids.includes(this.activeThreadId)) return this.activeThreadId;
1094
+ return ids[0];
1095
+ }
1096
+ card(id) {
1097
+ if (id === void 0) return null;
1098
+ return [...this.renderRoot.querySelectorAll(".thread")].find(
1099
+ (card) => card.dataset.threadId === id
1100
+ ) ?? null;
1101
+ }
1102
+ /** Focus the current thread, or the new-comment box when there is none. */
1103
+ focus(options) {
1104
+ const target = this.card(this.rovingId) ?? this.renderRoot.querySelector("textarea");
1105
+ if (target) target.focus(options);
1106
+ else super.focus(options);
1107
+ }
1108
+ submitNew() {
1109
+ const box = this.renderRoot.querySelector("textarea.new");
1110
+ const text = box?.value.trim();
1111
+ if (!box || !text || this.locked || present(this.addDisabled)) return;
1112
+ box.value = "";
1113
+ this.fire("comment-add", { text });
1114
+ }
1115
+ submitReply(threadId) {
1116
+ const box = this.card(threadId)?.querySelector("textarea.reply-box");
1117
+ const text = box?.value.trim();
1118
+ if (!box || !text || this.locked) return;
1119
+ box.value = "";
1120
+ this.fire("comment-reply", { threadId, text });
1121
+ }
1122
+ startEdit(commentId) {
1123
+ this.editingId = commentId;
1124
+ this.requestUpdate();
1125
+ this.renderRoot.querySelector("textarea.edit-box")?.focus();
1126
+ }
1127
+ stopEdit() {
1128
+ this.editingId = void 0;
1129
+ this.requestUpdate();
1130
+ }
1131
+ saveEdit(thread, comment) {
1132
+ const box = this.renderRoot.querySelector("textarea.edit-box");
1133
+ const text = box?.value.trim();
1134
+ this.stopEdit();
1135
+ if (!text || text === comment.text || this.locked) return;
1136
+ this.fire("comment-edit", { threadId: thread.id, commentId: comment.id, text });
1137
+ }
1138
+ /** Ctrl+Enter (Cmd+Enter) posts from any box, like Office. */
1139
+ onBoxKey(event, submit) {
1140
+ if (event.key === "Enter" && (event.ctrlKey || event.metaKey) && !event.isComposing) {
1141
+ event.preventDefault();
1142
+ submit();
1143
+ }
1144
+ }
1145
+ onEditKey(event, thread, comment) {
1146
+ if (event.key !== "Escape") return this.onBoxKey(event, () => this.saveEdit(thread, comment));
1147
+ event.preventDefault();
1148
+ event.stopPropagation();
1149
+ this.stopEdit();
1150
+ }
1151
+ select(threadId) {
1152
+ this.focusedId = threadId;
1153
+ this.requestUpdate();
1154
+ this.fire("thread-select", { threadId });
1155
+ }
1156
+ onThreadClick(event, threadId) {
1157
+ const inner = event.composedPath().some((node) => node instanceof HTMLElement && INTERACTIVE.has(node.tagName));
1158
+ if (!inner) this.select(threadId);
1159
+ }
1160
+ onListKey(event) {
1161
+ const card = event.composedPath()[0];
1162
+ if (!(card instanceof HTMLElement) || !card.classList.contains("thread")) return;
1163
+ const ids = this.threads.map((thread) => thread.id);
1164
+ const at = ids.indexOf(card.dataset.threadId ?? "");
1165
+ if (at < 0) return;
1166
+ const moves = {
1167
+ ArrowDown: Math.min(at + 1, ids.length - 1),
1168
+ ArrowUp: Math.max(at - 1, 0),
1169
+ Home: 0,
1170
+ End: ids.length - 1
1171
+ };
1172
+ const move = moves[event.key];
1173
+ if (move !== void 0) {
1174
+ event.preventDefault();
1175
+ this.focusedId = ids[move];
1176
+ this.requestUpdate();
1177
+ this.card(this.focusedId)?.focus();
1178
+ } else if (event.key === "Enter" || event.key === " ") {
1179
+ event.preventDefault();
1180
+ this.select(ids[at]);
1181
+ }
1182
+ }
1183
+ renderActions(thread, comment, first) {
1184
+ if (present(this.listOnly)) return nothing;
1185
+ const l = this.text;
1186
+ const locked = this.locked;
1187
+ const own = Boolean(this.currentAuthor) && comment.author === this.currentAuthor;
1188
+ const threadId = thread.id;
1189
+ const status = thread.resolved ? "reopen" : "resolve";
1190
+ return html`<div class="actions"
1191
+ >${first ? html`<button type="button" data-action=${status} ?disabled=${locked} @click=${() => thread.resolved ? this.fire("thread-reopen", { threadId }) : this.fire("thread-resolve", { threadId })}>${thread.resolved ? l.reopen : l.resolve}</button>` : nothing}${own && this.editingId !== comment.id ? html`<button type="button" data-action="edit" ?disabled=${locked} @click=${() => this.startEdit(comment.id)}>${l.edit}</button>` : nothing}<button
1192
+ type="button"
1193
+ data-action="delete"
1194
+ ?disabled=${locked}
1195
+ @click=${() => this.fire("comment-delete", { threadId, commentId: comment.id })}
1196
+ >${l.delete}</button
1197
+ ></div
1198
+ >`;
1199
+ }
1200
+ renderComment(thread, comment, first) {
1201
+ const l = this.text;
1202
+ const time = formatCommentTime(comment.created, this.locale ?? void 0);
1203
+ const body = this.editingId === comment.id && !this.locked ? html`<div class="edit">
1204
+ <textarea
1205
+ class="edit-box"
1206
+ aria-label=${l.edit}
1207
+ .value=${comment.text}
1208
+ @keydown=${(event) => this.onEditKey(event, thread, comment)}
1209
+ ></textarea
1210
+ ><div class="actions"
1211
+ ><button
1212
+ type="button"
1213
+ data-action="save"
1214
+ @click=${() => this.saveEdit(thread, comment)}
1215
+ >${l.save}</button
1216
+ ><button type="button" data-action="cancel" @click=${() => this.stopEdit()}
1217
+ >${l.cancel}</button
1218
+ ></div
1219
+ ></div
1220
+ >` : html`<p class="text">${comment.text}</p>`;
1221
+ return html`<div
1222
+ class="comment ${first ? "root" : "reply"} ${this.classNames.comment ?? ""}"
1223
+ data-comment-id=${comment.id}
1224
+ data-resolved=${String(thread.resolved)}
1225
+ ><div class="meta"
1226
+ ><span
1227
+ class="avatar"
1228
+ aria-hidden="true"
1229
+ style=${ifDefined(comment.color ? `background:${comment.color}` : void 0)}
1230
+ >${comment.initials || commentInitials(comment.author)}</span
1231
+ ><span class="author">${comment.author}</span
1232
+ >${time ? html`<time datetime=${ifDefined(comment.created)}>${time}</time>` : nothing}${comment.edited ? html`<span class="edited">${l.edited}</span>` : nothing}</div
1233
+ >${body}${this.renderActions(thread, comment, first)}</div
1234
+ >`;
1235
+ }
1236
+ renderThread(thread, roving) {
1237
+ const l = this.text;
1238
+ const [first, ...replies] = thread.comments;
1239
+ const badge = thread.resolved && l.resolved;
1240
+ const anchor = thread.anchorLabel || badge ? html`<div class="anchor"
1241
+ >${thread.anchorLabel ? html`<span class="anchor-label">${thread.anchorLabel}</span>` : nothing}${badge ? html`<span class="badge">${l.resolved}</span>` : nothing}</div
1242
+ >` : nothing;
1243
+ const reply = present(this.listOnly) ? nothing : html`<div class="reply">
1244
+ <textarea
1245
+ class="reply-box"
1246
+ aria-label=${l.reply}
1247
+ placeholder=${l.reply}
1248
+ ?disabled=${this.locked}
1249
+ @keydown=${(event) => this.onBoxKey(event, () => this.submitReply(thread.id))}
1250
+ ></textarea
1251
+ ><button
1252
+ type="button"
1253
+ data-action="reply"
1254
+ ?disabled=${this.locked}
1255
+ @click=${() => this.submitReply(thread.id)}
1256
+ >${l.reply}</button
1257
+ ></div
1258
+ >`;
1259
+ return html`<article
1260
+ role="listitem"
1261
+ class="thread ${this.classNames.thread ?? ""}"
1262
+ data-thread-id=${thread.id}
1263
+ data-resolved=${String(thread.resolved)}
1264
+ aria-current=${ifDefined(thread.id === this.activeThreadId ? "true" : void 0)}
1265
+ tabindex=${thread.id === roving ? "0" : "-1"}
1266
+ @click=${(event) => this.onThreadClick(event, thread.id)}
1267
+ >${anchor}${first ? this.renderComment(thread, first, true) : nothing}${replies.map((comment) => this.renderComment(thread, comment, false))}${reply}</article
1268
+ >`;
1269
+ }
1270
+ render() {
1271
+ const l = this.text;
1272
+ const closable = present(this.closable);
1273
+ const header = l.heading || closable ? html`<div class="header"
1274
+ >${l.heading ? html`<h2>${l.heading}</h2>` : nothing}${closable ? html`<button type="button" class="close" data-action="close" aria-label=${l.close} @click=${() => this.fire("comments-close", {})}>${l.close}</button>` : nothing}</div
1275
+ >` : nothing;
1276
+ const composer = present(this.listOnly) ? nothing : html`<div class="composer">
1277
+ <textarea
1278
+ class="new"
1279
+ aria-label=${l.newComment}
1280
+ placeholder=${l.newComment}
1281
+ ?disabled=${this.locked}
1282
+ @keydown=${(event) => this.onBoxKey(event, () => this.submitNew())}
1283
+ ></textarea
1284
+ ><button
1285
+ type="button"
1286
+ data-action="add"
1287
+ ?disabled=${this.locked || present(this.addDisabled)}
1288
+ @click=${() => this.submitNew()}
1289
+ >${l.add}</button
1290
+ ></div
1291
+ >`;
1292
+ const roving = this.rovingId;
1293
+ const list = this.threads.length ? html`<div class="threads" role="list" aria-label=${l.list} @keydown=${this.onListKey}
1294
+ >${repeat(
1295
+ this.threads,
1296
+ (thread) => thread.id,
1297
+ (thread) => this.renderThread(thread, roving)
1298
+ )}</div
1299
+ >` : html`<p class="empty">${l.empty}</p>`;
1300
+ return html`${header}${composer}${list}`;
1301
+ }
1302
+ };
1303
+ var defineCommentsPane = definer("office-ui-comments-pane", () => OfficeUiCommentsPane);
1304
+
1012
1305
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/chrome/print-preview.css?raw
1013
1306
  var print_preview_default = ":host {\n display: block;\n max-width: var(--office-print-preview-width);\n font: var(--office-font-size-sm) var(--office-font);\n color: var(--office-foreground);\n}\n.sheet {\n padding: var(--office-space-3);\n border: var(--office-border-width) solid var(--office-border);\n background: var(--office-paper);\n box-shadow: var(--office-shadow-sm);\n}\n.sheet > * {\n display: block;\n width: 100%;\n height: auto;\n}\n.empty {\n color: var(--office-muted-foreground);\n}\n.nav {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--office-space-2);\n margin-top: var(--office-space-2);\n}\n.nav[hidden] {\n display: none;\n}\nbutton {\n min-width: var(--office-target-size);\n min-height: var(--office-target-size);\n font: inherit;\n color: inherit;\n border: var(--office-border-width) solid var(--office-border);\n border-radius: var(--office-radius-sm);\n background: var(--office-background);\n cursor: pointer;\n}\nbutton:disabled {\n opacity: 0.5;\n cursor: default;\n}\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: calc(var(--office-focus-offset) / 2);\n}\n";
1014
1307
 
@@ -1100,7 +1393,7 @@ var OfficeUiPrintPreview = class extends OfficeElement {
1100
1393
  var definePrintPreview = definer("office-ui-print-preview", () => OfficeUiPrintPreview);
1101
1394
 
1102
1395
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/ribbon/ribbon-tabs.css?raw
1103
- var ribbon_tabs_default = ":host {\n display: block;\n min-width: 0;\n}\n.head {\n display: flex;\n align-items: stretch;\n min-width: 0;\n border-bottom: var(--office-border-width) solid var(--office-border);\n}\n.file {\n flex: none;\n min-height: var(--office-ribbon-tab-height);\n margin: 0 var(--office-space-1) 0 0;\n padding: var(--office-space-1-5) var(--office-space-4);\n border: 0;\n border-radius: 0;\n background: var(--office-accent);\n color: var(--office-accent-foreground);\n font: inherit;\n font-size: var(--office-font-size);\n cursor: pointer;\n}\n.file:hover {\n background: var(--office-accent-hover);\n}\n.file[hidden] {\n display: none;\n}\n[role='tablist'] {\n display: flex;\n flex: 0 1 auto;\n align-items: stretch;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n[role='tab'] {\n position: relative;\n flex: none;\n min-height: var(--office-ribbon-tab-height);\n padding: var(--office-space-1-5) var(--office-space-3);\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--office-muted-foreground);\n font: inherit;\n font-size: var(--office-font-size);\n cursor: pointer;\n}\n[role='tab']:hover {\n color: var(--office-foreground);\n background: var(--office-surface);\n}\n[role='tab'][aria-selected='true'] {\n color: var(--office-accent);\n}\n[role='tab'][aria-selected='true']::after {\n content: '';\n position: absolute;\n inset: auto 0 0;\n height: var(--office-tab-indicator-width);\n background: var(--office-accent);\n}\n[role='tab'][data-contextual],\n[role='tab'][data-contextual][aria-selected='true'] {\n color: var(--office-ribbon-contextual);\n}\n[role='tab'][data-contextual][aria-selected='true']::after {\n background: var(--office-ribbon-contextual);\n}\n.file:focus-visible,\n[role='tab']:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: calc(-1 * var(--office-focus-width));\n}\n::slotted([slot='search']) {\n align-self: center;\n}\n\n.collapse {\n flex: none;\n align-self: center;\n width: var(--office-target-size);\n height: var(--office-target-size);\n margin-inline: auto var(--office-space-1);\n padding: 0;\n border: 0;\n border-radius: var(--office-radius-sm);\n background: none;\n color: var(--office-muted-foreground);\n cursor: pointer;\n}\n.collapse[hidden] {\n display: none;\n}\n.collapse:hover {\n background: var(--office-surface);\n}\n.collapse:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n}\n.collapse .glyph {\n width: var(--office-icon-size);\n height: var(--office-icon-size);\n fill: none;\n stroke: currentColor;\n stroke-width: 1.5;\n transform: rotate(90deg);\n}\n.collapse[aria-pressed='true'] .glyph {\n transform: rotate(-90deg);\n}\n:host([collapsed][peek]) {\n position: relative;\n}\n:host([collapsed][peek]) ::slotted([data-ribbon-tab]:not([hidden])) {\n position: absolute;\n inset: 100% 0 auto;\n z-index: 60;\n border-bottom: var(--office-border-width) solid var(--office-border);\n background: var(--office-background);\n box-shadow: var(--office-shadow);\n}\n\n@media (max-width: 760px), (pointer: coarse) {\n .file,\n [role='tab'] {\n min-height: var(--office-target-size-touch);\n }\n .file {\n min-width: var(--office-ribbon-file-min-width);\n }\n}\n@media (forced-colors: active) {\n .file {\n border: var(--office-border-width) solid ButtonText;\n }\n [role='tab'][aria-selected='true']::after {\n background: Highlight;\n }\n}\n";
1396
+ var ribbon_tabs_default = ":host {\n display: block;\n min-width: 0;\n}\n.head {\n display: flex;\n align-items: stretch;\n min-width: 0;\n border-bottom: var(--office-border-width) solid var(--office-border);\n}\n.file {\n flex: none;\n min-height: var(--office-ribbon-tab-height);\n margin: 0 var(--office-space-1) 0 0;\n padding: var(--office-space-1-5) var(--office-space-4);\n border: 0;\n border-radius: 0;\n background: var(--office-accent);\n color: var(--office-accent-foreground);\n font: inherit;\n font-size: var(--office-font-size);\n cursor: pointer;\n}\n.file:hover {\n background: var(--office-accent-hover);\n}\n.file[hidden] {\n display: none;\n}\n[role='tablist'] {\n display: flex;\n flex: 0 1 auto;\n align-items: stretch;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: none;\n}\n[role='tab'] {\n position: relative;\n flex: none;\n min-height: var(--office-ribbon-tab-height);\n padding: var(--office-space-1-5) var(--office-space-3);\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--office-muted-foreground);\n font: inherit;\n font-size: var(--office-font-size);\n cursor: pointer;\n}\n[role='tab']:hover {\n color: var(--office-foreground);\n background: var(--office-surface);\n}\n[role='tab'][aria-selected='true'] {\n color: var(--office-accent);\n}\n[role='tab'][aria-selected='true']::after {\n content: '';\n position: absolute;\n inset: auto 0 0;\n height: var(--office-tab-indicator-width);\n background: var(--office-accent);\n}\n[role='tab'][data-contextual],\n[role='tab'][data-contextual][aria-selected='true'] {\n color: var(--office-ribbon-contextual);\n}\n[role='tab'][data-contextual][aria-selected='true']::after {\n background: var(--office-ribbon-contextual);\n}\n.file:focus-visible,\n[role='tab']:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: calc(-1 * var(--office-focus-width));\n}\n::slotted([slot='search']) {\n align-self: center;\n}\n/* The auto start margin keeps the actions, and the collapse button after them, at the right end of\n the tab row even while the slot is empty. */\nslot[name='actions'] {\n display: flex;\n flex: none;\n align-items: center;\n gap: var(--office-space-1);\n margin-inline: auto var(--office-space-1);\n}\n\n.collapse {\n flex: none;\n align-self: center;\n width: var(--office-target-size);\n height: var(--office-target-size);\n margin-inline: 0 var(--office-space-1);\n padding: 0;\n border: 0;\n border-radius: var(--office-radius-sm);\n background: none;\n color: var(--office-muted-foreground);\n cursor: pointer;\n}\n.collapse[hidden] {\n display: none;\n}\n.collapse:hover {\n background: var(--office-surface);\n}\n.collapse:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n}\n.collapse .glyph {\n width: var(--office-icon-size);\n height: var(--office-icon-size);\n fill: none;\n stroke: currentColor;\n stroke-width: 1.5;\n transform: rotate(90deg);\n}\n.collapse[aria-pressed='true'] .glyph {\n transform: rotate(-90deg);\n}\n:host([collapsed][peek]) {\n position: relative;\n}\n:host([collapsed][peek]) ::slotted([data-ribbon-tab]:not([hidden])) {\n position: absolute;\n inset: 100% 0 auto;\n z-index: 60;\n border-bottom: var(--office-border-width) solid var(--office-border);\n background: var(--office-background);\n box-shadow: var(--office-shadow);\n}\n\n@media (max-width: 760px), (pointer: coarse) {\n .file,\n [role='tab'] {\n min-height: var(--office-target-size-touch);\n }\n .file {\n min-width: var(--office-ribbon-file-min-width);\n }\n}\n@media (forced-colors: active) {\n .file {\n border: var(--office-border-width) solid ButtonText;\n }\n [role='tab'][aria-selected='true']::after {\n background: Highlight;\n }\n}\n";
1104
1397
 
1105
1398
  // src/ribbon/ribbon-tabs.ts
1106
1399
  var OfficeUiRibbon = class extends OfficeElement {
@@ -1322,6 +1615,7 @@ var OfficeUiRibbon = class extends OfficeElement {
1322
1615
  </div>
1323
1616
  <slot name="search"></slot>
1324
1617
  <slot name="end"></slot>
1618
+ <slot name="actions" part="actions"></slot>
1325
1619
  <button
1326
1620
  class="collapse"
1327
1621
  part="collapse"
@@ -1341,6 +1635,72 @@ var OfficeUiRibbon = class extends OfficeElement {
1341
1635
  };
1342
1636
  var defineRibbon = definer("office-ui-ribbon", () => OfficeUiRibbon);
1343
1637
 
1638
+ // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/ribbon/ribbon-actions.css?raw
1639
+ var ribbon_actions_default = ":host {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: var(--office-space-1-5);\n padding-inline-start: var(--office-space-2);\n color: var(--office-foreground);\n font: inherit;\n font-size: var(--office-font-size);\n}\n[hidden] {\n display: none !important;\n}\n.glyph {\n flex: none;\n width: var(--office-icon-size-md);\n height: var(--office-icon-size-md);\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n.glyph:not([data-painted]) {\n display: none;\n}\n.mode {\n position: relative;\n display: inline-flex;\n align-items: center;\n height: var(--office-control-height-md);\n}\n.mode > .glyph {\n position: absolute;\n inset-inline-start: var(--office-space-2);\n pointer-events: none;\n}\n.mode-select {\n height: var(--office-control-height-md);\n padding: 0 var(--office-space-1-5) 0 calc(var(--office-space-2) * 2 + var(--office-icon-size-md));\n border: var(--office-border-width) solid var(--office-border);\n border-radius: var(--office-radius-sm);\n background: var(--office-background);\n color: var(--office-foreground);\n font: inherit;\n cursor: pointer;\n}\nbutton {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--office-space-1-5);\n height: var(--office-control-height-md);\n padding: 0 var(--office-space-2-5);\n border: var(--office-border-width) solid var(--office-border);\n border-radius: var(--office-radius-sm);\n background: transparent;\n color: var(--office-foreground);\n font: inherit;\n white-space: nowrap;\n cursor: pointer;\n}\n.comments:hover {\n background: var(--office-surface);\n}\n.comments[aria-pressed='true'] {\n background: var(--office-selected);\n}\n.badge {\n min-width: var(--office-space-4);\n padding: 0 var(--office-space-1);\n border-radius: var(--office-radius-full);\n background: var(--office-accent);\n color: var(--office-accent-foreground);\n font-size: var(--office-font-size-2xs);\n line-height: var(--office-space-4);\n text-align: center;\n}\n.share {\n padding: 0 var(--office-space-3);\n border-color: var(--office-accent);\n background: var(--office-accent);\n color: var(--office-accent-foreground);\n}\n.share:hover,\n.share[aria-pressed='true'] {\n /* Darkened here rather than read from --office-accent-hover, which resolves where the theme\n is installed and so would miss a product's own accent. */\n filter: brightness(0.88);\n}\n.mode-select:focus-visible,\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n/* Narrow windows keep the icons and drop the labels, as Office's simplified layout does. */\n@media (max-width: 900px) {\n .label {\n display: none;\n }\n button {\n padding: 0 var(--office-space-1-5);\n }\n}\n";
1640
+
1641
+ // src/ribbon/ribbon-actions.ts
1642
+ var OfficeUiRibbonActions = class extends OfficeElement {
1643
+ static modeEvent = "office-ribbon-mode";
1644
+ static commentsEvent = "office-ribbon-comments";
1645
+ static shareEvent = "office-ribbon-share";
1646
+ static styles = controlStyles(ribbon_actions_default);
1647
+ static properties = {
1648
+ modes: { attribute: false },
1649
+ mode: { type: String },
1650
+ modeLabel: { attribute: "mode-label", type: String },
1651
+ commentsLabel: { attribute: "comments-label", type: String },
1652
+ commentsTitle: { attribute: "comments-title", type: String },
1653
+ commentsPressed: { attribute: "comments-pressed", ...flag },
1654
+ commentsCount: { attribute: "comments-count", type: Number },
1655
+ noComments: { attribute: "no-comments", ...flag },
1656
+ shareLabel: { attribute: "share-label", type: String },
1657
+ shareTitle: { attribute: "share-title", type: String },
1658
+ sharePressed: { attribute: "share-pressed", ...flag },
1659
+ noShare: { attribute: "no-share", ...flag }
1660
+ };
1661
+ constructor() {
1662
+ super();
1663
+ this.modes = [];
1664
+ this.mode = "";
1665
+ this.modeLabel = "Editing mode";
1666
+ this.commentsLabel = "Comments";
1667
+ this.commentsTitle = null;
1668
+ this.commentsPressed = false;
1669
+ this.commentsCount = 0;
1670
+ this.noComments = false;
1671
+ this.shareLabel = "Share";
1672
+ this.shareTitle = null;
1673
+ this.sharePressed = false;
1674
+ this.noShare = false;
1675
+ }
1676
+ /** The rendered control of a part, or null before the first render. */
1677
+ control(part) {
1678
+ return this.renderRoot.querySelector(`[part="${part}"]`);
1679
+ }
1680
+ onMode(event) {
1681
+ event.stopPropagation();
1682
+ const select = event.target;
1683
+ const mode = select.value;
1684
+ select.value = this.mode;
1685
+ if (mode !== this.mode) this.fire(this.events().modeEvent, { mode });
1686
+ }
1687
+ events() {
1688
+ return this.constructor;
1689
+ }
1690
+ updated() {
1691
+ const select = this.control("mode-select");
1692
+ if (select && select.value !== this.mode) select.value = this.mode;
1693
+ }
1694
+ render() {
1695
+ const modes = this.modes ?? [];
1696
+ const count = Number(this.commentsCount) || 0;
1697
+ const commentsTitle = this.commentsTitle ?? this.commentsLabel;
1698
+ const shareTitle = this.shareTitle ?? this.shareLabel;
1699
+ return html`<label class="mode" part="mode" ?hidden=${modes.length === 0}>${glyph("pencil", "glyph")}<select class="mode-select" part="mode-select" aria-label=${this.modeLabel} title=${this.modeLabel} @change=${this.onMode}>${modes.map((option) => html`<option value=${option.value} ?selected=${option.value === this.mode}>${option.label}</option>`)}</select></label><button class="comments" part="comments" type="button" aria-label=${this.commentsLabel} title=${count > 0 ? `${commentsTitle} (${count})` : commentsTitle} aria-pressed=${String(present(this.commentsPressed))} ?hidden=${present(this.noComments)} @click=${() => this.fire(this.events().commentsEvent, {})}>${glyph("message", "glyph")}<span class="label">${this.commentsLabel}</span>${count > 0 ? html`<span class="badge" aria-hidden="true">${count}</span>` : ""}</button><button class="share" part="share" type="button" aria-label=${this.shareLabel} title=${shareTitle} aria-pressed=${String(present(this.sharePressed))} ?hidden=${present(this.noShare)} @click=${() => this.fire(this.events().shareEvent, {})}>${glyph("share", "glyph")}<span class="label">${this.shareLabel}</span></button>`;
1700
+ }
1701
+ };
1702
+ var defineRibbonActions = definer("office-ui-ribbon-actions", () => OfficeUiRibbonActions);
1703
+
1344
1704
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/ribbon/button.css?raw
1345
1705
  var button_default = ":host {\n display: inline-flex;\n vertical-align: middle;\n}\nbutton {\n box-sizing: border-box;\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--office-space-1-5);\n min-width: var(--office-target-size);\n min-height: var(--office-target-size);\n padding: 0 var(--office-space-2);\n border: var(--office-border-width) solid transparent;\n border-radius: var(--office-radius);\n background: transparent;\n color: var(--office-foreground);\n font: inherit;\n font-size: var(--office-font-size-sm);\n cursor: pointer;\n white-space: nowrap;\n}\n:host([variant='stacked']) button {\n flex-direction: column;\n padding: var(--office-space-1) var(--office-space-2);\n}\nbutton:hover:not(:disabled) {\n background: var(--office-surface);\n}\nbutton:active:not(:disabled) {\n background: var(--office-selected);\n}\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: calc(var(--office-focus-offset) / 2);\n}\nbutton[aria-pressed='true'],\nbutton[aria-expanded='true'] {\n border-color: var(--office-accent);\n background: var(--office-surface);\n}\n:host([active]) button {\n background: var(--office-command-active);\n color: var(--office-accent);\n}\nbutton:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\nsvg {\n width: var(--office-icon-size-ml);\n height: var(--office-icon-size-ml);\n flex: none;\n color: var(--office-command-icon-color);\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\nsvg.glyph:not([data-painted]) {\n display: none;\n}\n.label[hidden],\n.caret[hidden],\n.badge[hidden] {\n display: none;\n}\n/* Office trails a menu chevron after the last line of the label. */\n.caret {\n display: inline-block;\n width: var(--office-icon-size-xs);\n height: var(--office-icon-size-xs);\n margin-inline-start: var(--office-space-0);\n vertical-align: middle;\n color: var(--office-muted-foreground);\n}\n.badge {\n position: absolute;\n top: 0;\n inset-inline-end: 0;\n padding: 0 var(--office-space-0);\n border-radius: var(--office-radius-full);\n background: var(--office-accent);\n color: var(--office-accent-foreground);\n font-size: var(--office-font-size-3xs);\n}\n\n/* Large ribbon command: a big glyph above a two-line label. */\n:host([size='large']) button {\n flex-direction: column;\n justify-content: flex-start;\n gap: var(--office-space-0);\n min-width: var(--office-command-large-min-width);\n max-width: var(--office-command-large-max-width);\n height: var(--office-command-large-height);\n padding: var(--office-space-0) var(--office-space-1);\n border: 0;\n white-space: normal;\n text-align: center;\n line-height: var(--office-line-height-tight);\n}\n:host([size='large']) svg.glyph {\n width: var(--office-command-large-icon);\n height: var(--office-command-large-icon);\n}\n\n/* Small ribbon command: icon and label in one row. */\n:host([size='small']) button {\n justify-content: flex-start;\n min-width: 0;\n height: var(--office-control-height);\n min-height: var(--office-control-height);\n padding: 0 var(--office-space-1-5);\n border: 0;\n text-align: start;\n}\n:host([size='small']) svg.glyph {\n width: var(--office-command-small-icon);\n height: var(--office-command-small-icon);\n}\n\n/* Tall, label-less tool tiles (pens, erasers). */\n:host([icon-only][tall]) button {\n min-width: var(--office-command-tall-min-width);\n height: var(--office-command-tall-height);\n padding: var(--office-space-1);\n}\n:host([icon-only][tall]) svg.glyph {\n width: var(--office-command-tall-icon);\n height: var(--office-command-tall-icon);\n}\n:host([icon-only][tall][active]) button {\n box-shadow: inset 0 0 0 var(--office-border-width) var(--office-accent);\n}\n\n@media (pointer: coarse), (max-width: 767px) {\n :host([size='small']) button {\n min-height: var(--office-target-size-touch);\n }\n :host([icon-only]) button {\n min-width: var(--office-target-size-touch);\n }\n}\n@media (forced-colors: active) {\n button {\n border-color: ButtonText;\n color: ButtonText;\n background: ButtonFace;\n }\n svg {\n color: ButtonText;\n }\n button:disabled {\n color: GrayText;\n border-color: GrayText;\n }\n button[aria-pressed='true'],\n button[aria-expanded='true'],\n :host([active]) button {\n background: Highlight;\n color: HighlightText;\n }\n}\n";
1346
1706
 
@@ -1975,7 +2335,7 @@ var OfficeUiGallery = class extends OfficeElement {
1975
2335
  var defineGallery = definer("office-ui-gallery", () => OfficeUiGallery);
1976
2336
 
1977
2337
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/chrome/ruler.css?raw
1978
- var ruler_default = ":host {\n display: block;\n box-sizing: border-box;\n background: var(--office-background);\n color: var(--office-muted-foreground);\n overflow: hidden;\n font-size: var(--office-font-size-3xs);\n font-family: var(--office-font);\n}\n:host(:not([orientation='vertical'])) {\n height: var(--office-ruler-size);\n border-bottom: var(--office-border-width) solid var(--office-border);\n}\n:host([orientation='vertical']) {\n width: var(--office-ruler-size);\n border-inline-end: var(--office-border-width) solid var(--office-border);\n}\ncanvas {\n display: block;\n width: 100%;\n height: 100%;\n}\n";
2338
+ var ruler_default = ":host {\n display: block;\n position: relative;\n box-sizing: border-box;\n background: var(--office-background);\n color: var(--office-muted-foreground);\n overflow: hidden;\n font-size: var(--office-font-size-3xs);\n font-family: var(--office-font);\n}\n:host(:not([orientation='vertical'])) {\n height: var(--office-ruler-size);\n border-bottom: var(--office-border-width) solid var(--office-border);\n}\n:host([orientation='vertical']) {\n width: var(--office-ruler-size);\n border-inline-end: var(--office-border-width) solid var(--office-border);\n}\ncanvas {\n position: relative;\n display: block;\n width: 100%;\n height: 100%;\n}\n.margin {\n position: absolute;\n top: 0;\n bottom: 0;\n background: var(--office-selected);\n}\n:host([orientation='vertical']) .margin {\n top: auto;\n bottom: auto;\n left: 0;\n right: 0;\n}\n.marker {\n position: absolute;\n z-index: 1;\n width: 0;\n height: 0;\n margin-left: calc(var(--office-space-1) * -1);\n border-right: var(--office-space-1) solid transparent;\n border-left: var(--office-space-1) solid transparent;\n cursor: ew-resize;\n touch-action: none;\n pointer-events: auto;\n}\n.marker::after {\n content: '';\n position: absolute;\n inset: calc(var(--office-space-1-5) * -1);\n margin-left: calc(var(--office-space-1) * -1);\n}\n.marker.top {\n top: var(--office-space-px);\n border-top: var(--office-space-1-5) solid var(--office-accent);\n}\n.marker.bottom {\n bottom: var(--office-space-px);\n border-bottom: var(--office-space-1-5) solid var(--office-accent);\n}\n:host([orientation='vertical']) .marker {\n margin-top: calc(var(--office-space-1) * -1);\n margin-left: 0;\n border: 0;\n border-top: var(--office-space-1) solid transparent;\n border-bottom: var(--office-space-1) solid transparent;\n cursor: ns-resize;\n}\n:host([orientation='vertical']) .marker.top {\n top: auto;\n left: var(--office-space-px);\n border-left: var(--office-space-1-5) solid var(--office-accent);\n}\n:host([orientation='vertical']) .marker.bottom {\n right: var(--office-space-px);\n bottom: auto;\n border-right: var(--office-space-1-5) solid var(--office-accent);\n}\n";
1979
2339
 
1980
2340
  // src/chrome/ruler.ts
1981
2341
  function rulerDivisions(unitPixels) {
@@ -1987,9 +2347,17 @@ var OfficeUiRuler = class extends OfficeElement {
1987
2347
  orientation: { type: String, reflect: true },
1988
2348
  origin: { type: Number },
1989
2349
  scale: { type: Number },
1990
- direction: { type: String }
2350
+ direction: { type: String },
2351
+ extent: { type: Number },
2352
+ marginStart: { type: Number },
2353
+ marginEnd: { type: Number },
2354
+ zoom: { type: Number },
2355
+ labelsWithinMargins: { type: Boolean },
2356
+ label: { type: String },
2357
+ markers: { attribute: false }
1991
2358
  };
1992
2359
  frame = 0;
2360
+ zoomApplied = false;
1993
2361
  observer;
1994
2362
  constructor() {
1995
2363
  super();
@@ -1997,6 +2365,13 @@ var OfficeUiRuler = class extends OfficeElement {
1997
2365
  this.origin = 0;
1998
2366
  this.scale = 96;
1999
2367
  this.direction = "";
2368
+ this.extent = 0;
2369
+ this.marginStart = 0;
2370
+ this.marginEnd = 0;
2371
+ this.zoom = 1;
2372
+ this.labelsWithinMargins = false;
2373
+ this.label = "";
2374
+ this.markers = [];
2000
2375
  }
2001
2376
  connectedCallback() {
2002
2377
  super.connectedCallback();
@@ -2018,11 +2393,61 @@ var OfficeUiRuler = class extends OfficeElement {
2018
2393
  if (!this.frame) this.draw();
2019
2394
  }
2020
2395
  willUpdate() {
2021
- this.setAttribute("aria-hidden", "true");
2396
+ if (this.label) {
2397
+ this.removeAttribute("aria-hidden");
2398
+ this.setAttribute("role", "img");
2399
+ this.setAttribute("aria-label", this.label);
2400
+ } else {
2401
+ this.setAttribute("aria-hidden", "true");
2402
+ if (this.getAttribute("role") === "img") this.removeAttribute("role");
2403
+ this.removeAttribute("aria-label");
2404
+ }
2022
2405
  }
2023
2406
  updated() {
2407
+ if (this.extent > 0)
2408
+ this.style.setProperty(
2409
+ this.orientation === "vertical" ? "height" : "width",
2410
+ `${this.extent}px`
2411
+ );
2412
+ if (this.zoom !== 1 && this.zoom > 0) {
2413
+ this.style.setProperty("zoom", String(this.zoom));
2414
+ this.zoomApplied = true;
2415
+ } else if (this.zoomApplied) {
2416
+ this.style.removeProperty("zoom");
2417
+ this.zoomApplied = false;
2418
+ }
2024
2419
  this.schedule();
2025
2420
  }
2421
+ get zoomFactor() {
2422
+ return this.zoom > 0 ? this.zoom : 1;
2423
+ }
2424
+ pointerPosition(event) {
2425
+ const box = this.getBoundingClientRect();
2426
+ const offset = this.orientation === "vertical" ? event.clientY - box.top : event.clientX - box.left;
2427
+ return offset / this.zoomFactor;
2428
+ }
2429
+ emit(type, detail) {
2430
+ this.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true }));
2431
+ }
2432
+ dragMarker(event, name) {
2433
+ if (event.button !== 0) return;
2434
+ event.preventDefault();
2435
+ const marker = event.currentTarget;
2436
+ marker.setPointerCapture?.(event.pointerId);
2437
+ const move = (e) => this.emit("ruler-marker-move", { name, position: this.pointerPosition(e) });
2438
+ const finish = (e) => {
2439
+ marker.removeEventListener("pointermove", move);
2440
+ marker.removeEventListener("pointerup", finish);
2441
+ marker.removeEventListener("pointercancel", finish);
2442
+ this.emit(e.type === "pointerup" ? "ruler-marker-commit" : "ruler-marker-cancel", {
2443
+ name,
2444
+ position: this.pointerPosition(e)
2445
+ });
2446
+ };
2447
+ marker.addEventListener("pointermove", move);
2448
+ marker.addEventListener("pointerup", finish);
2449
+ marker.addEventListener("pointercancel", finish);
2450
+ }
2026
2451
  draw() {
2027
2452
  this.frame = 0;
2028
2453
  const canvas = this.renderRoot.querySelector("canvas");
@@ -2031,9 +2456,9 @@ var OfficeUiRuler = class extends OfficeElement {
2031
2456
  const vertical = this.orientation === "vertical";
2032
2457
  const reverse = this.direction === "reverse";
2033
2458
  const box = this.getBoundingClientRect();
2034
- const length = vertical ? box.height : box.width;
2035
- const thickness = (vertical ? box.width : box.height) || parseFloat(OFFICE_TOKENS["--office-ruler-size"]);
2036
- const ratio = view?.devicePixelRatio ?? 1;
2459
+ const length = (vertical ? this.offsetHeight : this.offsetWidth) || (vertical ? box.height : box.width);
2460
+ const thickness = (vertical ? this.offsetWidth || box.width : this.offsetHeight || box.height) || parseFloat(OFFICE_TOKENS["--office-ruler-size"]);
2461
+ const ratio = (view?.devicePixelRatio ?? 1) * this.zoomFactor;
2037
2462
  canvas.width = Math.max(1, Math.round((vertical ? thickness : length) * ratio));
2038
2463
  canvas.height = Math.max(1, Math.round((vertical ? length : thickness) * ratio));
2039
2464
  const context = canvas.getContext?.("2d");
@@ -2066,6 +2491,8 @@ var OfficeUiRuler = class extends OfficeElement {
2066
2491
  context.lineTo(at, thickness - tick);
2067
2492
  }
2068
2493
  if (index % divisions !== 0) continue;
2494
+ if (this.labelsWithinMargins && (index < 0 || at < this.marginStart || at > length - this.marginEnd))
2495
+ continue;
2069
2496
  const label = String(index / divisions);
2070
2497
  if (!vertical) context.fillText(label, at + 2, 9);
2071
2498
  else {
@@ -2079,7 +2506,22 @@ var OfficeUiRuler = class extends OfficeElement {
2079
2506
  context.stroke();
2080
2507
  }
2081
2508
  render() {
2082
- return html`<canvas></canvas>`;
2509
+ const vertical = this.orientation === "vertical";
2510
+ const band = (side, size) => size > 0 ? html`<div
2511
+ class="margin"
2512
+ data-margin=${side}
2513
+ style="${side === "start" ? vertical ? "top" : "left" : vertical ? "bottom" : "right"}:0;${vertical ? "height" : "width"}:${size}px"
2514
+ ></div>` : nothing;
2515
+ return html`${band("start", this.marginStart)}${band("end", this.marginEnd)}<canvas
2516
+ ></canvas>${this.markers.map(
2517
+ (marker) => html`<div
2518
+ class="marker ${marker.edge === "top" ? "top" : "bottom"}"
2519
+ data-marker=${marker.name}
2520
+ style="${vertical ? "top" : "left"}:${marker.position}px"
2521
+ aria-label=${marker.label ?? nothing}
2522
+ @pointerdown=${(event) => this.dragMarker(event, marker.name)}
2523
+ ></div>`
2524
+ )}`;
2083
2525
  }
2084
2526
  };
2085
2527
  var defineRuler = definer("office-ui-ruler", () => OfficeUiRuler);
@@ -3867,7 +4309,7 @@ var OfficeUiSelect = class extends OfficeElement {
3867
4309
  var defineSelect = definer("office-ui-select", () => OfficeUiSelect);
3868
4310
 
3869
4311
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/chrome/status-bar.css?raw
3870
- var status_bar_default = ":host {\n display: flex;\n align-items: center;\n gap: var(--office-space-3);\n min-height: var(--office-status-bar-height);\n padding: 0 var(--office-space-2);\n font-size: var(--office-font-size-xs);\n background: var(--office-surface);\n color: var(--office-foreground);\n border-top: var(--office-border-width) solid var(--office-border);\n font-family: var(--office-font);\n}\n::slotted([slot='end']) {\n margin-inline-start: auto;\n}\n.bar {\n display: contents;\n}\n[hidden] {\n display: none !important;\n}\n:host([data-controlled]) {\n display: block;\n flex: none;\n padding: 0;\n gap: 0;\n}\n:host([data-controlled]) .bar {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--office-space-1);\n width: 100%;\n min-height: var(--office-status-bar-height);\n padding: var(--office-space-0) var(--office-space-2);\n color: var(--office-muted-foreground);\n}\n:host([data-controlled]) ::slotted([slot='end']) {\n margin-inline-start: 0;\n}\n.items {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n.item {\n flex: none;\n white-space: nowrap;\n}\n.item + .item::before {\n content: '';\n display: inline-block;\n width: var(--office-border-width);\n height: var(--office-space-3);\n margin: 0 var(--office-space-2);\n vertical-align: middle;\n background: var(--office-border);\n}\n.item.saving {\n color: var(--office-warning);\n}\n.item.error {\n color: var(--office-danger);\n}\n.spacer {\n flex: 1;\n}\n.toggles,\n.group {\n display: flex;\n align-items: center;\n gap: var(--office-space-0);\n}\n.sep {\n flex: none;\n width: var(--office-border-width);\n height: var(--office-space-3);\n margin: 0 var(--office-space-0);\n background: var(--office-border);\n}\n.bar button {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--office-space-1);\n min-width: var(--office-control-height-xs);\n min-height: var(--office-control-height-xs);\n padding: var(--office-space-1);\n border: 0;\n border-radius: var(--office-radius-sm);\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n touch-action: manipulation;\n}\n.bar button:hover {\n background: var(--office-selected);\n color: var(--office-foreground);\n}\n.bar button[aria-pressed='true'] {\n color: var(--office-accent);\n}\n.bar button:active {\n opacity: 0.8;\n}\n.bar button:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n.bar svg {\n flex: none;\n width: var(--office-icon-size);\n height: var(--office-icon-size);\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n.toggle svg,\n.zoom-step svg {\n width: var(--office-icon-size-sm);\n height: var(--office-icon-size-sm);\n}\n.zoom-fit {\n min-width: var(--office-zoom-value-width);\n font-variant-numeric: tabular-nums;\n}\n@media (max-width: 767px) {\n .narrow-hide,\n .toggle .label {\n display: none !important;\n }\n}\n@media (pointer: coarse) {\n .bar button {\n min-width: var(--office-target-size-touch);\n min-height: var(--office-target-size-touch);\n }\n}\n@media (forced-colors: active) {\n :host {\n background: Canvas;\n color: CanvasText;\n border-top-color: CanvasText;\n }\n .bar button {\n color: ButtonText;\n }\n .bar button:hover {\n background: Highlight;\n color: HighlightText;\n }\n .bar button[aria-pressed='true'] {\n border: var(--office-border-width) solid Highlight;\n }\n .bar button:focus-visible {\n outline-color: Highlight;\n }\n .sep,\n .item + .item::before {\n background: CanvasText;\n }\n}\n";
4312
+ var status_bar_default = ":host {\n display: flex;\n align-items: center;\n gap: var(--office-space-3);\n min-height: var(--office-status-bar-height);\n padding: 0 var(--office-space-2);\n font-size: var(--office-font-size-xs);\n background: var(--office-surface);\n color: var(--office-foreground);\n border-top: var(--office-border-width) solid var(--office-border);\n font-family: var(--office-font);\n}\n::slotted([slot='end']) {\n margin-inline-start: auto;\n}\n.bar {\n display: contents;\n}\n[hidden] {\n display: none !important;\n}\n:host([data-controlled]) {\n display: block;\n flex: none;\n padding: 0;\n gap: 0;\n}\n:host([data-controlled]) .bar {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--office-space-1);\n width: 100%;\n min-height: var(--office-status-bar-height);\n padding: var(--office-space-0) var(--office-space-2);\n color: var(--office-muted-foreground);\n}\n:host([data-controlled]) ::slotted([slot='end']) {\n margin-inline-start: 0;\n}\n.items {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n.item {\n flex: none;\n white-space: nowrap;\n}\n.item + .item::before {\n content: '';\n display: inline-block;\n width: var(--office-border-width);\n height: var(--office-space-3);\n margin: 0 var(--office-space-2);\n vertical-align: middle;\n background: var(--office-border);\n opacity: var(--office-status-bar-separator-opacity);\n}\n.item.saving {\n color: var(--office-warning);\n}\n.item.error {\n color: var(--office-danger);\n}\n.spacer {\n flex: 1;\n}\n.toggles,\n.group {\n display: flex;\n align-items: center;\n gap: var(--office-space-0);\n}\n.sep {\n flex: none;\n width: var(--office-border-width);\n height: var(--office-space-3);\n margin: 0 var(--office-space-0);\n background: var(--office-border);\n opacity: var(--office-status-bar-separator-opacity);\n}\n.bar button {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--office-space-1);\n min-width: var(--office-control-height-xs);\n min-height: var(--office-control-height-xs);\n padding: var(--office-space-1);\n border: 0;\n border-radius: var(--office-radius-sm);\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n touch-action: manipulation;\n}\n.bar button:hover {\n background: var(--office-selected);\n color: var(--office-foreground);\n}\n.bar button[aria-pressed='true'] {\n color: var(--office-accent);\n}\n.bar button:active {\n opacity: 0.8;\n}\n.bar button:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n.bar svg {\n flex: none;\n width: var(--office-icon-size);\n height: var(--office-icon-size);\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n.toggle svg,\n.zoom-step svg {\n width: var(--office-icon-size-sm);\n height: var(--office-icon-size-sm);\n}\n.zoom-fit {\n min-width: var(--office-zoom-value-width);\n font-variant-numeric: tabular-nums;\n}\n@media (max-width: 767px) {\n .narrow-hide,\n .toggle .label {\n display: none !important;\n }\n}\n@media (pointer: coarse) {\n .bar button {\n min-width: var(--office-target-size-touch);\n min-height: var(--office-target-size-touch);\n }\n}\n@media (forced-colors: active) {\n :host {\n background: Canvas;\n color: CanvasText;\n border-top-color: CanvasText;\n }\n .bar button {\n color: ButtonText;\n }\n .bar button:hover {\n background: Highlight;\n color: HighlightText;\n }\n .bar button[aria-pressed='true'] {\n border: var(--office-border-width) solid Highlight;\n }\n .bar button:focus-visible {\n outline-color: Highlight;\n }\n .sep,\n .item + .item::before {\n background: CanvasText;\n }\n}\n";
3871
4313
 
3872
4314
  // src/chrome/status-bar.ts
3873
4315
  var OfficeUiStatusBar = class extends OfficeElement {
@@ -3958,6 +4400,7 @@ var OfficeUiStatusBar = class extends OfficeElement {
3958
4400
  </span>
3959
4401
  <slot></slot>
3960
4402
  <span class="spacer" ?hidden=${!state}></span>
4403
+ <slot name="summary"></slot>
3961
4404
  <span class="toggles" ?hidden=${togglesHidden}>
3962
4405
  ${repeat(
3963
4406
  toggles,
@@ -4186,7 +4629,7 @@ function matchTitleBarCommands(search, query) {
4186
4629
  }
4187
4630
 
4188
4631
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/chrome/title-bar.css?raw
4189
- var title_bar_default = ":host {\n display: block;\n flex: none;\n}\n:host([data-empty]) {\n display: none !important;\n}\n[hidden] {\n display: none !important;\n}\n.bar {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--office-space-1);\n width: 100%;\n height: var(--office-title-bar-height);\n padding: 0 var(--office-space-2);\n border-bottom: var(--office-border-width) solid var(--office-title-bar-border);\n background: var(--office-title-bar-background);\n color: var(--office-title-bar-foreground);\n font: var(--office-font-size-xs)/var(--office-line-height-tight) var(--office-font);\n user-select: none;\n}\n:host([placement='belowRibbon']) .bar {\n height: auto;\n min-height: var(--office-title-bar-below-height);\n padding-block: var(--office-space-0);\n}\n.mark {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--office-title-bar-mark-size);\n height: var(--office-title-bar-mark-size);\n border-radius: var(--office-radius-sm);\n background: var(--office-title-bar-mark-background);\n color: var(--office-title-bar-mark-foreground);\n font-size: var(--office-font-size-2xs);\n font-weight: var(--office-font-weight-bold);\n}\n.autosave {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--office-space-1-5);\n padding: 0 var(--office-space-0) 0 var(--office-space-1-5);\n white-space: nowrap;\n}\n.label,\n.dot,\n.status {\n color: var(--office-muted-foreground);\n white-space: nowrap;\n}\n.sep {\n flex: none;\n width: var(--office-border-width);\n height: var(--office-space-4);\n margin: 0 var(--office-space-1);\n background: var(--office-title-bar-border);\n}\n.qat {\n display: flex;\n align-items: center;\n gap: var(--office-space-0);\n min-width: 0;\n}\n.qat button,\n.results button {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--office-space-1);\n min-width: var(--office-control-height-md);\n min-height: var(--office-control-height-md);\n padding: var(--office-space-1);\n border: 0;\n border-radius: var(--office-radius-sm);\n background: transparent;\n color: var(--office-muted-foreground);\n font: inherit;\n cursor: pointer;\n touch-action: manipulation;\n}\n.qat button:hover:not(:disabled) {\n background: var(--office-selected);\n}\n.qat button:active:not(:disabled) {\n opacity: 0.7;\n}\n.qat button:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.qat small {\n font-size: var(--office-font-size-xs);\n white-space: nowrap;\n}\nsvg {\n flex: none;\n width: var(--office-icon-size);\n height: var(--office-icon-size);\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n.file {\n display: flex;\n align-items: baseline;\n gap: var(--office-space-1-5);\n min-width: 0;\n padding: 0 var(--office-space-1);\n flex: 0 1 auto;\n}\n.name {\n max-width: var(--office-title-bar-name-max-width);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--office-title-bar-foreground);\n font-size: var(--office-font-size-sm);\n font-weight: var(--office-font-weight-medium);\n}\n.status.saving {\n color: var(--office-warning);\n}\n.status.error {\n color: var(--office-danger);\n}\n.search {\n position: relative;\n flex: 1;\n display: flex;\n justify-content: center;\n min-width: 0;\n padding: 0 var(--office-space-2);\n}\n.box {\n position: relative;\n width: 100%;\n max-width: var(--office-title-bar-search-max-width);\n min-width: 0;\n}\n.box > [part='search'] {\n width: 100%;\n}\n.results {\n position: absolute;\n z-index: var(--office-z-popover);\n top: calc(100% + var(--office-space-1));\n right: 0;\n left: 0;\n max-height: var(--office-title-bar-results-max-height);\n overflow-y: auto;\n border: var(--office-border-width) solid var(--office-border);\n border-radius: var(--office-radius-lg);\n background: var(--office-popover);\n color: var(--office-popover-foreground);\n box-shadow: var(--office-shadow-lg);\n}\n.heading {\n padding: var(--office-space-1-5) var(--office-space-3);\n color: var(--office-muted-foreground);\n font-size: var(--office-font-size-2xs);\n font-weight: var(--office-font-weight-bold);\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n.empty {\n padding: var(--office-space-2) var(--office-space-3);\n color: var(--office-muted-foreground);\n}\n.results button {\n display: flex;\n width: 100%;\n justify-content: flex-start;\n gap: var(--office-space-2);\n padding: var(--office-space-1-5) var(--office-space-3);\n border-radius: 0;\n color: inherit;\n text-align: start;\n}\n.results button:hover,\n.results button[aria-selected='true'] {\n background: var(--office-selected);\n}\n.results .cat {\n margin-inline-start: auto;\n color: var(--office-muted-foreground);\n font-size: var(--office-font-size-2xs);\n text-transform: capitalize;\n}\n.results .content {\n border-top: var(--office-border-width) solid var(--office-border);\n}\n.end {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--office-space-1);\n}\n.sr {\n position: absolute;\n width: var(--office-space-px);\n height: var(--office-space-px);\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n@media (max-width: 767px), (max-width: 1023px) and (max-height: 520px) {\n :host(:not([placement='belowRibbon'])) {\n display: none !important;\n }\n}\n@media (max-width: 1100px) {\n .qat small {\n display: none;\n }\n .name {\n max-width: var(--office-title-bar-name-max-width-narrow);\n }\n}\n@media (pointer: coarse) {\n .qat button,\n .results button {\n min-width: var(--office-target-size-touch);\n min-height: var(--office-target-size-touch);\n }\n .bar {\n height: auto;\n min-height: var(--office-target-size-touch);\n }\n}\n@media (forced-colors: active) {\n .bar {\n border-bottom-color: CanvasText;\n background: Canvas;\n color: CanvasText;\n }\n .mark {\n border: var(--office-border-width) solid CanvasText;\n background: Canvas;\n color: CanvasText;\n }\n .label,\n .dot,\n .status,\n .name,\n .qat button,\n .results button {\n color: CanvasText;\n }\n .sep {\n background: CanvasText;\n }\n .qat button:hover:not(:disabled),\n .results button:hover,\n .results button[aria-selected='true'] {\n background: Highlight;\n color: HighlightText;\n }\n .qat button:disabled {\n color: GrayText;\n opacity: 1;\n }\n .results {\n border-color: CanvasText;\n background: Canvas;\n }\n button:focus-visible {\n outline-color: Highlight;\n }\n}\n";
4632
+ var title_bar_default = ":host {\n display: block;\n flex: none;\n}\n:host([data-empty]) {\n display: none !important;\n}\n[hidden] {\n display: none !important;\n}\n.bar {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--office-space-1);\n width: 100%;\n height: var(--office-title-bar-height);\n padding: 0 var(--office-space-2);\n border-bottom: var(--office-border-width) solid var(--office-title-bar-border);\n background: var(--office-title-bar-background);\n color: var(--office-title-bar-foreground);\n font: var(--office-font-size-xs)/var(--office-line-height-tight) var(--office-font);\n user-select: none;\n}\n:host([placement='belowRibbon']) .bar {\n height: auto;\n min-height: var(--office-title-bar-below-height);\n padding-block: var(--office-space-0);\n}\n.mark {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--office-title-bar-mark-size);\n height: var(--office-title-bar-mark-size);\n border-radius: var(--office-radius-sm);\n background: var(--office-title-bar-mark-background);\n color: var(--office-title-bar-mark-foreground);\n font-size: var(--office-font-size-2xs);\n font-weight: var(--office-font-weight-bold);\n}\n.autosave {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--office-space-1-5);\n padding: 0 var(--office-space-0) 0 var(--office-space-1-5);\n white-space: nowrap;\n}\n.label,\n.dot,\n.status {\n color: var(--office-muted-foreground);\n white-space: nowrap;\n}\n.sep {\n flex: none;\n width: var(--office-border-width);\n height: var(--office-space-4);\n margin: 0 var(--office-space-1);\n background: var(--office-title-bar-border);\n}\n.qat {\n display: flex;\n align-items: center;\n gap: var(--office-space-0);\n min-width: 0;\n}\n.qat button,\n.results button {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--office-space-1);\n min-width: var(--office-control-height-md);\n min-height: var(--office-control-height-md);\n padding: var(--office-space-1);\n border: 0;\n border-radius: var(--office-radius-sm);\n background: transparent;\n color: var(--office-muted-foreground);\n font: inherit;\n cursor: pointer;\n touch-action: manipulation;\n}\n.qat button:hover:not(:disabled) {\n background: var(--office-selected);\n}\n.qat button:active:not(:disabled) {\n opacity: 0.7;\n}\n.qat button:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.qat small {\n font-size: var(--office-font-size-xs);\n white-space: nowrap;\n}\nsvg {\n flex: none;\n width: var(--office-icon-size);\n height: var(--office-icon-size);\n fill: none;\n stroke: currentColor;\n stroke-width: var(--office-icon-stroke);\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n.file {\n display: flex;\n align-items: baseline;\n gap: var(--office-space-1-5);\n min-width: 0;\n padding: 0 var(--office-space-1);\n flex: 0 1 auto;\n}\n.name {\n max-width: var(--office-title-bar-name-max-width);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--office-title-bar-name-foreground);\n font-size: var(--office-font-size-sm);\n font-weight: var(--office-font-weight-medium);\n}\n.status.saving {\n color: var(--office-warning);\n}\n.status.error {\n color: var(--office-danger);\n}\n.search {\n position: relative;\n flex: 1;\n display: flex;\n justify-content: center;\n min-width: 0;\n padding: 0 var(--office-space-2);\n}\n.box {\n position: relative;\n width: 100%;\n max-width: var(--office-title-bar-search-max-width);\n min-width: 0;\n}\n.box > [part='search'] {\n width: 100%;\n}\n.results {\n position: absolute;\n z-index: var(--office-z-popover);\n top: calc(100% + var(--office-space-1));\n right: 0;\n left: 0;\n max-height: var(--office-title-bar-results-max-height);\n overflow-y: auto;\n border: var(--office-border-width) solid var(--office-border);\n border-radius: var(--office-radius-lg);\n background: var(--office-popover);\n color: var(--office-popover-foreground);\n box-shadow: var(--office-shadow-lg);\n}\n.heading {\n padding: var(--office-space-1-5) var(--office-space-3);\n color: var(--office-muted-foreground);\n font-size: var(--office-font-size-2xs);\n font-weight: var(--office-font-weight-bold);\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n.empty {\n padding: var(--office-space-2) var(--office-space-3);\n color: var(--office-muted-foreground);\n}\n.results button {\n display: flex;\n width: 100%;\n justify-content: flex-start;\n gap: var(--office-space-2);\n padding: var(--office-space-1-5) var(--office-space-3);\n border-radius: 0;\n color: inherit;\n text-align: start;\n}\n.results button:hover,\n.results button[aria-selected='true'] {\n background: var(--office-title-bar-result-selected);\n}\n.results .cat {\n margin-inline-start: auto;\n color: var(--office-muted-foreground);\n font-size: var(--office-font-size-2xs);\n text-transform: capitalize;\n}\n.results .content {\n border-top: var(--office-border-width) solid var(--office-border);\n}\n.end {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--office-space-1);\n}\n.sr {\n position: absolute;\n width: var(--office-space-px);\n height: var(--office-space-px);\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: var(--office-focus-offset);\n}\n@media (max-width: 767px), (max-width: 1023px) and (max-height: 520px) {\n :host(:not([placement='belowRibbon'])) {\n display: none !important;\n }\n}\n@media (max-width: 1100px) {\n .qat small {\n display: none;\n }\n .name {\n max-width: var(--office-title-bar-name-max-width-narrow);\n }\n}\n@media (pointer: coarse) {\n .qat button,\n .results button {\n min-width: var(--office-target-size-touch);\n min-height: var(--office-target-size-touch);\n }\n .bar {\n height: auto;\n min-height: var(--office-target-size-touch);\n }\n}\n@media (forced-colors: active) {\n .bar {\n border-bottom-color: CanvasText;\n background: Canvas;\n color: CanvasText;\n }\n .mark {\n border: var(--office-border-width) solid CanvasText;\n background: Canvas;\n color: CanvasText;\n }\n .label,\n .dot,\n .status,\n .name,\n .qat button,\n .results button {\n color: CanvasText;\n }\n .sep {\n background: CanvasText;\n }\n .qat button:hover:not(:disabled),\n .results button:hover,\n .results button[aria-selected='true'] {\n background: Highlight;\n color: HighlightText;\n }\n .qat button:disabled {\n color: GrayText;\n opacity: 1;\n }\n .results {\n border-color: CanvasText;\n background: Canvas;\n }\n button:focus-visible {\n outline-color: Highlight;\n }\n}\n";
4190
4633
 
4191
4634
  // src/chrome/title-bar.ts
4192
4635
  var EMPTY = { fileName: "" };
@@ -4972,6 +5415,7 @@ var CONTROL_DEFINERS = [
4972
5415
  defineOptionsDialog,
4973
5416
  defineAccount,
4974
5417
  defineRibbon,
5418
+ defineRibbonActions,
4975
5419
  defineFindBar,
4976
5420
  defineRuler,
4977
5421
  defineBackstage,
@@ -4985,10 +5429,11 @@ var CONTROL_DEFINERS = [
4985
5429
  definePasteOptions,
4986
5430
  defineTitleBar,
4987
5431
  defineRibbonSection,
4988
- defineGallery
5432
+ defineGallery,
5433
+ defineCommentsPane
4989
5434
  ];
4990
5435
  function registerControls(registry) {
4991
5436
  for (const define of CONTROL_DEFINERS) define(registry);
4992
5437
  }
4993
5438
 
4994
- export { CONTROL_DEFINERS, DEFAULT_OFFICE_PROFILE, EMPTY_MENU_STATE, OFFICE_AVATAR_SWATCHES, OFFICE_COLOR_SWATCHES, OFFICE_COLOR_SWATCH_HEXES, OFFICE_PROFILE_STORAGE_KEY, OFFICE_TITLE_BAR_SEARCH_LIMIT, OFFICE_TOAST_VISIBLE_LIMIT, assignKeyTips, attachKeyTips, clampFlyoutPosition, clampOptionNumber, clearOfficeProfile, createRibbonOverflow, defineAccount, defineBackstage, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineDialogFooter, defineFindBar, defineGallery, defineIcon, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, definePasteOptions, definePrintPreview, defineRadio, defineReadOnlyBanner, defineRibbon, defineRibbonGroup, defineRibbonSection, defineRibbonStack, defineRibbonToggle, defineRuler, defineSearchField, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineTitleBar, defineToasts, defineToolbar, defineZoomSlider, glyph, nextEnabledIndex, parseSvgPreview, profileInitials, rangeControl, range_control_default, readOfficeProfile, registerControls, rulerDivisions, runKeyTips, sanitizeOfficeProfile, typeAheadIndex, writeOfficeProfile };
5439
+ export { CONTROL_DEFINERS, DEFAULT_COMMENTS_LABELS, DEFAULT_OFFICE_PROFILE, EMPTY_MENU_STATE, OFFICE_AVATAR_SWATCHES, OFFICE_COLOR_SWATCHES, OFFICE_COLOR_SWATCH_HEXES, OFFICE_PROFILE_STORAGE_KEY, OFFICE_TITLE_BAR_SEARCH_LIMIT, OFFICE_TOAST_VISIBLE_LIMIT, assignKeyTips, attachKeyTips, clampFlyoutPosition, clampOptionNumber, clearOfficeProfile, commentInitials, createRibbonOverflow, defineAccount, defineBackstage, defineButton, defineCheckbox, defineCommandSearch, defineCommentsPane, defineContextMenu, defineDialog, defineDialogFooter, defineFindBar, defineGallery, defineIcon, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, definePasteOptions, definePrintPreview, defineRadio, defineReadOnlyBanner, defineRibbon, defineRibbonActions, defineRibbonGroup, defineRibbonSection, defineRibbonStack, defineRibbonToggle, defineRuler, defineSearchField, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineTitleBar, defineToasts, defineToolbar, defineZoomSlider, formatCommentTime, glyph, nextEnabledIndex, parseSvgPreview, profileInitials, rangeControl, range_control_default, readOfficeProfile, registerControls, rulerDivisions, runKeyTips, sanitizeOfficeProfile, typeAheadIndex, writeOfficeProfile };