ooxml-ui 0.4.0 → 0.5.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.
package/README.md CHANGED
@@ -58,22 +58,23 @@ with an incompatible build of this package.
58
58
 
59
59
  ## Features: elements
60
60
 
61
- | Tag | Attributes / properties | Events (all bubble, composed) |
62
- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
63
- | `office-ui-button` | `label`, `icon`, `command`, `disabled`, `pressed`, `expanded`, `icon-only`, `variant="stacked"`, `keyshortcuts` | `office-command` `{ command }` |
64
- | `office-ui-checkbox`, `office-ui-switch` | `checked`, `disabled`, `value`, `aria-label`; form-associated | `input`, `change` |
65
- | `office-ui-select` | `options` `[{ value, label, disabled? }]`, `value`, `selectedIndex`, `disabled` | `input`, `change` |
66
- | `office-ui-ribbon-group` | `label`, `launcher` (dialog launcher command), `launcher-disabled`; default slot | launcher: `office-command` `{ command }` |
67
- | `office-ui-ribbon-stack` | `orientation="horizontal"`; default slot (three-row column of small commands by default) | none |
68
- | `office-ui-menu-button` / `-menu-item` | button: `label`, `icon`, `command` (split button), `variant`, `disabled`, `keyshortcuts`; item: `command`, `label`, `icon`, `disabled`, `checked` | item choice: `office-command` `{ command }` |
69
- | `office-ui-toolbar` | `aria-label`, `aria-orientation`; arrow-key focus movement | none |
70
- | `office-ui-dialog` | `open`, `heading`, `dismissible="false"`, `show()`, `close()`; slots default, `footer` | `office-dialog-close` `{ reason }` (cancelable) |
71
- | `office-ui-status-bar` / `-status-item` | `label`, `value`, `interactive`, `id` | `office-status-activate` `{ id }` |
72
- | `office-ui-zoom-slider` | `value` (percent), `min`, `max`, `step`, `disabled`, `fit` (fit button name), `label` | `input`, `change`; fit: `office-command` `{ command: 'zoom-fit' }` |
73
- | `office-ui-tab-strip` | `tabs` `[{ id, label, title? }]`, `selected`, `label`, `disabled` | `office-tab-select` `{ id }` (cancelable) |
74
- | `office-ui-presence` | `participants`, `max`, `label` | `office-presence-select` `{ id }` |
75
- | `office-ui-smartart` | `drawing` (core `DiagramDrawing`), `schemeColors`, `label` | `office-smartart-render` (render report) |
76
- | `office-ui-icon` | `name`, `label` | none |
61
+ | Tag | Attributes / properties | Events (all bubble, composed) |
62
+ | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
63
+ | `office-ui-button` | `label`, `icon`, `command`, `disabled`, `pressed`, `expanded`, `icon-only`, `variant="stacked"`, `keyshortcuts` | `office-command` `{ command }` |
64
+ | `office-ui-checkbox`, `office-ui-switch` | `checked`, `disabled`, `value`, `aria-label`; form-associated | `input`, `change` |
65
+ | `office-ui-select` | `options` `[{ value, label, disabled? }]`, `value`, `selectedIndex`, `disabled` | `input`, `change` |
66
+ | `office-ui-ribbon-group` | `label`, `launcher` (dialog launcher command), `launcher-disabled`; default slot | launcher: `office-command` `{ command }` |
67
+ | `office-ui-ribbon-stack` | `orientation="horizontal"`; default slot (three-row column of small commands by default) | none |
68
+ | `office-ui-menu-button` / `-menu-item` | button: `label`, `icon`, `command` (split button), `variant`, `disabled`, `keyshortcuts`; item: `command`, `label`, `icon`, `disabled`, `checked` | item choice: `office-command` `{ command }` |
69
+ | `office-ui-toolbar` | `aria-label`, `aria-orientation`; arrow-key focus movement | none |
70
+ | `office-ui-dialog` | `open`, `heading`, `dismissible="false"`, `show()`, `close()`; slots default, `footer` | `office-dialog-close` `{ reason }` (cancelable) |
71
+ | `office-ui-status-bar` / `-status-item` | `label`, `value`, `interactive`, `id` | `office-status-activate` `{ id }` |
72
+ | `office-ui-zoom-slider` | `value` (percent), `min`, `max`, `step`, `disabled`, `fit` (fit button name), `label` | `input`, `change`; fit: `office-command` `{ command: 'zoom-fit' }` |
73
+ | `office-ui-tab-strip` | `tabs` `[{ id, label, title? }]`, `selected`, `label`, `previous-label`, `next-label`, `add-label`, `add-disabled`, `add-title`, `disabled` | `office-tab-select` `{ id }` (cancelable); add: `office-command` `{ command: 'tab-add' }` |
74
+ | `office-ui-context-menu` / `office-ui-menu-separator` | `label`; `openAt(x, y)`, `close()`, `open`; `office-ui-menu-item` and separator children | item choice: `office-command` `{ command }` |
75
+ | `office-ui-presence` | `participants`, `max`, `label` | `office-presence-select` `{ id }` |
76
+ | `office-ui-smartart` | `drawing` (core `DiagramDrawing`), `schemeColors`, `label` | `office-smartart-render` (render report) |
77
+ | `office-ui-icon` | `name`, `label` | none |
77
78
 
