ooxml-ui 0.9.0 → 0.10.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 +6 -1
- package/dist/backstage.d.ts +28 -0
- package/dist/{chunk-TMSFX6TC.js → chunk-5YR7YA57.js} +750 -22
- package/dist/controls.d.ts +12 -2
- package/dist/controls.js +1 -1
- package/dist/find-bar.d.ts +15 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -2
- package/dist/print-preview.d.ts +11 -0
- package/dist/ribbon-tabs.d.ts +14 -0
- package/dist/ruler.d.ts +10 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -75,6 +75,11 @@ with an incompatible build of this package.
|
|
|
75
75
|
| `office-ui-command-search` | `commands` `[{ id, label, keywords?, description?, disabled?, title? }]`, `placeholder`, `label`, `limit` (Office's "Tell me what you want to do") | choice: `office-command` `{ command }` |
|
|
76
76
|
| `office-ui-options-dialog` | `categories` `[{ id, label, description?, disabled?, sections: [{ id, title, controls }] }]` (controls: `toggle`, `select`, `number`, `text`, each optionally `disabled` with a reason), `values`, `category`, `open`, `heading`, `show()`, `close()` | OK: `office-options-change` `{ values, changed }` |
|
|
77
77
|
| `office-ui-account` | `profile` `{ displayName, avatarColor, initial? }`; slots `sign-in` and default (product sections) | `office-profile-change` `{ profile }` |
|
|
78
|
+
| `office-ui-ribbon` | Tab row over tab panels. Panels are children with `data-ribbon-tab`, `data-label`, optional `data-tab-keytip`; slots `quick-access`, `search`, `end`; `selected`, `label`, `file-label`, `no-file`, `file-expanded`, `file-keytip`; `focusFile()`, `focusTab()` | `office-ribbon-select` `{ tab }` (cancelable), `office-ribbon-file` |
|
|
79
|
+
| `office-ui-backstage` | `items` `[{ id, label, group?: 'footer', disabled?, title? }]`, `open`, `selected`, `label`, `back-label`, `show(page?)`, `close()`; pages are children with `data-backstage-page` | `office-backstage-select` `{ id }` (cancelable), `office-backstage-close` `{ reason }` (cancelable) |
|
|
80
|
+
| `office-ui-find-bar` | `open`, `label`, `input-label`, `placeholder`, `maxlength`, `disabled`, `navigation-disabled`, `previous-label`, `next-label`, `close-label`; `value`, `status`, `statusTitle`, `show()`, `close()` | `office-find-input` `{ query }`, `office-find-step` `{ direction }`, `office-find-close` |
|
|
81
|
+
| `office-ui-ruler` | `orientation="vertical"`, `origin` (px offset of zero), `scale` (px per unit, default 96), `direction="reverse"`; decorative | none |
|
|
82
|
+
| `office-ui-print-preview` | `pages` (rendered nodes; an inert clone of the current one is shown), `index`, `label`, `empty-label` | `office-print-preview-page` `{ index }` |
|
|
78
83
|
| `office-ui-presence` | `participants`, `max`, `label` | `office-presence-select` `{ id }` |
|
|
79
84
|
| `office-ui-smartart` | `drawing` (core `DiagramDrawing`), `schemeColors`, `label` | `office-smartart-render` (render report) |
|
|
80
85
|
| `office-ui-icon` | `name`, `label` | none |
|
|
@@ -85,7 +90,7 @@ an origin shows the same name and avatar colour.
|
|
|
85
90
|
|
|
86
91
|
`attachKeyTips(scope)` (from `ooxml-ui/controls`) adds Office KeyTips to any element or shadow
|
|
87
92
|
root: press and release Alt to show badges on controls marked `data-keytip="H"`, type a badge to
|
|
88
|
-
activate it, and use `data-keytip-panel` / `data-keytip-level` for a tab's second level. Escape
|
|
93
|
+
activate it (controls inside open shadow roots of shared elements, such as ribbon tabs, are included), and use `data-keytip-panel` / `data-keytip-level` for a tab's second level. Escape
|
|
89
94
|
steps back; disabled controls are dimmed and never run.
|
|
90
95
|
|
|
91
96
|
Setting a property never emits an event; only user activation does. Controls honour
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Office's File view (backstage): a navigation column and one page per item. Generalised from
|
|
3
|
+
* pptx-viewer's `BACKSTAGE_NAV` model (render/backstage.ts) and the Visio viewer's backstage.
|
|
4
|
+
*/
|
|
5
|
+
export interface OfficeBackstageItem {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
/** Items in the footer group sit at the bottom of the column (Account, Options). */
|
|
9
|
+
group?: 'footer';
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
/** Tooltip, for example why an item is disabled. */
|
|
12
|
+
title?: string;
|
|
13
|
+
}
|
|
14
|
+
/** An item was chosen; cancelable (`preventDefault()` keeps the current page). */
|
|
15
|
+
export type OfficeBackstageSelectEvent = CustomEvent<{
|
|
16
|
+
id: string;
|
|
17
|
+
}>;
|
|
18
|
+
export type OfficeBackstageCloseEvent = CustomEvent<{
|
|
19
|
+
reason: 'back' | 'escape' | 'api';
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* `<office-ui-backstage>`: set `items`, put one light-DOM child per page with
|
|
23
|
+
* `data-backstage-page="<id>"`, then `show(id)`. Choosing an item emits `office-backstage-select`
|
|
24
|
+
* and, unless prevented, shows its page; items without a page (Save, Close) only emit. Back and
|
|
25
|
+
* Escape emit a cancelable `office-backstage-close` and close. Attributes: `open`, `selected`,
|
|
26
|
+
* `label` (default "File"), `back-label`. Nav buttons carry `data-backstage-item`.
|
|
27
|
+
*/
|
|
28
|
+
export declare const defineBackstage: import("./registry.js").Definer;
|
|
@@ -2,6 +2,716 @@ import { createIconSvg, paintIcon, defineIcon } from './chunk-PCSUQPMC.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
|
|
6
|
+
var CSS = `
|
|
7
|
+
:host { position: absolute; inset: 0; z-index: 30; display: none; min-width: 0;
|
|
8
|
+
background: var(--office-background, #fff); color: var(--office-foreground, #1f2937);
|
|
9
|
+
font-family: var(--office-font, system-ui, sans-serif); }
|
|
10
|
+
:host([open]) { display: block; }
|
|
11
|
+
.frame { display: flex; height: 100%; min-width: 0; }
|
|
12
|
+
nav { display: flex; flex: 0 0 200px; flex-direction: column; padding: 12px 0; overflow: auto;
|
|
13
|
+
background: var(--office-accent, #2563eb); color: var(--office-accent-foreground, #fff); }
|
|
14
|
+
nav button { border: 0; border-radius: 0; background: transparent; color: inherit; font: inherit; text-align: start; cursor: pointer; }
|
|
15
|
+
.back { width: 36px; min-height: 36px; margin: 0 0 12px 16px; padding: 0; border: 1.5px solid currentColor;
|
|
16
|
+
border-radius: 50%; font-size: 18px; text-align: center; }
|
|
17
|
+
.item { min-height: 38px; padding: 6px 24px; font-size: 14px; }
|
|
18
|
+
.item:hover:enabled, .item[aria-current="page"] { background: color-mix(in srgb, #000 22%, transparent); }
|
|
19
|
+
.item:disabled { opacity: .55; cursor: default; }
|
|
20
|
+
nav button:focus-visible { outline: 2px solid currentColor; outline-offset: -3px; }
|
|
21
|
+
.footer { display: flex; flex-direction: column; margin-top: auto; padding-top: 16px; }
|
|
22
|
+
.body { flex: 1; min-width: 0; overflow: auto; padding: 28px 40px; }
|
|
23
|
+
@media (max-width: 760px) {
|
|
24
|
+
.frame { flex-direction: column; }
|
|
25
|
+
nav { flex: none; flex-direction: row; flex-wrap: wrap; padding: 6px; }
|
|
26
|
+
.back { margin: 4px; }
|
|
27
|
+
.item { min-height: 44px; padding: 6px 12px; }
|
|
28
|
+
.footer { flex-direction: row; margin-top: 0; padding-top: 0; }
|
|
29
|
+
.body { padding: 16px; }
|
|
30
|
+
}
|
|
31
|
+
@media (forced-colors: active) { nav { border-inline-end: 1px solid CanvasText; } .item[aria-current="page"] { outline: 2px solid Highlight; } }
|
|
32
|
+
`;
|
|
33
|
+
var defineBackstage = definer("office-ui-backstage", () => {
|
|
34
|
+
class OfficeUiBackstage extends HTMLElement {
|
|
35
|
+
static observedAttributes = ["selected", "label", "back-label"];
|
|
36
|
+
#items = [];
|
|
37
|
+
#frame;
|
|
38
|
+
#nav;
|
|
39
|
+
#main;
|
|
40
|
+
#footer;
|
|
41
|
+
#back;
|
|
42
|
+
constructor() {
|
|
43
|
+
super();
|
|
44
|
+
const doc = this.ownerDocument;
|
|
45
|
+
const root = this.attachShadow({ mode: "open" });
|
|
46
|
+
attachStyles(root, controlCss(CSS));
|
|
47
|
+
this.#frame = doc.createElement("div");
|
|
48
|
+
this.#frame.className = "frame";
|
|
49
|
+
this.#frame.setAttribute("role", "dialog");
|
|
50
|
+
this.#frame.setAttribute("aria-modal", "true");
|
|
51
|
+
this.#nav = doc.createElement("nav");
|
|
52
|
+
this.#nav.setAttribute("part", "nav");
|
|
53
|
+
this.#back = doc.createElement("button");
|
|
54
|
+
this.#back.type = "button";
|
|
55
|
+
this.#back.className = "back";
|
|
56
|
+
this.#back.textContent = "\u2190";
|
|
57
|
+
this.#back.dataset.backstage = "back";
|
|
58
|
+
this.#main = doc.createElement("div");
|
|
59
|
+
this.#footer = doc.createElement("div");
|
|
60
|
+
this.#footer.className = "footer";
|
|
61
|
+
this.#nav.append(this.#back, this.#main, this.#footer);
|
|
62
|
+
const body = doc.createElement("div");
|
|
63
|
+
body.className = "body";
|
|
64
|
+
body.setAttribute("part", "body");
|
|
65
|
+
body.append(doc.createElement("slot"));
|
|
66
|
+
this.#frame.append(this.#nav, body);
|
|
67
|
+
root.append(this.#frame);
|
|
68
|
+
this.#back.addEventListener("click", () => this.#requestClose("back"));
|
|
69
|
+
this.#nav.addEventListener("click", (event) => {
|
|
70
|
+
const item = event.target.closest?.(
|
|
71
|
+
"[data-backstage-item]"
|
|
72
|
+
);
|
|
73
|
+
if (item && !item.disabled) this.#choose(item.dataset.backstageItem);
|
|
74
|
+
});
|
|
75
|
+
this.addEventListener("keydown", (event) => {
|
|
76
|
+
if (event.key !== "Escape" || !this.open) return;
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
event.stopPropagation();
|
|
79
|
+
this.#requestClose("escape");
|
|
80
|
+
});
|
|
81
|
+
this.#labels();
|
|
82
|
+
}
|
|
83
|
+
attributeChangedCallback(name) {
|
|
84
|
+
if (name === "selected") this.#sync();
|
|
85
|
+
else this.#labels();
|
|
86
|
+
}
|
|
87
|
+
get items() {
|
|
88
|
+
return this.#items;
|
|
89
|
+
}
|
|
90
|
+
set items(value) {
|
|
91
|
+
this.#items = value;
|
|
92
|
+
this.#render();
|
|
93
|
+
}
|
|
94
|
+
get open() {
|
|
95
|
+
return this.hasAttribute("open");
|
|
96
|
+
}
|
|
97
|
+
set open(value) {
|
|
98
|
+
this.toggleAttribute("open", Boolean(value));
|
|
99
|
+
}
|
|
100
|
+
get selected() {
|
|
101
|
+
return this.getAttribute("selected") ?? "";
|
|
102
|
+
}
|
|
103
|
+
set selected(id) {
|
|
104
|
+
this.setAttribute("selected", id);
|
|
105
|
+
}
|
|
106
|
+
/** Open on a page (default: the selected one) and focus its item. */
|
|
107
|
+
show(page = this.selected || this.#items.find((item) => this.#page(item.id))?.id || "") {
|
|
108
|
+
this.open = true;
|
|
109
|
+
if (page) this.selected = page;
|
|
110
|
+
this.#button(this.selected)?.focus();
|
|
111
|
+
}
|
|
112
|
+
/** Close without asking (emits `office-backstage-close` with reason `api`). */
|
|
113
|
+
close() {
|
|
114
|
+
if (!this.open) return;
|
|
115
|
+
this.open = false;
|
|
116
|
+
emit(this, "office-backstage-close", { reason: "api" });
|
|
117
|
+
}
|
|
118
|
+
#labels() {
|
|
119
|
+
const label = this.getAttribute("label") ?? "File";
|
|
120
|
+
this.#frame.setAttribute("aria-label", label);
|
|
121
|
+
this.#nav.setAttribute("aria-label", label);
|
|
122
|
+
const back = this.getAttribute("back-label") ?? "Back";
|
|
123
|
+
this.#back.setAttribute("aria-label", back);
|
|
124
|
+
this.#back.title = `${back} (Esc)`;
|
|
125
|
+
}
|
|
126
|
+
#page(id) {
|
|
127
|
+
return [...this.children].find(
|
|
128
|
+
(child) => child instanceof HTMLElement && child.dataset.backstagePage === id
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
#button(id) {
|
|
132
|
+
return [...this.#nav.querySelectorAll("[data-backstage-item]")].find(
|
|
133
|
+
(button) => button.dataset.backstageItem === id
|
|
134
|
+
) ?? null;
|
|
135
|
+
}
|
|
136
|
+
#render() {
|
|
137
|
+
const doc = this.ownerDocument;
|
|
138
|
+
const button = (item) => {
|
|
139
|
+
const element = doc.createElement("button");
|
|
140
|
+
element.type = "button";
|
|
141
|
+
element.className = "item";
|
|
142
|
+
element.dataset.backstageItem = item.id;
|
|
143
|
+
element.textContent = item.label;
|
|
144
|
+
element.disabled = !!item.disabled;
|
|
145
|
+
if (item.title) element.title = item.title;
|
|
146
|
+
return element;
|
|
147
|
+
};
|
|
148
|
+
this.#main.replaceChildren(
|
|
149
|
+
...this.#items.filter((item) => item.group !== "footer").map(button)
|
|
150
|
+
);
|
|
151
|
+
this.#footer.replaceChildren(
|
|
152
|
+
...this.#items.filter((item) => item.group === "footer").map(button)
|
|
153
|
+
);
|
|
154
|
+
this.#sync();
|
|
155
|
+
}
|
|
156
|
+
#sync() {
|
|
157
|
+
const selected = this.selected;
|
|
158
|
+
for (const item of this.#nav.querySelectorAll("[data-backstage-item]")) {
|
|
159
|
+
if (item.dataset.backstageItem === selected) item.setAttribute("aria-current", "page");
|
|
160
|
+
else item.removeAttribute("aria-current");
|
|
161
|
+
}
|
|
162
|
+
for (const child of this.children)
|
|
163
|
+
if (child instanceof HTMLElement && child.dataset.backstagePage !== void 0)
|
|
164
|
+
child.hidden = child.dataset.backstagePage !== selected;
|
|
165
|
+
}
|
|
166
|
+
#choose(id) {
|
|
167
|
+
if (emit(this, "office-backstage-select", { id }, true) && this.#page(id)) this.selected = id;
|
|
168
|
+
}
|
|
169
|
+
#requestClose(reason) {
|
|
170
|
+
if (emit(this, "office-backstage-close", { reason }, true)) this.open = false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return OfficeUiBackstage;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// src/find-bar.ts
|
|
177
|
+
var CSS2 = `
|
|
178
|
+
:host { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 4px 8px 4px 12px;
|
|
179
|
+
border-bottom: 1px solid var(--office-border, #d1d5db); background: var(--office-surface, #f3f4f6);
|
|
180
|
+
color: var(--office-foreground, #1f2937); font: 12px var(--office-font, system-ui, sans-serif); }
|
|
181
|
+
:host(:not([open])) { display: none; }
|
|
182
|
+
[role="search"] { display: flex; flex: 1; align-items: center; gap: 4px; min-width: 0; max-width: 640px; }
|
|
183
|
+
label { display: flex; flex: 1; align-items: center; gap: 6px; min-width: 0; }
|
|
184
|
+
input { flex: 1; min-width: 0; min-height: 26px; padding: 2px 6px; font: inherit; color: inherit;
|
|
185
|
+
border: 1px solid var(--office-border, #d1d5db); border-radius: 3px; background: var(--office-background, #fff); }
|
|
186
|
+
button { min-height: 26px; padding: 2px 8px; font: inherit; color: inherit; cursor: pointer;
|
|
187
|
+
border: 1px solid var(--office-border, #d1d5db); border-radius: 3px; background: var(--office-background, #fff); }
|
|
188
|
+
button:disabled { opacity: .5; cursor: default; }
|
|
189
|
+
.status { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
|
|
190
|
+
color: var(--office-muted-foreground, #6b7280); }
|
|
191
|
+
.close { margin-inline-start: auto; width: var(--office-target-size, 28px); padding: 0; border-color: transparent;
|
|
192
|
+
background: transparent; font-size: 18px; line-height: 1; }
|
|
193
|
+
input:focus-visible, button:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: 1px; }
|
|
194
|
+
@media (max-width: 760px) { :host { flex-wrap: wrap; } [role="search"] { flex-wrap: wrap; } }
|
|
195
|
+
`;
|
|
196
|
+
var defineFindBar = definer("office-ui-find-bar", () => {
|
|
197
|
+
class OfficeUiFindBar extends HTMLElement {
|
|
198
|
+
static observedAttributes = [
|
|
199
|
+
"label",
|
|
200
|
+
"input-label",
|
|
201
|
+
"placeholder",
|
|
202
|
+
"maxlength",
|
|
203
|
+
"disabled",
|
|
204
|
+
"navigation-disabled",
|
|
205
|
+
"previous-label",
|
|
206
|
+
"next-label",
|
|
207
|
+
"close-label"
|
|
208
|
+
];
|
|
209
|
+
#region;
|
|
210
|
+
#input;
|
|
211
|
+
#previous;
|
|
212
|
+
#next;
|
|
213
|
+
#status;
|
|
214
|
+
#close;
|
|
215
|
+
constructor() {
|
|
216
|
+
super();
|
|
217
|
+
const doc = this.ownerDocument;
|
|
218
|
+
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
219
|
+
attachStyles(root, controlCss(CSS2));
|
|
220
|
+
this.#region = doc.createElement("div");
|
|
221
|
+
this.#region.setAttribute("role", "search");
|
|
222
|
+
const field = doc.createElement("label");
|
|
223
|
+
field.append("Find ");
|
|
224
|
+
this.#input = doc.createElement("input");
|
|
225
|
+
this.#input.type = "search";
|
|
226
|
+
this.#input.autocomplete = "off";
|
|
227
|
+
this.#input.spellcheck = false;
|
|
228
|
+
this.#input.setAttribute("aria-describedby", "status");
|
|
229
|
+
field.append(this.#input);
|
|
230
|
+
const button = (action, text2) => {
|
|
231
|
+
const element = doc.createElement("button");
|
|
232
|
+
element.type = "button";
|
|
233
|
+
element.dataset.action = action;
|
|
234
|
+
element.textContent = text2;
|
|
235
|
+
return element;
|
|
236
|
+
};
|
|
237
|
+
this.#previous = button("previous", "Previous");
|
|
238
|
+
this.#next = button("next", "Next");
|
|
239
|
+
this.#status = doc.createElement("span");
|
|
240
|
+
this.#status.id = "status";
|
|
241
|
+
this.#status.className = "status";
|
|
242
|
+
this.#status.setAttribute("role", "status");
|
|
243
|
+
this.#status.setAttribute("aria-live", "polite");
|
|
244
|
+
this.#status.setAttribute("aria-atomic", "true");
|
|
245
|
+
this.#region.append(field, this.#previous, this.#next, this.#status);
|
|
246
|
+
this.#close = button("close", "\xD7");
|
|
247
|
+
this.#close.className = "close";
|
|
248
|
+
root.append(this.#region, this.#close);
|
|
249
|
+
this.#input.addEventListener(
|
|
250
|
+
"input",
|
|
251
|
+
() => emit(this, "office-find-input", { query: this.#input.value })
|
|
252
|
+
);
|
|
253
|
+
this.#input.addEventListener("keydown", (event) => this.#key(event));
|
|
254
|
+
this.#previous.addEventListener("click", () => this.#step("previous"));
|
|
255
|
+
this.#next.addEventListener("click", () => this.#step("next"));
|
|
256
|
+
this.#close.addEventListener("click", () => this.close());
|
|
257
|
+
this.#sync();
|
|
258
|
+
}
|
|
259
|
+
attributeChangedCallback() {
|
|
260
|
+
this.#sync();
|
|
261
|
+
}
|
|
262
|
+
get open() {
|
|
263
|
+
return this.hasAttribute("open");
|
|
264
|
+
}
|
|
265
|
+
set open(value) {
|
|
266
|
+
this.toggleAttribute("open", Boolean(value));
|
|
267
|
+
}
|
|
268
|
+
get value() {
|
|
269
|
+
return this.#input.value;
|
|
270
|
+
}
|
|
271
|
+
set value(query) {
|
|
272
|
+
if (this.#input.value !== query) this.#input.value = query;
|
|
273
|
+
}
|
|
274
|
+
get status() {
|
|
275
|
+
return this.#status.textContent ?? "";
|
|
276
|
+
}
|
|
277
|
+
set status(text2) {
|
|
278
|
+
this.#status.textContent = text2;
|
|
279
|
+
}
|
|
280
|
+
get statusTitle() {
|
|
281
|
+
return this.#status.title;
|
|
282
|
+
}
|
|
283
|
+
set statusTitle(text2) {
|
|
284
|
+
this.#status.title = text2;
|
|
285
|
+
}
|
|
286
|
+
/** Open, focus the field and select its query. */
|
|
287
|
+
show() {
|
|
288
|
+
this.open = true;
|
|
289
|
+
this.#input.focus();
|
|
290
|
+
this.#input.select();
|
|
291
|
+
}
|
|
292
|
+
/** Close and emit `office-find-close`. */
|
|
293
|
+
close() {
|
|
294
|
+
if (!this.open) return;
|
|
295
|
+
this.open = false;
|
|
296
|
+
emit(this, "office-find-close", {});
|
|
297
|
+
}
|
|
298
|
+
#step(direction) {
|
|
299
|
+
if (!this.hasAttribute("navigation-disabled")) emit(this, "office-find-step", { direction });
|
|
300
|
+
}
|
|
301
|
+
#key(event) {
|
|
302
|
+
if (event.isComposing) return;
|
|
303
|
+
if (event.key === "Enter") {
|
|
304
|
+
event.preventDefault();
|
|
305
|
+
this.#step(event.shiftKey ? "previous" : "next");
|
|
306
|
+
} else if (event.key === "Escape") {
|
|
307
|
+
event.preventDefault();
|
|
308
|
+
event.stopPropagation();
|
|
309
|
+
if (this.#input.value) {
|
|
310
|
+
this.#input.value = "";
|
|
311
|
+
emit(this, "office-find-input", { query: "" });
|
|
312
|
+
} else this.close();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
#sync() {
|
|
316
|
+
const text2 = (name, fallback) => this.getAttribute(name) ?? fallback;
|
|
317
|
+
this.#region.setAttribute("aria-label", text2("label", "Find"));
|
|
318
|
+
this.#input.setAttribute("aria-label", text2("input-label", "Find"));
|
|
319
|
+
this.#input.placeholder = text2("placeholder", "");
|
|
320
|
+
const max = Number(this.getAttribute("maxlength"));
|
|
321
|
+
if (Number.isInteger(max) && max > 0) this.#input.maxLength = max;
|
|
322
|
+
else this.#input.removeAttribute("maxlength");
|
|
323
|
+
this.#input.disabled = this.hasAttribute("disabled");
|
|
324
|
+
const stuck = this.hasAttribute("navigation-disabled") || this.#input.disabled;
|
|
325
|
+
this.#previous.disabled = this.#next.disabled = stuck;
|
|
326
|
+
this.#previous.setAttribute("aria-label", text2("previous-label", "Previous result"));
|
|
327
|
+
this.#next.setAttribute("aria-label", text2("next-label", "Next result"));
|
|
328
|
+
const close = text2("close-label", "Close Find");
|
|
329
|
+
this.#close.setAttribute("aria-label", close);
|
|
330
|
+
this.#close.title = `${close} (Esc)`;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return OfficeUiFindBar;
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// src/print-preview.ts
|
|
337
|
+
var CSS3 = `
|
|
338
|
+
:host { display: block; max-width: 420px; font: 12px var(--office-font, system-ui, sans-serif);
|
|
339
|
+
color: var(--office-foreground, #1f2937); }
|
|
340
|
+
.sheet { padding: 12px; border: 1px solid var(--office-border, #d1d5db); background: #fff;
|
|
341
|
+
box-shadow: 0 1px 4px rgb(0 0 0 / 15%); }
|
|
342
|
+
.sheet > * { display: block; width: 100%; height: auto; }
|
|
343
|
+
.empty { color: var(--office-muted-foreground, #6b7280); }
|
|
344
|
+
.nav { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 8px; }
|
|
345
|
+
.nav[hidden] { display: none; }
|
|
346
|
+
button { min-width: var(--office-target-size, 28px); min-height: var(--office-target-size, 28px); font: inherit;
|
|
347
|
+
color: inherit; border: 1px solid var(--office-border, #d1d5db); border-radius: 3px;
|
|
348
|
+
background: var(--office-background, #fff); cursor: pointer; }
|
|
349
|
+
button:disabled { opacity: .5; cursor: default; }
|
|
350
|
+
button:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: 1px; }
|
|
351
|
+
`;
|
|
352
|
+
var definePrintPreview = definer("office-ui-print-preview", () => {
|
|
353
|
+
class OfficeUiPrintPreview extends HTMLElement {
|
|
354
|
+
static observedAttributes = ["label", "empty-label"];
|
|
355
|
+
#pages = [];
|
|
356
|
+
#index = 0;
|
|
357
|
+
#sheet;
|
|
358
|
+
#nav;
|
|
359
|
+
#previous;
|
|
360
|
+
#next;
|
|
361
|
+
#count;
|
|
362
|
+
constructor() {
|
|
363
|
+
super();
|
|
364
|
+
const doc = this.ownerDocument;
|
|
365
|
+
const root = this.attachShadow({ mode: "open" });
|
|
366
|
+
attachStyles(root, controlCss(CSS3));
|
|
367
|
+
this.#sheet = doc.createElement("div");
|
|
368
|
+
this.#sheet.className = "sheet";
|
|
369
|
+
this.#sheet.setAttribute("role", "img");
|
|
370
|
+
this.#nav = doc.createElement("div");
|
|
371
|
+
this.#nav.className = "nav";
|
|
372
|
+
const button = (label, text2, step) => {
|
|
373
|
+
const element = doc.createElement("button");
|
|
374
|
+
element.type = "button";
|
|
375
|
+
element.setAttribute("aria-label", label);
|
|
376
|
+
element.textContent = text2;
|
|
377
|
+
element.addEventListener("click", () => this.#go(this.#index + step));
|
|
378
|
+
return element;
|
|
379
|
+
};
|
|
380
|
+
this.#previous = button("Previous page", "\u2039", -1);
|
|
381
|
+
this.#next = button("Next page", "\u203A", 1);
|
|
382
|
+
this.#count = doc.createElement("span");
|
|
383
|
+
this.#nav.append(this.#previous, this.#count, this.#next);
|
|
384
|
+
root.append(this.#sheet, this.#nav);
|
|
385
|
+
this.#render();
|
|
386
|
+
}
|
|
387
|
+
attributeChangedCallback() {
|
|
388
|
+
this.#render();
|
|
389
|
+
}
|
|
390
|
+
get pages() {
|
|
391
|
+
return this.#pages;
|
|
392
|
+
}
|
|
393
|
+
set pages(value) {
|
|
394
|
+
this.#pages = value;
|
|
395
|
+
this.#index = Math.min(this.#index, Math.max(0, value.length - 1));
|
|
396
|
+
this.#render();
|
|
397
|
+
}
|
|
398
|
+
get index() {
|
|
399
|
+
return this.#index;
|
|
400
|
+
}
|
|
401
|
+
set index(value) {
|
|
402
|
+
const next = Math.max(0, Math.min(this.#pages.length - 1, Math.trunc(value) || 0));
|
|
403
|
+
if (next === this.#index) return;
|
|
404
|
+
this.#index = next;
|
|
405
|
+
this.#render();
|
|
406
|
+
}
|
|
407
|
+
#go(index) {
|
|
408
|
+
const before = this.#index;
|
|
409
|
+
this.index = index;
|
|
410
|
+
if (this.#index !== before) emit(this, "office-print-preview-page", { index: this.#index });
|
|
411
|
+
}
|
|
412
|
+
#render() {
|
|
413
|
+
const doc = this.ownerDocument;
|
|
414
|
+
const total = this.#pages.length;
|
|
415
|
+
const page = this.#pages[this.#index];
|
|
416
|
+
const label = this.getAttribute("label") ?? "Print preview";
|
|
417
|
+
this.#sheet.setAttribute(
|
|
418
|
+
"aria-label",
|
|
419
|
+
total > 1 ? `${label}, page ${this.#index + 1} of ${total}` : label
|
|
420
|
+
);
|
|
421
|
+
if (!page) {
|
|
422
|
+
const empty = doc.createElement("p");
|
|
423
|
+
empty.className = "empty";
|
|
424
|
+
empty.textContent = this.getAttribute("empty-label") ?? "Nothing to print.";
|
|
425
|
+
this.#sheet.replaceChildren(empty);
|
|
426
|
+
} else {
|
|
427
|
+
const clone = doc.importNode(page, true);
|
|
428
|
+
if (clone instanceof Element) {
|
|
429
|
+
clone.removeAttribute("style");
|
|
430
|
+
clone.removeAttribute("tabindex");
|
|
431
|
+
clone.querySelectorAll("[tabindex]").forEach((node) => node.removeAttribute("tabindex"));
|
|
432
|
+
}
|
|
433
|
+
this.#sheet.replaceChildren(clone);
|
|
434
|
+
}
|
|
435
|
+
this.#nav.hidden = total < 2;
|
|
436
|
+
this.#count.textContent = `${this.#index + 1} of ${total}`;
|
|
437
|
+
this.#previous.disabled = this.#index === 0;
|
|
438
|
+
this.#next.disabled = this.#index >= total - 1;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return OfficeUiPrintPreview;
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// src/ribbon-tabs.ts
|
|
445
|
+
var CSS4 = `
|
|
446
|
+
:host { display: block; min-width: 0; }
|
|
447
|
+
.head { display: flex; align-items: stretch; min-width: 0; border-bottom: 1px solid var(--office-border, #d1d5db); }
|
|
448
|
+
.file { flex: none; min-height: var(--office-ribbon-tab-height, 35px); margin: 0 4px 0 0; padding: 6px 16px; border: 0;
|
|
449
|
+
border-radius: 0; background: var(--office-accent, #2563eb); color: var(--office-accent-foreground, #fff);
|
|
450
|
+
font: inherit; font-size: 13px; cursor: pointer; }
|
|
451
|
+
.file:hover { background: color-mix(in srgb, var(--office-accent, #2563eb) 85%, #000); }
|
|
452
|
+
.file[hidden] { display: none; }
|
|
453
|
+
[role="tablist"] { display: flex; flex: 0 1 auto; align-items: stretch; min-width: 0; overflow-x: auto; scrollbar-width: none; }
|
|
454
|
+
[role="tab"] { position: relative; flex: none; min-height: var(--office-ribbon-tab-height, 35px); padding: 6px 12px; border: 0;
|
|
455
|
+
border-radius: 0; background: transparent; color: var(--office-muted-foreground, #6b7280); font: inherit; font-size: 13px;
|
|
456
|
+
cursor: pointer; }
|
|
457
|
+
[role="tab"]:hover { color: var(--office-foreground, #1f2937); background: var(--office-surface, #f3f4f6); }
|
|
458
|
+
[role="tab"][aria-selected="true"] { color: var(--office-accent, #2563eb); }
|
|
459
|
+
[role="tab"][aria-selected="true"]::after { content: ""; position: absolute; inset: auto 0 0; height: 2.5px;
|
|
460
|
+
background: var(--office-accent, #2563eb); }
|
|
461
|
+
.file:focus-visible, [role="tab"]:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: -2px; }
|
|
462
|
+
::slotted([slot="search"]) { align-self: center; }
|
|
463
|
+
@media (max-width: 760px), (pointer: coarse) {
|
|
464
|
+
.file, [role="tab"] { min-height: 44px; }
|
|
465
|
+
.file { min-width: 52px; }
|
|
466
|
+
}
|
|
467
|
+
@media (forced-colors: active) {
|
|
468
|
+
.file { border: 1px solid ButtonText; }
|
|
469
|
+
[role="tab"][aria-selected="true"]::after { background: Highlight; }
|
|
470
|
+
}
|
|
471
|
+
`;
|
|
472
|
+
var defineRibbon = definer("office-ui-ribbon", () => {
|
|
473
|
+
class OfficeUiRibbon extends HTMLElement {
|
|
474
|
+
static observedAttributes = [
|
|
475
|
+
"selected",
|
|
476
|
+
"label",
|
|
477
|
+
"file-label",
|
|
478
|
+
"no-file",
|
|
479
|
+
"file-expanded",
|
|
480
|
+
"file-keytip"
|
|
481
|
+
];
|
|
482
|
+
#file;
|
|
483
|
+
#tabs;
|
|
484
|
+
#panelSlot;
|
|
485
|
+
constructor() {
|
|
486
|
+
super();
|
|
487
|
+
const doc = this.ownerDocument;
|
|
488
|
+
const root = this.attachShadow({ mode: "open" });
|
|
489
|
+
attachStyles(root, controlCss(CSS4));
|
|
490
|
+
const head = doc.createElement("div");
|
|
491
|
+
head.className = "head";
|
|
492
|
+
head.setAttribute("part", "head");
|
|
493
|
+
const slot = (name) => {
|
|
494
|
+
const element = doc.createElement("slot");
|
|
495
|
+
element.name = name;
|
|
496
|
+
return element;
|
|
497
|
+
};
|
|
498
|
+
this.#file = doc.createElement("button");
|
|
499
|
+
this.#file.type = "button";
|
|
500
|
+
this.#file.className = "file";
|
|
501
|
+
this.#file.setAttribute("part", "file");
|
|
502
|
+
this.#file.setAttribute("aria-haspopup", "dialog");
|
|
503
|
+
this.#file.setAttribute("aria-expanded", "false");
|
|
504
|
+
this.#file.addEventListener("click", () => emit(this, "office-ribbon-file", {}));
|
|
505
|
+
this.#tabs = doc.createElement("div");
|
|
506
|
+
this.#tabs.setAttribute("role", "tablist");
|
|
507
|
+
this.#tabs.setAttribute("part", "tabs");
|
|
508
|
+
this.#tabs.addEventListener("click", (event) => {
|
|
509
|
+
const tab = event.target.closest?.('[role="tab"]');
|
|
510
|
+
if (tab) this.#choose(tab.dataset.tab);
|
|
511
|
+
});
|
|
512
|
+
this.#tabs.addEventListener("keydown", (event) => this.#key(event));
|
|
513
|
+
head.append(slot("quick-access"), this.#file, this.#tabs, slot("search"), slot("end"));
|
|
514
|
+
this.#panelSlot = doc.createElement("slot");
|
|
515
|
+
this.#panelSlot.addEventListener("slotchange", () => this.#build());
|
|
516
|
+
root.append(head, this.#panelSlot);
|
|
517
|
+
this.#syncFile();
|
|
518
|
+
}
|
|
519
|
+
connectedCallback() {
|
|
520
|
+
this.#build();
|
|
521
|
+
}
|
|
522
|
+
attributeChangedCallback(name) {
|
|
523
|
+
if (name === "selected") this.#sync();
|
|
524
|
+
else if (name === "label")
|
|
525
|
+
this.#tabs.setAttribute("aria-label", this.getAttribute("label") ?? "Ribbon");
|
|
526
|
+
else this.#syncFile();
|
|
527
|
+
}
|
|
528
|
+
get selected() {
|
|
529
|
+
return this.getAttribute("selected") ?? this.#panels()[0]?.dataset.ribbonTab ?? "";
|
|
530
|
+
}
|
|
531
|
+
set selected(tab) {
|
|
532
|
+
this.setAttribute("selected", tab);
|
|
533
|
+
}
|
|
534
|
+
/** Focus the File button (for example when the backstage it opened closes). */
|
|
535
|
+
focusFile() {
|
|
536
|
+
this.#file.focus();
|
|
537
|
+
}
|
|
538
|
+
/** Focus the selected tab. */
|
|
539
|
+
focusTab() {
|
|
540
|
+
this.#tabs.querySelector('[aria-selected="true"]')?.focus();
|
|
541
|
+
}
|
|
542
|
+
#panels() {
|
|
543
|
+
return [...this.children].filter(
|
|
544
|
+
(child) => child instanceof HTMLElement && !!child.dataset.ribbonTab
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
#build() {
|
|
548
|
+
const doc = this.ownerDocument;
|
|
549
|
+
if (!this.#tabs.hasAttribute("aria-label"))
|
|
550
|
+
this.#tabs.setAttribute("aria-label", this.getAttribute("label") ?? "Ribbon");
|
|
551
|
+
this.#tabs.replaceChildren(
|
|
552
|
+
...this.#panels().map((panel) => {
|
|
553
|
+
const id = panel.dataset.ribbonTab;
|
|
554
|
+
const tab = doc.createElement("button");
|
|
555
|
+
tab.type = "button";
|
|
556
|
+
tab.setAttribute("role", "tab");
|
|
557
|
+
tab.id = `tab-${id}`;
|
|
558
|
+
tab.dataset.tab = id;
|
|
559
|
+
tab.textContent = panel.dataset.label ?? id;
|
|
560
|
+
if (panel.dataset.tabKeytip) {
|
|
561
|
+
tab.dataset.keytip = panel.dataset.tabKeytip;
|
|
562
|
+
if (panel.id) tab.dataset.keytipPanel = panel.id;
|
|
563
|
+
}
|
|
564
|
+
panel.setAttribute("role", "tabpanel");
|
|
565
|
+
panel.setAttribute("aria-label", panel.dataset.label ?? id);
|
|
566
|
+
return tab;
|
|
567
|
+
})
|
|
568
|
+
);
|
|
569
|
+
this.#sync();
|
|
570
|
+
}
|
|
571
|
+
#sync() {
|
|
572
|
+
const selected = this.selected;
|
|
573
|
+
for (const tab of this.#tabs.querySelectorAll('[role="tab"]')) {
|
|
574
|
+
const on = tab.dataset.tab === selected;
|
|
575
|
+
tab.setAttribute("aria-selected", String(on));
|
|
576
|
+
tab.tabIndex = on ? 0 : -1;
|
|
577
|
+
}
|
|
578
|
+
for (const panel of this.#panels()) panel.hidden = panel.dataset.ribbonTab !== selected;
|
|
579
|
+
}
|
|
580
|
+
#syncFile() {
|
|
581
|
+
this.#file.textContent = this.getAttribute("file-label") ?? "File";
|
|
582
|
+
this.#file.hidden = this.hasAttribute("no-file");
|
|
583
|
+
this.#file.setAttribute(
|
|
584
|
+
"aria-expanded",
|
|
585
|
+
String(this.getAttribute("file-expanded") === "true")
|
|
586
|
+
);
|
|
587
|
+
const keytip = this.getAttribute("file-keytip");
|
|
588
|
+
if (keytip) this.#file.dataset.keytip = keytip;
|
|
589
|
+
else delete this.#file.dataset.keytip;
|
|
590
|
+
}
|
|
591
|
+
#choose(tab) {
|
|
592
|
+
if (tab === this.selected) return;
|
|
593
|
+
if (emit(this, "office-ribbon-select", { tab }, true)) this.selected = tab;
|
|
594
|
+
}
|
|
595
|
+
#key(event) {
|
|
596
|
+
const tabs = [...this.#tabs.querySelectorAll('[role="tab"]')];
|
|
597
|
+
const at = tabs.findIndex((tab) => tab.dataset.tab === this.selected);
|
|
598
|
+
const step = { ArrowRight: 1, ArrowLeft: -1 }[event.key];
|
|
599
|
+
const next = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs.at(-1) : step ? tabs[(at + step + tabs.length) % tabs.length] : void 0;
|
|
600
|
+
if (!next) return;
|
|
601
|
+
event.preventDefault();
|
|
602
|
+
this.#choose(next.dataset.tab);
|
|
603
|
+
this.focusTab();
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return OfficeUiRibbon;
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
// src/ruler.ts
|
|
610
|
+
var CSS5 = `
|
|
611
|
+
:host { display: block; box-sizing: border-box; background: var(--office-background, #fff);
|
|
612
|
+
color: var(--office-muted-foreground, #605e5c); overflow: hidden; }
|
|
613
|
+
:host(:not([orientation="vertical"])) { height: 18px; border-bottom: 1px solid var(--office-border, #d1d5db); }
|
|
614
|
+
:host([orientation="vertical"]) { width: 18px; border-inline-end: 1px solid var(--office-border, #d1d5db); }
|
|
615
|
+
canvas { display: block; width: 100%; height: 100%; }
|
|
616
|
+
`;
|
|
617
|
+
function rulerDivisions(unitPixels) {
|
|
618
|
+
return unitPixels >= 192 ? 16 : unitPixels >= 96 ? 8 : unitPixels >= 48 ? 4 : 2;
|
|
619
|
+
}
|
|
620
|
+
var defineRuler = definer("office-ui-ruler", () => {
|
|
621
|
+
class OfficeUiRuler extends HTMLElement {
|
|
622
|
+
static observedAttributes = ["orientation", "origin", "scale", "direction"];
|
|
623
|
+
#canvas;
|
|
624
|
+
#frame = 0;
|
|
625
|
+
#observer;
|
|
626
|
+
constructor() {
|
|
627
|
+
super();
|
|
628
|
+
const root = this.attachShadow({ mode: "open" });
|
|
629
|
+
attachStyles(root, controlCss(CSS5));
|
|
630
|
+
this.#canvas = this.ownerDocument.createElement("canvas");
|
|
631
|
+
root.append(this.#canvas);
|
|
632
|
+
}
|
|
633
|
+
connectedCallback() {
|
|
634
|
+
this.setAttribute("aria-hidden", "true");
|
|
635
|
+
const Observer = this.ownerDocument.defaultView?.ResizeObserver;
|
|
636
|
+
this.#observer = Observer ? new Observer(() => this.#schedule()) : void 0;
|
|
637
|
+
this.#observer?.observe(this);
|
|
638
|
+
this.#schedule();
|
|
639
|
+
}
|
|
640
|
+
disconnectedCallback() {
|
|
641
|
+
this.#observer?.disconnect();
|
|
642
|
+
if (this.#frame) this.ownerDocument.defaultView?.cancelAnimationFrame?.(this.#frame);
|
|
643
|
+
this.#frame = 0;
|
|
644
|
+
}
|
|
645
|
+
attributeChangedCallback() {
|
|
646
|
+
this.#schedule();
|
|
647
|
+
}
|
|
648
|
+
#number(name, fallback) {
|
|
649
|
+
const value = Number(this.getAttribute(name));
|
|
650
|
+
return this.hasAttribute(name) && Number.isFinite(value) ? value : fallback;
|
|
651
|
+
}
|
|
652
|
+
#schedule() {
|
|
653
|
+
if (this.#frame || !this.isConnected) return;
|
|
654
|
+
const view = this.ownerDocument.defaultView;
|
|
655
|
+
this.#frame = view?.requestAnimationFrame?.(() => this.#draw()) ?? 0;
|
|
656
|
+
if (!this.#frame) this.#draw();
|
|
657
|
+
}
|
|
658
|
+
#draw() {
|
|
659
|
+
this.#frame = 0;
|
|
660
|
+
const view = this.ownerDocument.defaultView;
|
|
661
|
+
const vertical = this.getAttribute("orientation") === "vertical";
|
|
662
|
+
const reverse = this.getAttribute("direction") === "reverse";
|
|
663
|
+
const box = this.getBoundingClientRect();
|
|
664
|
+
const length = vertical ? box.height : box.width;
|
|
665
|
+
const thickness = (vertical ? box.width : box.height) || 18;
|
|
666
|
+
const ratio = view?.devicePixelRatio ?? 1;
|
|
667
|
+
const canvas = this.#canvas;
|
|
668
|
+
canvas.width = Math.max(1, Math.round((vertical ? thickness : length) * ratio));
|
|
669
|
+
canvas.height = Math.max(1, Math.round((vertical ? length : thickness) * ratio));
|
|
670
|
+
const context = canvas.getContext?.("2d");
|
|
671
|
+
if (!context || !length) return;
|
|
672
|
+
context.scale(ratio, ratio);
|
|
673
|
+
const ink = view?.getComputedStyle(this).color || "#605e5c";
|
|
674
|
+
context.strokeStyle = ink;
|
|
675
|
+
context.fillStyle = ink;
|
|
676
|
+
context.lineWidth = 1;
|
|
677
|
+
context.font = `9px ${view?.getComputedStyle(this).fontFamily || "system-ui, sans-serif"}`;
|
|
678
|
+
const origin = this.#number("origin", 0);
|
|
679
|
+
const unit = Math.max(1, this.#number("scale", 96));
|
|
680
|
+
const divisions = rulerDivisions(unit);
|
|
681
|
+
const step = unit / divisions;
|
|
682
|
+
const sign = reverse ? -1 : 1;
|
|
683
|
+
const a = (0 - origin) / (sign * step);
|
|
684
|
+
const b = (length - origin) / (sign * step);
|
|
685
|
+
const first = Math.floor(Math.min(a, b)) - 1;
|
|
686
|
+
const last = Math.ceil(Math.max(a, b)) + 1;
|
|
687
|
+
context.beginPath();
|
|
688
|
+
for (let index = first; index <= last; index++) {
|
|
689
|
+
const at = Math.round(origin + sign * index * step) + 0.5;
|
|
690
|
+
const tick = index % divisions === 0 ? thickness : index % (divisions / 2) === 0 ? thickness * 0.5 : thickness * 0.3;
|
|
691
|
+
if (vertical) {
|
|
692
|
+
context.moveTo(thickness, at);
|
|
693
|
+
context.lineTo(thickness - tick, at);
|
|
694
|
+
} else {
|
|
695
|
+
context.moveTo(at, thickness);
|
|
696
|
+
context.lineTo(at, thickness - tick);
|
|
697
|
+
}
|
|
698
|
+
if (index % divisions !== 0) continue;
|
|
699
|
+
const label = String(index / divisions);
|
|
700
|
+
if (!vertical) context.fillText(label, at + 2, 9);
|
|
701
|
+
else {
|
|
702
|
+
context.save();
|
|
703
|
+
context.translate(9, at - 2);
|
|
704
|
+
context.rotate(-Math.PI / 2);
|
|
705
|
+
context.fillText(label, 0, 0);
|
|
706
|
+
context.restore();
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
context.stroke();
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
return OfficeUiRuler;
|
|
713
|
+
});
|
|
714
|
+
|
|
5
715
|
// src/account.ts
|
|
6
716
|
var DEFAULT_OFFICE_PROFILE = { displayName: "", avatarColor: "#6366f1" };
|
|
7
717
|
var OFFICE_AVATAR_SWATCHES = [
|
|
@@ -52,7 +762,7 @@ function clearOfficeProfile(storage = defaultStorage(), key = OFFICE_PROFILE_STO
|
|
|
52
762
|
} catch {
|
|
53
763
|
}
|
|
54
764
|
}
|
|
55
|
-
var
|
|
765
|
+
var CSS6 = `
|
|
56
766
|
:host { display: block; font-family: var(--office-font, system-ui, sans-serif); font-size: 13px; }
|
|
57
767
|
h2 { margin: 0 0 12px; font-size: 15px; font-weight: 600; }
|
|
58
768
|
.who { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
|
|
@@ -82,7 +792,7 @@ var defineAccount = definer("office-ui-account", () => {
|
|
|
82
792
|
super();
|
|
83
793
|
const doc = this.ownerDocument;
|
|
84
794
|
const root = this.attachShadow({ mode: "open" });
|
|
85
|
-
attachStyles(root, controlCss(
|
|
795
|
+
attachStyles(root, controlCss(CSS6));
|
|
86
796
|
const heading = doc.createElement("h2");
|
|
87
797
|
heading.textContent = "User Information";
|
|
88
798
|
const who = doc.createElement("div");
|
|
@@ -183,7 +893,7 @@ var defineAccount = definer("office-ui-account", () => {
|
|
|
183
893
|
});
|
|
184
894
|
|
|
185
895
|
// src/button.ts
|
|
186
|
-
var
|
|
896
|
+
var CSS7 = `
|
|
187
897
|
:host { display: inline-flex; vertical-align: middle; }
|
|
188
898
|
button { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
|
|
189
899
|
gap: 6px; min-width: var(--office-target-size, 28px); min-height: var(--office-target-size, 28px);
|
|
@@ -224,7 +934,7 @@ var defineButton = definer("office-ui-button", () => {
|
|
|
224
934
|
constructor() {
|
|
225
935
|
super();
|
|
226
936
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
227
|
-
attachStyles(root, controlCss(
|
|
937
|
+
attachStyles(root, controlCss(CSS7));
|
|
228
938
|
this.button = this.ownerDocument.createElement("button");
|
|
229
939
|
this.button.type = "button";
|
|
230
940
|
this.button.setAttribute("part", "button");
|
|
@@ -399,7 +1109,7 @@ var defineCheckbox = definer(
|
|
|
399
1109
|
var defineSwitch = definer("office-ui-switch", makeCheckable("switch", SWITCH_CSS));
|
|
400
1110
|
|
|
401
1111
|
// src/dialog.ts
|
|
402
|
-
var
|
|
1112
|
+
var CSS8 = `
|
|
403
1113
|
:host { display: none; position: fixed; inset: 0; z-index: 1000; align-items: center; justify-content: center; }
|
|
404
1114
|
:host([open]) { display: flex; }
|
|
405
1115
|
.backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / .4); }
|
|
@@ -432,7 +1142,7 @@ var defineDialog = definer("office-ui-dialog", () => {
|
|
|
432
1142
|
super();
|
|
433
1143
|
const doc = this.ownerDocument;
|
|
434
1144
|
const root = this.attachShadow({ mode: "open" });
|
|
435
|
-
attachStyles(root, controlCss(
|
|
1145
|
+
attachStyles(root, controlCss(CSS8));
|
|
436
1146
|
const backdrop = doc.createElement("div");
|
|
437
1147
|
backdrop.className = "backdrop";
|
|
438
1148
|
this.box = doc.createElement("div");
|
|
@@ -535,7 +1245,7 @@ var defineDialog = definer("office-ui-dialog", () => {
|
|
|
535
1245
|
});
|
|
536
1246
|
|
|
537
1247
|
// src/command-search.ts
|
|
538
|
-
var
|
|
1248
|
+
var CSS9 = `
|
|
539
1249
|
:host { display: inline-flex; align-items: center; min-width: 0; font-family: var(--office-font, system-ui, sans-serif); }
|
|
540
1250
|
.field { display: flex; align-items: center; gap: 6px; width: 100%; min-width: 0; height: var(--office-target-size, 28px);
|
|
541
1251
|
padding: 0 8px; box-sizing: border-box; border: 1px solid transparent; border-radius: var(--office-radius, 4px);
|
|
@@ -575,7 +1285,7 @@ var defineCommandSearch = definer("office-ui-command-search", () => {
|
|
|
575
1285
|
super();
|
|
576
1286
|
const doc = this.ownerDocument;
|
|
577
1287
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
578
|
-
attachStyles(root, controlCss(
|
|
1288
|
+
attachStyles(root, controlCss(CSS9));
|
|
579
1289
|
const field = doc.createElement("div");
|
|
580
1290
|
field.className = "field";
|
|
581
1291
|
const glass = createIconSvg(doc);
|
|
@@ -732,7 +1442,7 @@ var defineCommandSearch = definer("office-ui-command-search", () => {
|
|
|
732
1442
|
});
|
|
733
1443
|
|
|
734
1444
|
// src/context-menu.ts
|
|
735
|
-
var
|
|
1445
|
+
var CSS10 = `
|
|
736
1446
|
:host { display: contents; }
|
|
737
1447
|
.panel { position: fixed; inset: auto; margin: 0; min-width: 200px; padding: 4px; box-sizing: border-box;
|
|
738
1448
|
background: var(--office-background, #fff); color: var(--office-foreground, #1f2937);
|
|
@@ -768,7 +1478,7 @@ var defineContextMenu = definer("office-ui-context-menu", () => {
|
|
|
768
1478
|
super();
|
|
769
1479
|
const doc = this.ownerDocument;
|
|
770
1480
|
const root = this.attachShadow({ mode: "open" });
|
|
771
|
-
attachStyles(root, controlCss(
|
|
1481
|
+
attachStyles(root, controlCss(CSS10));
|
|
772
1482
|
this.panel = doc.createElement("div");
|
|
773
1483
|
this.panel.className = "panel";
|
|
774
1484
|
this.panel.setAttribute("role", "menu");
|
|
@@ -1178,7 +1888,7 @@ function clampOptionNumber(raw, min, max) {
|
|
|
1178
1888
|
const parsed = Number(raw);
|
|
1179
1889
|
return Number.isFinite(parsed) && raw.trim() !== "" ? Math.min(max, Math.max(min, parsed)) : void 0;
|
|
1180
1890
|
}
|
|
1181
|
-
var
|
|
1891
|
+
var CSS11 = `
|
|
1182
1892
|
:host { display: contents; }
|
|
1183
1893
|
office-ui-dialog { --office-dialog-width: min(820px, 100vw); --office-dialog-max-width: min(820px, 100vw); }
|
|
1184
1894
|
.layout { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 0; min-height: min(440px, 70vh); margin: -16px; }
|
|
@@ -1227,7 +1937,7 @@ var defineOptionsDialog = definer("office-ui-options-dialog", () => {
|
|
|
1227
1937
|
super();
|
|
1228
1938
|
const doc = this.ownerDocument;
|
|
1229
1939
|
const root = this.attachShadow({ mode: "open" });
|
|
1230
|
-
attachStyles(root, controlCss(
|
|
1940
|
+
attachStyles(root, controlCss(CSS11));
|
|
1231
1941
|
this.#dialog = doc.createElement("office-ui-dialog");
|
|
1232
1942
|
const layout = doc.createElement("div");
|
|
1233
1943
|
layout.className = "layout";
|
|
@@ -1572,7 +2282,7 @@ var defineToolbar = definer("office-ui-toolbar", () => {
|
|
|
1572
2282
|
});
|
|
1573
2283
|
|
|
1574
2284
|
// src/select.ts
|
|
1575
|
-
var
|
|
2285
|
+
var CSS12 = `
|
|
1576
2286
|
:host { display: inline-block; position: relative; vertical-align: middle; }
|
|
1577
2287
|
button { box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
|
1578
2288
|
width: 100%; min-height: var(--office-target-size, 28px); padding: 0 8px; font: inherit; font-size: 12px;
|
|
@@ -1611,7 +2321,7 @@ var defineSelect = definer("office-ui-select", () => {
|
|
|
1611
2321
|
super();
|
|
1612
2322
|
const doc = this.ownerDocument;
|
|
1613
2323
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
1614
|
-
attachStyles(root, controlCss(
|
|
2324
|
+
attachStyles(root, controlCss(CSS12));
|
|
1615
2325
|
this.trigger = doc.createElement("button");
|
|
1616
2326
|
this.trigger.type = "button";
|
|
1617
2327
|
this.trigger.setAttribute("role", "combobox");
|
|
@@ -1862,7 +2572,7 @@ var defineStatusItem = definer("office-ui-status-item", () => {
|
|
|
1862
2572
|
});
|
|
1863
2573
|
|
|
1864
2574
|
// src/tab-strip.ts
|
|
1865
|
-
var
|
|
2575
|
+
var CSS13 = `
|
|
1866
2576
|
:host { display: flex; align-items: stretch; min-width: 0; min-height: 28px; gap: 2px; padding: 0 6px;
|
|
1867
2577
|
background: var(--office-surface, #f3f4f6); color: var(--office-muted-foreground, #6b7280);
|
|
1868
2578
|
border-top: 1px solid var(--office-border, #d1d5db); font-size: 12px;
|
|
@@ -1909,7 +2619,7 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
|
|
|
1909
2619
|
super();
|
|
1910
2620
|
const doc = this.ownerDocument;
|
|
1911
2621
|
const root = this.attachShadow({ mode: "open" });
|
|
1912
|
-
attachStyles(root, controlCss(
|
|
2622
|
+
attachStyles(root, controlCss(CSS13));
|
|
1913
2623
|
const step = (name, icon) => {
|
|
1914
2624
|
const button = doc.createElement("button");
|
|
1915
2625
|
button.type = "button";
|
|
@@ -2048,7 +2758,7 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
|
|
|
2048
2758
|
});
|
|
2049
2759
|
|
|
2050
2760
|
// src/zoom-slider.ts
|
|
2051
|
-
var
|
|
2761
|
+
var CSS14 = `
|
|
2052
2762
|
:host { display: inline-flex; align-items: center; gap: 2px; font-size: 11px;
|
|
2053
2763
|
color: var(--office-foreground, #1f2937); font-family: var(--office-font, system-ui, sans-serif); }
|
|
2054
2764
|
button { box-sizing: border-box; display: inline-grid; place-items: center; min-width: var(--office-target-size, 24px);
|
|
@@ -2084,7 +2794,7 @@ var defineZoomSlider = definer("office-ui-zoom-slider", () => {
|
|
|
2084
2794
|
super();
|
|
2085
2795
|
const doc = this.ownerDocument;
|
|
2086
2796
|
const root = this.attachShadow({ mode: "open" });
|
|
2087
|
-
attachStyles(root, controlCss(
|
|
2797
|
+
attachStyles(root, controlCss(CSS14));
|
|
2088
2798
|
const button = (name, text2) => {
|
|
2089
2799
|
const element = doc.createElement("button");
|
|
2090
2800
|
element.type = "button";
|
|
@@ -2186,6 +2896,19 @@ var visible = (el) => {
|
|
|
2186
2896
|
const box = el.getBoundingClientRect();
|
|
2187
2897
|
return box.width > 0 && box.height > 0;
|
|
2188
2898
|
};
|
|
2899
|
+
function deepTips(root) {
|
|
2900
|
+
const found = [...root.querySelectorAll("[data-keytip]")];
|
|
2901
|
+
for (const host of root.querySelectorAll("*")) {
|
|
2902
|
+
const shadow = host.shadowRoot;
|
|
2903
|
+
if (!shadow) continue;
|
|
2904
|
+
const inner = deepTips(shadow);
|
|
2905
|
+
if (!inner.length) continue;
|
|
2906
|
+
for (const el of inner) hostOf.set(el, host);
|
|
2907
|
+
found.push(...inner);
|
|
2908
|
+
}
|
|
2909
|
+
return found;
|
|
2910
|
+
}
|
|
2911
|
+
var hostOf = /* @__PURE__ */ new WeakMap();
|
|
2189
2912
|
function activate(el) {
|
|
2190
2913
|
const inner = el.shadowRoot?.querySelector(".main, button");
|
|
2191
2914
|
(inner ?? el).click();
|
|
@@ -2203,8 +2926,8 @@ function attachKeyTips(scope) {
|
|
|
2203
2926
|
let levels = [];
|
|
2204
2927
|
let typed = "";
|
|
2205
2928
|
let altAlone = false;
|
|
2206
|
-
const tipsAt = (container) =>
|
|
2207
|
-
const owner = el.parentElement?.closest("[data-keytip-level]") ?? null;
|
|
2929
|
+
const tipsAt = (container) => deepTips(container ?? scope).filter((el) => {
|
|
2930
|
+
const owner = (hostOf.get(el) ?? el.parentElement)?.closest("[data-keytip-level]") ?? null;
|
|
2208
2931
|
return owner === container && visible(el);
|
|
2209
2932
|
});
|
|
2210
2933
|
const current = () => tipsAt(levels.at(-1) ?? null);
|
|
@@ -2333,10 +3056,15 @@ var CONTROL_DEFINERS = [
|
|
|
2333
3056
|
defineZoomSlider,
|
|
2334
3057
|
defineTabStrip,
|
|
2335
3058
|
defineOptionsDialog,
|
|
2336
|
-
defineAccount
|
|
3059
|
+
defineAccount,
|
|
3060
|
+
defineRibbon,
|
|
3061
|
+
defineFindBar,
|
|
3062
|
+
defineRuler,
|
|
3063
|
+
defineBackstage,
|
|
3064
|
+
definePrintPreview
|
|
2337
3065
|
];
|
|
2338
3066
|
function registerControls(registry) {
|
|
2339
3067
|
for (const define of CONTROL_DEFINERS) define(registry);
|
|
2340
3068
|
}
|
|
2341
3069
|
|
|
2342
|
-
export { CONTROL_DEFINERS, DEFAULT_OFFICE_PROFILE, OFFICE_AVATAR_SWATCHES, OFFICE_PROFILE_STORAGE_KEY, attachKeyTips, clampOptionNumber, clearOfficeProfile, defineAccount, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, profileInitials, readOfficeProfile, registerControls, sanitizeOfficeProfile, writeOfficeProfile };
|
|
3070
|
+
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 };
|
package/dist/controls.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { defineBackstage } from './backstage.js';
|
|
2
|
+
import { defineFindBar } from './find-bar.js';
|
|
3
|
+
import { definePrintPreview } from './print-preview.js';
|
|
4
|
+
import { defineRibbon } from './ribbon-tabs.js';
|
|
5
|
+
import { defineRuler } from './ruler.js';
|
|
1
6
|
import { defineAccount } from './account.js';
|
|
2
7
|
import { defineButton } from './button.js';
|
|
3
8
|
import { defineCheckbox, defineSwitch } from './checkable.js';
|
|
@@ -12,7 +17,7 @@ import { defineSelect } from './select.js';
|
|
|
12
17
|
import { defineStatusBar, defineStatusItem } from './status-bar.js';
|
|
13
18
|
import { defineTabStrip } from './tab-strip.js';
|
|
14
19
|
import { defineZoomSlider } from './zoom-slider.js';
|
|
15
|
-
export { defineAccount, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineIcon, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, };
|
|
20
|
+
export { defineAccount, defineBackstage, defineFindBar, definePrintPreview, defineRibbon, defineRuler, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineIcon, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, };
|
|
16
21
|
export type { OfficeCommandEvent } from './button.js';
|
|
17
22
|
export type { OfficeDialogCloseEvent, OfficeDialogCloseReason } from './dialog.js';
|
|
18
23
|
export type { OfficeSelectOption } from './select.js';
|
|
@@ -20,9 +25,14 @@ export type { OfficeStatusActivateEvent } from './status-bar.js';
|
|
|
20
25
|
export type { OfficeTab, OfficeTabSelectEvent } from './tab-strip.js';
|
|
21
26
|
export type { OfficeSearchCommand } from './command-search.js';
|
|
22
27
|
export { attachKeyTips, type KeyTipsHandle } from './keytips.js';
|
|
28
|
+
export type { OfficeBackstageCloseEvent, OfficeBackstageItem, OfficeBackstageSelectEvent, } from './backstage.js';
|
|
29
|
+
export type { OfficeFindInputEvent, OfficeFindStepEvent } from './find-bar.js';
|
|
30
|
+
export type { OfficePrintPreviewPageEvent } from './print-preview.js';
|
|
31
|
+
export type { OfficeRibbonSelectEvent } from './ribbon-tabs.js';
|
|
32
|
+
export { rulerDivisions } from './ruler.js';
|
|
23
33
|
export { clearOfficeProfile, DEFAULT_OFFICE_PROFILE, OFFICE_AVATAR_SWATCHES, OFFICE_PROFILE_STORAGE_KEY, profileInitials, readOfficeProfile, sanitizeOfficeProfile, writeOfficeProfile, type OfficeProfile, type OfficeProfileChangeEvent, } from './account.js';
|
|
24
34
|
export { clampOptionNumber, type OfficeOptionCategory, type OfficeOptionChoice, type OfficeOptionControl, type OfficeOptionSection, type OfficeOptionsChangeEvent, type OfficeOptionValue, type OfficeOptionValues, } from './options.js';
|
|
25
35
|
/** Every control of this entry. */
|
|
26
|
-
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, import("./registry.js").Definer, import("./registry.js").Definer, import("./registry.js").Definer];
|
|
36
|
+
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, 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];
|
|
27
37
|
/** Idempotent, SSR-safe (no-op without a DOM). */
|
|
28
38
|
export declare function registerControls(registry?: CustomElementRegistry): void;
|
package/dist/controls.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { CONTROL_DEFINERS, DEFAULT_OFFICE_PROFILE, OFFICE_AVATAR_SWATCHES, OFFICE_PROFILE_STORAGE_KEY, attachKeyTips, clampOptionNumber, clearOfficeProfile, defineAccount, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, profileInitials, readOfficeProfile, registerControls, sanitizeOfficeProfile, writeOfficeProfile } from './chunk-
|
|
1
|
+
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 } from './chunk-5YR7YA57.js';
|
|
2
2
|
export { defineIcon } from './chunk-PCSUQPMC.js';
|
|
3
3
|
import './chunk-RLPL7Q6J.js';
|
|
4
4
|
import './chunk-EY266IK3.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type OfficeFindInputEvent = CustomEvent<{
|
|
2
|
+
query: string;
|
|
3
|
+
}>;
|
|
4
|
+
export type OfficeFindStepEvent = CustomEvent<{
|
|
5
|
+
direction: 'next' | 'previous';
|
|
6
|
+
}>;
|
|
7
|
+
/**
|
|
8
|
+
* `<office-ui-find-bar>`: Office's on-demand Find bar under the ribbon. Shown while `open`;
|
|
9
|
+
* `show()` opens it and selects the query. Enter steps to the next result, Shift+Enter to the
|
|
10
|
+
* previous; Escape clears a query, or closes the bar when it is already empty. Attributes:
|
|
11
|
+
* `open`, `label`, `input-label`, `placeholder`, `maxlength`, `disabled`, `navigation-disabled`,
|
|
12
|
+
* `previous-label`, `next-label`, `close-label`. Properties: `value`, `status`, `statusTitle`.
|
|
13
|
+
* Events: `office-find-input` `{ query }`, `office-find-step` `{ direction }`, `office-find-close`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const defineFindBar: import("./registry.js").Definer;
|
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-menu-separator", "office-ui-context-menu", "office-ui-command-search", "office-ui-toolbar", "office-ui-dialog", "office-ui-status-bar", "office-ui-status-item", "office-ui-zoom-slider", "office-ui-tab-strip", "office-ui-options-dialog", "office-ui-account", "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-command-search", "office-ui-toolbar", "office-ui-dialog", "office-ui-status-bar", "office-ui-status-item", "office-ui-zoom-slider", "office-ui-tab-strip", "office-ui-options-dialog", "office-ui-account", "office-ui-ribbon", "office-ui-find-bar", "office-ui-ruler", "office-ui-backstage", "office-ui-print-preview", "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-
|
|
4
|
-
export { CONTROL_DEFINERS, DEFAULT_OFFICE_PROFILE, OFFICE_AVATAR_SWATCHES, OFFICE_PROFILE_STORAGE_KEY, attachKeyTips, clampOptionNumber, clearOfficeProfile, defineAccount, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, profileInitials, readOfficeProfile, registerControls, sanitizeOfficeProfile, writeOfficeProfile } from './chunk-
|
|
3
|
+
import { registerControls } from './chunk-5YR7YA57.js';
|
|
4
|
+
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 } from './chunk-5YR7YA57.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';
|
|
@@ -31,6 +31,11 @@ var OFFICE_UI_TAGS = [
|
|
|
31
31
|
"office-ui-tab-strip",
|
|
32
32
|
"office-ui-options-dialog",
|
|
33
33
|
"office-ui-account",
|
|
34
|
+
"office-ui-ribbon",
|
|
35
|
+
"office-ui-find-bar",
|
|
36
|
+
"office-ui-ruler",
|
|
37
|
+
"office-ui-backstage",
|
|
38
|
+
"office-ui-print-preview",
|
|
34
39
|
"office-ui-presence",
|
|
35
40
|
"office-ui-smartart"
|
|
36
41
|
];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type OfficePrintPreviewPageEvent = CustomEvent<{
|
|
2
|
+
index: number;
|
|
3
|
+
}>;
|
|
4
|
+
/**
|
|
5
|
+
* `<office-ui-print-preview>`: the Print page's paper preview with page navigation. Set `pages`
|
|
6
|
+
* to rendered nodes (for example the SVG of each page); the element shows a deep clone of the
|
|
7
|
+
* current one with `tabindex` and inline `style` removed, so the preview is inert and never
|
|
8
|
+
* parses markup. `index` selects the page; the arrows emit `office-print-preview-page`.
|
|
9
|
+
* Attributes: `label` (default "Print preview"), `empty-label`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const definePrintPreview: import("./registry.js").Definer;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Emitted when the user picks a tab; cancelable (`preventDefault()` keeps the current tab). */
|
|
2
|
+
export type OfficeRibbonSelectEvent = CustomEvent<{
|
|
3
|
+
tab: string;
|
|
4
|
+
}>;
|
|
5
|
+
/**
|
|
6
|
+
* `<office-ui-ribbon>`: the Office tab row (Quick Access Toolbar, File, tabs, search) over the
|
|
7
|
+
* tab panels. Panels are light-DOM children carrying `data-ribbon-tab` (id), `data-label` and
|
|
8
|
+
* optionally `data-tab-keytip`; the element builds the tabs from them, keeps exactly one panel
|
|
9
|
+
* visible and moves between tabs with the arrow keys, Home and End. Slots: `quick-access`,
|
|
10
|
+
* `search`, `end`. Attributes: `selected`, `label` (tab list name), `file-label` (default "File"),
|
|
11
|
+
* `no-file`, `file-expanded`, `file-keytip`. Events: `office-ribbon-select` `{ tab }`
|
|
12
|
+
* (cancelable) and `office-ribbon-file` when File is activated.
|
|
13
|
+
*/
|
|
14
|
+
export declare const defineRibbon: import("./registry.js").Definer;
|
package/dist/ruler.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Tick subdivisions per unit for a given unit length in CSS pixels, finer as it grows. */
|
|
2
|
+
export declare function rulerDivisions(unitPixels: number): number;
|
|
3
|
+
/**
|
|
4
|
+
* `<office-ui-ruler>`: a decorative Office ruler (inches by default). The product positions it
|
|
5
|
+
* and says where zero is: `origin` is the CSS-pixel offset of zero from the ruler's start edge,
|
|
6
|
+
* `scale` the CSS pixels per unit (96 at 100% for inches). `orientation="vertical"` draws a
|
|
7
|
+
* side ruler; `direction="reverse"` makes values grow toward the start edge, as Visio's
|
|
8
|
+
* vertical ruler grows upward from the page bottom. Hidden from assistive technology.
|
|
9
|
+
*/
|
|
10
|
+
export declare const defineRuler: import("./registry.js").Definer;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ooxml-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.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.
|
|
73
|
+
"ooxml-core": "^0.14.1"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@types/jsdom": "^21.1.7",
|