ooxml-ui 0.9.1 → 0.10.1
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-27XQVGRI.js} +751 -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,717 @@ 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 focused = event.target.closest?.('[role="tab"]');
|
|
598
|
+
const at = focused ? tabs.indexOf(focused) : tabs.findIndex((tab) => tab.dataset.tab === this.selected);
|
|
599
|
+
const step = { ArrowRight: 1, ArrowLeft: -1 }[event.key];
|
|
600
|
+
const next = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs.at(-1) : step ? tabs[(at + step + tabs.length) % tabs.length] : void 0;
|
|
601
|
+
if (!next) return;
|
|
602
|
+
event.preventDefault();
|
|
603
|
+
this.#choose(next.dataset.tab);
|
|
604
|
+
this.focusTab();
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return OfficeUiRibbon;
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
// src/ruler.ts
|
|
611
|
+
var CSS5 = `
|
|
612
|
+
:host { display: block; box-sizing: border-box; background: var(--office-background, #fff);
|
|
613
|
+
color: var(--office-muted-foreground, #605e5c); overflow: hidden; }
|
|
614
|
+
:host(:not([orientation="vertical"])) { height: 18px; border-bottom: 1px solid var(--office-border, #d1d5db); }
|
|
615
|
+
:host([orientation="vertical"]) { width: 18px; border-inline-end: 1px solid var(--office-border, #d1d5db); }
|
|
616
|
+
canvas { display: block; width: 100%; height: 100%; }
|
|
617
|
+
`;
|
|
618
|
+
function rulerDivisions(unitPixels) {
|
|
619
|
+
return unitPixels >= 192 ? 16 : unitPixels >= 96 ? 8 : unitPixels >= 48 ? 4 : 2;
|
|
620
|
+
}
|
|
621
|
+
var defineRuler = definer("office-ui-ruler", () => {
|
|
622
|
+
class OfficeUiRuler extends HTMLElement {
|
|
623
|
+
static observedAttributes = ["orientation", "origin", "scale", "direction"];
|
|
624
|
+
#canvas;
|
|
625
|
+
#frame = 0;
|
|
626
|
+
#observer;
|
|
627
|
+
constructor() {
|
|
628
|
+
super();
|
|
629
|
+
const root = this.attachShadow({ mode: "open" });
|
|
630
|
+
attachStyles(root, controlCss(CSS5));
|
|
631
|
+
this.#canvas = this.ownerDocument.createElement("canvas");
|
|
632
|
+
root.append(this.#canvas);
|
|
633
|
+
}
|
|
634
|
+
connectedCallback() {
|
|
635
|
+
this.setAttribute("aria-hidden", "true");
|
|
636
|
+
const Observer = this.ownerDocument.defaultView?.ResizeObserver;
|
|
637
|
+
this.#observer = Observer ? new Observer(() => this.#schedule()) : void 0;
|
|
638
|
+
this.#observer?.observe(this);
|
|
639
|
+
this.#schedule();
|
|
640
|
+
}
|
|
641
|
+
disconnectedCallback() {
|
|
642
|
+
this.#observer?.disconnect();
|
|
643
|
+
if (this.#frame) this.ownerDocument.defaultView?.cancelAnimationFrame?.(this.#frame);
|
|
644
|
+
this.#frame = 0;
|
|
645
|
+
}
|
|
646
|
+
attributeChangedCallback() {
|
|
647
|
+
this.#schedule();
|
|
648
|
+
}
|
|
649
|
+
#number(name, fallback) {
|
|
650
|
+
const value = Number(this.getAttribute(name));
|
|
651
|
+
return this.hasAttribute(name) && Number.isFinite(value) ? value : fallback;
|
|
652
|
+
}
|
|
653
|
+
#schedule() {
|
|
654
|
+
if (this.#frame || !this.isConnected) return;
|
|
655
|
+
const view = this.ownerDocument.defaultView;
|
|
656
|
+
this.#frame = view?.requestAnimationFrame?.(() => this.#draw()) ?? 0;
|
|
657
|
+
if (!this.#frame) this.#draw();
|
|
658
|
+
}
|
|
659
|
+
#draw() {
|
|
660
|
+
this.#frame = 0;
|
|
661
|
+
const view = this.ownerDocument.defaultView;
|
|
662
|
+
const vertical = this.getAttribute("orientation") === "vertical";
|
|
663
|
+
const reverse = this.getAttribute("direction") === "reverse";
|
|
664
|
+
const box = this.getBoundingClientRect();
|
|
665
|
+
const length = vertical ? box.height : box.width;
|
|
666
|
+
const thickness = (vertical ? box.width : box.height) || 18;
|
|
667
|
+
const ratio = view?.devicePixelRatio ?? 1;
|
|
668
|
+
const canvas = this.#canvas;
|
|
669
|
+
canvas.width = Math.max(1, Math.round((vertical ? thickness : length) * ratio));
|
|
670
|
+
canvas.height = Math.max(1, Math.round((vertical ? length : thickness) * ratio));
|
|
671
|
+
const context = canvas.getContext?.("2d");
|
|
672
|
+
if (!context || !length) return;
|
|
673
|
+
context.scale(ratio, ratio);
|
|
674
|
+
const ink = view?.getComputedStyle(this).color || "#605e5c";
|
|
675
|
+
context.strokeStyle = ink;
|
|
676
|
+
context.fillStyle = ink;
|
|
677
|
+
context.lineWidth = 1;
|
|
678
|
+
context.font = `9px ${view?.getComputedStyle(this).fontFamily || "system-ui, sans-serif"}`;
|
|
679
|
+
const origin = this.#number("origin", 0);
|
|
680
|
+
const unit = Math.max(1, this.#number("scale", 96));
|
|
681
|
+
const divisions = rulerDivisions(unit);
|
|
682
|
+
const step = unit / divisions;
|
|
683
|
+
const sign = reverse ? -1 : 1;
|
|
684
|
+
const a = (0 - origin) / (sign * step);
|
|
685
|
+
const b = (length - origin) / (sign * step);
|
|
686
|
+
const first = Math.floor(Math.min(a, b)) - 1;
|
|
687
|
+
const last = Math.ceil(Math.max(a, b)) + 1;
|
|
688
|
+
context.beginPath();
|
|
689
|
+
for (let index = first; index <= last; index++) {
|
|
690
|
+
const at = Math.round(origin + sign * index * step) + 0.5;
|
|
691
|
+
const tick = index % divisions === 0 ? thickness : index % (divisions / 2) === 0 ? thickness * 0.5 : thickness * 0.3;
|
|
692
|
+
if (vertical) {
|
|
693
|
+
context.moveTo(thickness, at);
|
|
694
|
+
context.lineTo(thickness - tick, at);
|
|
695
|
+
} else {
|
|
696
|
+
context.moveTo(at, thickness);
|
|
697
|
+
context.lineTo(at, thickness - tick);
|
|
698
|
+
}
|
|
699
|
+
if (index % divisions !== 0) continue;
|
|
700
|
+
const label = String(index / divisions);
|
|
701
|
+
if (!vertical) context.fillText(label, at + 2, 9);
|
|
702
|
+
else {
|
|
703
|
+
context.save();
|
|
704
|
+
context.translate(9, at - 2);
|
|
705
|
+
context.rotate(-Math.PI / 2);
|
|
706
|
+
context.fillText(label, 0, 0);
|
|
707
|
+
context.restore();
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
context.stroke();
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return OfficeUiRuler;
|
|
714
|
+
});
|
|
715
|
+
|
|
5
716
|
// src/account.ts
|
|
6
717
|
var DEFAULT_OFFICE_PROFILE = { displayName: "", avatarColor: "#6366f1" };
|
|
7
718
|
var OFFICE_AVATAR_SWATCHES = [
|
|
@@ -52,7 +763,7 @@ function clearOfficeProfile(storage = defaultStorage(), key = OFFICE_PROFILE_STO
|
|
|
52
763
|
} catch {
|
|
53
764
|
}
|
|
54
765
|
}
|
|
55
|
-
var
|
|
766
|
+
var CSS6 = `
|
|
56
767
|
:host { display: block; font-family: var(--office-font, system-ui, sans-serif); font-size: 13px; }
|
|
57
768
|
h2 { margin: 0 0 12px; font-size: 15px; font-weight: 600; }
|
|
58
769
|
.who { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
|
|
@@ -82,7 +793,7 @@ var defineAccount = definer("office-ui-account", () => {
|
|
|
82
793
|
super();
|
|
83
794
|
const doc = this.ownerDocument;
|
|
84
795
|
const root = this.attachShadow({ mode: "open" });
|
|
85
|
-
attachStyles(root, controlCss(
|
|
796
|
+
attachStyles(root, controlCss(CSS6));
|
|
86
797
|
const heading = doc.createElement("h2");
|
|
87
798
|
heading.textContent = "User Information";
|
|
88
799
|
const who = doc.createElement("div");
|
|
@@ -183,7 +894,7 @@ var defineAccount = definer("office-ui-account", () => {
|
|
|
183
894
|
});
|
|
184
895
|
|
|
185
896
|
// src/button.ts
|
|
186
|
-
var
|
|
897
|
+
var CSS7 = `
|
|
187
898
|
:host { display: inline-flex; vertical-align: middle; }
|
|
188
899
|
button { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
|
|
189
900
|
gap: 6px; min-width: var(--office-target-size, 28px); min-height: var(--office-target-size, 28px);
|
|
@@ -224,7 +935,7 @@ var defineButton = definer("office-ui-button", () => {
|
|
|
224
935
|
constructor() {
|
|
225
936
|
super();
|
|
226
937
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
227
|
-
attachStyles(root, controlCss(
|
|
938
|
+
attachStyles(root, controlCss(CSS7));
|
|
228
939
|
this.button = this.ownerDocument.createElement("button");
|
|
229
940
|
this.button.type = "button";
|
|
230
941
|
this.button.setAttribute("part", "button");
|
|
@@ -399,7 +1110,7 @@ var defineCheckbox = definer(
|
|
|
399
1110
|
var defineSwitch = definer("office-ui-switch", makeCheckable("switch", SWITCH_CSS));
|
|
400
1111
|
|
|
401
1112
|
// src/dialog.ts
|
|
402
|
-
var
|
|
1113
|
+
var CSS8 = `
|
|
403
1114
|
:host { display: none; position: fixed; inset: 0; z-index: 1000; align-items: center; justify-content: center; }
|
|
404
1115
|
:host([open]) { display: flex; }
|
|
405
1116
|
.backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / .4); }
|
|
@@ -432,7 +1143,7 @@ var defineDialog = definer("office-ui-dialog", () => {
|
|
|
432
1143
|
super();
|
|
433
1144
|
const doc = this.ownerDocument;
|
|
434
1145
|
const root = this.attachShadow({ mode: "open" });
|
|
435
|
-
attachStyles(root, controlCss(
|
|
1146
|
+
attachStyles(root, controlCss(CSS8));
|
|
436
1147
|
const backdrop = doc.createElement("div");
|
|
437
1148
|
backdrop.className = "backdrop";
|
|
438
1149
|
this.box = doc.createElement("div");
|
|
@@ -535,7 +1246,7 @@ var defineDialog = definer("office-ui-dialog", () => {
|
|
|
535
1246
|
});
|
|
536
1247
|
|
|
537
1248
|
// src/command-search.ts
|
|
538
|
-
var
|
|
1249
|
+
var CSS9 = `
|
|
539
1250
|
:host { display: inline-flex; align-items: center; min-width: 0; font-family: var(--office-font, system-ui, sans-serif); }
|
|
540
1251
|
.field { display: flex; align-items: center; gap: 6px; width: 100%; min-width: 0; height: var(--office-target-size, 28px);
|
|
541
1252
|
padding: 0 8px; box-sizing: border-box; border: 1px solid transparent; border-radius: var(--office-radius, 4px);
|
|
@@ -575,7 +1286,7 @@ var defineCommandSearch = definer("office-ui-command-search", () => {
|
|
|
575
1286
|
super();
|
|
576
1287
|
const doc = this.ownerDocument;
|
|
577
1288
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
578
|
-
attachStyles(root, controlCss(
|
|
1289
|
+
attachStyles(root, controlCss(CSS9));
|
|
579
1290
|
const field = doc.createElement("div");
|
|
580
1291
|
field.className = "field";
|
|
581
1292
|
const glass = createIconSvg(doc);
|
|
@@ -732,7 +1443,7 @@ var defineCommandSearch = definer("office-ui-command-search", () => {
|
|
|
732
1443
|
});
|
|
733
1444
|
|
|
734
1445
|
// src/context-menu.ts
|
|
735
|
-
var
|
|
1446
|
+
var CSS10 = `
|
|
736
1447
|
:host { display: contents; }
|
|
737
1448
|
.panel { position: fixed; inset: auto; margin: 0; min-width: 200px; padding: 4px; box-sizing: border-box;
|
|
738
1449
|
background: var(--office-background, #fff); color: var(--office-foreground, #1f2937);
|
|
@@ -768,7 +1479,7 @@ var defineContextMenu = definer("office-ui-context-menu", () => {
|
|
|
768
1479
|
super();
|
|
769
1480
|
const doc = this.ownerDocument;
|
|
770
1481
|
const root = this.attachShadow({ mode: "open" });
|
|
771
|
-
attachStyles(root, controlCss(
|
|
1482
|
+
attachStyles(root, controlCss(CSS10));
|
|
772
1483
|
this.panel = doc.createElement("div");
|
|
773
1484
|
this.panel.className = "panel";
|
|
774
1485
|
this.panel.setAttribute("role", "menu");
|
|
@@ -1178,7 +1889,7 @@ function clampOptionNumber(raw, min, max) {
|
|
|
1178
1889
|
const parsed = Number(raw);
|
|
1179
1890
|
return Number.isFinite(parsed) && raw.trim() !== "" ? Math.min(max, Math.max(min, parsed)) : void 0;
|
|
1180
1891
|
}
|
|
1181
|
-
var
|
|
1892
|
+
var CSS11 = `
|
|
1182
1893
|
:host { display: contents; }
|
|
1183
1894
|
office-ui-dialog { --office-dialog-width: min(820px, 100vw); --office-dialog-max-width: min(820px, 100vw); }
|
|
1184
1895
|
.layout { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 0; min-height: min(440px, 70vh); margin: -16px; }
|
|
@@ -1227,7 +1938,7 @@ var defineOptionsDialog = definer("office-ui-options-dialog", () => {
|
|
|
1227
1938
|
super();
|
|
1228
1939
|
const doc = this.ownerDocument;
|
|
1229
1940
|
const root = this.attachShadow({ mode: "open" });
|
|
1230
|
-
attachStyles(root, controlCss(
|
|
1941
|
+
attachStyles(root, controlCss(CSS11));
|
|
1231
1942
|
this.#dialog = doc.createElement("office-ui-dialog");
|
|
1232
1943
|
const layout = doc.createElement("div");
|
|
1233
1944
|
layout.className = "layout";
|
|
@@ -1572,7 +2283,7 @@ var defineToolbar = definer("office-ui-toolbar", () => {
|
|
|
1572
2283
|
});
|
|
1573
2284
|
|
|
1574
2285
|
// src/select.ts
|
|
1575
|
-
var
|
|
2286
|
+
var CSS12 = `
|
|
1576
2287
|
:host { display: inline-block; position: relative; vertical-align: middle; }
|
|
1577
2288
|
button { box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
|
1578
2289
|
width: 100%; min-height: var(--office-target-size, 28px); padding: 0 8px; font: inherit; font-size: 12px;
|
|
@@ -1611,7 +2322,7 @@ var defineSelect = definer("office-ui-select", () => {
|
|
|
1611
2322
|
super();
|
|
1612
2323
|
const doc = this.ownerDocument;
|
|
1613
2324
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
1614
|
-
attachStyles(root, controlCss(
|
|
2325
|
+
attachStyles(root, controlCss(CSS12));
|
|
1615
2326
|
this.trigger = doc.createElement("button");
|
|
1616
2327
|
this.trigger.type = "button";
|
|
1617
2328
|
this.trigger.setAttribute("role", "combobox");
|
|
@@ -1862,7 +2573,7 @@ var defineStatusItem = definer("office-ui-status-item", () => {
|
|
|
1862
2573
|
});
|
|
1863
2574
|
|
|
1864
2575
|
// src/tab-strip.ts
|
|
1865
|
-
var
|
|
2576
|
+
var CSS13 = `
|
|
1866
2577
|
:host { display: flex; align-items: stretch; min-width: 0; min-height: 28px; gap: 2px; padding: 0 6px;
|
|
1867
2578
|
background: var(--office-surface, #f3f4f6); color: var(--office-muted-foreground, #6b7280);
|
|
1868
2579
|
border-top: 1px solid var(--office-border, #d1d5db); font-size: 12px;
|
|
@@ -1909,7 +2620,7 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
|
|
|
1909
2620
|
super();
|
|
1910
2621
|
const doc = this.ownerDocument;
|
|
1911
2622
|
const root = this.attachShadow({ mode: "open" });
|
|
1912
|
-
attachStyles(root, controlCss(
|
|
2623
|
+
attachStyles(root, controlCss(CSS13));
|
|
1913
2624
|
const step = (name, icon) => {
|
|
1914
2625
|
const button = doc.createElement("button");
|
|
1915
2626
|
button.type = "button";
|
|
@@ -2048,7 +2759,7 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
|
|
|
2048
2759
|
});
|
|
2049
2760
|
|
|
2050
2761
|
// src/zoom-slider.ts
|
|
2051
|
-
var
|
|
2762
|
+
var CSS14 = `
|
|
2052
2763
|
:host { display: inline-flex; align-items: center; gap: 2px; font-size: 11px;
|
|
2053
2764
|
color: var(--office-foreground, #1f2937); font-family: var(--office-font, system-ui, sans-serif); }
|
|
2054
2765
|
button { box-sizing: border-box; display: inline-grid; place-items: center; min-width: var(--office-target-size, 24px);
|
|
@@ -2084,7 +2795,7 @@ var defineZoomSlider = definer("office-ui-zoom-slider", () => {
|
|
|
2084
2795
|
super();
|
|
2085
2796
|
const doc = this.ownerDocument;
|
|
2086
2797
|
const root = this.attachShadow({ mode: "open" });
|
|
2087
|
-
attachStyles(root, controlCss(
|
|
2798
|
+
attachStyles(root, controlCss(CSS14));
|
|
2088
2799
|
const button = (name, text2) => {
|
|
2089
2800
|
const element = doc.createElement("button");
|
|
2090
2801
|
element.type = "button";
|
|
@@ -2186,6 +2897,19 @@ var visible = (el) => {
|
|
|
2186
2897
|
const box = el.getBoundingClientRect();
|
|
2187
2898
|
return box.width > 0 && box.height > 0;
|
|
2188
2899
|
};
|
|
2900
|
+
function deepTips(root) {
|
|
2901
|
+
const found = [...root.querySelectorAll("[data-keytip]")];
|
|
2902
|
+
for (const host of root.querySelectorAll("*")) {
|
|
2903
|
+
const shadow = host.shadowRoot;
|
|
2904
|
+
if (!shadow) continue;
|
|
2905
|
+
const inner = deepTips(shadow);
|
|
2906
|
+
if (!inner.length) continue;
|
|
2907
|
+
for (const el of inner) hostOf.set(el, host);
|
|
2908
|
+
found.push(...inner);
|
|
2909
|
+
}
|
|
2910
|
+
return found;
|
|
2911
|
+
}
|
|
2912
|
+
var hostOf = /* @__PURE__ */ new WeakMap();
|
|
2189
2913
|
function activate(el) {
|
|
2190
2914
|
const inner = el.shadowRoot?.querySelector(".main, button");
|
|
2191
2915
|
(inner ?? el).click();
|
|
@@ -2203,8 +2927,8 @@ function attachKeyTips(scope) {
|
|
|
2203
2927
|
let levels = [];
|
|
2204
2928
|
let typed = "";
|
|
2205
2929
|
let altAlone = false;
|
|
2206
|
-
const tipsAt = (container) =>
|
|
2207
|
-
const owner = el.parentElement?.closest("[data-keytip-level]") ?? null;
|
|
2930
|
+
const tipsAt = (container) => deepTips(container ?? scope).filter((el) => {
|
|
2931
|
+
const owner = (hostOf.get(el) ?? el.parentElement)?.closest("[data-keytip-level]") ?? null;
|
|
2208
2932
|
return owner === container && visible(el);
|
|
2209
2933
|
});
|
|
2210
2934
|
const current = () => tipsAt(levels.at(-1) ?? null);
|
|
@@ -2333,10 +3057,15 @@ var CONTROL_DEFINERS = [
|
|
|
2333
3057
|
defineZoomSlider,
|
|
2334
3058
|
defineTabStrip,
|
|
2335
3059
|
defineOptionsDialog,
|
|
2336
|
-
defineAccount
|
|
3060
|
+
defineAccount,
|
|
3061
|
+
defineRibbon,
|
|
3062
|
+
defineFindBar,
|
|
3063
|
+
defineRuler,
|
|
3064
|
+
defineBackstage,
|
|
3065
|
+
definePrintPreview
|
|
2337
3066
|
];
|
|
2338
3067
|
function registerControls(registry) {
|
|
2339
3068
|
for (const define of CONTROL_DEFINERS) define(registry);
|
|
2340
3069
|
}
|
|
2341
3070
|
|
|
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 };
|
|
3071
|
+
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-27XQVGRI.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-27XQVGRI.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-27XQVGRI.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.1",
|
|
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.14.
|
|
73
|
+
"ooxml-core": "^0.14.1"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@types/jsdom": "^21.1.7",
|