78
79
  Setting a property never emits an event; only user activation does. Controls honour
79
80
  `prefers-color-scheme`, `forced-colors: active` (system colours and a visible focus ring) and
@@ -353,6 +353,137 @@ var defineDialog = definer("office-ui-dialog", () => {
353
353
  return OfficeUiDialog;
354
354
  });
355
355
 
356
+ // src/context-menu.ts
357
+ var CSS3 = `
358
+ :host { display: contents; }
359
+ .panel { position: fixed; inset: auto; margin: 0; min-width: 200px; padding: 4px; box-sizing: border-box;
360
+ background: var(--office-background, #fff); color: var(--office-foreground, #1f2937);
361
+ border: 1px solid var(--office-border, #d1d5db); border-radius: var(--office-radius, 4px);
362
+ box-shadow: 0 8px 24px rgb(0 0 0 / 18%); font-family: var(--office-font, system-ui, sans-serif); }
363
+ .panel[hidden] { display: none; }
364
+ @media (forced-colors: active) { .panel { border-color: CanvasText; background: Canvas; color: CanvasText; } }
365
+ `;
366
+ var SEPARATOR_CSS = `
367
+ :host { display: block; height: 1px; margin: 4px 6px; background: var(--office-border, #d1d5db); }
368
+ @media (forced-colors: active) { :host { background: CanvasText; } }
369
+ `;
370
+ var ITEMS = "office-ui-menu-item:not([disabled]):not([hidden])";
371
+ var defineMenuSeparator = definer("office-ui-menu-separator", () => {
372
+ class OfficeUiMenuSeparator extends HTMLElement {
373
+ constructor() {
374
+ super();
375
+ attachStyles(this.attachShadow({ mode: "open" }), controlCss(SEPARATOR_CSS));
376
+ }
377
+ connectedCallback() {
378
+ this.setAttribute("role", "separator");
379
+ }
380
+ }
381
+ return OfficeUiMenuSeparator;
382
+ });
383
+ var defineContextMenu = definer("office-ui-context-menu", () => {
384
+ class OfficeUiContextMenu extends HTMLElement {
385
+ static observedAttributes = ["label"];
386
+ panel;
387
+ returnFocus = null;
388
+ outside;
389
+ constructor() {
390
+ super();
391
+ const doc = this.ownerDocument;
392
+ const root = this.attachShadow({ mode: "open" });
393
+ attachStyles(root, controlCss(CSS3));
394
+ this.panel = doc.createElement("div");
395
+ this.panel.className = "panel";
396
+ this.panel.setAttribute("role", "menu");
397
+ if (typeof this.panel.showPopover === "function")
398
+ this.panel.setAttribute("popover", "auto");
399
+ else this.panel.hidden = true;
400
+ this.panel.append(doc.createElement("slot"));
401
+ root.append(this.panel);
402
+ this.panel.addEventListener("toggle", (event) => {
403
+ if (event.newState === "closed") this.closed(false);
404
+ });
405
+ this.panel.addEventListener("keydown", (event) => this.onKey(event));
406
+ this.addEventListener("office-command", () => this.close());
407
+ }
408
+ connectedCallback() {
409
+ this.panel.setAttribute("aria-label", this.getAttribute("label") ?? "Context menu");
410
+ }
411
+ attributeChangedCallback() {
412
+ this.panel.setAttribute("aria-label", this.getAttribute("label") ?? "Context menu");
413
+ }
414
+ disconnectedCallback() {
415
+ this.close();
416
+ }
417
+ get open() {
418
+ return this.hasAttribute("data-open");
419
+ }
420
+ items() {
421
+ return [...this.querySelectorAll(ITEMS)];
422
+ }
423
+ /** Show at client coordinates; focus the first enabled item. */
424
+ openAt(x, y) {
425
+ const doc = this.ownerDocument;
426
+ const active = doc.activeElement;
427
+ this.returnFocus = active instanceof HTMLElement ? active : null;
428
+ if (this.panel.hasAttribute("popover")) {
429
+ if (!this.open) this.panel.showPopover?.();
430
+ } else {
431
+ this.panel.hidden = false;
432
+ this.outside ??= (event) => {
433
+ if (!event.composedPath().includes(this)) this.close();
434
+ };
435
+ doc.addEventListener("pointerdown", this.outside, true);
436
+ }
437
+ this.setAttribute("data-open", "");
438
+ const view = doc.defaultView;
439
+ const width = this.panel.offsetWidth;
440
+ const height = this.panel.offsetHeight;
441
+ const left = view && width ? Math.min(x, view.innerWidth - width - 4) : x;
442
+ const top = view && height ? Math.min(y, view.innerHeight - height - 4) : y;
443
+ this.panel.style.left = `${Math.max(4, Math.round(left))}px`;
444
+ this.panel.style.top = `${Math.max(4, Math.round(top))}px`;
445
+ this.items()[0]?.focus();
446
+ }
447
+ close() {
448
+ if (!this.open) return;
449
+ if (this.panel.hasAttribute("popover")) {
450
+ try {
451
+ this.panel.hidePopover?.();
452
+ } catch {
453
+ }
454
+ }
455
+ this.closed(true);
456
+ }
457
+ closed(restoreFocus) {
458
+ if (!this.open) return;
459
+ this.removeAttribute("data-open");
460
+ if (!this.panel.hasAttribute("popover")) this.panel.hidden = true;
461
+ if (this.outside) this.ownerDocument.removeEventListener("pointerdown", this.outside, true);
462
+ if (restoreFocus) this.returnFocus?.focus?.();
463
+ this.returnFocus = null;
464
+ }
465
+ onKey(event) {
466
+ const items = this.items();
467
+ const from = items.findIndex(
468
+ (item) => item === event.target || item.contains(event.target)
469
+ );
470
+ const move = (index) => {
471
+ event.preventDefault();
472
+ items[(index + items.length) % items.length]?.focus();
473
+ };
474
+ if (event.key === "ArrowDown") move(from + 1);
475
+ else if (event.key === "ArrowUp") move(from - 1);
476
+ else if (event.key === "Home") move(0);
477
+ else if (event.key === "End") move(items.length - 1);
478
+ else if (event.key === "Escape" || event.key === "Tab") {
479
+ if (event.key === "Escape") event.preventDefault();
480
+ this.close();
481
+ }
482
+ }
483
+ }
484
+ return OfficeUiContextMenu;
485
+ });
486
+
356
487
  // src/menu.ts
