ooxml-ui 1.6.2 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/README.md +90 -37
  2. package/custom-elements.json +303 -4
  3. package/dist/chrome/ruler.d.ts +7 -1
  4. package/dist/chrome/ruler.d.ts.map +1 -1
  5. package/dist/chrome/status-bar.d.ts.map +1 -1
  6. package/dist/chrome/tab-strip.d.ts +3 -1
  7. package/dist/chrome/tab-strip.d.ts.map +1 -1
  8. package/dist/chrome/task-pane.d.ts +29 -0
  9. package/dist/chrome/task-pane.d.ts.map +1 -0
  10. package/dist/chrome/title-bar.d.ts +2 -1
  11. package/dist/chrome/title-bar.d.ts.map +1 -1
  12. package/dist/{chunk-QAIVGTQZ.js → chunk-7US5GCXF.js} +158 -153
  13. package/dist/{chunk-Z7CS3UUK.js → chunk-KF72ZA6V.js} +5 -2
  14. package/dist/{chunk-QHAE6Y5B.js → chunk-O7APCA5N.js} +680 -98
  15. package/dist/chunk-W6AV3GHC.js +112 -0
  16. package/dist/controls.d.ts +9 -2
  17. package/dist/controls.d.ts.map +1 -1
  18. package/dist/controls.js +1 -1
  19. package/dist/dialog/dialog-footer.d.ts.map +1 -1
  20. package/dist/dialog/options-dialog.d.ts.map +1 -1
  21. package/dist/docx/editor-core.d.ts +3 -0
  22. package/dist/docx/editor-shell.d.ts +2 -0
  23. package/dist/docx/element-api.d.ts +7 -0
  24. package/dist/docx/events.d.ts +4 -1
  25. package/dist/docx/index.d.ts +1 -0
  26. package/dist/docx/ribbon-color-grid.d.ts +3 -4
  27. package/dist/docx.js +46 -78
  28. package/dist/edit-worker.js +52 -3
  29. package/dist/form/color-custom.d.ts +79 -0
  30. package/dist/form/color-custom.d.ts.map +1 -0
  31. package/dist/form/color-grid.d.ts +125 -0
  32. package/dist/form/color-grid.d.ts.map +1 -0
  33. package/dist/index.d.ts +2 -1
  34. package/dist/index.js +4 -3
  35. package/dist/menu/context-menu.d.ts.map +1 -1
  36. package/dist/menu/menu-button.d.ts +2 -1
  37. package/dist/menu/menu-button.d.ts.map +1 -1
  38. package/dist/notices/paste-options.d.ts.map +1 -1
  39. package/dist/notices/toasts.d.ts.map +1 -1
  40. package/dist/pptx/{chart-3d-view-scene-ERX2GRCD.mjs → chart-3d-view-scene-P6MAFEGL.mjs} +2 -2
  41. package/dist/pptx/{chart-3d-view-scene-55WDENSO.cjs → chart-3d-view-scene-V74F7ZOC.cjs} +38 -38
  42. package/dist/pptx/{chunk-G2YUKLRX.cjs → chunk-526IHNIH.cjs} +1 -1
  43. package/dist/pptx/{chunk-SVN6OBG4.mjs → chunk-DPOES4WM.mjs} +26 -11
  44. package/dist/pptx/{chunk-BLAJIEXA.cjs → chunk-GCS5KBMR.cjs} +511 -653
  45. package/dist/pptx/{chunk-RPRC2EG5.cjs → chunk-K3S2A64B.cjs} +13 -13
  46. package/dist/pptx/{chunk-E55NU4BF.mjs → chunk-MCHPNO42.mjs} +289 -493
  47. package/dist/pptx/{chunk-AWQRQUPL.mjs → chunk-NAFUYAQP.mjs} +1 -1
  48. package/dist/pptx/{chunk-LCIXR7WE.cjs → chunk-VFPVEVF4.cjs} +26 -11
  49. package/dist/pptx/{chunk-TKATCPOK.mjs → chunk-ZAOYPCAM.mjs} +1 -1
  50. package/dist/pptx/dom/activex-controls-overlay.d.ts.map +1 -1
  51. package/dist/pptx/dom/elements/image.d.ts.map +1 -1
  52. package/dist/pptx/dom/elements/media.d.ts.map +1 -1
  53. package/dist/pptx/dom/elements/text-block.d.ts.map +1 -1
  54. package/dist/pptx/dom/elements/zoom.d.ts.map +1 -1
  55. package/dist/pptx/dom/index.cjs +252 -247
  56. package/dist/pptx/dom/index.mjs +11 -6
  57. package/dist/pptx/export/html2canvas-clone.cjs +2 -2
  58. package/dist/pptx/export/html2canvas-clone.mjs +1 -1
  59. package/dist/pptx/index.cjs +3059 -3023
  60. package/dist/pptx/index.mjs +4 -4
  61. package/dist/pptx/render/chart-combo-series.d.ts.map +1 -1
  62. package/dist/pptx/render/chart-combo-stock.cjs +3 -3
  63. package/dist/pptx/render/chart-combo-stock.mjs +1 -1
  64. package/dist/pptx/render/chart-marker-shape.d.ts.map +1 -1
  65. package/dist/pptx/render/chart-overlays.cjs +7 -7
  66. package/dist/pptx/render/chart-overlays.mjs +1 -1
  67. package/dist/pptx/render/chart-surface-treemap.cjs +4 -4
  68. package/dist/pptx/render/chart-surface-treemap.mjs +1 -1
  69. package/dist/pptx/render/chart-view-model.cjs +44 -44
  70. package/dist/pptx/render/chart-view-model.mjs +1 -1
  71. package/dist/pptx/render/chart-waterfall-map.cjs +6 -6
  72. package/dist/pptx/render/chart-waterfall-map.mjs +1 -1
  73. package/dist/pptx/render/connector-router-types.d.ts +4 -52
  74. package/dist/pptx/render/connector-router-types.d.ts.map +1 -1
  75. package/dist/pptx/render/connector-router.d.ts +4 -32
  76. package/dist/pptx/render/connector-router.d.ts.map +1 -1
  77. package/dist/pptx/render/editor-keymap-arrows.d.ts +0 -7
  78. package/dist/pptx/render/editor-keymap-arrows.d.ts.map +1 -1
  79. package/dist/pptx/render/element-interaction.d.ts +2 -6
  80. package/dist/pptx/render/element-interaction.d.ts.map +1 -1
  81. package/dist/pptx/render/index.d.ts +1 -0
  82. package/dist/pptx/render/index.d.ts.map +1 -1
  83. package/dist/pptx/render/ribbon-add-ins.d.ts +53 -0
  84. package/dist/pptx/render/ribbon-add-ins.d.ts.map +1 -0
  85. package/dist/pptx/web-components/index.d.ts +1 -0
  86. package/dist/pptx/web-components/index.d.ts.map +1 -1
  87. package/dist/pptx/web-components/ribbon-add-in.d.ts +20 -0
  88. package/dist/pptx/web-components/ribbon-add-in.d.ts.map +1 -0
  89. package/dist/ribbon/add-in-tabs.d.ts +36 -0
  90. package/dist/ribbon/group-overflow.d.ts +37 -0
  91. package/dist/ribbon/group-overflow.d.ts.map +1 -0
  92. package/dist/ribbon/ribbon-tabs.d.ts.map +1 -1
  93. package/dist/teams/app/index.d.ts +1 -1
  94. package/dist/teams.js +2 -2
  95. package/dist/visio/format-pane-fields.d.ts +42 -0
  96. package/dist/visio/format-pane-view.d.ts +44 -0
  97. package/dist/visio/index.d.ts +1 -0
  98. package/dist/visio/page-setup-action.d.ts +4 -0
  99. package/dist/visio/ribbon-action.d.ts +20 -7
  100. package/dist/visio/ribbon-change-shape.d.ts +17 -6
  101. package/dist/visio/ribbon-color-menu.d.ts +29 -0
  102. package/dist/visio/ribbon-inline-galleries.d.ts +20 -0
  103. package/dist/visio/ribbon-overflow.d.ts +7 -0
  104. package/dist/visio/ribbon-review.d.ts +5 -2
  105. package/dist/visio/ribbon-router.d.ts +3 -3
  106. package/dist/visio/ribbon-shape-styles.d.ts +4 -1
  107. package/dist/visio/ribbon-style-options.d.ts +4 -3
  108. package/dist/visio/ribbon.d.ts +2 -2
  109. package/dist/visio/shapes-document.d.ts +29 -0
  110. package/dist/visio/shapes-sections.d.ts +19 -5
  111. package/dist/visio/shapes-storage.d.ts +15 -0
  112. package/dist/visio/shapes-window.d.ts +9 -2
  113. package/dist/visio/status-bar.d.ts +7 -4
  114. package/dist/visio/stencil-catalog.d.ts +4 -0
  115. package/dist/visio/styles/theme.d.ts +1 -1
  116. package/dist/visio/styles.d.ts +1 -1
  117. package/dist/visio/text-measurer.d.ts +25 -0
  118. package/dist/visio/title-bar.d.ts +9 -0
  119. package/dist/visio/viewer-auto-connect-parts.d.ts +12 -0
  120. package/dist/visio/viewer-auto-connect.d.ts +33 -0
  121. package/dist/visio/viewer-backstage.d.ts +2 -1
  122. package/dist/visio/viewer-canvas.d.ts +1 -1
  123. package/dist/visio/viewer-change-shape.d.ts +8 -4
  124. package/dist/visio/viewer-chrome.d.ts +13 -5
  125. package/dist/visio/viewer-color-menus.d.ts +34 -0
  126. package/dist/visio/viewer-commands.d.ts +4 -1
  127. package/dist/visio/viewer-connector-tool.d.ts +5 -3
  128. package/dist/visio/viewer-data-window.d.ts +5 -1
  129. package/dist/visio/viewer-draw-tool.d.ts +1 -11
  130. package/dist/visio/viewer-element.d.ts +16 -0
  131. package/dist/visio/viewer-format-pane.d.ts +26 -0
  132. package/dist/visio/viewer-guides.d.ts +7 -4
  133. package/dist/visio/viewer-inline-text.d.ts +31 -0
  134. package/dist/visio/viewer-input.d.ts +5 -1
  135. package/dist/visio/viewer-layer-properties.d.ts +18 -0
  136. package/dist/visio/viewer-layout-commands.d.ts +8 -2
  137. package/dist/visio/viewer-more-colors.d.ts +16 -0
  138. package/dist/visio/viewer-options.d.ts +18 -4
  139. package/dist/visio/viewer-page-setup.d.ts +6 -0
  140. package/dist/visio/viewer-ruler-grid.d.ts +25 -0
  141. package/dist/visio/viewer-ruler.d.ts +11 -3
  142. package/dist/visio/viewer-snap-glue.d.ts +23 -0
  143. package/dist/visio/viewer-stencil.d.ts +4 -1
  144. package/dist/visio.js +7595 -5944
  145. package/dist/xlsx/component.d.ts +8 -0
  146. package/dist/xlsx/dialogs/format-cells/color-swatches.d.ts +4 -2
  147. package/dist/xlsx/dialogs/styles.d.ts +1 -1
  148. package/dist/xlsx/events.d.ts +4 -1
  149. package/dist/xlsx/index.d.ts +1 -0
  150. package/dist/xlsx/ribbon/color-grid.d.ts +25 -7
  151. package/dist/xlsx/ribbon/ribbon.d.ts +3 -0
  152. package/dist/xlsx.js +121 -163
  153. package/package.json +3 -2
  154. package/dist/pptx/render/connector-router-astar.d.ts +0 -24
  155. package/dist/pptx/render/connector-router-astar.d.ts.map +0 -1
  156. package/dist/pptx/render/connector-router-graph.d.ts +0 -38
  157. package/dist/pptx/render/connector-router-graph.d.ts.map +0 -1
  158. package/dist/visio/format-shape-dialog.d.ts +0 -21
  159. package/dist/visio/viewer-edit-controls.d.ts +0 -12
  160. package/dist/visio/viewer-format-shape.d.ts +0 -16
  161. package/dist/visio/viewer-geometry-controls.d.ts +0 -14
  162. package/dist/visio/viewer-layer-controls.d.ts +0 -5
  163. package/dist/visio/viewer-paint-dialog.d.ts +0 -28
  164. package/dist/visio/viewer-paint-properties.d.ts +0 -13
