ooxml-ui 0.10.2 → 0.11.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.
@@ -1,9 +1,878 @@
1
- import { createIconSvg, paintIcon, defineIcon } from './chunk-PCSUQPMC.js';
1
+ import { createIconSvg, paintIcon, defineIcon } from './chunk-YZ2JQNHX.js';
2
2
  import { initialsOf } from './chunk-RLPL7Q6J.js';
3
3
  import { definer, attachStyles, controlCss, emit } from './chunk-EY266IK3.js';
4
4
 
5
- // src/backstage.ts
5
+ // src/chrome-controls.ts
6
+ var ICON = `svg { flex: none; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.45;
7
+ stroke-linecap: round; stroke-linejoin: round; }`;
8
+ function icon(doc, name) {
9
+ const svg = createIconSvg(doc);
10
+ paintIcon(svg, name);
11
+ return svg;
12
+ }
13
+ function emit2(host, type, detail) {
14
+ host.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true }));
15
+ }
16
+ var config = (el) => el.constructor;
17
+ var FOOTER_CSS = `
18
+ :host { display: block; flex: 1 1 auto; min-width: 0; }
19
+ :host([hidden]) { display: none !important; }
20
+ ${ICON}
21
+ .footer { box-sizing: border-box; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
22
+ button { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
23
+ min-width: 24px; min-height: 32px; padding: 6px 14px; border: 1px solid var(--office-border, #d1d5db);
24
+ border-radius: 6px; background: var(--office-surface, #f3f4f6); color: var(--office-foreground, #1f2937);
25
+ font: 500 13px/1.2 var(--office-font, system-ui, sans-serif); cursor: pointer; touch-action: manipulation; }
26
+ button:hover:not(:disabled) { background: var(--office-selected, #e5e7eb); }
27
+ button.primary { border-color: var(--office-accent, #2563eb); background: var(--office-accent, #2563eb);
28
+ color: var(--office-accent-foreground, #fff); }
29
+ button.primary:hover:not(:disabled) { opacity: .9; background: var(--office-accent, #2563eb); }
30
+ button.warning { border-color: #d97706; background: #d97706; color: #fff; }
31
+ button.warning:hover:not(:disabled) { opacity: .9; background: #d97706; }
32
+ button.danger { border-color: var(--office-danger, #b91c1c); background: var(--office-danger, #b91c1c); color: #fff; }
33
+ button.danger:hover:not(:disabled) { opacity: .9; background: var(--office-danger, #b91c1c); }
34
+ button.start { margin-right: auto; }
35
+ button.busy::before { content: ''; width: 12px; height: 12px; border: 2px solid currentColor; border-right-color: transparent;
36
+ border-radius: 50%; animation: office-footer-spin .8s linear infinite; }
37
+ @keyframes office-footer-spin { to { transform: rotate(360deg); } }
38
+ @media (prefers-reduced-motion: reduce) { button.busy::before { animation: none; } }
39
+ button:disabled { cursor: not-allowed; opacity: .55; }
40
+ button:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: 2px; }
41
+ @media (pointer: coarse), (max-width: 767px) { button { min-width: 44px; min-height: 44px; } }
42
+ @media (forced-colors: active) {
43
+ button, button.primary, button.warning, button.danger { border-color: ButtonText; background: ButtonFace; color: ButtonText; }
44
+ button:hover:not(:disabled) { background: Highlight; color: HighlightText; }
45
+ button.primary { border-width: 2px; }
46
+ button:focus-visible { outline-color: Highlight; }
47
+ }
48
+ `;
49
+ var defineDialogFooter = definer("office-ui-dialog-footer", () => {
50
+ class OfficeUiDialogFooter extends HTMLElement {
51
+ static requestEvent = "office-dialog-footer-request";
52
+ static testIdPrefix = "office-dialog-footer";
53
+ model = { actions: [] };
54
+ row = this.ownerDocument.createElement("div");
55
+ buttons = /* @__PURE__ */ new Map();
56
+ constructor() {
57
+ super();
58
+ const root = this.attachShadow({ mode: "open" });
59
+ attachStyles(root, controlCss(FOOTER_CSS));
60
+ this.row.className = "footer";
61
+ this.row.setAttribute("part", "footer");
62
+ root.append(this.row);
63
+ }
64
+ get state() {
65
+ return this.model;
66
+ }
67
+ set state(value) {
68
+ this.model = value;
69
+ this.render();
70
+ }
71
+ connectedCallback() {
72
+ this.render();
73
+ }
74
+ /** Move keyboard focus to an action, for example the primary one when a dialog opens. */
75
+ focusAction(id) {
76
+ this.render();
77
+ this.buttons.get(id)?.focus();
78
+ }
79
+ button(id) {
80
+ let button = this.buttons.get(id);
81
+ if (!button) {
82
+ button = this.ownerDocument.createElement("button");
83
+ button.type = "button";
84
+ button.dataset.action = id;
85
+ button.addEventListener("click", () => emit2(this, config(this).requestEvent, { id }));
86
+ this.buttons.set(id, button);
87
+ }
88
+ return button;
89
+ }
90
+ patch(button, action) {
91
+ button.className = action.variant === "secondary" ? "" : action.variant ?? "";
92
+ button.disabled = action.disabled === true || action.busy === true;
93
+ if (action.title) button.title = action.title;
94
+ else button.removeAttribute("title");
95
+ button.classList.toggle("start", action.align === "start");
96
+ button.classList.toggle("busy", action.busy === true);
97
+ if (action.busy) button.setAttribute("aria-busy", "true");
98
+ else button.removeAttribute("aria-busy");
99
+ if (action.testId) button.dataset.testid = action.testId;
100
+ else delete button.dataset.testid;
101
+ const glyph = action.icon ?? "";
102
+ if (button.dataset.icon !== glyph || button.dataset.label !== action.label) {
103
+ button.dataset.icon = glyph;
104
+ button.dataset.label = action.label;
105
+ button.replaceChildren(
106
+ ...glyph ? [icon(this.ownerDocument, glyph)] : [],
107
+ this.ownerDocument.createTextNode(action.label)
108
+ );
109
+ }
110
+ }
111
+ render() {
112
+ const wanted = this.model.actions.map((action) => {
113
+ const button = this.button(action.id);
114
+ this.patch(button, action);
115
+ return button;
116
+ });
117
+ for (const [id, button] of this.buttons)
118
+ if (!wanted.includes(button)) {
119
+ button.remove();
120
+ this.buttons.delete(id);
121
+ }
122
+ wanted.forEach((button, index) => {
123
+ const at = this.row.children[index];
124
+ if (at !== button) this.row.insertBefore(button, at ?? null);
125
+ });
126
+ }
127
+ }
128
+ return OfficeUiDialogFooter;
129
+ });
130
+ var OFFICE_TOAST_VISIBLE_LIMIT = 5;
131
+ var TOASTS_CSS = `
132
+ :host { box-sizing: border-box; display: flex; flex-direction: column; overflow-y: auto; max-height: 70%; pointer-events: none; }
133
+ :host([hidden]) { display: none !important; }
134
+ [hidden] { display: none !important; }
135
+ ${ICON}
136
+ .header, .toast, .overflow { pointer-events: auto; }
137
+ .header { display: flex; align-items: center; justify-content: space-between; padding: 0 4px;
138
+ color: var(--office-muted-foreground, #6b7280); font: 600 11px/1.4 var(--office-font, system-ui, sans-serif); }
139
+ .toast { box-sizing: border-box; display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; margin-top: 8px;
140
+ border: 1px solid var(--office-border, #d1d5db); border-radius: 6px; background: var(--office-popover, var(--office-background, #fff));
141
+ color: var(--office-foreground, #1f2937); box-shadow: 0 8px 20px rgba(0, 0, 0, .2);
142
+ font: 12px/1.4 var(--office-font, system-ui, sans-serif); }
143
+ .toast svg { width: 16px; height: 16px; margin-top: 1px; }
144
+ .toast[data-severity="warning"] svg { color: #f59e0b; }
145
+ .toast[data-severity="info"] svg { color: #3b82f6; }
146
+ .message { flex: 1; min-width: 0; margin: 0; overflow-wrap: anywhere; }
147
+ .overflow { margin: 8px 0 0; text-align: center; color: var(--office-muted-foreground, #6b7280); font: 11px var(--office-font, system-ui, sans-serif); }
148
+ button { box-sizing: border-box; flex: none; display: inline-flex; align-items: center; justify-content: center;
149
+ min-width: 24px; min-height: 24px; padding: 2px 4px; border: 0; border-radius: 4px; background: transparent;
150
+ color: var(--office-muted-foreground, #6b7280); font: inherit; cursor: pointer; touch-action: manipulation; }
151
+ button:hover { background: var(--office-surface, #f3f4f6); color: var(--office-foreground, #1f2937); }
152
+ .dismiss-all { font-weight: 500; text-decoration: underline; text-underline-offset: 2px; }
153
+ button:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: 1px; }
154
+ @media (pointer: coarse) { button { min-width: 44px; min-height: 44px; } }
155
+ @media (forced-colors: active) {
156
+ .toast { border-color: CanvasText; background: Canvas; color: CanvasText; }
157
+ .toast svg, button { color: ButtonText; } button:hover { background: Highlight; color: HighlightText; }
158
+ button:focus-visible { outline-color: Highlight; }
159
+ }
160
+ `;
161
+ var defineToasts = definer("office-ui-toasts", () => {
162
+ class OfficeUiToasts extends HTMLElement {
163
+ static requestEvent = "office-toasts-request";
164
+ static testIdPrefix = "office-toast";
165
+ model = { toasts: [] };
166
+ signature = "";
167
+ stack = this.ownerDocument.createElement("div");
168
+ constructor() {
169
+ super();
170
+ const root = this.attachShadow({ mode: "open" });
171
+ attachStyles(root, controlCss(TOASTS_CSS));
172
+ root.append(this.stack);
173
+ }
174
+ get state() {
175
+ return this.model;
176
+ }
177
+ set state(value) {
178
+ this.model = value;
179
+ this.render();
180
+ }
181
+ connectedCallback() {
182
+ this.render();
183
+ }
184
+ render() {
185
+ const s = this.model;
186
+ const { requestEvent, testIdPrefix: p } = config(this);
187
+ this.dataset.testid = `${p}s`;
188
+ this.hidden = s.toasts.length === 0;
189
+ const visible2 = s.toasts.slice(0, OFFICE_TOAST_VISIBLE_LIMIT);
190
+ const hiddenCount = (s.overflowCount ?? 0) + s.toasts.length - visible2.length;
191
+ const labels = [
192
+ s.labels?.title ?? "Compatibility",
193
+ s.labels?.dismissAll ?? "Dismiss all",
194
+ s.labels?.dismiss ?? "Dismiss"
195
+ ];
196
+ const signature = JSON.stringify([
197
+ labels,
198
+ hiddenCount,
199
+ visible2.map((toast) => [toast.id, toast.code, toast.severity, toast.message])
200
+ ]);
201
+ if (signature === this.signature) return;
202
+ this.signature = signature;
203
+ const doc = this.ownerDocument;
204
+ const header = doc.createElement("div");
205
+ header.className = "header";
206
+ const heading = doc.createElement("span");
207
+ heading.textContent = labels[0];
208
+ const dismissAll = doc.createElement("button");
209
+ dismissAll.type = "button";
210
+ dismissAll.className = "dismiss-all";
211
+ dismissAll.dataset.testid = `${p}s-dismiss-all`;
212
+ dismissAll.textContent = labels[1];
213
+ dismissAll.addEventListener("click", () => emit2(this, requestEvent, { id: "dismissAll" }));
214
+ header.append(heading, dismissAll);
215
+ const rows = [header];
216
+ for (const toast of visible2) {
217
+ const item = doc.createElement("div");
218
+ item.className = "toast";
219
+ item.dataset.testid = p;
220
+ if (toast.code) item.dataset.code = toast.code;
221
+ item.dataset.severity = toast.severity;
222
+ item.setAttribute("role", "status");
223
+ const message = doc.createElement("p");
224
+ message.className = "message";
225
+ message.textContent = toast.message;
226
+ const dismiss = doc.createElement("button");
227
+ dismiss.type = "button";
228
+ dismiss.dataset.testid = `${p}-dismiss`;
229
+ dismiss.setAttribute("aria-label", labels[2]);
230
+ dismiss.append(icon(doc, "close"));
231
+ dismiss.addEventListener(
232
+ "click",
233
+ () => emit2(this, requestEvent, { id: "dismiss", toastId: toast.id })
234
+ );
235
+ item.append(icon(doc, toast.severity === "warning" ? "warning" : "info"), message, dismiss);
236
+ rows.push(item);
237
+ }
238
+ if (hiddenCount > 0) {
239
+ const overflow = doc.createElement("p");
240
+ overflow.className = "overflow";
241
+ overflow.textContent = `+${hiddenCount}`;
242
+ rows.push(overflow);
243
+ }
244
+ this.stack.replaceChildren(...rows);
245
+ }
246
+ }
247
+ return OfficeUiToasts;
248
+ });
249
+
250
+ // src/document-notices.ts
251
+ var config2 = (el) => el.constructor;
252
+ var emit3 = (host, type, detail) => host.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true }));
253
+ var BANNER_CSS = `
254
+ :host { display: block; flex: none; }
255
+ :host([hidden]) { display: none !important; }
256
+ [hidden] { display: none !important; }
257
+ svg { flex: none; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.45;
258
+ stroke-linecap: round; stroke-linejoin: round; color: #d97706; }
259
+ .banner { box-sizing: border-box; display: flex; align-items: center; gap: 12px; padding: 6px 16px;
260
+ border-bottom: 1px solid rgba(180, 83, 9, .3); background: var(--office-notice-background, #fef3c7);
261
+ color: var(--office-notice-foreground, #78350f); font: 12px/1.4 var(--office-font, system-ui, sans-serif); }
262
+ .text { flex: 1 1 auto; min-width: 0; margin: 0; }
263
+ .form { display: flex; flex: none; align-items: center; gap: 8px; }
264
+ .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
265
+ clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
266
+ button, input { font: inherit; }
267
+ button { box-sizing: border-box; flex: none; min-height: 24px; padding: 4px 12px; border: 1px solid transparent;
268
+ border-radius: 4px; background: transparent; color: inherit; font-weight: 500; cursor: pointer; touch-action: manipulation; }
269
+ button.primary { border-color: rgba(217, 119, 6, .5); }
270
+ button:hover { background: rgba(180, 83, 9, .15); }
271
+ button:disabled { opacity: .6; cursor: not-allowed; }
272
+ button:focus-visible, input:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: 1px; }
273
+ input { box-sizing: border-box; min-height: 24px; padding: 4px 8px; border: 1px solid rgba(217, 119, 6, .4);
274
+ border-radius: 4px; background: var(--office-background, #fff); color: var(--office-foreground, #1f2937); }
275
+ .error { flex: none; color: var(--office-danger, #b91c1c); }
276
+ @media (pointer: coarse) { button, input { min-height: 44px; min-width: 44px; } }
277
+ @media (forced-colors: active) {
278
+ .banner { border-bottom-color: CanvasText; background: Canvas; color: CanvasText; }
279
+ svg, .error { color: CanvasText; }
280
+ button, input { border-color: ButtonText; color: ButtonText; background: ButtonFace; }
281
+ button:focus-visible, input:focus-visible { outline-color: Highlight; }
282
+ }
283
+ `;
284
+ var defineReadOnlyBanner = definer("office-ui-read-only-banner", () => {
285
+ class OfficeUiReadOnlyBanner extends HTMLElement {
286
+ static requestEvent = "office-read-only-request";
287
+ static testIdPrefix = "office-readonly";
288
+ model = { kind: null, message: "" };
289
+ promptWasOpen = false;
290
+ pendingFocus = false;
291
+ parts = this.build();
292
+ constructor() {
293
+ super();
294
+ const root = this.attachShadow({ mode: "open" });
295
+ attachStyles(root, controlCss(BANNER_CSS));
296
+ root.append(this.parts.banner);
297
+ }
298
+ get state() {
299
+ return this.model;
300
+ }
301
+ set state(value) {
302
+ this.model = value;
303
+ this.render();
304
+ }
305
+ connectedCallback() {
306
+ this.render();
307
+ if (this.pendingFocus) {
308
+ this.pendingFocus = false;
309
+ this.parts.input.focus();
310
+ }
311
+ }
312
+ build() {
313
+ const doc = this.ownerDocument;
314
+ const p = config2(this).testIdPrefix;
315
+ const el = (tag, className = "") => {
316
+ const node = doc.createElement(tag);
317
+ node.className = className;
318
+ return node;
319
+ };
320
+ const send = (intent) => emit3(this, config2(this).requestEvent, intent);
321
+ const button = (testId, className, intent) => {
322
+ const node = el("button", className);
323
+ node.type = "button";
324
+ node.dataset.testid = `${p}-${testId}`;
325
+ node.addEventListener("click", () => send(intent));
326
+ return node;
327
+ };
328
+ const banner = el("div", "banner");
329
+ banner.setAttribute("role", "status");
330
+ banner.setAttribute("part", "banner");
331
+ const title = el("strong");
332
+ const message = el("span");
333
+ const text2 = el("p", "text");
334
+ text2.append(title, ": ", message);
335
+ const editAnyway = button("edit-anyway", "primary", { id: "editAnyway" });
336
+ const dismiss = button("dismiss", "", { id: "dismiss" });
337
+ const form = el("form", "form");
338
+ form.dataset.testid = `${p}-password-form`;
339
+ const label = el("label", "sr-only");
340
+ const input = el("input");
341
+ input.id = "password";
342
+ input.type = "password";
343
+ input.dataset.testid = `${p}-password-input`;
344
+ label.htmlFor = input.id;
345
+ const unlock = el("button", "primary");
346
+ unlock.type = "submit";
347
+ unlock.dataset.testid = `${p}-unlock`;
348
+ const cancel = button("password-cancel", "", { id: "cancelPassword" });
349
+ const error = el("span", "error");
350
+ error.id = "error";
351
+ error.setAttribute("role", "alert");
352
+ error.dataset.testid = `${p}-password-error`;
353
+ form.addEventListener("submit", (event) => {
354
+ event.preventDefault();
355
+ send({ id: "submitPassword", password: input.value });
356
+ });
357
+ form.append(label, input, unlock, cancel, error);
358
+ const lock = createIconSvg(doc);
359
+ paintIcon(lock, "lock");
360
+ banner.append(lock, text2, editAnyway, dismiss, form);
361
+ return {
362
+ banner,
363
+ title,
364
+ message,
365
+ editAnyway,
366
+ dismiss,
367
+ form,
368
+ label,
369
+ input,
370
+ unlock,
371
+ cancel,
372
+ error
373
+ };
374
+ }
375
+ render() {
376
+ const s = this.model;
377
+ const l = s.labels ?? {};
378
+ const p = this.parts;
379
+ this.dataset.testid = `${config2(this).testIdPrefix}-banner`;
380
+ if (s.kind) this.dataset.kind = s.kind;
381
+ else delete this.dataset.kind;
382
+ p.title.textContent = l.title ?? "Read-only recommended";
383
+ p.message.textContent = s.message;
384
+ p.editAnyway.textContent = l.editAnyway ?? "Edit anyway";
385
+ p.dismiss.textContent = l.dismiss ?? "Dismiss";
386
+ const open = s.passwordPromptOpen === true;
387
+ p.editAnyway.hidden = p.dismiss.hidden = open;
388
+ p.form.hidden = !open;
389
+ p.label.textContent = l.passwordLabel ?? "Password";
390
+ p.input.placeholder = l.passwordPlaceholder ?? "Password";
391
+ p.unlock.textContent = l.unlock ?? "Unlock";
392
+ p.cancel.textContent = l.cancel ?? "Cancel";
393
+ p.input.disabled = p.unlock.disabled = s.checkingPassword === true;
394
+ const failed = s.passwordError ?? null;
395
+ p.input.setAttribute("aria-invalid", String(failed !== null));
396
+ if (failed) p.input.setAttribute("aria-describedby", p.error.id);
397
+ else p.input.removeAttribute("aria-describedby");
398
+ p.error.hidden = failed === null;
399
+ p.error.textContent = failed ?? "";
400
+ if (open && !this.promptWasOpen) {
401
+ if (this.isConnected) p.input.focus();
402
+ else this.pendingFocus = true;
403
+ } else if (!open && this.promptWasOpen) p.input.value = "";
404
+ this.promptWasOpen = open;
405
+ }
406
+ }
407
+ return OfficeUiReadOnlyBanner;
408
+ });
409
+ var PASTE_CSS = `
410
+ :host { position: fixed; z-index: 1100; display: block; }
411
+ :host([hidden]) { display: none !important; }
412
+ .toolbar { box-sizing: border-box; display: flex; align-items: center; gap: 2px; padding: 4px;
413
+ border: 1px solid var(--office-border, #d1d5db); border-radius: 4px; background: var(--office-popover, var(--office-background, #fff));
414
+ box-shadow: 0 10px 25px rgba(0, 0, 0, .2); font: 11px/1.2 var(--office-font, system-ui, sans-serif); }
415
+ button { box-sizing: border-box; min-height: 24px; padding: 4px 8px; border: 0; border-radius: 4px; background: transparent;
416
+ color: var(--office-foreground, #1f2937); font: inherit; white-space: nowrap; cursor: pointer; touch-action: manipulation; }
417
+ button:hover { background: var(--office-surface, #f3f4f6); }
418
+ button:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: 1px; }
419
+ @media (pointer: coarse) { button { min-height: 44px; min-width: 44px; } }
420
+ @media (forced-colors: active) {
421
+ .toolbar { border-color: CanvasText; background: Canvas; }
422
+ button { color: ButtonText; } button:hover { background: Highlight; color: HighlightText; }
423
+ button:focus-visible { outline-color: Highlight; }
424
+ }
425
+ `;
426
+ var definePasteOptions = definer("office-ui-paste-options", () => {
427
+ class OfficeUiPasteOptions extends HTMLElement {
428
+ static requestEvent = "office-paste-options-request";
429
+ static dismissEvent = "office-paste-options-dismiss";
430
+ static testIdPrefix = "office-paste-options";
431
+ model = { left: 0, top: 0, options: [] };
432
+ toolbar = this.ownerDocument.createElement("div");
433
+ disarm;
434
+ constructor() {
435
+ super();
436
+ const root = this.attachShadow({ mode: "open" });
437
+ attachStyles(root, controlCss(PASTE_CSS));
438
+ this.toolbar.className = "toolbar";
439
+ this.toolbar.setAttribute("role", "toolbar");
440
+ this.toolbar.tabIndex = -1;
441
+ this.toolbar.addEventListener("mousedown", (event) => event.stopPropagation());
442
+ root.append(this.toolbar);
443
+ }
444
+ get state() {
445
+ return this.model;
446
+ }
447
+ set state(value) {
448
+ this.model = value;
449
+ this.render();
450
+ }
451
+ connectedCallback() {
452
+ this.render();
453
+ const view = this.ownerDocument.defaultView;
454
+ if (!view) return;
455
+ const dismiss = (event) => {
456
+ if (event.composedPath().includes(this.toolbar) && (!(event instanceof KeyboardEvent) || event.key !== "Escape"))
457
+ return;
458
+ emit3(this, config2(this).dismissEvent);
459
+ };
460
+ const timer = view.setTimeout(() => {
461
+ view.addEventListener("pointerdown", dismiss, true);
462
+ view.addEventListener("keydown", dismiss, true);
463
+ }, 0);
464
+ this.disarm = () => {
465
+ view.clearTimeout(timer);
466
+ view.removeEventListener("pointerdown", dismiss, true);
467
+ view.removeEventListener("keydown", dismiss, true);
468
+ };
469
+ }
470
+ disconnectedCallback() {
471
+ this.disarm?.();
472
+ this.disarm = void 0;
473
+ }
474
+ render() {
475
+ const s = this.model;
476
+ this.toolbar.setAttribute("aria-label", s.label ?? "Paste Options");
477
+ this.style.left = `${s.left + 4}px`;
478
+ this.style.top = `${s.top + 4}px`;
479
+ const doc = this.ownerDocument;
480
+ const existing = [...this.toolbar.querySelectorAll("button")];
481
+ const same = existing.length === s.options.length && existing.every((button, i) => button.dataset.format === s.options[i].id);
482
+ if (!same)
483
+ this.toolbar.replaceChildren(
484
+ ...s.options.map((option) => {
485
+ const button = doc.createElement("button");
486
+ button.type = "button";
487
+ button.dataset.format = option.id;
488
+ button.addEventListener("click", () => {
489
+ emit3(this, config2(this).requestEvent, { format: option.id });
490
+ emit3(this, config2(this).dismissEvent);
491
+ });
492
+ return button;
493
+ })
494
+ );
495
+ this.toolbar.querySelectorAll("button").forEach((button, i) => {
496
+ const label = s.options[i].label;
497
+ button.textContent = label;
498
+ button.title = label;
499
+ });
500
+ }
501
+ }
502
+ return OfficeUiPasteOptions;
503
+ });
504
+
505
+ // src/radio.ts
6
506
  var CSS = `
507
+ :host { display: inline-grid; box-sizing: border-box; width: var(--office-checkbox-size, 16px);
508
+ height: var(--office-checkbox-size, 16px); flex: none; place-items: center;
509
+ border: 1px solid var(--office-checkbox-border, var(--office-border, #d1d5db)); border-radius: 50%;
510
+ background: var(--office-checkbox-background, var(--office-background, #fff)); cursor: pointer; vertical-align: middle; }
511
+ :host([checked]) { border-color: var(--office-checkbox-accent, var(--office-accent, #2563eb)); }
512
+ :host(:focus-visible) { outline: 2px solid var(--office-ring, #2563eb); outline-offset: 2px; }
513
+ :host([disabled]) { opacity: .5; cursor: not-allowed; }
514
+ .dot { display: none; width: var(--office-radio-dot-size, 8px); height: var(--office-radio-dot-size, 8px);
515
+ border-radius: 50%; background: var(--office-checkbox-accent, var(--office-accent, #2563eb)); }
516
+ :host([checked]) .dot { display: block; }
517
+ @media (pointer: coarse), (max-width: 767px) {
518
+ :host { width: var(--office-checkbox-size-touch, 22px); height: var(--office-checkbox-size-touch, 22px); }
519
+ .dot { width: var(--office-radio-dot-size-touch, 12px); height: var(--office-radio-dot-size-touch, 12px); }
520
+ }
521
+ @media (forced-colors: active) {
522
+ :host { border-color: CanvasText; background: Canvas; forced-color-adjust: auto; }
523
+ :host([checked]) { border-color: Highlight; }
524
+ .dot { background: Highlight; }
525
+ :host([disabled]) { border-color: GrayText; }
526
+ :host([disabled]) .dot { background: GrayText; }
527
+ :host(:focus-visible) { outline-color: Highlight; }
528
+ }
529
+ `;
530
+ function groupOf(radio, scope) {
531
+ const name = radio.name;
532
+ if (!name || !scope) return [radio];
533
+ return [...scope.querySelectorAll(radio.localName)].filter(
534
+ (other) => other.name === name && other.form === radio.form
535
+ );
536
+ }
537
+ function labelText(label, self) {
538
+ let text2 = "";
539
+ for (const node of label.childNodes) {
540
+ if (node === self) continue;
541
+ if (node.nodeType === 3) text2 += node.textContent ?? "";
542
+ else if (node instanceof Element && !node.localName.includes("-") && !/^(select|input|textarea)$/u.test(node.localName))
543
+ text2 += labelText(node, self);
544
+ }
545
+ return text2;
546
+ }
547
+ function refreshTabStops(group) {
548
+ const enabled = group.filter((item) => !item.disabled);
549
+ const stop = enabled.find((item) => item.checked) ?? enabled[0];
550
+ for (const item of group) item.tabIndex = item === stop ? 0 : -1;
551
+ }
552
+ var defineRadio = definer("office-ui-radio", () => {
553
+ class OfficeUiRadio extends HTMLElement {
554
+ static formAssociated = true;
555
+ static observedAttributes = ["checked", "disabled", "value", "name"];
556
+ internals;
557
+ defaultChecked = false;
558
+ scope = null;
559
+ autoNamed = false;
560
+ constructor() {
561
+ super();
562
+ try {
563
+ this.internals = this.attachInternals();
564
+ } catch {
565
+ this.internals = void 0;
566
+ }
567
+ const root = this.attachShadow({ mode: "open" });
568
+ attachStyles(root, controlCss(CSS));
569
+ const dot = this.ownerDocument.createElement("span");
570
+ dot.className = "dot";
571
+ root.append(dot);
572
+ this.addEventListener("click", (event) => {
573
+ if (this.disabled) {
574
+ event.preventDefault();
575
+ return;
576
+ }
577
+ this.select(true);
578
+ });
579
+ this.addEventListener("keydown", (event) => this.onKey(event));
580
+ this.addEventListener("focus", () => this.syncName());
581
+ }
582
+ connectedCallback() {
583
+ this.defaultChecked = this.checked;
584
+ const root = this.getRootNode();
585
+ this.scope = root instanceof Document || root instanceof ShadowRoot ? root : null;
586
+ this.sync();
587
+ this.syncName();
588
+ }
589
+ disconnectedCallback() {
590
+ if (this.scope)
591
+ refreshTabStops(groupOf(this, this.scope).filter((item) => item !== this));
592
+ }
593
+ /**
594
+ * A custom element is not named by a wrapping `<label>` in every browser's accessibility
595
+ * tree, so mirror the label text into `aria-label` unless the host named it.
596
+ */
597
+ syncName() {
598
+ if (this.hasAttribute("aria-labelledby")) return;
599
+ if (this.hasAttribute("aria-label") && !this.autoNamed) return;
600
+ const label = this.closest("label") ?? this.internals?.labels?.[0];
601
+ const text2 = label ? labelText(label, this).replace(/\s+/gu, " ").trim() : "";
602
+ if (text2) {
603
+ this.autoNamed = true;
604
+ this.setAttribute("aria-label", text2);
605
+ }
606
+ }
607
+ attributeChangedCallback(name) {
608
+ if (name === "checked" && this.checked) this.uncheckPeers();
609
+ this.sync();
610
+ }
611
+ get checked() {
612
+ return this.hasAttribute("checked");
613
+ }
614
+ set checked(next) {
615
+ this.toggleAttribute("checked", Boolean(next));
616
+ }
617
+ get disabled() {
618
+ return this.hasAttribute("disabled");
619
+ }
620
+ set disabled(next) {
621
+ this.toggleAttribute("disabled", Boolean(next));
622
+ }
623
+ get value() {
624
+ return this.getAttribute("value") ?? "on";
625
+ }
626
+ set value(next) {
627
+ this.setAttribute("value", String(next));
628
+ }
629
+ get name() {
630
+ return this.getAttribute("name") ?? "";
631
+ }
632
+ set name(next) {
633
+ this.setAttribute("name", String(next));
634
+ }
635
+ get form() {
636
+ return this.internals?.form ?? null;
637
+ }
638
+ formResetCallback() {
639
+ this.checked = this.defaultChecked;
640
+ }
641
+ formDisabledCallback(disabled) {
642
+ this.disabled = disabled;
643
+ }
644
+ /** Check this radio and, for user intent, announce it. No-op when already checked. */
645
+ select(emit4) {
646
+ if (this.checked) return;
647
+ this.checked = true;
648
+ if (emit4) {
649
+ this.dispatchEvent(new Event("input", { bubbles: true, composed: true }));
650
+ this.dispatchEvent(new Event("change", { bubbles: true, composed: true }));
651
+ }
652
+ }
653
+ peers() {
654
+ return groupOf(this, this.scope ?? this.getRootNode());
655
+ }
656
+ uncheckPeers() {
657
+ for (const peer of this.peers()) if (peer !== this && peer.checked) peer.checked = false;
658
+ }
659
+ onKey(event) {
660
+ if (this.disabled || event.ctrlKey || event.metaKey || event.altKey) return;
661
+ if (event.key === " ") {
662
+ event.preventDefault();
663
+ this.select(true);
664
+ return;
665
+ }
666
+ const list = this.peers().filter((item) => !item.disabled);
667
+ const index = list.indexOf(this);
668
+ const last = list.length - 1;
669
+ const next = event.key === "ArrowRight" || event.key === "ArrowDown" ? (index + 1) % list.length : event.key === "ArrowLeft" || event.key === "ArrowUp" ? (index + last) % list.length : event.key === "Home" ? 0 : event.key === "End" ? last : -1;
670
+ if (next < 0 || index < 0) return;
671
+ event.preventDefault();
672
+ event.stopPropagation();
673
+ const target = list[next];
674
+ target.select(true);
675
+ target.focus();
676
+ }
677
+ sync() {
678
+ this.setAttribute("role", "radio");
679
+ this.setAttribute("aria-checked", String(this.checked));
680
+ this.setAttribute("aria-disabled", String(this.disabled));
681
+ this.internals?.setFormValue?.(this.checked && !this.disabled ? this.value : null);
682
+ if (this.isConnected) {
683
+ this.scope = this.getRootNode();
684
+ refreshTabStops(this.peers());
685
+ } else this.tabIndex = this.disabled ? -1 : 0;
686
+ }
687
+ }
688
+ return OfficeUiRadio;
689
+ });
690
+
691
+ // src/ribbon-toggle.ts
692
+ var CSS2 = `
693
+ :host { display: block; }
694
+ label { display: flex; align-items: center; gap: 4px; min-height: 22px; padding: 0 4px;
695
+ color: var(--office-foreground, #1f2937); font: inherit; font-size: 12px; white-space: nowrap; cursor: pointer; }
696
+ :host([disabled]) label { color: var(--office-muted-foreground, #6b7280); cursor: not-allowed; }
697
+ @media (pointer: coarse), (max-width: 767px) { label { min-height: 44px; font-size: 12px; } }
698
+ `;
699
+ var defineRibbonToggle = definer("office-ui-ribbon-toggle", () => {
700
+ class OfficeUiRibbonToggle extends HTMLElement {
701
+ static requestEvent = "office-toggle";
702
+ static idAttribute = "command";
703
+ static detailKey = "command";
704
+ static get observedAttributes() {
705
+ return ["label", "checked", "disabled", "title"];
706
+ }
707
+ checkbox;
708
+ text;
709
+ constructor() {
710
+ super();
711
+ const doc = this.ownerDocument;
712
+ const root = this.attachShadow({ mode: "open" });
713
+ attachStyles(root, controlCss(CSS2));
714
+ const label = doc.createElement("label");
715
+ this.checkbox = doc.createElement("office-ui-checkbox");
716
+ this.text = doc.createTextNode("");
717
+ label.append(this.checkbox, this.text);
718
+ label.addEventListener("click", (event) => {
719
+ event.preventDefault();
720
+ if (event.target !== this.checkbox) this.checkbox.click();
721
+ });
722
+ this.checkbox.addEventListener("input", (event) => event.stopPropagation());
723
+ this.checkbox.addEventListener("change", (event) => {
724
+ event.stopPropagation();
725
+ const checked = this.checkbox.checked;
726
+ this.sync();
727
+ const { requestEvent, idAttribute, detailKey } = this.constructor;
728
+ const id = this.getAttribute(idAttribute);
729
+ if (!this.hasAttribute("disabled") && id)
730
+ this.dispatchEvent(
731
+ new CustomEvent(requestEvent, {
732
+ detail: { [detailKey]: id, checked },
733
+ bubbles: true,
734
+ composed: true
735
+ })
736
+ );
737
+ });
738
+ root.append(label);
739
+ }
740
+ connectedCallback() {
741
+ this.sync();
742
+ }
743
+ attributeChangedCallback() {
744
+ this.sync();
745
+ }
746
+ get checked() {
747
+ return this.hasAttribute("checked");
748
+ }
749
+ set checked(value) {
750
+ this.toggleAttribute("checked", Boolean(value));
751
+ }
752
+ sync() {
753
+ const label = this.getAttribute("label") ?? "";
754
+ this.text.textContent = label;
755
+ this.checkbox.setAttribute("aria-label", label);
756
+ this.checkbox.title = this.getAttribute("title") ?? label;
757
+ this.checkbox.checked = this.hasAttribute("checked");
758
+ this.checkbox.disabled = this.hasAttribute("disabled");
759
+ }
760
+ }
761
+ return OfficeUiRibbonToggle;
762
+ });
763
+
764
+ // src/search-field.ts
765
+ var SVG_NS = "http://www.w3.org/2000/svg";
766
+ var CSS3 = `
767
+ :host { display: flex; align-items: center; gap: 8px; box-sizing: border-box; width: 100%;
768
+ height: var(--office-field-height-lg, 40px); padding: 0 12px;
769
+ border: 1px solid var(--office-field-border, var(--office-border, #d1d5db));
770
+ border-radius: var(--office-field-radius, 5px); background: var(--office-field-background, var(--office-background, #fff));
771
+ color: var(--office-field-placeholder, var(--office-muted-foreground, #6b7280)); font: inherit; }
772
+ :host(:focus-within) { border-color: var(--office-field-border-focus, var(--office-ring, #2563eb)); }
773
+ :host([variant="titlebar"]) { height: var(--office-field-height, 28px); gap: 7px; padding-inline: 14px;
774
+ border-color: var(--office-border, #d1d5db); border-radius: 6px; background: var(--office-background, #fff); }
775
+ :host([variant="titlebar"]:focus-within) { color: var(--office-foreground, #1f2937); }
776
+ :host([disabled]) { opacity: .5; cursor: not-allowed; }
777
+ svg { width: 16px; height: 16px; flex: none; }
778
+ :host([variant="titlebar"]) svg { width: 14px; height: 14px; }
779
+ input { min-width: 0; width: 100%; height: 100%; flex: 1; padding: 0; border: 0; outline: 0; background: transparent;
780
+ color: var(--office-field-foreground, var(--office-foreground, #1f2937)); font: inherit; font-size: 13px; }
781
+ :host([variant="titlebar"]) input { font-size: 11px; color: var(--office-foreground, #1f2937); }
782
+ input::placeholder { color: var(--office-field-placeholder, var(--office-muted-foreground, #6b7280)); opacity: .8; }
783
+ input::-webkit-search-cancel-button { display: none; }
784
+ @media (forced-colors: active) {
785
+ :host { border-color: CanvasText; background: Canvas; color: CanvasText; }
786
+ :host(:focus-within) { outline: 2px solid Highlight; outline-offset: 2px; }
787
+ input { color: CanvasText; }
788
+ }
789
+ `;
790
+ var defineSearchField = definer("office-ui-search", () => {
791
+ class OfficeUiSearch extends HTMLElement {
792
+ static observedAttributes = ["placeholder", "aria-label", "disabled", "value"];
793
+ input;
794
+ currentValue = "";
795
+ constructor() {
796
+ super();
797
+ const doc = this.ownerDocument;
798
+ const root = this.attachShadow({ mode: "open", delegatesFocus: true });
799
+ attachStyles(root, controlCss(CSS3));
800
+ const icon2 = doc.createElementNS(SVG_NS, "svg");
801
+ icon2.setAttribute("part", "icon");
802
+ icon2.setAttribute("viewBox", "0 0 24 24");
803
+ icon2.setAttribute("fill", "none");
804
+ icon2.setAttribute("stroke", "currentColor");
805
+ icon2.setAttribute("stroke-width", "2");
806
+ icon2.setAttribute("stroke-linecap", "round");
807
+ icon2.setAttribute("aria-hidden", "true");
808
+ const circle = doc.createElementNS(SVG_NS, "circle");
809
+ circle.setAttribute("cx", "11");
810
+ circle.setAttribute("cy", "11");
811
+ circle.setAttribute("r", "8");
812
+ const handle = doc.createElementNS(SVG_NS, "path");
813
+ handle.setAttribute("d", "m21 21-4.35-4.35");
814
+ icon2.append(circle, handle);
815
+ this.input = doc.createElement("input");
816
+ this.input.type = "search";
817
+ this.input.setAttribute("part", "input");
818
+ this.input.addEventListener("input", (event) => {
819
+ event.stopPropagation();
820
+ this.currentValue = this.input.value;
821
+ this.dispatchEvent(new Event("input", { bubbles: true, composed: true }));
822
+ });
823
+ this.input.addEventListener("change", (event) => {
824
+ event.stopPropagation();
825
+ this.dispatchEvent(new Event("change", { bubbles: true, composed: true }));
826
+ });
827
+ root.append(icon2, this.input);
828
+ }
829
+ connectedCallback() {
830
+ this.sync();
831
+ if (this.hasAttribute("value")) this.value = this.getAttribute("value") ?? "";
832
+ }
833
+ attributeChangedCallback(name) {
834
+ if (name === "value") this.value = this.getAttribute("value") ?? "";
835
+ else this.sync();
836
+ }
837
+ get value() {
838
+ return this.currentValue;
839
+ }
840
+ set value(next) {
841
+ this.currentValue = String(next ?? "");
842
+ if (this.input.value !== this.currentValue) this.input.value = this.currentValue;
843
+ }
844
+ get placeholder() {
845
+ return this.getAttribute("placeholder") ?? "";
846
+ }
847
+ set placeholder(next) {
848
+ this.setAttribute("placeholder", String(next ?? ""));
849
+ }
850
+ get disabled() {
851
+ return this.hasAttribute("disabled");
852
+ }
853
+ set disabled(next) {
854
+ this.toggleAttribute("disabled", Boolean(next));
855
+ }
856
+ focus(options) {
857
+ this.input.focus(options);
858
+ }
859
+ select() {
860
+ this.input.select();
861
+ }
862
+ sync() {
863
+ this.input.placeholder = this.getAttribute("placeholder") ?? "";
864
+ this.input.setAttribute(
865
+ "aria-label",
866
+ this.getAttribute("aria-label") ?? this.input.placeholder
867
+ );
868
+ this.input.disabled = this.hasAttribute("disabled");
869
+ }
870
+ }
871
+ return OfficeUiSearch;
872
+ });
873
+
874
+ // src/backstage.ts
875
+ var CSS4 = `
7
876
  :host { position: absolute; inset: 0; z-index: 30; display: none; min-width: 0;
8
877
  background: var(--office-background, #fff); color: var(--office-foreground, #1f2937);
9
878
  font-family: var(--office-font, system-ui, sans-serif); }
@@ -44,7 +913,7 @@ var defineBackstage = definer("office-ui-backstage", () => {
44
913
  super();
45
914
  const doc = this.ownerDocument;
46
915
  const root = this.attachShadow({ mode: "open" });
47
- attachStyles(root, controlCss(CSS));
916
+ attachStyles(root, controlCss(CSS4));
48
917
  this.#frame = doc.createElement("div");
49
918
  this.#frame.className = "frame";
50
919
  this.#frame.setAttribute("role", "dialog");
@@ -176,7 +1045,7 @@ var defineBackstage = definer("office-ui-backstage", () => {
176
1045
  });
177
1046
 
178
1047
  // src/find-bar.ts
179
- var CSS2 = `
1048
+ var CSS5 = `
180
1049
  :host { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 4px 8px 4px 12px;
181
1050
  border-bottom: 1px solid var(--office-border, #d1d5db); background: var(--office-surface, #f3f4f6);
182
1051
  color: var(--office-foreground, #1f2937); font: 12px var(--office-font, system-ui, sans-serif); }
@@ -218,7 +1087,7 @@ var defineFindBar = definer("office-ui-find-bar", () => {
218
1087
  super();
219
1088
  const doc = this.ownerDocument;
220
1089
  const root = this.attachShadow({ mode: "open", delegatesFocus: true });
221
- attachStyles(root, controlCss(CSS2));
1090
+ attachStyles(root, controlCss(CSS5));
222
1091
  this.#region = doc.createElement("div");
223
1092
  this.#region.setAttribute("role", "search");
224
1093
  const field = doc.createElement("label");
@@ -336,7 +1205,7 @@ var defineFindBar = definer("office-ui-find-bar", () => {
336
1205
  });
337
1206
 
338
1207
  // src/print-preview.ts
339
- var CSS3 = `
1208
+ var CSS6 = `
340
1209
  :host { display: block; max-width: 420px; font: 12px var(--office-font, system-ui, sans-serif);
341
1210
  color: var(--office-foreground, #1f2937); }
342
1211
  .sheet { padding: 12px; border: 1px solid var(--office-border, #d1d5db); background: #fff;
@@ -365,7 +1234,7 @@ var definePrintPreview = definer("office-ui-print-preview", () => {
365
1234
  super();
366
1235
  const doc = this.ownerDocument;
367
1236
  const root = this.attachShadow({ mode: "open" });
368
- attachStyles(root, controlCss(CSS3));
1237
+ attachStyles(root, controlCss(CSS6));
369
1238
  this.#sheet = doc.createElement("div");
370
1239
  this.#sheet.className = "sheet";
371
1240
  this.#sheet.setAttribute("role", "img");
@@ -444,7 +1313,7 @@ var definePrintPreview = definer("office-ui-print-preview", () => {
444
1313
  });
445
1314
 
446
1315
  // src/ribbon-tabs.ts
447
- var CSS4 = `
1316
+ var CSS7 = `
448
1317
  :host { display: block; min-width: 0; }
449
1318
  .head { display: flex; align-items: stretch; min-width: 0; border-bottom: 1px solid var(--office-border, #d1d5db); }
450
1319
  .file { flex: none; min-height: var(--office-ribbon-tab-height, 35px); margin: 0 4px 0 0; padding: 6px 16px; border: 0;
@@ -488,7 +1357,7 @@ var defineRibbon = definer("office-ui-ribbon", () => {
488
1357
  super();
489
1358
  const doc = this.ownerDocument;
490
1359
  const root = this.attachShadow({ mode: "open" });
491
- attachStyles(root, controlCss(CSS4));
1360
+ attachStyles(root, controlCss(CSS7));
492
1361
  const head = doc.createElement("div");
493
1362
  head.className = "head";
494
1363
  head.setAttribute("part", "head");
@@ -610,7 +1479,7 @@ var defineRibbon = definer("office-ui-ribbon", () => {
610
1479
  });
611
1480
 
612
1481
  // src/ruler.ts
613
- var CSS5 = `
1482
+ var CSS8 = `
614
1483
  :host { display: block; box-sizing: border-box; background: var(--office-background, #fff);
615
1484
  color: var(--office-muted-foreground, #605e5c); overflow: hidden; }
616
1485
  :host(:not([orientation="vertical"])) { height: 18px; border-bottom: 1px solid var(--office-border, #d1d5db); }
@@ -629,7 +1498,7 @@ var defineRuler = definer("office-ui-ruler", () => {
629
1498
  constructor() {
630
1499
  super();
631
1500
  const root = this.attachShadow({ mode: "open" });
632
- attachStyles(root, controlCss(CSS5));
1501
+ attachStyles(root, controlCss(CSS8));
633
1502
  this.#canvas = this.ownerDocument.createElement("canvas");
634
1503
  root.append(this.#canvas);
635
1504
  }
@@ -765,7 +1634,7 @@ function clearOfficeProfile(storage = defaultStorage(), key = OFFICE_PROFILE_STO
765
1634
  } catch {
766
1635
  }
767
1636
  }
768
- var CSS6 = `
1637
+ var CSS9 = `
769
1638
  :host { display: block; font-family: var(--office-font, system-ui, sans-serif); font-size: 13px; }
770
1639
  h2 { margin: 0 0 12px; font-size: 15px; font-weight: 600; }
771
1640
  .who { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
@@ -795,7 +1664,7 @@ var defineAccount = definer("office-ui-account", () => {
795
1664
  super();
796
1665
  const doc = this.ownerDocument;
797
1666
  const root = this.attachShadow({ mode: "open" });
798
- attachStyles(root, controlCss(CSS6));
1667
+ attachStyles(root, controlCss(CSS9));
799
1668
  const heading = doc.createElement("h2");
800
1669
  heading.textContent = "User Information";
801
1670
  const who = doc.createElement("div");
@@ -896,7 +1765,7 @@ var defineAccount = definer("office-ui-account", () => {
896
1765
  });
897
1766
 
898
1767
  // src/button.ts
899
- var CSS7 = `
1768
+ var CSS10 = `
900
1769
  :host { display: inline-flex; vertical-align: middle; }
901
1770
  button { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
902
1771
  gap: 6px; min-width: var(--office-target-size, 28px); min-height: var(--office-target-size, 28px);
@@ -937,7 +1806,7 @@ var defineButton = definer("office-ui-button", () => {
937
1806
  constructor() {
938
1807
  super();
939
1808
  const root = this.attachShadow({ mode: "open", delegatesFocus: true });
940
- attachStyles(root, controlCss(CSS7));
1809
+ attachStyles(root, controlCss(CSS10));
941
1810
  this.button = this.ownerDocument.createElement("button");
942
1811
  this.button.type = "button";
943
1812
  this.button.setAttribute("part", "button");
@@ -1112,7 +1981,7 @@ var defineCheckbox = definer(
1112
1981
  var defineSwitch = definer("office-ui-switch", makeCheckable("switch", SWITCH_CSS));
1113
1982
 
1114
1983
  // src/dialog.ts
1115
- var CSS8 = `
1984
+ var CSS11 = `
1116
1985
  :host { display: none; position: fixed; inset: 0; z-index: 1000; align-items: center; justify-content: center; }
1117
1986
  :host([open]) { display: flex; }
1118
1987
  .backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / .4); }
@@ -1145,7 +2014,7 @@ var defineDialog = definer("office-ui-dialog", () => {
1145
2014
  super();
1146
2015
  const doc = this.ownerDocument;
1147
2016
  const root = this.attachShadow({ mode: "open" });
1148
- attachStyles(root, controlCss(CSS8));
2017
+ attachStyles(root, controlCss(CSS11));
1149
2018
  const backdrop = doc.createElement("div");
1150
2019
  backdrop.className = "backdrop";
1151
2020
  this.box = doc.createElement("div");
@@ -1161,9 +2030,9 @@ var defineDialog = definer("office-ui-dialog", () => {
1161
2030
  this.closeButton.type = "button";
1162
2031
  this.closeButton.className = "close";
1163
2032
  this.closeButton.setAttribute("aria-label", "Close");
1164
- const icon = createIconSvg(doc);
1165
- paintIcon(icon, "close");
1166
- this.closeButton.append(icon);
2033
+ const icon2 = createIconSvg(doc);
2034
+ paintIcon(icon2, "close");
2035
+ this.closeButton.append(icon2);
1167
2036
  header.append(this.heading, this.closeButton);
1168
2037
  const body = doc.createElement("div");
1169
2038
  body.className = "body";
@@ -1248,7 +2117,7 @@ var defineDialog = definer("office-ui-dialog", () => {
1248
2117
  });
1249
2118
 
1250
2119
  // src/command-search.ts
1251
- var CSS9 = `
2120
+ var CSS12 = `
1252
2121
  :host { display: inline-flex; align-items: center; min-width: 0; font-family: var(--office-font, system-ui, sans-serif); }
1253
2122
  .field { display: flex; align-items: center; gap: 6px; width: 100%; min-width: 0; height: var(--office-target-size, 28px);
1254
2123
  padding: 0 8px; box-sizing: border-box; border: 1px solid transparent; border-radius: var(--office-radius, 4px);
@@ -1288,7 +2157,7 @@ var defineCommandSearch = definer("office-ui-command-search", () => {
1288
2157
  super();
1289
2158
  const doc = this.ownerDocument;
1290
2159
  const root = this.attachShadow({ mode: "open", delegatesFocus: true });
1291
- attachStyles(root, controlCss(CSS9));
2160
+ attachStyles(root, controlCss(CSS12));
1292
2161
  const field = doc.createElement("div");
1293
2162
  field.className = "field";
1294
2163
  const glass = createIconSvg(doc);
@@ -1445,7 +2314,7 @@ var defineCommandSearch = definer("office-ui-command-search", () => {
1445
2314
  });
1446
2315
 
1447
2316
  // src/context-menu.ts
1448
- var CSS10 = `
2317
+ var CSS13 = `
1449
2318
  :host { display: contents; }
1450
2319
  .panel { position: fixed; inset: auto; margin: 0; min-width: 200px; padding: 4px; box-sizing: border-box;
1451
2320
  background: var(--office-background, #fff); color: var(--office-foreground, #1f2937);
@@ -1481,7 +2350,7 @@ var defineContextMenu = definer("office-ui-context-menu", () => {
1481
2350
  super();
1482
2351
  const doc = this.ownerDocument;
1483
2352
  const root = this.attachShadow({ mode: "open" });
1484
- attachStyles(root, controlCss(CSS10));
2353
+ attachStyles(root, controlCss(CSS13));
1485
2354
  this.panel = doc.createElement("div");
1486
2355
  this.panel.className = "panel";
1487
2356
  this.panel.setAttribute("role", "menu");
@@ -1891,7 +2760,7 @@ function clampOptionNumber(raw, min, max) {
1891
2760
  const parsed = Number(raw);
1892
2761
  return Number.isFinite(parsed) && raw.trim() !== "" ? Math.min(max, Math.max(min, parsed)) : void 0;
1893
2762
  }
1894
- var CSS11 = `
2763
+ var CSS14 = `
1895
2764
  :host { display: contents; }
1896
2765
  office-ui-dialog { --office-dialog-width: min(820px, 100vw); --office-dialog-max-width: min(820px, 100vw); }
1897
2766
  .layout { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 0; min-height: min(440px, 70vh); margin: -16px; }
@@ -1940,7 +2809,7 @@ var defineOptionsDialog = definer("office-ui-options-dialog", () => {
1940
2809
  super();
1941
2810
  const doc = this.ownerDocument;
1942
2811
  const root = this.attachShadow({ mode: "open" });
1943
- attachStyles(root, controlCss(CSS11));
2812
+ attachStyles(root, controlCss(CSS14));
1944
2813
  this.#dialog = doc.createElement("office-ui-dialog");
1945
2814
  const layout = doc.createElement("div");
1946
2815
  layout.className = "layout";
@@ -2285,7 +3154,7 @@ var defineToolbar = definer("office-ui-toolbar", () => {
2285
3154
  });
2286
3155
 
2287
3156
  // src/select.ts
2288
- var CSS12 = `
3157
+ var CSS15 = `
2289
3158
  :host { display: inline-block; position: relative; vertical-align: middle; }
2290
3159
  button { box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 8px;
2291
3160
  width: 100%; min-height: var(--office-target-size, 28px); padding: 0 8px; font: inherit; font-size: 12px;
@@ -2324,7 +3193,7 @@ var defineSelect = definer("office-ui-select", () => {
2324
3193
  super();
2325
3194
  const doc = this.ownerDocument;
2326
3195
  const root = this.attachShadow({ mode: "open", delegatesFocus: true });
2327
- attachStyles(root, controlCss(CSS12));
3196
+ attachStyles(root, controlCss(CSS15));
2328
3197
  this.trigger = doc.createElement("button");
2329
3198
  this.trigger.type = "button";
2330
3199
  this.trigger.setAttribute("role", "combobox");
@@ -2575,7 +3444,7 @@ var defineStatusItem = definer("office-ui-status-item", () => {
2575
3444
  });
2576
3445
 
2577
3446
  // src/tab-strip.ts
2578
- var CSS13 = `
3447
+ var CSS16 = `
2579
3448
  :host { display: flex; align-items: stretch; min-width: 0; min-height: 28px; gap: 2px; padding: 0 6px;
2580
3449
  background: var(--office-surface, #f3f4f6); color: var(--office-muted-foreground, #6b7280);
2581
3450
  border-top: 1px solid var(--office-border, #d1d5db); font-size: 12px;
@@ -2622,15 +3491,15 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
2622
3491
  super();
2623
3492
  const doc = this.ownerDocument;
2624
3493
  const root = this.attachShadow({ mode: "open" });
2625
- attachStyles(root, controlCss(CSS13));
2626
- const step = (name, icon) => {
3494
+ attachStyles(root, controlCss(CSS16));
3495
+ const step = (name, icon2) => {
2627
3496
  const button = doc.createElement("button");
2628
3497
  button.type = "button";
2629
3498
  button.className = "step";
2630
3499
  button.setAttribute("aria-label", name);
2631
3500
  button.title = name;
2632
3501
  const svg = createIconSvg(doc);
2633
- paintIcon(svg, icon);
3502
+ paintIcon(svg, icon2);
2634
3503
  button.append(svg);
2635
3504
  return button;
2636
3505
  };
@@ -2761,7 +3630,7 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
2761
3630
  });
2762
3631
 
2763
3632
  // src/zoom-slider.ts
2764
- var CSS14 = `
3633
+ var CSS17 = `
2765
3634
  :host { display: inline-flex; align-items: center; gap: 2px; font-size: 11px;
2766
3635
  color: var(--office-foreground, #1f2937); font-family: var(--office-font, system-ui, sans-serif); }
2767
3636
  button { box-sizing: border-box; display: inline-grid; place-items: center; min-width: var(--office-target-size, 24px);
@@ -2797,7 +3666,7 @@ var defineZoomSlider = definer("office-ui-zoom-slider", () => {
2797
3666
  super();
2798
3667
  const doc = this.ownerDocument;
2799
3668
  const root = this.attachShadow({ mode: "open" });
2800
- attachStyles(root, controlCss(CSS14));
3669
+ attachStyles(root, controlCss(CSS17));
2801
3670
  const button = (name, text2) => {
2802
3671
  const element = doc.createElement("button");
2803
3672
  element.type = "button";
@@ -3064,10 +3933,17 @@ var CONTROL_DEFINERS = [
3064
3933
  defineFindBar,
3065
3934
  defineRuler,
3066
3935
  defineBackstage,
3067
- definePrintPreview
3936
+ definePrintPreview,
3937
+ defineRadio,
3938
+ defineSearchField,
3939
+ defineRibbonToggle,
3940
+ defineDialogFooter,
3941
+ defineToasts,
3942
+ defineReadOnlyBanner,
3943
+ definePasteOptions
3068
3944
  ];
3069
3945
  function registerControls(registry) {
3070
3946
  for (const define of CONTROL_DEFINERS) define(registry);
3071
3947
  }
3072
3948
 
3073
- export { CONTROL_DEFINERS, DEFAULT_OFFICE_PROFILE, OFFICE_AVATAR_SWATCHES, OFFICE_PROFILE_STORAGE_KEY, attachKeyTips, clampOptionNumber, clearOfficeProfile, defineAccount, defineBackstage, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineFindBar, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, definePrintPreview, defineRibbon, defineRibbonGroup, defineRibbonStack, defineRuler, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, profileInitials, readOfficeProfile, registerControls, rulerDivisions, sanitizeOfficeProfile, writeOfficeProfile };
3949
+ export { CONTROL_DEFINERS, DEFAULT_OFFICE_PROFILE, OFFICE_AVATAR_SWATCHES, OFFICE_PROFILE_STORAGE_KEY, OFFICE_TOAST_VISIBLE_LIMIT, attachKeyTips, clampOptionNumber, clearOfficeProfile, defineAccount, defineBackstage, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineDialogFooter, defineFindBar, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, definePasteOptions, definePrintPreview, defineRadio, defineReadOnlyBanner, defineRibbon, defineRibbonGroup, defineRibbonStack, defineRibbonToggle, defineRuler, defineSearchField, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToasts, defineToolbar, defineZoomSlider, profileInitials, readOfficeProfile, registerControls, rulerDivisions, sanitizeOfficeProfile, writeOfficeProfile };