357
488
  var BUTTON_CSS = `
358
489
  :host { display: inline-flex; vertical-align: middle; }
@@ -798,7 +929,7 @@ var defineToolbar = definer("office-ui-toolbar", () => {
798
929
  });
799
930
 
800
931
  // src/select.ts
801
- var CSS3 = `
932
+ var CSS4 = `
802
933
  :host { display: inline-block; position: relative; vertical-align: middle; }
803
934
  button { box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 8px;
804
935
  width: 100%; min-height: var(--office-target-size, 28px); padding: 0 8px; font: inherit; font-size: 12px;
@@ -837,7 +968,7 @@ var defineSelect = definer("office-ui-select", () => {
837
968
  super();
838
969
  const doc = this.ownerDocument;
839
970
  const root = this.attachShadow({ mode: "open", delegatesFocus: true });
840
- attachStyles(root, controlCss(CSS3));
971
+ attachStyles(root, controlCss(CSS4));
841
972
  this.trigger = doc.createElement("button");
842
973
  this.trigger.type = "button";
843
974
  this.trigger.setAttribute("role", "combobox");
@@ -1088,7 +1219,7 @@ var defineStatusItem = definer("office-ui-status-item", () => {
1088
1219
  });
1089
1220
 
1090
1221
  // src/tab-strip.ts
1091
- var CSS4 = `
1222
+ var CSS5 = `
1092
1223
  :host { display: flex; align-items: stretch; min-width: 0; min-height: 28px; gap: 2px; padding: 0 6px;
1093
1224
  background: var(--office-surface, #f3f4f6); color: var(--office-muted-foreground, #6b7280);
1094
1225
  border-top: 1px solid var(--office-border, #d1d5db); font-size: 12px;
@@ -1097,6 +1228,8 @@ var CSS4 = `
1097
1228
  min-height: var(--office-target-size, 26px);