@@ -8,6 +8,7 @@ import { repeat } from 'lit/directives/repeat.js';
8
8
  import { unsafeStatic, html as html$1 } from 'lit/static-html.js';
9
9
  import { live } from 'lit/directives/live.js';
10
10
  import { keyed } from 'lit/directives/keyed.js';
11
+ import { OFFICE_STANDARD_COLORS, normalizePaletteHex, buildThemePalette, hslToRgb, toHex, hexToRgbChannels, rgbToHsl } from 'ooxml-core/color';
11
12
 
12
13
  function glyph(name, className = "glyph", hidden = false) {
13
14
  const found = getIcon(name);
@@ -57,16 +58,16 @@ var OfficeUiDialogFooter = class extends OfficeElement {
57
58
  this.model.actions,
58
59
  (action) => action.id,
59
60
  (action) => html`<button
60
- type="button"
61
- class=${this.classes(action)}
62
- data-action=${action.id}
63
- data-testid=${ifDefined(action.testId)}
64
- title=${ifDefined(action.title)}
65
- aria-busy=${ifDefined(action.busy ? "true" : void 0)}
66
- ?disabled=${action.disabled === true || action.busy === true}
67
- @click=${() => this.fire(requestEvent, { id: action.id })}
68
- >${action.icon ? glyph(action.icon, "icon") : ""}${action.label}</button
69
- >`
61
+ type="button"
62
+ class=${this.classes(action)}
63
+ data-action=${action.id}
64
+ data-testid=${ifDefined(action.testId)}
65
+ title=${ifDefined(action.title)}
66
+ aria-busy=${ifDefined(action.busy ? "true" : void 0)}
67
+ ?disabled=${action.disabled === true || action.busy === true}
68
+ @click=${() => this.fire(requestEvent, { id: action.id })}
69
+ >${action.icon ? glyph(action.icon, "icon") : ""}${action.label}</button
70
+ >`
70
71
  )}
71
72
  </div>
72
73
  `;
@@ -118,22 +119,22 @@ var OfficeUiToasts = class extends OfficeElement {
118
119
  </div>
119
120
  ${visible2.map(
120
121
  (toast) => html`<div
121
- class="toast"
122
- role="status"
123
- data-testid=${p}
124
- data-code=${ifDefined(toast.code)}
125
- data-severity=${toast.severity}
126
- >
127
- ${glyph(toast.severity === "warning" ? "warning" : "info", "icon")}
128
- <p class="message">${toast.message}</p>
129
- <button
130
- type="button"
131
- data-testid="${p}-dismiss"
132
- aria-label=${labels.dismiss ?? "Dismiss"}
133
- @click=${() => this.fire(requestEvent, { id: "dismiss", toastId: toast.id })}
134
- >${glyph("close", "icon")}</button
122
+ class="toast"
123
+ role="status"
124
+ data-testid=${p}
125
+ data-code=${ifDefined(toast.code)}
126
+ data-severity=${toast.severity}
135
127
  >
136
- </div>`
128
+ ${glyph(toast.severity === "warning" ? "warning" : "info", "icon")}
129
+ <p class="message">${toast.message}</p>
130
+ <button
131
+ type="button"
132
+ data-testid="${p}-dismiss"
133
+ aria-label=${labels.dismiss ?? "Dismiss"}
134
+ @click=${() => this.fire(requestEvent, { id: "dismiss", toastId: toast.id })}
135
+ >${glyph("close", "icon")}</button
136
+ >
137
+ </div>`
137
138
  )}
138
139
  ${hiddenCount > 0 ? html`<p class="overflow">+${hiddenCount}</p>` : ""}
139
140
  </div>
@@ -216,12 +217,12 @@ var OfficeUiPasteOptions = class extends OfficeElement {
216
217
  this.model.options,
217
218
  (option) => option.id,
218
219
  (option) => html`<button
219
- type="button"
220
- data-format=${option.id}
221
- title=${option.label}
222
- @click=${() => this.choose(option)}
223
- >${option.label}</button
224
- >`
220
+ type="button"
221
+ data-format=${option.id}
222
+ title=${option.label}
223
+ @click=${() => this.choose(option)}
224
+ >${option.label}</button
225
+ >`
225
226
  )}
226
227
  </div>
227
228
  `;
@@ -1704,17 +1705,17 @@ var OfficeUiRibbon = class extends OfficeElement {
1704
1705
  >
1705
1706
  ${this.tabs.map(
1706
1707
  (tab) => html`<button
1707
- type="button"
1708
- role="tab"
1709
- id="tab-${tab.id}"
1710
- data-tab=${tab.id}
1711
- data-contextual=${ifDefined(tab.contextual ? "" : void 0)}
1712
- data-keytip=${ifDefined(tab.keytip)}
1713
- data-keytip-panel=${ifDefined(tab.keytipPanel)}
1714
- aria-selected=${String(tab.id === selected)}
1715
- tabindex=${tab.id === selected ? 0 : -1}
1716
- >${tab.label}</button
1717
- >`
1708
+ type="button"
1709
+ role="tab"
1710
+ id="tab-${tab.id}"
1711
+ data-tab=${tab.id}
1712
+ data-contextual=${ifDefined(tab.contextual ? "" : void 0)}
1713
+ data-keytip=${ifDefined(tab.keytip)}
1714
+ data-keytip-panel=${ifDefined(tab.keytipPanel)}
1715
+ aria-selected=${String(tab.id === selected)}
1716
+ tabindex=${tab.id === selected ? 0 : -1}
1717
+ >${tab.label}</button
1718
+ >`
1718
1719
  )}
1719
1720
  </div>
1720
1721
  <slot name="search"></slot>
@@ -2462,6 +2463,7 @@ var OfficeUiRuler = class extends OfficeElement {
2462
2463
  origin: { type: Number },
2463
2464
  scale: { type: Number },
2464
2465
  direction: { type: String },
2466
+ density: { type: Number },
2465
2467
  extent: { type: Number },
2466
2468
  marginStart: { type: Number },
2467
2469
  marginEnd: { type: Number },
@@ -2479,6 +2481,7 @@ var OfficeUiRuler = class extends OfficeElement {
2479
2481
  this.origin = 0;
2480
2482
  this.scale = 96;
2481
2483
  this.direction = "";
2484
+ this.density = 1;
2482
2485
  this.extent = 0;
2483
2486
  this.marginStart = 0;
2484
2487
  this.marginEnd = 0;
@@ -2586,7 +2589,8 @@ var OfficeUiRuler = class extends OfficeElement {
2586
2589
  context.font = `${style?.fontSize || OFFICE_TOKENS["--office-font-size-3xs"]} ${style?.fontFamily || OFFICE_TOKENS["--office-font"]}`;
2587
2590
  const origin = Number.isFinite(this.origin) ? this.origin : 0;
2588
2591
  const unit = Math.max(1, Number.isFinite(this.scale) ? this.scale : 96);
2589
- const divisions = rulerDivisions(unit);
2592
+ const density = this.density > 0 && this.density <= 1 ? this.density : 1;
2593
+ const divisions = Math.max(1, Math.round(rulerDivisions(unit) * density));
2590
2594
  const step = unit / divisions;
2591
2595
  const sign = reverse ? -1 : 1;
2592
2596
  const a = (0 - origin) / (sign * step);
@@ -2629,12 +2633,12 @@ var OfficeUiRuler = class extends OfficeElement {
2629
2633
  return html`${band("start", this.marginStart)}${band("end", this.marginEnd)}<canvas
2630
2634
  ></canvas>${this.markers.map(
2631
2635
  (marker) => html`<div
2632
- class="marker ${marker.edge === "top" ? "top" : "bottom"}"
2633
- data-marker=${marker.name}
2634
- style="${vertical ? "top" : "left"}:${marker.position}px"
2635
- aria-label=${marker.label ?? nothing}
2636
- @pointerdown=${(event) => this.dragMarker(event, marker.name)}
2637
- ></div>`
2636
+ class="marker ${marker.edge === "top" ? "top" : "bottom"}"
2637
+ data-marker=${marker.name}
2638
+ style="${vertical ? "top" : "left"}:${marker.position}px"
2639
+ aria-label=${marker.label ?? nothing}
2640
+ @pointerdown=${(event) => this.dragMarker(event, marker.name)}
2641
+ ></div>`
2638
2642
  )}`;
2639
2643
  }
2640
2644
  };
@@ -3419,9 +3423,11 @@ var OfficeUiContextMenu = class extends OfficeElement {
3419
3423
  let group;
3420
3424
  const closeGroup = () => {
3421
3425
  if (!group) return;
3422
- out.push(html`<div role="group" aria-label=${group.heading}>
3423
- <div class="heading" aria-hidden="true">${group.heading}</div>${group.rows}</div
3424
- >`);
3426
+ out.push(
3427
+ html`<div role="group" aria-label=${group.heading}>
3428
+ <div class="heading" aria-hidden="true">${group.heading}</div>${group.rows}</div
3429
+ >`
3430
+ );
3425
3431
  group = void 0;
3426
3432
  };
3427
3433
  this.model.items.forEach((item, index) => {
@@ -3600,7 +3606,7 @@ var OfficeUiMenuButton = class _OfficeUiMenuButton extends OfficeElement {
3600
3606
  }
3601
3607
  items() {
3602
3608
  return [...this.querySelectorAll("*")].filter(
3603
- (item) => (item instanceof OfficeUiMenuItem || item instanceof _OfficeUiMenuButton && present(item.submenu)) && !present(item.disabled) && !item.hidden && menuOwner(item) === this
3609
+ (item) => (item instanceof OfficeUiMenuItem || item instanceof _OfficeUiMenuButton && present(item.submenu) || item.hasAttribute("data-menu-item")) && !present(item.disabled) && !item.hidden && menuOwner(item) === this
3604
3610
  );
3605
3611
  }
3606
3612
  focus(options) {
@@ -3911,10 +3917,10 @@ var OfficeUiOptionsDialog = class extends OfficeElement {
3911
3917
  ${category.disabled ? html`<p class="unavailable">${category.disabled}</p>` : ""}
3912
3918
  ${category.sections.map(
3913
3919
  (section) => html`<section>
3914
- <h3>${section.title}</h3>
3915
- ${section.description ? html`<p class="desc">${section.description}</p>` : ""}
3916
- ${section.controls.map((control) => this.control(control))}
3917
- </section>`
3920
+ <h3>${section.title}</h3>
3921
+ ${section.description ? html`<p class="desc">${section.description}</p>` : ""}
3922
+ ${section.controls.map((control) => this.control(control))}
3923
+ </section>`
3918
3924
  )}
3919
3925
  `;
3920
3926
  }
@@ -3937,16 +3943,16 @@ var OfficeUiOptionsDialog = class extends OfficeElement {
3937
3943
  >
3938
3944
  ${this.categories.map(
3939
3945
  (entry) => html`<button
3940
- type="button"
3941
- role="tab"
3942
- id="tab-${entry.id}"
3943
- data-category=${entry.id}
3944
- aria-controls="pane"
3945
- aria-selected=${String(entry.id === this.active)}
3946
- tabindex=${entry.id === this.active ? 0 : -1}
3947
- @click=${() => this.category = entry.id}
3948
- >${entry.label}</button
3949
- >`
3946
+ type="button"
3947
+ role="tab"
3948
+ id="tab-${entry.id}"
3949
+ data-category=${entry.id}
3950
+ aria-controls="pane"
3951
+ aria-selected=${String(entry.id === this.active)}
3952
+ tabindex=${entry.id === this.active ? 0 : -1}
3953
+ @click=${() => this.category = entry.id}
3954
+ >${entry.label}</button
3955
+ >`
3950
3956
  )}
3951
3957
  </nav>
3952
3958
  <div
@@ -4506,12 +4512,12 @@ var OfficeUiStatusBar = class extends OfficeElement {
4506
4512
  items,
4507
4513
  (spec) => spec.id,
4508
4514
  (spec) => html`<span
4509
- class="item${spec.tone === "saving" ? " saving" : ""}${spec.tone === "error" ? " error" : ""}${spec.narrowHide ? " narrow-hide" : ""}"
4510
- data-item=${spec.id}
4511
- title=${ifDefined(spec.title)}
4512
- aria-live=${ifDefined(spec.live ? "polite" : void 0)}
4513
- >${spec.text}</span
4514
- >`
4515
+ class="item${spec.tone === "saving" ? " saving" : ""}${spec.tone === "error" ? " error" : ""}${spec.narrowHide ? " narrow-hide" : ""}"
4516
+ data-item=${spec.id}
4517
+ title=${ifDefined(spec.title)}
4518
+ aria-live=${ifDefined(spec.live ? "polite" : void 0)}
4519
+ >${spec.text}</span
4520
+ >`
4515
4521
  )}
4516
4522
  </span>
4517
4523
  <slot></slot>
@@ -4592,7 +4598,7 @@ var OfficeUiStatusItem = class extends OfficeElement {
4592
4598
  var defineStatusItem = definer("office-ui-status-item", () => OfficeUiStatusItem);
4593
4599
 
4594
4600
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/chrome/tab-strip.css?raw
4595
- var tab_strip_default = ":host {\n display: flex;\n align-items: stretch;\n min-width: 0;\n min-height: var(--office-tab-height);\n gap: var(--office-space-0);\n padding: 0 var(--office-space-1-5);\n background: var(--office-surface);\n color: var(--office-muted-foreground);\n border-top: var(--office-border-width) solid var(--office-border);\n font-size: var(--office-font-size-sm);\n font-family: var(--office-font);\n}\n.step {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: var(--office-target-size);\n min-height: var(--office-target-size);\n padding: 0;\n border: 0;\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n.step:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.add {\n font-size: var(--office-font-size-xl);\n line-height: 1;\n}\n.add[hidden] {\n display: none;\n}\n.list {\n display: flex;\n align-items: stretch;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: thin;\n}\n.tab {\n flex: none;\n max-width: var(--office-tab-max-width);\n min-height: var(--office-target-size);\n margin-top: calc(-1 * var(--office-space-px));\n padding: var(--office-space-0) var(--office-space-3-5);\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n border: var(--office-border-width) solid transparent;\n border-top: 0;\n border-radius: 0 0 var(--office-radius) var(--office-radius);\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n.tab:hover {\n color: var(--office-foreground);\n}\n.tab[aria-selected='true'] {\n border-color: var(--office-border);\n background: var(--office-background);\n color: var(--office-accent);\n font-weight: 600;\n box-shadow: inset 0 var(--office-border-width-thick) 0 var(--office-accent);\n}\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: calc(-1 * var(--office-focus-width));\n}\nsvg {\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@media (forced-colors: active) {\n :host {\n border-top-color: CanvasText;\n }\n .tab[aria-selected='true'] {\n background: Highlight;\n color: HighlightText;\n forced-color-adjust: none;\n }\n}\n";
4601
+ var tab_strip_default = ":host {\n display: flex;\n align-items: stretch;\n min-width: 0;\n min-height: var(--office-tab-height);\n gap: var(--office-space-0);\n padding: 0 var(--office-space-1-5);\n background: var(--office-surface);\n color: var(--office-muted-foreground);\n border-top: var(--office-border-width) solid var(--office-border);\n font-size: var(--office-font-size-sm);\n font-family: var(--office-font);\n}\n.step {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: var(--office-target-size);\n min-height: var(--office-target-size);\n padding: 0;\n border: 0;\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n.step:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.add {\n font-size: var(--office-font-size-xl);\n line-height: 1;\n}\n.add[hidden] {\n display: none;\n}\n.list {\n display: flex;\n align-items: stretch;\n min-width: 0;\n overflow-x: auto;\n scrollbar-width: thin;\n}\n.tab {\n flex: none;\n max-width: var(--office-tab-max-width);\n min-height: var(--office-target-size);\n margin-top: calc(-1 * var(--office-space-px));\n padding: var(--office-space-0) var(--office-space-3-5);\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n border: var(--office-border-width) solid transparent;\n border-top: 0;\n border-radius: 0 0 var(--office-radius) var(--office-radius);\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n.tab:hover {\n color: var(--office-foreground);\n}\n.tab[aria-selected='true'] {\n border-color: var(--office-border);\n background: var(--office-background);\n color: var(--office-accent);\n font-weight: 600;\n box-shadow: inset 0 var(--office-border-width-thick) 0 var(--office-accent);\n}\n:host([plain]) .tab[aria-selected='true'] {\n border-color: transparent;\n background: transparent;\n box-shadow: none;\n}\n::slotted([slot='after-tabs']) {\n align-self: center;\n}\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: calc(-1 * var(--office-focus-width));\n}\nsvg {\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@media (forced-colors: active) {\n :host {\n border-top-color: CanvasText;\n }\n .tab[aria-selected='true'] {\n background: Highlight;\n color: HighlightText;\n forced-color-adjust: none;\n }\n}\n";
4596
4602
 
4597
4603
  // src/chrome/tab-strip.ts
4598
4604
  var KEY_STEPS = {
@@ -4721,6 +4727,7 @@ var OfficeUiTabStrip = class extends OfficeElement {
4721
4727
  >`;
4722
4728
  })}