1098
1229
  padding: 0; border: 0; background: transparent; color: inherit; cursor: pointer; }
1099
1230
  .step:disabled { opacity: .4; cursor: default; }
1231
+ .add { font-size: 18px; line-height: 1; }
1232
+ .add[hidden] { display: none; }
1100
1233
  .list { display: flex; align-items: stretch; min-width: 0; overflow-x: auto; scrollbar-width: thin; }
1101
1234
  .tab { flex: none; max-width: 220px; min-height: var(--office-target-size, 26px); margin-top: -1px;
1102
1235
  padding: 2px 14px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
@@ -1115,16 +1248,25 @@ svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width:
1115
1248
  `;
1116
1249
  var defineTabStrip = definer("office-ui-tab-strip", () => {
1117
1250
  class OfficeUiTabStrip extends HTMLElement {
1118
- static observedAttributes = ["label", "disabled", "selected", "previous-label", "next-label"];
1251
+ static observedAttributes = [
1252
+ "label",
1253
+ "disabled",
1254
+ "selected",
1255
+ "previous-label",
1256
+ "next-label",
1257
+ "add-label",
1258
+ "add-disabled"
1259
+ ];
1119
1260
  items = [];
1120
1261
  list;
1121
1262
  previous;
1122
1263
  next;
1264
+ add;
1123
1265
  constructor() {
1124
1266
  super();
1125
1267
  const doc = this.ownerDocument;
1126
1268
  const root = this.attachShadow({ mode: "open" });
1127
- attachStyles(root, controlCss(CSS4));
1269
+ attachStyles(root, controlCss(CSS5));
1128
1270
  const step = (name, icon) => {
1129
1271
  const button = doc.createElement("button");
1130
1272
  button.type = "button";
@@ -1141,7 +1283,14 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
1141
1283
  this.list = doc.createElement("div");
1142
1284
  this.list.className = "list";
1143
1285
  this.list.setAttribute("role", "tablist");
1144
- root.append(this.previous, this.next, this.list);
1286
+ this.add = doc.createElement("button");
1287
+ this.add.type = "button";
1288
+ this.add.className = "step add";
1289
+ this.add.textContent = "+";
1290
+ this.add.addEventListener("click", () => {
1291
+ if (!this.add.disabled) emit(this, "office-command", { command: "tab-add" });
1292
+ });
1293
+ root.append(this.previous, this.next, this.list, this.add);
1145
1294
  this.previous.addEventListener("click", () => this.move(-1, false));
1146
1295
  this.next.addEventListener("click", () => this.move(1, false));
1147
1296
  this.list.addEventListener("click", (event) => {
@@ -1244,6 +1393,11 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
1244
1393
  if (selected) tab.scrollIntoView?.({ block: "nearest", inline: "nearest" });
1245
1394
  }
1246
1395
  this.previous.disabled = disabled || index <= 0;
1396
+ const addLabel = this.getAttribute("add-label");
1397
+ this.add.hidden = !addLabel;
1398
+ this.add.disabled = disabled || this.hasAttribute("add-disabled");
1399
+ this.add.setAttribute("aria-label", addLabel ?? "Add");
1400
+ this.add.title = this.getAttribute("add-title") ?? addLabel ?? "";
1247
1401
  this.next.disabled = disabled || index < 0 || index >= this.items.length - 1;
1248
1402
  }
1249
1403
  }
@@ -1251,7 +1405,7 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
1251
1405
  });
1252
1406
 
1253
1407
  // src/zoom-slider.ts
1254
- var CSS5 = `
1408
+ var CSS6 = `
1255
1409
  :host { display: inline-flex; align-items: center; gap: 2px; font-size: 11px;
1256
1410
  color: var(--office-foreground, #1f2937); font-family: var(--office-font, system-ui, sans-serif); }
1257
1411
  button { box-sizing: border-box; display: inline-grid; place-items: center; min-width: var(--office-target-size, 24px);
@@ -1287,7 +1441,7 @@ var defineZoomSlider = definer("office-ui-zoom-slider", () => {
1287
1441
  super();
1288
1442
  const doc = this.ownerDocument;
1289
1443
  const root = this.attachShadow({ mode: "open" });
1290
- attachStyles(root, controlCss(CSS5));
1444
+ attachStyles(root, controlCss(CSS6));
1291
1445
  const button = (name, text) => {
1292
1446
  const element = doc.createElement("button");
1293
1447
  element.type = "button";
@@ -1391,7 +1545,9 @@ var CONTROL_DEFINERS = [
1391
1545
  defineRibbonGroup,
1392
1546
  defineRibbonStack,
1393
1547
  defineMenuItem,
1548
+ defineMenuSeparator,
1394
1549
  defineMenuButton,
1550
+ defineContextMenu,
1395
1551
  defineToolbar,
1396
1552
  defineDialog,
1397
1553
  defineStatusBar,
@@ -1403,4 +1559,4 @@ function registerControls(registry) {
1403
1559
  for (const define of CONTROL_DEFINERS) define(registry);
1404
1560
  }
1405
1561
 
1406
- export { CONTROL_DEFINERS, defineButton, defineCheckbox, defineDialog, defineMenuButton, defineMenuItem, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls };
1562
+ export { CONTROL_DEFINERS, defineButton, defineCheckbox, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls };
@@ -0,0 +1,10 @@
1
+ /** A `role="separator"` rule between groups of menu items. */
2
+ export declare const defineMenuSeparator: import("./registry.js").Definer;
3
+ /**
4
+ * Right-click menu of `office-ui-menu-item` and `office-ui-menu-separator` children (Office's
5
+ * shape and text context menus). `openAt(x, y)` shows it at client coordinates in the popover
6
+ * top layer, kept inside the viewport; `close()` hides it. Arrow keys, Home and End move between
7
+ * enabled items; Escape and Tab close and return focus to the element that was focused. Choosing
8
+ * an item closes the menu and its `office-command` bubbles to the host. `label` names the menu.
9
+ */
10
+ export declare const defineContextMenu: import("./registry.js").Definer;
@@ -2,19 +2,20 @@ import { defineButton } from './button.js';
2
2
  import { defineCheckbox, defineSwitch } from './checkable.js';
3
3
  import { defineDialog } from './dialog.js';
4
4
  import { defineIcon } from './icons.js';
5
+ import { defineContextMenu, defineMenuSeparator } from './context-menu.js';
5
6
  import { defineMenuButton, defineMenuItem } from './menu.js';
6
7
  import { defineRibbonGroup, defineRibbonStack, defineToolbar } from './ribbon.js';
7
8
  import { defineSelect } from './select.js';
8
9
  import { defineStatusBar, defineStatusItem } from './status-bar.js';
9
10
  import { defineTabStrip } from './tab-strip.js';
10
11
  import { defineZoomSlider } from './zoom-slider.js';
11
- export { defineButton, defineCheckbox, defineDialog, defineIcon, defineMenuButton, defineMenuItem, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, };
12
+ export { defineButton, defineCheckbox, defineContextMenu, defineDialog, defineIcon, defineMenuButton, defineMenuItem, defineMenuSeparator, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, };
12
13
  export type { OfficeCommandEvent } from './button.js';
13
14
  export type { OfficeDialogCloseEvent, OfficeDialogCloseReason } from './dialog.js';
14
15
  export type { OfficeSelectOption } from './select.js';
15
16
  export type { OfficeStatusActivateEvent } from './status-bar.js';
16
17
  export type { OfficeTab, OfficeTabSelectEvent } from './tab-strip.js';
17
18
  /** Every control of this entry. */
18
- export declare const CONTROL_DEFINERS: readonly [import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer];
19
+ export declare const CONTROL_DEFINERS: readonly [import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer];
19
20
  /** Idempotent, SSR-safe (no-op without a DOM). */
20
21
  export declare function registerControls(registry?: CustomElementRegistry): void;
package/dist/controls.js CHANGED
@@ -1,3 +1,3 @@
1
- export { CONTROL_DEFINERS, defineButton, defineCheckbox, defineDialog, defineMenuButton, defineMenuItem, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls } from './chunk-RYUUWQ7F.js';
1
+ export { CONTROL_DEFINERS, defineButton, defineCheckbox, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls } from './chunk-7NLQECYW.js';
2
2
  export { defineIcon } from './chunk-PCSUQPMC.js';
3
3
  import './chunk-EY266IK3.js';
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export * from './smartart.js';
5
5
  export * from './theme.js';
6
6
  export { CONTRACT_REVISION, type Definer } from './registry.js';
7
7
  /** Every ooxml-ui tag this package defines, in registration order. */
8
- export declare const OFFICE_UI_TAGS: readonly ["office-ui-icon", "office-ui-button", "office-ui-checkbox", "office-ui-switch", "office-ui-select", "office-ui-ribbon-group", "office-ui-ribbon-stack", "office-ui-menu-item", "office-ui-menu-button", "office-ui-toolbar", "office-ui-dialog", "office-ui-status-bar", "office-ui-status-item", "office-ui-zoom-slider", "office-ui-tab-strip", "office-ui-presence", "office-ui-smartart"];
8
+ export declare const OFFICE_UI_TAGS: readonly ["office-ui-icon", "office-ui-button", "office-ui-checkbox", "office-ui-switch", "office-ui-select", "office-ui-ribbon-group", "office-ui-ribbon-stack", "office-ui-menu-item", "office-ui-menu-button", "office-ui-menu-separator", "office-ui-context-menu", "office-ui-toolbar", "office-ui-dialog", "office-ui-status-bar", "office-ui-status-item", "office-ui-zoom-slider", "office-ui-tab-strip", "office-ui-presence", "office-ui-smartart"];
9
9
  /**
10
10
  * Install the theme tokens and define every element. Idempotent and safe to call from every
11
11
  * viewer binding; a no-op where there is no DOM (SSR).
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { installOfficeUiTheme } from './chunk-H4KFVIGT.js';
2
2
  export { THEME_CSS, THEME_STYLE_ID, installOfficeUiTheme } from './chunk-H4KFVIGT.js';
3
- import { registerControls } from './chunk-RYUUWQ7F.js';
4
- export { CONTROL_DEFINERS, defineButton, defineCheckbox, defineDialog, defineMenuButton, defineMenuItem, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls } from './chunk-RYUUWQ7F.js';
3
+ import { registerControls } from './chunk-7NLQECYW.js';
4
+ export { CONTROL_DEFINERS, defineButton, defineCheckbox, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls } from './chunk-7NLQECYW.js';
5
5
  export { ICON_CSS, createIconSvg, defineIcon, getIcon, listIcons, paintIcon, registerIcon } from './chunk-PCSUQPMC.js';
6
6
  import { definePresence } from './chunk-RLPL7Q6J.js';
7
7
  export { definePresence, initialsOf, participantsFromAwareness } from './chunk-RLPL7Q6J.js';
@@ -20,6 +20,8 @@ var OFFICE_UI_TAGS = [
20
20
  "office-ui-ribbon-stack",
21
21
  "office-ui-menu-item",
22
22
  "office-ui-menu-button",
23
+ "office-ui-menu-separator",
24
+ "office-ui-context-menu",
23
25
  "office-ui-toolbar",
24
26
  "office-ui-dialog",
25
27
  "office-ui-status-bar",
@@ -13,6 +13,8 @@ export type OfficeTabSelectEvent = CustomEvent<{
13
13
  * keys move the selection; the tab list uses a roving tabindex. User selection emits
14
14
  * `office-tab-select` `{ id }` (cancelable); setting properties never emits.
15
15
  * Attributes: `label` (tab list name, default "Tabs"), `previous-label` and `next-label`
16
- * (step button names, default "Previous" and "Next"), `disabled`.
16
+ * (step button names, default "Previous" and "Next"), `disabled`, and `add-label` to show an
17
+ * add button after the tabs (Insert Page, New Sheet) that emits `office-command`
18
+ * `{ command: 'tab-add' }`; `add-disabled` and `add-title` disable and explain it.
17
19
  */
18
20
  export declare const defineTabStrip: import("./registry.js").Definer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ooxml-ui",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Shared, format-neutral web components and styles for the Office viewers (Word, PowerPoint, Excel)",
5
5
  "keywords": [
6
6
  "custom-elements",
@@ -70,7 +70,7 @@
70
70
  "test:package": "node scripts/package-smoke.mjs"
71
71
  },
72
72
  "dependencies": {
73
- "ooxml-core": "^0.12.0"
73
+ "ooxml-core": "^0.13.0"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@types/jsdom": "^21.1.7",