4723
4729
  </div>
4730
+ <slot name="after-tabs"></slot>
4724
4731
  <button
4725
4732
  type="button"
4726
4733
  class="step add"
@@ -4736,6 +4743,43 @@ var OfficeUiTabStrip = class extends OfficeElement {
4736
4743
  };
4737
4744
  var defineTabStrip = definer("office-ui-tab-strip", () => OfficeUiTabStrip);
4738
4745
 
4746
+ // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/chrome/task-pane.css?raw
4747
+ var task_pane_default = ":host {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n background: var(--office-background);\n color: var(--office-foreground);\n font-family: var(--office-font);\n font-size: var(--office-font-size-sm);\n}\n:host([hidden]) {\n display: none;\n}\n.header {\n display: flex;\n align-items: center;\n gap: var(--office-space-2);\n padding: var(--office-space-2-5) var(--office-space-2) var(--office-space-2) var(--office-space-3);\n}\n.title {\n flex: 1;\n min-width: 0;\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--office-font-size-lg);\n font-weight: var(--office-font-weight-bold);\n}\n.close {\n display: inline-grid;\n place-items: center;\n flex: none;\n width: var(--office-target-size);\n height: var(--office-target-size);\n padding: 0;\n border: 0;\n border-radius: var(--office-radius-sm);\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n.close:hover {\n background: var(--office-surface);\n}\n.close:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n}\n.icon {\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.body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 0 var(--office-space-3) var(--office-space-3);\n}\n@media (forced-colors: active) {\n .close:focus-visible {\n outline-color: Highlight;\n }\n}\n";
4748
+
4749
+ // src/chrome/task-pane.ts
4750
+ var OfficeUiTaskPane = class extends OfficeElement {
4751
+ static closeEvent = "office-pane-close";
4752
+ static styles = controlStyles(task_pane_default);
4753
+ static properties = {
4754
+ label: { type: String },
4755
+ closeLabel: { type: String, attribute: "close-label" }
4756
+ };
4757
+ constructor() {
4758
+ super();
4759
+ this.label = "";
4760
+ this.closeLabel = "";
4761
+ }
4762
+ willUpdate() {
4763
+ this.setAttribute("role", "complementary");
4764
+ this.setAttribute("aria-label", this.label);
4765
+ }
4766
+ render() {
4767
+ const close = this.closeLabel || `Close ${this.label}`;
4768
+ return html`<div class="header" part="header"
4769
+ ><h2 class="title">${this.label}</h2
4770
+ ><button
4771
+ type="button"
4772
+ class="close"
4773
+ title=${close}
4774
+ aria-label=${close}
4775
+ @click=${() => this.fire(this.constructor.closeEvent, {})}
4776
+ >${glyph("close", "icon")}</button
4777
+ ></div
4778
+ ><div class="body" part="body"><slot></slot></div>`;
4779
+ }
4780
+ };
4781
+ var defineTaskPane = definer("office-ui-task-pane", () => OfficeUiTaskPane);
4782
+
4739
4783
  // src/chrome/title-bar-types.ts
4740
4784
  var OFFICE_TITLE_BAR_SEARCH_LIMIT = 8;
4741
4785
  function matchTitleBarCommands(search, query) {
@@ -4745,7 +4789,7 @@ function matchTitleBarCommands(search, query) {
4745
4789
  }
4746
4790
 
4747
4791
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/chrome/title-bar.css?raw
4748
- 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";
4792
+ 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/* `centered`: the file name sits in the middle of the bar, as in Visio's window title. */\n@media (min-width: 761px) {\n :host([centered]) .bar {\n position: relative;\n }\n :host([centered]) .file {\n position: absolute;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n }\n :host([centered][dir='rtl']) .file {\n transform: translateX(50%);\n }\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 /* Without a search box nothing else pushes the account to the far edge. */\n margin-inline-start: auto;\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";
4749
4793
 
4750
4794
  // src/chrome/title-bar.ts
4751
4795
  var EMPTY = { fileName: "" };
@@ -4845,15 +4889,15 @@ var OfficeUiTitleBar = class extends OfficeElement {
4845
4889
  items,
4846
4890
  (item) => item.id,
4847
4891
  (item) => html`<button
4848
- type="button"
4849
- data-command=${item.id}
4850
- aria-label=${item.label}
4851
- title=${ifDefined(item.title)}
4852
- tabindex=${item === current ? 0 : -1}
4853
- ?disabled=${item.disabled === true}
4854
- @click=${() => this.activate(item.id)}
4855
- >${glyph(item.icon, "icon")}${qa?.showLabels === true ? html`<small>${item.label}</small>` : ""}</button
4856
- >`
4892
+ type="button"
4893
+ data-command=${item.id}
4894
+ aria-label=${item.label}
4895
+ title=${ifDefined(item.title)}
4896
+ tabindex=${item === current ? 0 : -1}
4897
+ ?disabled=${item.disabled === true}
4898
+ @click=${() => this.activate(item.id)}
4899
+ >${glyph(item.icon, "icon")}${qa?.showLabels === true ? html`<small>${item.label}</small>` : ""}</button
4900
+ >`
4857
4901
  )}
4858
4902
  </div>`;
4859
4903
  }
@@ -4915,15 +4959,15 @@ var OfficeUiTitleBar = class extends OfficeElement {
4915
4959
  <div class="results" role="listbox" ?hidden=${!this.resultsOpen}>
4916
4960
  ${this.found.length > 0 ? html`<div class="heading">${search.heading}</div> ${this.found.map(
4917
4961
  (entry, index) => html`<button
4918
- type="button"
4919
- role="option"
4920
- tabindex="-1"
4921
- aria-selected=${String(index === this.active)}
4922
- @mousedown=${(event) => pick(event, () => this.commit(entry))}
4923
- @mouseenter=${() => this.active = index}
4924
- ><span>${entry.label}</span
4925
- ><span class="cat">${entry.category ?? ""}</span></button
4926
- >`
4962
+ type="button"
4963
+ role="option"
4964
+ tabindex="-1"
4965
+ aria-selected=${String(index === this.active)}
4966
+ @mousedown=${(event) => pick(event, () => this.commit(entry))}
4967
+ @mouseenter=${() => this.active = index}
4968
+ ><span>${entry.label}</span
4969
+ ><span class="cat">${entry.category ?? ""}</span></button
4970
+ >`
4927
4971
  )}` : html`<div class="empty">${search.empty}</div>`}
4928
4972
  ${search.content ? html`<button
4929
4973
  type="button"
@@ -5300,6 +5344,405 @@ var OfficeUiSymbolPicker = class extends OfficeElement {
5300
5344
  };
5301
5345
  var defineSymbolPicker = definer("office-ui-symbol-picker", () => OfficeUiSymbolPicker);
5302
5346
 
5347
+ // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/form/color-grid.css?raw
5348
+ var color_grid_default = "/* Tokens: --office-space-*, --office-border, --office-selected, --office-field-border-focus. */\n:host {\n display: block;\n color: var(--office-foreground);\n font: var(--office-font-size-sm) / var(--office-line-height-tight) var(--office-font);\n}\n:host([hidden]) {\n display: none;\n}\n.grid {\n display: grid;\n gap: var(--office-space-1);\n padding: var(--office-space-1);\n width: max-content;\n}\n.heading {\n padding: var(--office-space-0) var(--office-space-1);\n background: var(--office-selected);\n color: var(--office-foreground);\n font-weight: var(--office-font-weight-bold);\n}\n.cells {\n display: grid;\n grid-template-columns: repeat(10, var(--office-space-4));\n gap: var(--office-space-1);\n}\n/* The five variant rows sit flush under one another, as in Office. */\n.variants {\n display: grid;\n gap: 0;\n}\n.swatch {\n box-sizing: border-box;\n width: var(--office-space-4);\n height: var(--office-space-4);\n padding: 0;\n border: var(--office-border-width) solid var(--office-border);\n border-radius: 0;\n background: var(--swatch);\n cursor: pointer;\n}\n.swatch:hover:not(:disabled),\n.swatch:focus-visible,\n.swatch[aria-checked='true'] {\n outline: var(--office-space-0) solid var(--office-field-border-focus);\n outline-offset: var(--office-space-px);\n position: relative;\n z-index: 1;\n}\n.command {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n width: 100%;\n min-height: var(--office-control-height-md);\n padding: 0 var(--office-space-2);\n border: 0;\n border-radius: var(--office-radius-sm);\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: start;\n cursor: pointer;\n}\n.command:hover:not(:disabled),\n.command:focus-visible,\n.command[aria-checked='true'] {\n background: var(--office-selected);\n outline: none;\n}\nbutton:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n@media (forced-colors: active) {\n .swatch {\n forced-color-adjust: none;\n border-color: CanvasText;\n }\n .swatch:focus-visible,\n .swatch[aria-checked='true'] {\n outline-color: Highlight;\n }\n}\n";
5349
+
5350
+ // src/form/color-grid.ts
5351
+ var COLUMNS = 10;
5352
+ var OfficeUiColorGrid = class extends OfficeElement {
5353
+ static styles = controlStyles(color_grid_default);
5354
+ static properties = {
5355
+ themeColors: { attribute: false },
5356
+ themeNames: { attribute: false },
5357
+ variantLabel: { attribute: false },
5358
+ extraColors: { attribute: false },
5359
+ standardColors: { attribute: false },
5360
+ recentColors: { attribute: false },
5361
+ value: { type: String },
5362
+ label: { type: String },
5363
+ noneLabel: { attribute: "none-label", type: String },
5364
+ automaticLabel: { attribute: "automatic-label", type: String },
5365
+ moreLabel: { attribute: "more-label", type: String },
5366
+ themeHeading: { attribute: "theme-heading", type: String },
5367
+ standardHeading: { attribute: "standard-heading", type: String },
5368
+ recentHeading: { attribute: "recent-heading", type: String },
5369
+ disabled: flag
5370
+ };
5371
+ constructor() {
5372
+ super();
5373
+ this.themeColors = null;
5374
+ this.themeNames = null;
5375
+ this.variantLabel = null;
5376
+ this.extraColors = [];
5377
+ this.standardColors = OFFICE_STANDARD_COLORS;
5378
+ this.recentColors = [];
5379
+ this.value = null;
5380
+ this.label = null;
5381
+ this.noneLabel = null;
5382
+ this.automaticLabel = null;
5383
+ this.moreLabel = null;
5384
+ this.themeHeading = "Theme Colors";
5385
+ this.standardHeading = "Standard Colors";
5386
+ this.recentHeading = "Recent Colors";
5387
+ this.disabled = false;
5388
+ }
5389
+ /** Focus the current choice, or the first item. */
5390
+ focus(options) {
5391
+ const items = this.items();
5392
+ (items.find((item) => item.getAttribute("aria-checked") === "true") ?? items[0])?.focus(
5393
+ options
5394
+ );
5395
+ }
5396
+ items() {
5397
+ return [...this.renderRoot.querySelectorAll("button:not(:disabled)")];
5398
+ }
5399
+ pick(color, source, label, more = {}) {
5400
+ if (present(this.disabled)) return;
5401
+ emit(this, "office-color-pick", { color, source, label, ...more });
5402
+ }
5403
+ more() {
5404
+ if (!present(this.disabled)) emit(this, "office-color-more", {});
5405
+ }
5406
+ onKey(event) {
5407
+ const items = this.items();
5408
+ const current = items.indexOf(event.target);
5409
+ if (current < 0) return;
5410
+ const at = (item) => ({
5411
+ row: Number(item.dataset.row),
5412
+ column: Number(item.dataset.column)
5413
+ });
5414
+ const from = at(items[current]);
5415
+ const inRow = (row) => items.filter((item) => at(item).row === row);
5416
+ const rows = [...new Set(items.map((item) => at(item).row))];
5417
+ const vertical = (step) => {
5418
+ const target = rows[rows.indexOf(from.row) + step];
5419
+ if (target === void 0) return void 0;
5420
+ return inRow(target).reduce(
5421
+ (best, item) => Math.abs(at(item).column - from.column) < Math.abs(at(best).column - from.column) ? item : best
5422
+ );
5423
+ };
5424
+ const next = event.key === "ArrowRight" ? items[current + 1] : event.key === "ArrowLeft" ? items[current - 1] : event.key === "ArrowDown" ? vertical(1) : event.key === "ArrowUp" ? vertical(-1) : event.key === "Home" ? items[0] : event.key === "End" ? items.at(-1) : void 0;
5425
+ if (!["ArrowRight", "ArrowLeft", "ArrowDown", "ArrowUp", "Home", "End"].includes(event.key))
5426
+ return;
5427
+ if (!next && (event.key === "ArrowDown" || event.key === "ArrowUp")) return;
5428
+ event.preventDefault();
5429
+ event.stopPropagation();
5430
+ next?.focus();
5431
+ }
5432
+ willUpdate() {
5433
+ this.setAttribute("role", "group");
5434
+ this.setAttribute("aria-label", this.label ?? "Colors");
5435
+ }
5436
+ render() {
5437
+ const disabled = present(this.disabled);
5438
+ const value = this.value ? normalizePaletteHex(this.value) ?? this.value : null;
5439
+ let row = 0;
5440
+ const command = (text, name2, checked, run) => html`<button
5441
+ type="button"
5442
+ class="command"
5443
+ data-command=${name2}
5444
+ data-row=${row++}
5445
+ data-column="0"
5446
+ role=${checked === void 0 ? "button" : "menuitemradio"}
5447
+ aria-checked=${checked === void 0 ? nothing : String(checked)}
5448
+ ?disabled=${disabled}
5449
+ @click=${run}
5450
+ >${text}</button
5451
+ >`;
5452
+ const swatch = (item, source, column) => html`<button
5453
+ type="button"
5454
+ class="swatch"
5455
+ role="menuitemradio"
5456
+ data-color=${item.hex}
5457
+ data-source=${source}
5458
+ data-row=${row}
5459
+ data-column=${column}
5460
+ title=${item.label}
5461
+ aria-label=${item.label}
5462
+ aria-checked=${String(value === item.hex)}
5463
+ style=${`--swatch:${item.hex}`}
5464
+ ?disabled=${disabled}
5465
+ @click=${() => this.pick(
5466
+ item.hex,
5467
+ source,
5468
+ item.label,
5469
+ source === "theme" ? { theme: { column, ...item.variant ? { variant: item.variant } : {} } } : source === "extra" ? { index: column } : {}
5470
+ )}
5471
+ ></button>`;
5472
+ const cells = (items, source) => {
5473
+ const result = html`<div class="cells" data-cells=${source}
5474
+ >${items.map((item, index) => swatch(item, source, index))}</div
5475
+ >`;
5476
+ row++;
5477
+ return result;
5478
+ };
5479
+ const palette = buildThemePalette(this.themeColors ?? void 0, this.themeNames ?? void 0);
5480
+ const extra = (this.extraColors ?? []).slice(0, COLUMNS);
5481
+ const name = this.variantLabel;
5482
+ const variants = (index) => palette.map((column) => {
5483
+ const item = column.variants[index];
5484
+ return name ? { ...item, label: name(column.name, item.variant) } : item;
5485
+ });
5486
+ const recent = (this.recentColors ?? []).map((hex) => normalizePaletteHex(hex)).filter((hex) => !!hex).slice(0, COLUMNS).map((hex) => ({ hex, label: hex.toUpperCase() }));
5487
+ const automatic = this.automaticLabel;
5488
+ const none = this.noneLabel;
5489
+ const more = this.moreLabel;
5490
+ return html`<div class="grid" part="grid" @keydown=${this.onKey}
5491
+ >${automatic ? command(
5492
+ automatic,
5493
+ "automatic",
5494
+ value === "automatic",
5495
+ () => this.pick("automatic", "automatic", automatic)
5496
+ ) : nothing}${none ? command(none, "none", value === "none", () => this.pick("none", "none", none)) : nothing}
5497
+ <div class="heading">${this.themeHeading}</div>
5498
+ ${cells(
5499
+ palette.map((column) => column.base),
5500
+ "theme"
5501
+ )}
5502
+ <div class="variants">${[0, 1, 2, 3, 4].map((index) => cells(variants(index), "theme"))}</div>
5503
+ ${extra.length ? cells(extra, "extra") : nothing}
5504
+ <div class="heading">${this.standardHeading}</div>
5505
+ ${cells(this.standardColors ?? OFFICE_STANDARD_COLORS, "standard")}
5506
+ ${recent.length ? html`<div class="heading">${this.recentHeading}</div> ${cells(recent, "recent")}` : nothing}
5507
+ ${more ? command(more, "more", void 0, () => this.more()) : nothing}</div
5508
+ >`;
5509
+ }
5510
+ };
5511
+ var defineColorGrid = definer("office-ui-color-grid", () => OfficeUiColorGrid);
5512
+
5513
+ // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/form/color-custom.css?raw
5514
+ var color_custom_default = "/* Tokens: --office-space-*, --office-border, --office-field-*, --office-foreground. */\n:host {\n display: block;\n color: var(--office-foreground);\n font: var(--office-font-size-sm) / var(--office-line-height-tight) var(--office-font);\n}\n:host([hidden]) {\n display: none;\n}\n.custom {\n display: flex;\n flex-wrap: wrap;\n gap: var(--office-space-4);\n align-items: flex-start;\n}\n.picker {\n display: flex;\n gap: var(--office-space-3);\n}\n/* Hue runs across; saturation falls to grey at the bottom, as in Office. */\n.square {\n position: relative;\n width: calc(var(--office-space-4) * 13);\n height: calc(var(--office-space-4) * 10);\n border: var(--office-border-width) solid var(--office-border);\n background:\n linear-gradient(to top, hsl(0 0% 50%), hsl(0 0% 50% / 0)),\n linear-gradient(\n to right,\n hsl(0 100% 50%),\n hsl(60 100% 50%),\n hsl(120 100% 50%),\n hsl(180 100% 50%),\n hsl(240 100% 50%),\n hsl(300 100% 50%),\n hsl(360 100% 50%)\n );\n cursor: crosshair;\n touch-action: none;\n}\n:host(:dir(rtl)) .square {\n background:\n linear-gradient(to top, hsl(0 0% 50%), hsl(0 0% 50% / 0)),\n linear-gradient(\n to left,\n hsl(0 100% 50%),\n hsl(60 100% 50%),\n hsl(120 100% 50%),\n hsl(180 100% 50%),\n hsl(240 100% 50%),\n hsl(300 100% 50%),\n hsl(360 100% 50%)\n );\n}\n.cross {\n position: absolute;\n box-sizing: border-box;\n width: var(--office-space-3);\n height: var(--office-space-3);\n margin: calc(var(--office-space-3) / -2);\n border: var(--office-space-0) solid var(--office-foreground);\n border-radius: 50%;\n box-shadow: 0 0 0 var(--office-space-px) var(--office-surface);\n pointer-events: none;\n}\n.slider {\n position: relative;\n width: var(--office-space-4);\n height: calc(var(--office-space-4) * 10);\n border: var(--office-border-width) solid var(--office-border);\n background: linear-gradient(to top, hsl(0 0% 0%), var(--_pure), hsl(0 0% 100%));\n cursor: ns-resize;\n touch-action: none;\n}\n.thumb {\n position: absolute;\n inset-inline: calc(var(--office-space-1) * -1);\n height: var(--office-space-1);\n margin-top: calc(var(--office-space-1) / -2);\n border: var(--office-border-width) solid var(--office-foreground);\n background: var(--office-surface);\n pointer-events: none;\n}\n.square:focus-visible,\n.slider:focus-visible {\n outline: var(--office-space-0) solid var(--office-field-border-focus);\n outline-offset: var(--office-space-0);\n}\n.fields {\n display: grid;\n grid-template-columns: auto auto;\n gap: var(--office-space-1) var(--office-space-3);\n align-content: start;\n}\nlabel {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--office-space-2);\n}\n.hex,\n.preview {\n grid-column: 1 / -1;\n}\ninput {\n box-sizing: border-box;\n width: calc(var(--office-space-4) * 4);\n min-height: var(--office-control-height-md);\n padding: 0 var(--office-space-1);\n border: var(--office-border-width) solid var(--office-field-border);\n border-radius: var(--office-radius-sm);\n background: var(--office-field-background);\n color: inherit;\n font: inherit;\n}\n.hex input {\n width: calc(var(--office-space-4) * 6);\n}\ninput:focus-visible {\n outline: none;\n border-color: var(--office-field-border-focus);\n}\ninput[aria-invalid='true'] {\n border-color: var(--office-danger);\n}\n.preview {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: center;\n gap: 0 var(--office-space-2);\n margin-top: var(--office-space-2);\n}\n.swatch {\n grid-column: 2;\n height: var(--office-space-5);\n border: var(--office-border-width) solid var(--office-border);\n background: var(--_swatch);\n}\n.swatch[data-preview='current'] {\n border-top: 0;\n}\n.preview span:first-child {\n grid-row: 1;\n}\n.preview span:last-child {\n grid-row: 2;\n grid-column: 1;\n}\n[aria-disabled='true'],\ninput:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n@media (forced-colors: active) {\n .square,\n .slider,\n .swatch {\n forced-color-adjust: none;\n border-color: CanvasText;\n }\n}\n";
5515
+
5516
+ // src/form/color-custom.ts
5517
+ var SCALE = 255;
5518
+ var CHANNELS = [
5519
+ ["red", "Red"],
5520
+ ["green", "Green"],
5521
+ ["blue", "Blue"],
5522
+ ["hue", "Hue"],
5523
+ ["sat", "Sat"],
5524
+ ["lum", "Lum"]
5525
+ ];
5526
+ var clamp = (value, max = 1) => Math.min(max, Math.max(0, value));
5527
+ var OfficeUiColorCustom = class extends OfficeElement {
5528
+ static styles = controlStyles(color_custom_default);
5529
+ static properties = {
5530
+ value: { type: String, noAccessor: true },
5531
+ current: { type: String },
5532
+ label: { type: String },
5533
+ disabled: flag,
5534
+ hsl: { state: true },
5535
+ typed: { state: true },
5536
+ bad: { state: true }
5537
+ };
5538
+ constructor() {
5539
+ super();
5540
+ this.current = null;
5541
+ this.label = null;
5542
+ this.disabled = false;
5543
+ this.hsl = { h: 0, s: 0, l: 0 };
5544
+ this.typed = null;
5545
+ this.bad = null;
5546
+ }
5547
+ get value() {
5548
+ const { r, g, b } = hslToRgb(this.hsl.h, this.hsl.s, this.hsl.l);
5549
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toLowerCase();
5550
+ }
5551
+ set value(next) {
5552
+ const color = normalizePaletteHex(next ?? "");
5553
+ if (!color || color === this.value) return;
5554
+ const rgb = hexToRgbChannels(color);
5555
+ this.hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
5556
+ this.typed = null;
5557
+ this.bad = null;
5558
+ }
5559
+ set(next) {
5560
+ if (present(this.disabled)) return;
5561
+ this.hsl = { ...this.hsl, ...next };
5562
+ this.typed = null;
5563
+ this.bad = null;
5564
+ emit(this, "office-color-change", { color: this.value });
5565
+ }
5566
+ fromSquare(event) {
5567
+ const box = event.currentTarget.getBoundingClientRect();
5568
+ if (!box.width || !box.height) return;
5569
+ this.set({
5570
+ h: clamp((event.clientX - box.left) / box.width) * 359.999,
5571
+ s: 1 - clamp((event.clientY - box.top) / box.height)
5572
+ });
5573
+ }
5574
+ fromSlider(event) {
5575
+ const box = event.currentTarget.getBoundingClientRect();
5576
+ if (box.height) this.set({ l: 1 - clamp((event.clientY - box.top) / box.height) });
5577
+ }
5578
+ drag(move) {
5579
+ return (event) => {
5580
+ if (present(this.disabled) || event.button > 0) return;
5581
+ const target = event.currentTarget;
5582
+ target.setPointerCapture?.(event.pointerId);
5583
+ target.focus();
5584
+ move.call(this, event);
5585
+ const onMove = (next) => move.call(this, next);
5586
+ const stop = () => {
5587
+ target.removeEventListener("pointermove", onMove);
5588
+ target.removeEventListener("pointerup", stop);
5589
+ target.removeEventListener("pointercancel", stop);
5590
+ };
5591
+ target.addEventListener("pointermove", onMove);
5592
+ target.addEventListener("pointerup", stop);
5593
+ target.addEventListener("pointercancel", stop);
5594
+ };
5595
+ }
5596
+ squareKey(event) {
5597
+ const step = event.shiftKey ? 10 : 1;
5598
+ const { h, s } = this.hsl;
5599
+ const next = event.key === "ArrowRight" ? { h: clamp(h + step * (360 / SCALE), 359.999) } : event.key === "ArrowLeft" ? { h: clamp(h - step * (360 / SCALE), 359.999) } : event.key === "ArrowUp" ? { s: clamp(s + step / SCALE) } : event.key === "ArrowDown" ? { s: clamp(s - step / SCALE) } : event.key === "Home" ? { h: 0 } : event.key === "End" ? { h: 359.999 } : void 0;
5600
+ if (!next) return;
5601
+ event.preventDefault();
5602
+ event.stopPropagation();
5603
+ this.set(next);
5604
+ }
5605
+ sliderKey(event) {
5606
+ const step = (event.shiftKey ? 10 : 1) / SCALE;
5607
+ const { l } = this.hsl;
5608
+ const next = event.key === "ArrowUp" || event.key === "ArrowRight" ? clamp(l + step) : event.key === "ArrowDown" || event.key === "ArrowLeft" ? clamp(l - step) : event.key === "Home" ? 0 : event.key === "End" ? 1 : void 0;
5609
+ if (next === void 0) return;
5610
+ event.preventDefault();
5611
+ event.stopPropagation();
5612
+ this.set({ l: next });
5613
+ }
5614
+ channels() {
5615
+ const { r, g, b } = hslToRgb(this.hsl.h, this.hsl.s, this.hsl.l);
5616
+ return {
5617
+ red: r,
5618
+ green: g,
5619
+ blue: b,
5620
+ hue: Math.round(this.hsl.h / 360 * SCALE),
5621
+ sat: Math.round(this.hsl.s * SCALE),
5622
+ lum: Math.round(this.hsl.l * SCALE)
5623
+ };
5624
+ }
5625
+ onChannel(name, event) {
5626
+ const input = event.target;
5627
+ const value = Number(input.value);
5628
+ if (present(this.disabled)) return;
5629
+ if (input.value.trim() === "" || !Number.isInteger(value) || value < 0 || value > SCALE) {
5630
+ this.bad = name;
5631
+ return;
5632
+ }
5633
+ if (name === "hue") return this.set({ h: Math.min(359.999, value / SCALE * 360) });
5634
+ if (name === "sat") return this.set({ s: value / SCALE });
5635
+ if (name === "lum") return this.set({ l: value / SCALE });
5636
+ const now = this.channels();
5637
+ const rgb = { ...now, [name]: value };
5638
+ const next = rgbToHsl(rgb.red, rgb.green, rgb.blue);
5639
+ this.set(next.s === 0 ? { ...next, h: this.hsl.h } : next);
5640
+ }
5641
+ onHex(event) {
5642
+ if (present(this.disabled)) return;
5643
+ const text = event.target.value;
5644
+ const color = /^#?[0-9a-f]{6}$/i.test(text.trim()) ? normalizePaletteHex(text) : void 0;
5645
+ if (!color) {
5646
+ this.typed = text;
5647
+ return;
5648
+ }
5649
+ const rgb = hexToRgbChannels(color);
5650
+ this.set(rgbToHsl(rgb.r, rgb.g, rgb.b));
5651
+ }
5652
+ /** Whether the fields hold a colour (a half-typed hex or an out-of-range channel does not). */
5653
+ get valid() {
5654
+ return this.typed === null && this.bad === null;
5655
+ }
5656
+ willUpdate() {
5657
+ this.setAttribute("role", "group");
5658
+ this.setAttribute("aria-label", this.label ?? "Custom color");
5659
+ }
5660
+ render() {
5661
+ const disabled = present(this.disabled);
5662
+ const { h, s, l } = this.hsl;
5663
+ const values = this.channels();
5664
+ const color = this.value;
5665
+ const current = normalizePaletteHex(this.current ?? "");
5666
+ return html`<div class="custom" part="custom">
5667
+ <div class="picker">
5668
+ <div
5669
+ class="square"
5670
+ role="slider"
5671
+ tabindex=${disabled ? -1 : 0}
5672
+ aria-label="Hue and saturation"
5673
+ aria-valuemin="0"
5674
+ aria-valuemax=${SCALE}
5675
+ aria-valuenow=${values.hue}
5676
+ aria-valuetext=${`Hue ${values.hue}, saturation ${values.sat}`}
5677
+ aria-disabled=${String(disabled)}
5678
+ @pointerdown=${this.drag(this.fromSquare)}
5679
+ @keydown=${this.squareKey}
5680
+ ><span
5681
+ class="cross"
5682
+ style=${`inset-inline-start:${h / 360 * 100}%;top:${(1 - s) * 100}%`}
5683
+ ></span
5684
+ ></div>
5685
+ <div
5686
+ class="slider"
5687
+ role="slider"
5688
+ tabindex=${disabled ? -1 : 0}
5689
+ aria-label="Luminance"
5690
+ aria-orientation="vertical"
5691
+ aria-valuemin="0"
5692
+ aria-valuemax=${SCALE}
5693
+ aria-valuenow=${values.lum}
5694
+ aria-disabled=${String(disabled)}
5695
+ style=${`--_pure:hsl(${h} ${s * 100}% 50%)`}
5696
+ @pointerdown=${this.drag(this.fromSlider)}
5697
+ @keydown=${this.sliderKey}
5698
+ ><span class="thumb" style=${`top:${(1 - l) * 100}%`}></span
5699
+ ></div>
5700
+ </div>
5701
+ <div class="fields">
5702
+ <label class="hex"
5703
+ ><span>Hex</span
5704
+ ><input
5705
+ type="text"
5706
+ maxlength="7"
5707
+ spellcheck="false"
5708
+ data-color-field="hex"
5709
+ placeholder="#RRGGBB"
5710
+ aria-invalid=${String(this.typed !== null)}
5711
+ .value=${this.typed ?? color.toUpperCase()}
5712
+ ?disabled=${disabled}
5713
+ @input=${this.onHex}
5714
+ /></label>
5715
+ ${CHANNELS.map(
5716
+ ([name, text]) => html`<label
5717
+ ><span>${text}</span
5718
+ ><input
5719
+ type="number"
5720
+ min="0"
5721
+ max=${SCALE}
5722
+ step="1"
5723
+ data-color-field=${name}
5724
+ aria-invalid=${String(this.bad === name)}
5725
+ .value=${String(values[name])}
5726
+ ?disabled=${disabled}
5727
+ @input=${(event) => this.onChannel(name, event)}
5728
+ /></label>`
5729
+ )}
5730
+ <div class="preview" aria-hidden="true">
5731
+ <span>New</span>
5732
+ <span class="swatch" data-preview="new" style=${`--_swatch:${color}`}></span>
5733
+ <span
5734
+ class="swatch"
5735
+ data-preview="current"
5736
+ style=${`--_swatch:${current ?? "transparent"}`}
5737
+ ></span>
5738
+ <span>Current</span>
5739
+ </div>
5740
+ </div>
5741
+ </div>`;
5742
+ }
5743
+ };
5744
+ var defineColorCustom = definer("office-ui-color-custom", () => OfficeUiColorCustom);
5745
+
5303
5746
  // src/keytips.ts
5304
5747
  var BADGE_CSS = "position:fixed;inset:auto;margin:0;padding:0;border:0;background:transparent;overflow:visible;pointer-events:none";
5305
5748
  var TIP_CSS = `position:fixed;transform:translate(-50%,-30%);min-width:${tok("--office-icon-size")};padding:${tok("--office-space-px")} ${tok("--office-space-1")};border:${tok("--office-border-width")} solid ${tok("--office-keytip-border")};border-radius:${tok("--office-radius-xs")};background:${tok("--office-keytip-background")};color:${tok("--office-keytip-foreground")};font:${tok("--office-font-weight-bold")} ${tok("--office-font-size-xs")}/${tok("--office-icon-size")} ${tok("--office-font")};text-align:center;box-shadow:${tok("--office-shadow-sm")}`;
@@ -5628,7 +6071,7 @@ function createRibbonOverflow(options) {
5628
6071
  group.setAttribute("data-collapsed", "");
5629
6072
  }
5630
6073
  }
5631
- const panelsOf = (root) => root.querySelectorAll(".ribbon-panel");
6074
+ const panelsOf2 = (root) => root.querySelectorAll(".ribbon-panel");
5632
6075
  return {
5633
6076
  fitPanel,
5634
6077
  attach(root) {
@@ -5637,16 +6080,152 @@ function createRibbonOverflow(options) {
5637
6080
  const observer = new ResizeObserver((entries) => {
5638
6081
  for (const entry of entries) fitPanel(entry.target);
5639
6082
  });
5640
- for (const panel of panelsOf(root)) observer.observe(panel);
6083
+ for (const panel of panelsOf2(root)) observer.observe(panel);
5641
6084
  return () => observer.disconnect();
5642
6085
  },
5643
6086
  refit(root) {
5644
- for (const panel of panelsOf(root)) fitPanel(panel);
6087
+ for (const panel of panelsOf2(root)) fitPanel(panel);
5645
6088
  },
5646
6089
  close: () => closeOpen?.()
5647
6090
  };
5648
6091
  }
5649
6092
 
6093
+ // src/ribbon/group-overflow.ts
6094
+ var GROUP = "office-ui-ribbon-group";
6095
+ var TOGGLE = "office-ribbon-collapse-toggle";
6096
+ var panelsOf = (ribbon) => [...ribbon.children].filter(
6097
+ (child) => child instanceof HTMLElement && !!child.dataset.ribbonTab
6098
+ );
6099
+ var groupsOf = (panel) => [...panel.querySelectorAll(GROUP)].filter(
6100
+ (group) => group.parentElement?.closest(GROUP) === null && group.getBoundingClientRect().width > 0
6101
+ );
6102
+ var faceOf = (group) => group.shadowRoot?.querySelector(".face") ?? null;
6103
+ function fitRibbonGroups(panel, options = {}) {
6104
+ for (const group of panel.querySelectorAll(`${GROUP}[data-collapsed]`)) {
6105
+ group.removeAttribute("data-open");
6106
+ group.removeAttribute("data-collapsed");
6107
+ }
6108
+ const width = panel.ownerDocument.defaultView?.innerWidth ?? Number.POSITIVE_INFINITY;
6109
+ if (panel.hidden || width < (options.minWidth ?? 0)) return [];
6110
+ const overflows = () => panel.scrollWidth - panel.clientWidth > 1;
6111
+ const collapsed = [];
6112
+ if (!overflows()) return collapsed;
6113
+ for (const group of groupsOf(panel).reverse()) {
6114
+ const icon = group.getAttribute("icon") ?? options.icon?.(group);
6115
+ if (icon) group.setAttribute("icon", icon);
6116
+ group.setAttribute("data-collapsed", "");
6117
+ collapsed.push(group.getAttribute("label") ?? "");
6118
+ if (!overflows()) break;
6119
+ }
6120
+ return collapsed;
6121
+ }
6122
+ function place(group) {
6123
+ const face = faceOf(group);
6124
+ if (!face) return;
6125
+ const rect = face.getBoundingClientRect();
6126
+ const view = group.ownerDocument.defaultView;
6127
+ const width = view?.innerWidth ?? 1024;
6128
+ group.style.setProperty("--office-ribbon-collapse-y", `${Math.round(rect.bottom + 2)}px`);
6129
+ group.style.setProperty("--office-ribbon-collapse-x", `${Math.round(rect.left)}px`);
6130
+ const popup = group.shadowRoot?.querySelector(".row")?.getBoundingClientRect();
6131
+ const left = Math.max(4, Math.min(rect.left, width - (popup?.width ?? 0) - 8));
6132
+ group.style.setProperty("--office-ribbon-collapse-x", `${Math.round(left)}px`);
6133
+ }
6134
+ function attachRibbonGroupOverflow(ribbon, options = {}) {
6135
+ const doc = ribbon.ownerDocument;
6136
+ const view = doc.defaultView;
6137
+ let frame = 0;
6138
+ let fitted = -1;
6139
+ const openGroup = () => ribbon.querySelector(`${GROUP}[data-open]`);
6140
+ const close = () => {
6141
+ for (const group of ribbon.querySelectorAll(`${GROUP}[data-open]`))
6142
+ group.removeAttribute("data-open");
6143
+ };
6144
+ const visible2 = () => panelsOf(ribbon).find((panel) => !panel.hidden);
6145
+ const refit = () => {
6146
+ const panel = visible2();
6147
+ for (const other of panelsOf(ribbon)) if (other !== panel) fitRibbonGroups(other, options);
6148
+ fitted = panel?.clientWidth ?? -1;
6149
+ if (panel) fitRibbonGroups(panel, options);
6150
+ };
6151
+ const schedule = (force) => {
6152
+ if (!force && openGroup() && fitted === visible2()?.clientWidth) return;
6153
+ if (frame || !view) return;
6154
+ frame = view.requestAnimationFrame(() => {
6155
+ frame = 0;
6156
+ refit();
6157
+ watch();
6158
+ });
6159
+ };
6160
+ let watch = () => {
6161
+ };
6162
+ const toggle = (event) => {
6163
+ const group = event.composedPath().find((node) => node instanceof HTMLElement && node.localName === GROUP);
6164
+ if (!group?.hasAttribute("data-collapsed")) return;
6165
+ const wasOpen = group.hasAttribute("data-open");
6166
+ close();
6167
+ if (wasOpen) return;
6168
+ group.setAttribute("data-open", "");
6169
+ place(group);
6170
+ };
6171
+ const nested = (group) => [...group.querySelectorAll("*")].some(
6172
+ (el) => el.localName.startsWith("office-ui-") && el.open === true
6173
+ );
6174
+ const outside = (event) => {
6175
+ const open = openGroup();
6176
+ if (open && !event.composedPath().includes(open) && !nested(open)) close();
6177
+ };
6178
+ const escape = (event) => {
6179
+ const open = openGroup();
6180
+ if (event.key !== "Escape" || !open || nested(open)) return;
6181
+ event.stopPropagation();
6182
+ close();
6183
+ faceOf(open)?.focus();
6184
+ };
6185
+ const command = (event) => {
6186
+ const open = openGroup();
6187
+ if (open && event.composedPath().includes(open)) queueMicrotask(close);
6188
+ };
6189
+ const onSelect = () => schedule(true);
6190
+ const resize = view && "ResizeObserver" in view ? new view.ResizeObserver(() => schedule(false)) : void 0;
6191
+ const mutation = view && "MutationObserver" in view ? new view.MutationObserver(() => schedule(true)) : void 0;
6192
+ resize?.observe(ribbon);
6193
+ watch = () => {
6194
+ mutation?.disconnect();
6195
+ mutation?.observe(ribbon, { childList: true });
6196
+ for (const panel of panelsOf(ribbon))
6197
+ mutation?.observe(panel, { attributes: true, attributeFilter: ["hidden"] });
6198
+ };
6199
+ watch();
6200
+ ribbon.addEventListener(TOGGLE, toggle);
6201
+ ribbon.addEventListener("office-command", command, true);
6202
+ ribbon.addEventListener("office-ribbon-select", onSelect);
6203
+ doc.addEventListener("pointerdown", outside, true);
6204
+ doc.addEventListener("keydown", escape, true);
6205
+ schedule(true);
6206
+ return {
6207
+ refit,
6208
+ close,
6209
+ destroy() {
6210
+ if (frame) view?.cancelAnimationFrame(frame);
6211
+ frame = 0;
6212
+ resize?.disconnect();
6213
+ mutation?.disconnect();
6214
+ ribbon.removeEventListener(TOGGLE, toggle);
6215
+ ribbon.removeEventListener("office-command", command, true);
6216
+ ribbon.removeEventListener("office-ribbon-select", onSelect);
6217
+ doc.removeEventListener("pointerdown", outside, true);
6218
+ doc.removeEventListener("keydown", escape, true);
6219
+ for (const panel of panelsOf(ribbon)) {
6220
+ for (const group of panel.querySelectorAll(`${GROUP}[data-collapsed]`)) {
6221
+ group.removeAttribute("data-open");
6222
+ group.removeAttribute("data-collapsed");
6223
+ }
6224
+ }
6225
+ }
6226
+ };
6227
+ }
6228
+
5650
6229
  // src/controls.ts
5651
6230
  var CONTROL_DEFINERS = [
5652
6231
  defineIcon,
@@ -5667,6 +6246,7 @@ var CONTROL_DEFINERS = [
5667
6246
  defineStatusItem,
5668
6247
  defineZoomSlider,
5669
6248
  defineTabStrip,
6249
+ defineTaskPane,
5670
6250
  defineOptionsDialog,
5671
6251
  defineAccount,
5672
6252
  defineRibbon,
@@ -5686,10 +6266,12 @@ var CONTROL_DEFINERS = [
5686
6266
  defineRibbonSection,
5687
6267
  defineGallery,
5688
6268
  defineCommentsPane,
5689
- defineSymbolPicker
6269
+ defineSymbolPicker,
6270
+ defineColorGrid,
6271
+ defineColorCustom
5690
6272
  ];
5691
6273
  function registerControls(registry) {
5692
6274
  for (const define of CONTROL_DEFINERS) define(registry);
5693
6275
  }
5694
6276
 
5695
- 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_SYMBOLS, 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, defineSymbolPicker, defineTabStrip, defineTitleBar, defineToasts, defineToolbar, defineZoomSlider, formatCommentTime, glyph, nextEnabledIndex, parseOfficeSymbolCode, parseSvgPreview, profileInitials, rangeControl, range_control_default, readOfficeProfile, registerControls, rulerDivisions, runKeyTips, sanitizeOfficeProfile, typeAheadIndex, writeOfficeProfile };
6277
+ 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_SYMBOLS, OFFICE_TITLE_BAR_SEARCH_LIMIT, OFFICE_TOAST_VISIBLE_LIMIT, assignKeyTips, attachKeyTips, attachRibbonGroupOverflow, clampFlyoutPosition, clampOptionNumber, clearOfficeProfile, commentInitials, createRibbonOverflow, defineAccount, defineBackstage, defineButton, defineCheckbox, defineColorCustom, defineColorGrid, 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, defineSymbolPicker, defineTabStrip, defineTaskPane, defineTitleBar, defineToasts, defineToolbar, defineZoomSlider, fitRibbonGroups, formatCommentTime, glyph, nextEnabledIndex, parseOfficeSymbolCode, parseSvgPreview, profileInitials, rangeControl, range_control_default, readOfficeProfile, registerControls, rulerDivisions, runKeyTips, sanitizeOfficeProfile, typeAheadIndex, writeOfficeProfile };