ooxml-ui 0.8.0 → 0.9.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 +24 -18
- package/dist/account.d.ts +39 -0
- package/dist/{chunk-L5FYB6M7.js → chunk-TMSFX6TC.js} +467 -19
- package/dist/controls.d.ts +6 -2
- package/dist/controls.js +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -2
- package/dist/options.d.ts +66 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,24 +58,30 @@ with an incompatible build of this package.
|
|
|
58
58
|
|
|
59
59
|
## Features: elements
|
|
60
60
|
|
|
61
|
-
| Tag | Attributes / properties
|
|
62
|
-
| ----------------------------------------------------- |
|
|
63
|
-
| `office-ui-button` | `label`, `icon`, `command`, `disabled`, `pressed`, `expanded`, `icon-only`, `variant="stacked"`, `keyshortcuts`
|
|
64
|
-
| `office-ui-checkbox`, `office-ui-switch` | `checked`, `disabled`, `value`, `aria-label`; form-associated
|
|
65
|
-
| `office-ui-select` | `options` `[{ value, label, disabled? }]`, `value`, `selectedIndex`, `disabled`
|
|
66
|
-
| `office-ui-ribbon-group` | `label`, `launcher` (dialog launcher command), `launcher-disabled`; default slot
|
|
67
|
-
| `office-ui-ribbon-stack` | `orientation="horizontal"`; default slot (three-row column of small commands by default)
|
|
68
|
-
| `office-ui-menu-button` / `-menu-item` | button: `label`, `icon`, `command` (split button), `variant`, `disabled`, `keyshortcuts`; item: `command`, `label`, `icon`, `disabled`, `checked`
|
|
69
|
-
| `office-ui-toolbar` | `aria-label`, `aria-orientation`; arrow-key focus movement
|
|
70
|
-
| `office-ui-dialog` | `open`, `heading`, `dismissible="false"`, `show()`, `close()`; slots default, `footer`
|
|
71
|
-
| `office-ui-status-bar` / `-status-item` | `label`, `value`, `interactive`, `id`
|
|
72
|
-
| `office-ui-zoom-slider` | `value` (percent), `min`, `max`, `step`, `disabled`, `fit` (fit button name), `label`
|
|
73
|
-
| `office-ui-tab-strip` | `tabs` `[{ id, label, title? }]`, `selected`, `label`, `previous-label`, `next-label`, `add-label`, `add-disabled`, `add-title`, `disabled`
|
|
74
|
-
| `office-ui-context-menu` / `office-ui-menu-separator` | `label`; `openAt(x, y)`, `close()`, `open`; `office-ui-menu-item` and separator children
|
|
75
|
-
| `office-ui-command-search` | `commands` `[{ id, label, keywords?, description?, disabled?, title? }]`, `placeholder`, `label`, `limit` (Office's "Tell me what you want to do")
|
|
76
|
-
| `office-ui-
|
|
77
|
-
| `office-ui-
|
|
78
|
-
| `office-ui-
|
|
61
|
+
| Tag | Attributes / properties | Events (all bubble, composed) |
|
|
62
|
+
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
63
|
+
| `office-ui-button` | `label`, `icon`, `command`, `disabled`, `pressed`, `expanded`, `icon-only`, `variant="stacked"`, `keyshortcuts` | `office-command` `{ command }` |
|
|
64
|
+
| `office-ui-checkbox`, `office-ui-switch` | `checked`, `disabled`, `value`, `aria-label`; form-associated | `input`, `change` |
|
|
65
|
+
| `office-ui-select` | `options` `[{ value, label, disabled? }]`, `value`, `selectedIndex`, `disabled` | `input`, `change` |
|
|
66
|
+
| `office-ui-ribbon-group` | `label`, `launcher` (dialog launcher command), `launcher-disabled`; default slot | launcher: `office-command` `{ command }` |
|
|
67
|
+
| `office-ui-ribbon-stack` | `orientation="horizontal"`; default slot (three-row column of small commands by default) | none |
|
|
68
|
+
| `office-ui-menu-button` / `-menu-item` | button: `label`, `icon`, `command` (split button), `variant`, `disabled`, `keyshortcuts`; item: `command`, `label`, `icon`, `disabled`, `checked` | item choice: `office-command` `{ command }` |
|
|
69
|
+
| `office-ui-toolbar` | `aria-label`, `aria-orientation`; arrow-key focus movement | none |
|
|
70
|
+
| `office-ui-dialog` | `open`, `heading`, `dismissible="false"`, `show()`, `close()`; slots default, `footer` | `office-dialog-close` `{ reason }` (cancelable) |
|
|
71
|
+
| `office-ui-status-bar` / `-status-item` | `label`, `value`, `interactive`, `id` | `office-status-activate` `{ id }` |
|
|
72
|
+
| `office-ui-zoom-slider` | `value` (percent), `min`, `max`, `step`, `disabled`, `fit` (fit button name), `label` | `input`, `change`; fit: `office-command` `{ command: 'zoom-fit' }` |
|
|
73
|
+
| `office-ui-tab-strip` | `tabs` `[{ id, label, title? }]`, `selected`, `label`, `previous-label`, `next-label`, `add-label`, `add-disabled`, `add-title`, `disabled` | `office-tab-select` `{ id }` (cancelable); add: `office-command` `{ command: 'tab-add' }` |
|
|
74
|
+
| `office-ui-context-menu` / `office-ui-menu-separator` | `label`; `openAt(x, y)`, `close()`, `open`; `office-ui-menu-item` and separator children | item choice: `office-command` `{ command }` |
|
|
75
|
+
| `office-ui-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
|
+
| `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
|
+
| `office-ui-account` | `profile` `{ displayName, avatarColor, initial? }`; slots `sign-in` and default (product sections) | `office-profile-change` `{ profile }` |
|
|
78
|
+
| `office-ui-presence` | `participants`, `max`, `label` | `office-presence-select` `{ id }` |
|
|
79
|
+
| `office-ui-smartart` | `drawing` (core `DiagramDrawing`), `schemeColors`, `label` | `office-smartart-render` (render report) |
|
|
80
|
+
| `office-ui-icon` | `name`, `label` | none |
|
|
81
|
+
|
|
82
|
+
The local profile behind `office-ui-account` is stored on the device only, under one suite-wide
|
|
83
|
+
key (`readOfficeProfile`, `writeOfficeProfile`, `clearOfficeProfile`), so every Office viewer on
|
|
84
|
+
an origin shows the same name and avatar colour.
|
|
79
85
|
|
|
80
86
|
`attachKeyTips(scope)` (from `ooxml-ui/controls`) adds Office KeyTips to any element or shadow
|
|
81
87
|
root: press and release Alt to show badges on controls marked `data-keytip="H"`, type a badge to
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Office File > Account: the local display profile (name and avatar colour) shared by the suite.
|
|
3
|
+
* Moved from pptx-viewer `render/account.ts`. The profile is cosmetic and local: it is stored on
|
|
4
|
+
* this device only and never sent anywhere, except as the collaborator identity a product passes
|
|
5
|
+
* to a live session the user starts.
|
|
6
|
+
*/
|
|
7
|
+
export interface OfficeProfile {
|
|
8
|
+
displayName: string;
|
|
9
|
+
/** CSS colour of the avatar bubble, e.g. `'#c2431f'`. */
|
|
10
|
+
avatarColor: string;
|
|
11
|
+
/** Character(s) in the avatar bubble; derived from `displayName` when omitted. */
|
|
12
|
+
initial?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const DEFAULT_OFFICE_PROFILE: OfficeProfile;
|
|
15
|
+
/** Suggested avatar colours (indigo, vermilion, cyan, green, amber, pink, slate). */
|
|
16
|
+
export declare const OFFICE_AVATAR_SWATCHES: readonly string[];
|
|
17
|
+
/** One key for the whole suite, so Word, PowerPoint, Excel and Visio on one origin share it. */
|
|
18
|
+
export declare const OFFICE_PROFILE_STORAGE_KEY = "ooxml-office-profile";
|
|
19
|
+
export type OfficeProfileChangeEvent = CustomEvent<{
|
|
20
|
+
profile: OfficeProfile;
|
|
21
|
+
}>;
|
|
22
|
+
/** Validate untrusted stored data into a profile. */
|
|
23
|
+
export declare function sanitizeOfficeProfile(raw: unknown): OfficeProfile;
|
|
24
|
+
/** The avatar bubble text: explicit initial, else initials of the name, else `?`. */
|
|
25
|
+
export declare function profileInitials(profile: OfficeProfile): string;
|
|
26
|
+
type StorageLike = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
|
|
27
|
+
/** Read the stored profile; the default when storage is unavailable, empty or corrupt. */
|
|
28
|
+
export declare function readOfficeProfile(storage?: StorageLike | undefined, key?: string): OfficeProfile;
|
|
29
|
+
/** Persist the profile on this device. Silently does nothing when storage is unavailable. */
|
|
30
|
+
export declare function writeOfficeProfile(profile: OfficeProfile, storage?: StorageLike | undefined, key?: string): void;
|
|
31
|
+
/** Forget the stored profile. */
|
|
32
|
+
export declare function clearOfficeProfile(storage?: StorageLike | undefined, key?: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* `<office-ui-account>`: User Information with avatar, display name and avatar colour. Set or read
|
|
35
|
+
* `profile`; edits emit `office-profile-change`. `slot="sign-in"` hosts a product sign-in flow;
|
|
36
|
+
* the default slot holds product sections (theme, product information).
|
|
37
|
+
*/
|
|
38
|
+
export declare const defineAccount: import("./registry.js").Definer;
|
|
39
|
+
export {};
|
|
@@ -1,8 +1,189 @@
|
|
|
1
1
|
import { createIconSvg, paintIcon, defineIcon } from './chunk-PCSUQPMC.js';
|
|
2
|
+
import { initialsOf } from './chunk-RLPL7Q6J.js';
|
|
2
3
|
import { definer, attachStyles, controlCss, emit } from './chunk-EY266IK3.js';
|
|
3
4
|
|
|
4
|
-
// src/
|
|
5
|
+
// src/account.ts
|
|
6
|
+
var DEFAULT_OFFICE_PROFILE = { displayName: "", avatarColor: "#6366f1" };
|
|
7
|
+
var OFFICE_AVATAR_SWATCHES = [
|
|
8
|
+
"#6366f1",
|
|
9
|
+
"#c2431f",
|
|
10
|
+
"#0891b2",
|
|
11
|
+
"#16a34a",
|
|
12
|
+
"#ca8a04",
|
|
13
|
+
"#db2777",
|
|
14
|
+
"#64748b"
|
|
15
|
+
];
|
|
16
|
+
var OFFICE_PROFILE_STORAGE_KEY = "ooxml-office-profile";
|
|
17
|
+
var COLOR = /^#[0-9a-f]{6}$/i;
|
|
18
|
+
function sanitizeOfficeProfile(raw) {
|
|
19
|
+
const value = raw && typeof raw === "object" ? raw : {};
|
|
20
|
+
const displayName = typeof value.displayName === "string" ? value.displayName.trim().slice(0, 64) : "";
|
|
21
|
+
const avatarColor = typeof value.avatarColor === "string" && COLOR.test(value.avatarColor) ? value.avatarColor : DEFAULT_OFFICE_PROFILE.avatarColor;
|
|
22
|
+
const initial = typeof value.initial === "string" && value.initial.trim() ? value.initial.trim().slice(0, 2) : void 0;
|
|
23
|
+
return { displayName, avatarColor, ...initial ? { initial } : {} };
|
|
24
|
+
}
|
|
25
|
+
function profileInitials(profile) {
|
|
26
|
+
return (profile.initial ?? initialsOf(profile.displayName)).toUpperCase();
|
|
27
|
+
}
|
|
28
|
+
var defaultStorage = () => {
|
|
29
|
+
try {
|
|
30
|
+
return typeof localStorage === "undefined" ? void 0 : localStorage;
|
|
31
|
+
} catch {
|
|
32
|
+
return void 0;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
function readOfficeProfile(storage = defaultStorage(), key = OFFICE_PROFILE_STORAGE_KEY) {
|
|
36
|
+
try {
|
|
37
|
+
const raw = storage?.getItem(key);
|
|
38
|
+
return raw ? sanitizeOfficeProfile(JSON.parse(raw)) : { ...DEFAULT_OFFICE_PROFILE };
|
|
39
|
+
} catch {
|
|
40
|
+
return { ...DEFAULT_OFFICE_PROFILE };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function writeOfficeProfile(profile, storage = defaultStorage(), key = OFFICE_PROFILE_STORAGE_KEY) {
|
|
44
|
+
try {
|
|
45
|
+
storage?.setItem(key, JSON.stringify(sanitizeOfficeProfile(profile)));
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function clearOfficeProfile(storage = defaultStorage(), key = OFFICE_PROFILE_STORAGE_KEY) {
|
|
50
|
+
try {
|
|
51
|
+
storage?.removeItem(key);
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
}
|
|
5
55
|
var CSS = `
|
|
56
|
+
:host { display: block; font-family: var(--office-font, system-ui, sans-serif); font-size: 13px; }
|
|
57
|
+
h2 { margin: 0 0 12px; font-size: 15px; font-weight: 600; }
|
|
58
|
+
.who { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
|
|
59
|
+
.avatar { display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%;
|
|
60
|
+
color: #fff; font-weight: 600; font-size: 18px; flex: none; }
|
|
61
|
+
.name { font-size: 14px; font-weight: 600; }
|
|
62
|
+
.note { margin: 2px 0 0; color: var(--office-muted, #6b7280); font-size: 12px; }
|
|
63
|
+
label { display: grid; gap: 4px; max-width: 320px; margin-bottom: 12px; }
|
|
64
|
+
input { min-height: 28px; box-sizing: border-box; padding: 2px 6px; font: inherit; color: inherit;
|
|
65
|
+
border: 1px solid var(--office-border, #d1d5db); border-radius: 3px; background: var(--office-background, #fff); }
|
|
66
|
+
.swatches { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 12px; }
|
|
67
|
+
.swatches button { width: var(--office-target-size, 28px); height: var(--office-target-size, 28px); padding: 0;
|
|
68
|
+
border: 2px solid transparent; border-radius: 50%; cursor: pointer; }
|
|
69
|
+
.swatches button[aria-checked="true"] { border-color: var(--office-foreground, #1f2937);
|
|
70
|
+
box-shadow: inset 0 0 0 2px var(--office-background, #fff); }
|
|
71
|
+
.swatches button:focus-visible, input:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: 1px; }
|
|
72
|
+
@media (forced-colors: active) { .swatches button { forced-color-adjust: none; } }
|
|
73
|
+
`;
|
|
74
|
+
var defineAccount = definer("office-ui-account", () => {
|
|
75
|
+
class OfficeUiAccount extends HTMLElement {
|
|
76
|
+
#profile = { ...DEFAULT_OFFICE_PROFILE };
|
|
77
|
+
#avatar;
|
|
78
|
+
#name;
|
|
79
|
+
#input;
|
|
80
|
+
#swatches;
|
|
81
|
+
constructor() {
|
|
82
|
+
super();
|
|
83
|
+
const doc = this.ownerDocument;
|
|
84
|
+
const root = this.attachShadow({ mode: "open" });
|
|
85
|
+
attachStyles(root, controlCss(CSS));
|
|
86
|
+
const heading = doc.createElement("h2");
|
|
87
|
+
heading.textContent = "User Information";
|
|
88
|
+
const who = doc.createElement("div");
|
|
89
|
+
who.className = "who";
|
|
90
|
+
this.#avatar = doc.createElement("div");
|
|
91
|
+
this.#avatar.className = "avatar";
|
|
92
|
+
this.#avatar.setAttribute("aria-hidden", "true");
|
|
93
|
+
const details = doc.createElement("div");
|
|
94
|
+
this.#name = doc.createElement("div");
|
|
95
|
+
this.#name.className = "name";
|
|
96
|
+
const note = doc.createElement("p");
|
|
97
|
+
note.className = "note";
|
|
98
|
+
note.textContent = "Stored on this device only. Never sent anywhere.";
|
|
99
|
+
details.append(this.#name, note);
|
|
100
|
+
who.append(this.#avatar, details);
|
|
101
|
+
const field = doc.createElement("label");
|
|
102
|
+
field.append("Display name");
|
|
103
|
+
this.#input = doc.createElement("input");
|
|
104
|
+
this.#input.type = "text";
|
|
105
|
+
this.#input.maxLength = 64;
|
|
106
|
+
this.#input.autocomplete = "name";
|
|
107
|
+
this.#input.addEventListener(
|
|
108
|
+
"change",
|
|
109
|
+
() => this.#update({ ...this.#profile, displayName: this.#input.value.trim() })
|
|
110
|
+
);
|
|
111
|
+
field.append(this.#input);
|
|
112
|
+
const colorLabel = doc.createElement("div");
|
|
113
|
+
colorLabel.id = "color-label";
|
|
114
|
+
colorLabel.textContent = "Avatar colour";
|
|
115
|
+
this.#swatches = doc.createElement("div");
|
|
116
|
+
this.#swatches.className = "swatches";
|
|
117
|
+
this.#swatches.setAttribute("role", "radiogroup");
|
|
118
|
+
this.#swatches.setAttribute("aria-labelledby", "color-label");
|
|
119
|
+
for (const color of OFFICE_AVATAR_SWATCHES) {
|
|
120
|
+
const swatch = doc.createElement("button");
|
|
121
|
+
swatch.type = "button";
|
|
122
|
+
swatch.setAttribute("role", "radio");
|
|
123
|
+
swatch.setAttribute("aria-label", color);
|
|
124
|
+
swatch.dataset.color = color;
|
|
125
|
+
swatch.style.background = color;
|
|
126
|
+
swatch.addEventListener(
|
|
127
|
+
"click",
|
|
128
|
+
() => this.#update({ ...this.#profile, avatarColor: color })
|
|
129
|
+
);
|
|
130
|
+
this.#swatches.append(swatch);
|
|
131
|
+
}
|
|
132
|
+
this.#swatches.addEventListener("keydown", (event) => this.#swatchKey(event));
|
|
133
|
+
const signIn = doc.createElement("slot");
|
|
134
|
+
signIn.name = "sign-in";
|
|
135
|
+
root.append(
|
|
136
|
+
heading,
|
|
137
|
+
who,
|
|
138
|
+
field,
|
|
139
|
+
colorLabel,
|
|
140
|
+
this.#swatches,
|
|
141
|
+
signIn,
|
|
142
|
+
doc.createElement("slot")
|
|
143
|
+
);
|
|
144
|
+
this.#sync();
|
|
145
|
+
}
|
|
146
|
+
get profile() {
|
|
147
|
+
return { ...this.#profile };
|
|
148
|
+
}
|
|
149
|
+
set profile(value) {
|
|
150
|
+
this.#profile = sanitizeOfficeProfile(value);
|
|
151
|
+
this.#sync();
|
|
152
|
+
}
|
|
153
|
+
#update(next) {
|
|
154
|
+
this.#profile = sanitizeOfficeProfile(next);
|
|
155
|
+
this.#sync();
|
|
156
|
+
emit(this, "office-profile-change", { profile: this.profile });
|
|
157
|
+
}
|
|
158
|
+
#swatchKey(event) {
|
|
159
|
+
const step = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key];
|
|
160
|
+
if (!step) return;
|
|
161
|
+
event.preventDefault();
|
|
162
|
+
const colors = OFFICE_AVATAR_SWATCHES;
|
|
163
|
+
const at = Math.max(0, colors.indexOf(this.#profile.avatarColor));
|
|
164
|
+
const color = colors[(at + step + colors.length) % colors.length];
|
|
165
|
+
this.#update({ ...this.#profile, avatarColor: color });
|
|
166
|
+
this.#swatches.querySelector(`[data-color="${color}"]`)?.focus();
|
|
167
|
+
}
|
|
168
|
+
#sync() {
|
|
169
|
+
const { displayName, avatarColor } = this.#profile;
|
|
170
|
+
this.#avatar.textContent = profileInitials(this.#profile);
|
|
171
|
+
this.#avatar.style.background = avatarColor;
|
|
172
|
+
this.#name.textContent = displayName || "No display name";
|
|
173
|
+
if (this.#input.value.trim() !== displayName) this.#input.value = displayName;
|
|
174
|
+
const known = OFFICE_AVATAR_SWATCHES.includes(avatarColor);
|
|
175
|
+
this.#swatches.querySelectorAll('[role="radio"]').forEach((swatch, index) => {
|
|
176
|
+
const checked = swatch.dataset.color === avatarColor;
|
|
177
|
+
swatch.setAttribute("aria-checked", String(checked));
|
|
178
|
+
swatch.tabIndex = checked || !known && index === 0 ? 0 : -1;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return OfficeUiAccount;
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// src/button.ts
|
|
186
|
+
var CSS2 = `
|
|
6
187
|
:host { display: inline-flex; vertical-align: middle; }
|
|
7
188
|
button { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
|
|
8
189
|
gap: 6px; min-width: var(--office-target-size, 28px); min-height: var(--office-target-size, 28px);
|
|
@@ -43,7 +224,7 @@ var defineButton = definer("office-ui-button", () => {
|
|
|
43
224
|
constructor() {
|
|
44
225
|
super();
|
|
45
226
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
46
|
-
attachStyles(root, controlCss(
|
|
227
|
+
attachStyles(root, controlCss(CSS2));
|
|
47
228
|
this.button = this.ownerDocument.createElement("button");
|
|
48
229
|
this.button.type = "button";
|
|
49
230
|
this.button.setAttribute("part", "button");
|
|
@@ -218,12 +399,12 @@ var defineCheckbox = definer(
|
|
|
218
399
|
var defineSwitch = definer("office-ui-switch", makeCheckable("switch", SWITCH_CSS));
|
|
219
400
|
|
|
220
401
|
// src/dialog.ts
|
|
221
|
-
var
|
|
402
|
+
var CSS3 = `
|
|
222
403
|
:host { display: none; position: fixed; inset: 0; z-index: 1000; align-items: center; justify-content: center; }
|
|
223
404
|
:host([open]) { display: flex; }
|
|
224
405
|
.backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / .4); }
|
|
225
406
|
.box { position: relative; box-sizing: border-box; display: flex; flex-direction: column;
|
|
226
|
-
min-width: min(320px, 100vw); max-width: min(640px, 100vw); max-height: 90vh;
|
|
407
|
+
width: var(--office-dialog-width, auto); min-width: min(320px, 100vw); max-width: var(--office-dialog-max-width, min(640px, 100vw)); max-height: 90vh;
|
|
227
408
|
background: var(--office-background, #fff); color: var(--office-foreground, #1f2937);
|
|
228
409
|
border: 1px solid var(--office-border, #d1d5db); border-radius: 8px; font-family: var(--office-font, system-ui, sans-serif); }
|
|
229
410
|
header { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 16px;
|
|
@@ -251,7 +432,7 @@ var defineDialog = definer("office-ui-dialog", () => {
|
|
|
251
432
|
super();
|
|
252
433
|
const doc = this.ownerDocument;
|
|
253
434
|
const root = this.attachShadow({ mode: "open" });
|
|
254
|
-
attachStyles(root, controlCss(
|
|
435
|
+
attachStyles(root, controlCss(CSS3));
|
|
255
436
|
const backdrop = doc.createElement("div");
|
|
256
437
|
backdrop.className = "backdrop";
|
|
257
438
|
this.box = doc.createElement("div");
|
|
@@ -354,7 +535,7 @@ var defineDialog = definer("office-ui-dialog", () => {
|
|
|
354
535
|
});
|
|
355
536
|
|
|
356
537
|
// src/command-search.ts
|
|
357
|
-
var
|
|
538
|
+
var CSS4 = `
|
|
358
539
|
:host { display: inline-flex; align-items: center; min-width: 0; font-family: var(--office-font, system-ui, sans-serif); }
|
|
359
540
|
.field { display: flex; align-items: center; gap: 6px; width: 100%; min-width: 0; height: var(--office-target-size, 28px);
|
|
360
541
|
padding: 0 8px; box-sizing: border-box; border: 1px solid transparent; border-radius: var(--office-radius, 4px);
|
|
@@ -394,7 +575,7 @@ var defineCommandSearch = definer("office-ui-command-search", () => {
|
|
|
394
575
|
super();
|
|
395
576
|
const doc = this.ownerDocument;
|
|
396
577
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
397
|
-
attachStyles(root, controlCss(
|
|
578
|
+
attachStyles(root, controlCss(CSS4));
|
|
398
579
|
const field = doc.createElement("div");
|
|
399
580
|
field.className = "field";
|
|
400
581
|
const glass = createIconSvg(doc);
|
|
@@ -551,7 +732,7 @@ var defineCommandSearch = definer("office-ui-command-search", () => {
|
|
|
551
732
|
});
|
|
552
733
|
|
|
553
734
|
// src/context-menu.ts
|
|
554
|
-
var
|
|
735
|
+
var CSS5 = `
|
|
555
736
|
:host { display: contents; }
|
|
556
737
|
.panel { position: fixed; inset: auto; margin: 0; min-width: 200px; padding: 4px; box-sizing: border-box;
|
|
557
738
|
background: var(--office-background, #fff); color: var(--office-foreground, #1f2937);
|
|
@@ -587,7 +768,7 @@ var defineContextMenu = definer("office-ui-context-menu", () => {
|
|
|
587
768
|
super();
|
|
588
769
|
const doc = this.ownerDocument;
|
|
589
770
|
const root = this.attachShadow({ mode: "open" });
|
|
590
|
-
attachStyles(root, controlCss(
|
|
771
|
+
attachStyles(root, controlCss(CSS5));
|
|
591
772
|
this.panel = doc.createElement("div");
|
|
592
773
|
this.panel.className = "panel";
|
|
593
774
|
this.panel.setAttribute("role", "menu");
|
|
@@ -992,6 +1173,271 @@ var defineMenuButton = definer("office-ui-menu-button", () => {
|
|
|
992
1173
|
return OfficeUiMenuButton;
|
|
993
1174
|
});
|
|
994
1175
|
|
|
1176
|
+
// src/options.ts
|
|
1177
|
+
function clampOptionNumber(raw, min, max) {
|
|
1178
|
+
const parsed = Number(raw);
|
|
1179
|
+
return Number.isFinite(parsed) && raw.trim() !== "" ? Math.min(max, Math.max(min, parsed)) : void 0;
|
|
1180
|
+
}
|
|
1181
|
+
var CSS6 = `
|
|
1182
|
+
:host { display: contents; }
|
|
1183
|
+
office-ui-dialog { --office-dialog-width: min(820px, 100vw); --office-dialog-max-width: min(820px, 100vw); }
|
|
1184
|
+
.layout { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 0; min-height: min(440px, 70vh); margin: -16px; }
|
|
1185
|
+
nav { display: flex; flex-direction: column; padding: 8px 0; border-inline-end: 1px solid var(--office-border, #d1d5db);
|
|
1186
|
+
background: var(--office-surface, #f3f4f6); overflow: auto; }
|
|
1187
|
+
nav button { min-height: 30px; padding: 4px 14px; border: 0; border-radius: 0; background: transparent; color: inherit;
|
|
1188
|
+
font: inherit; text-align: start; cursor: pointer; }
|
|
1189
|
+
nav button[aria-selected="true"] { background: var(--office-selected, #e5e7eb); font-weight: 600;
|
|
1190
|
+
box-shadow: inset 3px 0 0 var(--office-accent, #2563eb); }
|
|
1191
|
+
nav button:focus-visible { outline: 2px solid var(--office-ring, #2563eb); outline-offset: -2px; }
|
|
1192
|
+
[role="tabpanel"] { padding: 16px 20px; overflow: auto; }
|
|
1193
|
+
.lead { margin: 0 0 12px; font-size: 14px; }
|
|
1194
|
+
.unavailable { margin: 0 0 12px; color: var(--office-muted, #6b7280); }
|
|
1195
|
+
section + section { margin-top: 16px; }
|
|
1196
|
+
h3 { margin: 0 0 8px; padding-bottom: 4px; border-bottom: 1px solid var(--office-border, #d1d5db); font-size: 13px; font-weight: 600; }
|
|
1197
|
+
.desc { margin: 0 0 8px; color: var(--office-muted, #6b7280); }
|
|
1198
|
+
.row { display: flex; align-items: center; gap: 8px; min-height: 30px; }
|
|
1199
|
+
.row.indent { padding-inline-start: 24px; }
|
|
1200
|
+
.row.field > span:first-child { min-width: 180px; }
|
|
1201
|
+
.row[data-disabled] { color: var(--office-muted, #6b7280); }
|
|
1202
|
+
input[type="text"], input[type="number"], select { min-height: 26px; box-sizing: border-box; font: inherit;
|
|
1203
|
+
border: 1px solid var(--office-border, #d1d5db); border-radius: 3px; background: var(--office-background, #fff); color: inherit; }
|
|
1204
|
+
input[type="number"] { width: 80px; }
|
|
1205
|
+
.info { display: inline-grid; place-items: center; width: 15px; height: 15px; border: 1px solid currentColor;
|
|
1206
|
+
border-radius: 50%; font-size: 10px; color: var(--office-muted, #6b7280); cursor: help; }
|
|
1207
|
+
.actions { display: flex; gap: 8px; }
|
|
1208
|
+
.actions button { min-width: 76px; min-height: 28px; font: inherit; cursor: pointer; }
|
|
1209
|
+
@media (max-width: 600px) {
|
|
1210
|
+
.layout { grid-template-columns: 1fr; }
|
|
1211
|
+
nav { flex-direction: row; border-inline-end: 0; border-bottom: 1px solid var(--office-border, #d1d5db); }
|
|
1212
|
+
nav button { white-space: nowrap; }
|
|
1213
|
+
.row.field { flex-wrap: wrap; }
|
|
1214
|
+
}
|
|
1215
|
+
`;
|
|
1216
|
+
var defineOptionsDialog = definer("office-ui-options-dialog", () => {
|
|
1217
|
+
class OfficeUiOptionsDialog extends HTMLElement {
|
|
1218
|
+
static observedAttributes = ["open", "heading"];
|
|
1219
|
+
#categories = [];
|
|
1220
|
+
#values = {};
|
|
1221
|
+
#draft = {};
|
|
1222
|
+
#active = "";
|
|
1223
|
+
#dialog;
|
|
1224
|
+
#nav;
|
|
1225
|
+
#pane;
|
|
1226
|
+
constructor() {
|
|
1227
|
+
super();
|
|
1228
|
+
const doc = this.ownerDocument;
|
|
1229
|
+
const root = this.attachShadow({ mode: "open" });
|
|
1230
|
+
attachStyles(root, controlCss(CSS6));
|
|
1231
|
+
this.#dialog = doc.createElement("office-ui-dialog");
|
|
1232
|
+
const layout = doc.createElement("div");
|
|
1233
|
+
layout.className = "layout";
|
|
1234
|
+
this.#nav = doc.createElement("nav");
|
|
1235
|
+
this.#nav.setAttribute("role", "tablist");
|
|
1236
|
+
this.#nav.setAttribute("aria-orientation", "vertical");
|
|
1237
|
+
this.#nav.setAttribute("aria-label", "Categories");
|
|
1238
|
+
this.#pane = doc.createElement("div");
|
|
1239
|
+
this.#pane.setAttribute("role", "tabpanel");
|
|
1240
|
+
this.#pane.id = "pane";
|
|
1241
|
+
layout.append(this.#nav, this.#pane);
|
|
1242
|
+
const actions = doc.createElement("div");
|
|
1243
|
+
actions.slot = "footer";
|
|
1244
|
+
actions.className = "actions";
|
|
1245
|
+
const ok = this.#button("OK", () => this.#commit());
|
|
1246
|
+
ok.dataset.action = "ok";
|
|
1247
|
+
const cancel = this.#button("Cancel", () => this.#closeDialog());
|
|
1248
|
+
cancel.dataset.action = "cancel";
|
|
1249
|
+
actions.append(ok, cancel);
|
|
1250
|
+
this.#dialog.append(layout, actions);
|
|
1251
|
+
root.append(this.#dialog);
|
|
1252
|
+
this.#dialog.addEventListener("office-dialog-close", (event) => {
|
|
1253
|
+
if (!event.defaultPrevented) this.removeAttribute("open");
|
|
1254
|
+
});
|
|
1255
|
+
this.#nav.addEventListener("keydown", (event) => this.#navKey(event));
|
|
1256
|
+
}
|
|
1257
|
+
get categories() {
|
|
1258
|
+
return this.#categories;
|
|
1259
|
+
}
|
|
1260
|
+
set categories(value) {
|
|
1261
|
+
this.#categories = value;
|
|
1262
|
+
if (!value.some((category) => category.id === this.#active))
|
|
1263
|
+
this.#active = value[0]?.id ?? "";
|
|
1264
|
+
this.#render();
|
|
1265
|
+
}
|
|
1266
|
+
get values() {
|
|
1267
|
+
return { ...this.#values };
|
|
1268
|
+
}
|
|
1269
|
+
set values(value) {
|
|
1270
|
+
this.#values = { ...value };
|
|
1271
|
+
if (!this.open) this.#draft = { ...value };
|
|
1272
|
+
this.#render();
|
|
1273
|
+
}
|
|
1274
|
+
/** The selected category id. */
|
|
1275
|
+
get category() {
|
|
1276
|
+
return this.#active;
|
|
1277
|
+
}
|
|
1278
|
+
set category(id) {
|
|
1279
|
+
if (this.#categories.some((category) => category.id === id)) {
|
|
1280
|
+
this.#active = id;
|
|
1281
|
+
this.#render();
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
get open() {
|
|
1285
|
+
return this.hasAttribute("open");
|
|
1286
|
+
}
|
|
1287
|
+
set open(value) {
|
|
1288
|
+
this.toggleAttribute("open", Boolean(value));
|
|
1289
|
+
}
|
|
1290
|
+
show() {
|
|
1291
|
+
this.open = true;
|
|
1292
|
+
}
|
|
1293
|
+
close() {
|
|
1294
|
+
this.#closeDialog();
|
|
1295
|
+
}
|
|
1296
|
+
attributeChangedCallback(name, old, value) {
|
|
1297
|
+
if (name === "heading") this.#dialog.setAttribute("heading", value ?? "Options");
|
|
1298
|
+
if (name === "open" && old === null !== (value === null)) {
|
|
1299
|
+
if (value !== null) {
|
|
1300
|
+
this.#draft = { ...this.#values };
|
|
1301
|
+
this.#render();
|
|
1302
|
+
}
|
|
1303
|
+
this.#dialog.open = value !== null;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
connectedCallback() {
|
|
1307
|
+
if (!this.hasAttribute("heading")) this.#dialog.setAttribute("heading", "Options");
|
|
1308
|
+
}
|
|
1309
|
+
#button(label, run) {
|
|
1310
|
+
const button = this.ownerDocument.createElement("button");
|
|
1311
|
+
button.type = "button";
|
|
1312
|
+
button.textContent = label;
|
|
1313
|
+
button.addEventListener("click", run);
|
|
1314
|
+
return button;
|
|
1315
|
+
}
|
|
1316
|
+
#closeDialog() {
|
|
1317
|
+
this.removeAttribute("open");
|
|
1318
|
+
}
|
|
1319
|
+
#commit() {
|
|
1320
|
+
const changed = Object.keys(this.#draft).filter(
|
|
1321
|
+
(key) => this.#draft[key] !== this.#values[key]
|
|
1322
|
+
);
|
|
1323
|
+
this.#values = { ...this.#draft };
|
|
1324
|
+
emit(this, "office-options-change", { values: { ...this.#values }, changed });
|
|
1325
|
+
this.#closeDialog();
|
|
1326
|
+
}
|
|
1327
|
+
#navKey(event) {
|
|
1328
|
+
const tabs = [...this.#nav.querySelectorAll('[role="tab"]')];
|
|
1329
|
+
const at = tabs.findIndex((tab) => tab.getAttribute("aria-selected") === "true");
|
|
1330
|
+
const step = { ArrowDown: 1, ArrowRight: 1, ArrowUp: -1, ArrowLeft: -1 }[event.key];
|
|
1331
|
+
const target = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs.at(-1) : step ? tabs[(at + step + tabs.length) % tabs.length] : void 0;
|
|
1332
|
+
if (!target) return;
|
|
1333
|
+
event.preventDefault();
|
|
1334
|
+
this.category = target.dataset.category;
|
|
1335
|
+
this.#nav.querySelector('[aria-selected="true"]')?.focus();
|
|
1336
|
+
}
|
|
1337
|
+
#render() {
|
|
1338
|
+
const doc = this.ownerDocument;
|
|
1339
|
+
this.#nav.replaceChildren(
|
|
1340
|
+
...this.#categories.map((category2) => {
|
|
1341
|
+
const tab = this.#button(category2.label, () => this.category = category2.id);
|
|
1342
|
+
tab.setAttribute("role", "tab");
|
|
1343
|
+
tab.dataset.category = category2.id;
|
|
1344
|
+
tab.id = `tab-${category2.id}`;
|
|
1345
|
+
tab.setAttribute("aria-controls", "pane");
|
|
1346
|
+
const selected = category2.id === this.#active;
|
|
1347
|
+
tab.setAttribute("aria-selected", String(selected));
|
|
1348
|
+
tab.tabIndex = selected ? 0 : -1;
|
|
1349
|
+
return tab;
|
|
1350
|
+
})
|
|
1351
|
+
);
|
|
1352
|
+
const category = this.#categories.find((entry) => entry.id === this.#active);
|
|
1353
|
+
this.#pane.replaceChildren();
|
|
1354
|
+
if (!category) return;
|
|
1355
|
+
this.#pane.setAttribute("aria-labelledby", `tab-${category.id}`);
|
|
1356
|
+
if (category.description) this.#pane.append(text(doc, "p", category.description, "lead"));
|
|
1357
|
+
if (category.disabled) this.#pane.append(text(doc, "p", category.disabled, "unavailable"));
|
|
1358
|
+
for (const section of category.sections) {
|
|
1359
|
+
const block = doc.createElement("section");
|
|
1360
|
+
block.append(text(doc, "h3", section.title));
|
|
1361
|
+
if (section.description) block.append(text(doc, "p", section.description, "desc"));
|
|
1362
|
+
for (const control of section.controls) block.append(this.#control(control));
|
|
1363
|
+
this.#pane.append(block);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
#control(control) {
|
|
1367
|
+
const doc = this.ownerDocument;
|
|
1368
|
+
const row = doc.createElement("label");
|
|
1369
|
+
row.className = `row${control.indent ? " indent" : ""}${control.kind === "toggle" ? "" : " field"}`;
|
|
1370
|
+
row.dataset.key = control.key;
|
|
1371
|
+
const value = this.#draft[control.key];
|
|
1372
|
+
const set = (next) => this.#draft[control.key] = next;
|
|
1373
|
+
let input;
|
|
1374
|
+
if (control.kind === "toggle") {
|
|
1375
|
+
const box = doc.createElement("input");
|
|
1376
|
+
box.type = "checkbox";
|
|
1377
|
+
box.checked = value === true;
|
|
1378
|
+
box.addEventListener("change", () => set(box.checked));
|
|
1379
|
+
input = box;
|
|
1380
|
+
row.append(box, text(doc, "span", control.label));
|
|
1381
|
+
} else if (control.kind === "select") {
|
|
1382
|
+
const select = doc.createElement("select");
|
|
1383
|
+
for (const choice of control.choices) {
|
|
1384
|
+
const option = doc.createElement("option");
|
|
1385
|
+
option.value = choice.value;
|
|
1386
|
+
option.textContent = choice.label;
|
|
1387
|
+
select.append(option);
|
|
1388
|
+
}
|
|
1389
|
+
select.value = String(value ?? control.choices[0]?.value ?? "");
|
|
1390
|
+
select.addEventListener("change", () => set(select.value));
|
|
1391
|
+
input = select;
|
|
1392
|
+
row.append(text(doc, "span", control.label), select);
|
|
1393
|
+
} else {
|
|
1394
|
+
const field = doc.createElement("input");
|
|
1395
|
+
field.type = control.kind === "number" ? "number" : "text";
|
|
1396
|
+
field.value = value === void 0 ? "" : String(value);
|
|
1397
|
+
if (control.kind === "number") {
|
|
1398
|
+
field.min = String(control.min);
|
|
1399
|
+
field.max = String(control.max);
|
|
1400
|
+
if (control.step) field.step = String(control.step);
|
|
1401
|
+
field.addEventListener("change", () => {
|
|
1402
|
+
const next = clampOptionNumber(field.value, control.min, control.max);
|
|
1403
|
+
if (next === void 0) field.value = String(this.#draft[control.key] ?? "");
|
|
1404
|
+
else {
|
|
1405
|
+
field.value = String(next);
|
|
1406
|
+
set(next);
|
|
1407
|
+
}
|
|
1408
|
+
});
|
|
1409
|
+
} else {
|
|
1410
|
+
if (control.maxLength) field.maxLength = control.maxLength;
|
|
1411
|
+
field.addEventListener("input", () => set(field.value));
|
|
1412
|
+
}
|
|
1413
|
+
input = field;
|
|
1414
|
+
row.append(text(doc, "span", control.label), field);
|
|
1415
|
+
if (control.kind === "number" && control.unit) row.append(text(doc, "span", control.unit));
|
|
1416
|
+
}
|
|
1417
|
+
if (control.disabled) {
|
|
1418
|
+
input.disabled = true;
|
|
1419
|
+
row.dataset.disabled = "";
|
|
1420
|
+
row.title = control.disabled;
|
|
1421
|
+
}
|
|
1422
|
+
if (control.info) {
|
|
1423
|
+
const info = text(doc, "span", "i", "info");
|
|
1424
|
+
info.title = control.info;
|
|
1425
|
+
info.setAttribute("role", "img");
|
|
1426
|
+
info.setAttribute("aria-label", control.info);
|
|
1427
|
+
row.append(info);
|
|
1428
|
+
}
|
|
1429
|
+
return row;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
return OfficeUiOptionsDialog;
|
|
1433
|
+
});
|
|
1434
|
+
function text(doc, tag, content, className) {
|
|
1435
|
+
const el = doc.createElement(tag);
|
|
1436
|
+
el.textContent = content;
|
|
1437
|
+
if (className) el.className = className;
|
|
1438
|
+
return el;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
995
1441
|
// src/ribbon.ts
|
|
996
1442
|
var GROUP_CSS = `
|
|
997
1443
|
:host { display: inline-flex; flex: none; align-self: stretch; }
|
|
@@ -1126,7 +1572,7 @@ var defineToolbar = definer("office-ui-toolbar", () => {
|
|
|
1126
1572
|
});
|
|
1127
1573
|
|
|
1128
1574
|
// src/select.ts
|
|
1129
|
-
var
|
|
1575
|
+
var CSS7 = `
|
|
1130
1576
|
:host { display: inline-block; position: relative; vertical-align: middle; }
|
|
1131
1577
|
button { box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
|
1132
1578
|
width: 100%; min-height: var(--office-target-size, 28px); padding: 0 8px; font: inherit; font-size: 12px;
|
|
@@ -1165,7 +1611,7 @@ var defineSelect = definer("office-ui-select", () => {
|
|
|
1165
1611
|
super();
|
|
1166
1612
|
const doc = this.ownerDocument;
|
|
1167
1613
|
const root = this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
1168
|
-
attachStyles(root, controlCss(
|
|
1614
|
+
attachStyles(root, controlCss(CSS7));
|
|
1169
1615
|
this.trigger = doc.createElement("button");
|
|
1170
1616
|
this.trigger.type = "button";
|
|
1171
1617
|
this.trigger.setAttribute("role", "combobox");
|
|
@@ -1416,7 +1862,7 @@ var defineStatusItem = definer("office-ui-status-item", () => {
|
|
|
1416
1862
|
});
|
|
1417
1863
|
|
|
1418
1864
|
// src/tab-strip.ts
|
|
1419
|
-
var
|
|
1865
|
+
var CSS8 = `
|
|
1420
1866
|
:host { display: flex; align-items: stretch; min-width: 0; min-height: 28px; gap: 2px; padding: 0 6px;
|
|
1421
1867
|
background: var(--office-surface, #f3f4f6); color: var(--office-muted-foreground, #6b7280);
|
|
1422
1868
|
border-top: 1px solid var(--office-border, #d1d5db); font-size: 12px;
|
|
@@ -1463,7 +1909,7 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
|
|
|
1463
1909
|
super();
|
|
1464
1910
|
const doc = this.ownerDocument;
|
|
1465
1911
|
const root = this.attachShadow({ mode: "open" });
|
|
1466
|
-
attachStyles(root, controlCss(
|
|
1912
|
+
attachStyles(root, controlCss(CSS8));
|
|
1467
1913
|
const step = (name, icon) => {
|
|
1468
1914
|
const button = doc.createElement("button");
|
|
1469
1915
|
button.type = "button";
|
|
@@ -1602,7 +2048,7 @@ var defineTabStrip = definer("office-ui-tab-strip", () => {
|
|
|
1602
2048
|
});
|
|
1603
2049
|
|
|
1604
2050
|
// src/zoom-slider.ts
|
|
1605
|
-
var
|
|
2051
|
+
var CSS9 = `
|
|
1606
2052
|
:host { display: inline-flex; align-items: center; gap: 2px; font-size: 11px;
|
|
1607
2053
|
color: var(--office-foreground, #1f2937); font-family: var(--office-font, system-ui, sans-serif); }
|
|
1608
2054
|
button { box-sizing: border-box; display: inline-grid; place-items: center; min-width: var(--office-target-size, 24px);
|
|
@@ -1638,13 +2084,13 @@ var defineZoomSlider = definer("office-ui-zoom-slider", () => {
|
|
|
1638
2084
|
super();
|
|
1639
2085
|
const doc = this.ownerDocument;
|
|
1640
2086
|
const root = this.attachShadow({ mode: "open" });
|
|
1641
|
-
attachStyles(root, controlCss(
|
|
1642
|
-
const button = (name,
|
|
2087
|
+
attachStyles(root, controlCss(CSS9));
|
|
2088
|
+
const button = (name, text2) => {
|
|
1643
2089
|
const element = doc.createElement("button");
|
|
1644
2090
|
element.type = "button";
|
|
1645
2091
|
element.setAttribute("aria-label", name);
|
|
1646
2092
|
element.title = name;
|
|
1647
|
-
element.textContent =
|
|
2093
|
+
element.textContent = text2;
|
|
1648
2094
|
return element;
|
|
1649
2095
|
};
|
|
1650
2096
|
this.out = button("Zoom out", "\u2212");
|
|
@@ -1885,10 +2331,12 @@ var CONTROL_DEFINERS = [
|
|
|
1885
2331
|
defineStatusBar,
|
|
1886
2332
|
defineStatusItem,
|
|
1887
2333
|
defineZoomSlider,
|
|
1888
|
-
defineTabStrip
|
|
2334
|
+
defineTabStrip,
|
|
2335
|
+
defineOptionsDialog,
|
|
2336
|
+
defineAccount
|
|
1889
2337
|
];
|
|
1890
2338
|
function registerControls(registry) {
|
|
1891
2339
|
for (const define of CONTROL_DEFINERS) define(registry);
|
|
1892
2340
|
}
|
|
1893
2341
|
|
|
1894
|
-
export { CONTROL_DEFINERS, attachKeyTips, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls };
|
|
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 };
|
package/dist/controls.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { defineAccount } from './account.js';
|
|
1
2
|
import { defineButton } from './button.js';
|
|
2
3
|
import { defineCheckbox, defineSwitch } from './checkable.js';
|
|
3
4
|
import { defineDialog } from './dialog.js';
|
|
@@ -5,12 +6,13 @@ import { defineIcon } from './icons.js';
|
|
|
5
6
|
import { defineCommandSearch } from './command-search.js';
|
|
6
7
|
import { defineContextMenu, defineMenuSeparator } from './context-menu.js';
|
|
7
8
|
import { defineMenuButton, defineMenuItem } from './menu.js';
|
|
9
|
+
import { defineOptionsDialog } from './options.js';
|
|
8
10
|
import { defineRibbonGroup, defineRibbonStack, defineToolbar } from './ribbon.js';
|
|
9
11
|
import { defineSelect } from './select.js';
|
|
10
12
|
import { defineStatusBar, defineStatusItem } from './status-bar.js';
|
|
11
13
|
import { defineTabStrip } from './tab-strip.js';
|
|
12
14
|
import { defineZoomSlider } from './zoom-slider.js';
|
|
13
|
-
export { defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineIcon, defineMenuButton, defineMenuItem, defineMenuSeparator, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, };
|
|
15
|
+
export { defineAccount, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineIcon, defineMenuButton, defineMenuItem, defineMenuSeparator, defineOptionsDialog, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, };
|
|
14
16
|
export type { OfficeCommandEvent } from './button.js';
|
|
15
17
|
export type { OfficeDialogCloseEvent, OfficeDialogCloseReason } from './dialog.js';
|
|
16
18
|
export type { OfficeSelectOption } from './select.js';
|
|
@@ -18,7 +20,9 @@ export type { OfficeStatusActivateEvent } from './status-bar.js';
|
|
|
18
20
|
export type { OfficeTab, OfficeTabSelectEvent } from './tab-strip.js';
|
|
19
21
|
export type { OfficeSearchCommand } from './command-search.js';
|
|
20
22
|
export { attachKeyTips, type KeyTipsHandle } from './keytips.js';
|
|
23
|
+
export { clearOfficeProfile, DEFAULT_OFFICE_PROFILE, OFFICE_AVATAR_SWATCHES, OFFICE_PROFILE_STORAGE_KEY, profileInitials, readOfficeProfile, sanitizeOfficeProfile, writeOfficeProfile, type OfficeProfile, type OfficeProfileChangeEvent, } from './account.js';
|
|
24
|
+
export { clampOptionNumber, type OfficeOptionCategory, type OfficeOptionChoice, type OfficeOptionControl, type OfficeOptionSection, type OfficeOptionsChangeEvent, type OfficeOptionValue, type OfficeOptionValues, } from './options.js';
|
|
21
25
|
/** Every control of this entry. */
|
|
22
|
-
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];
|
|
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];
|
|
23
27
|
/** Idempotent, SSR-safe (no-op without a DOM). */
|
|
24
28
|
export declare function registerControls(registry?: CustomElementRegistry): void;
|
package/dist/controls.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { CONTROL_DEFINERS, attachKeyTips, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls } from './chunk-
|
|
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-TMSFX6TC.js';
|
|
2
2
|
export { defineIcon } from './chunk-PCSUQPMC.js';
|
|
3
|
+
import './chunk-RLPL7Q6J.js';
|
|
3
4
|
import './chunk-EY266IK3.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export * from './smartart.js';
|
|
|
5
5
|
export * from './theme.js';
|
|
6
6
|
export { CONTRACT_REVISION, type Definer } from './registry.js';
|
|
7
7
|
/** Every ooxml-ui tag this package defines, in registration order. */
|
|
8
|
-
export declare const OFFICE_UI_TAGS: readonly ["office-ui-icon", "office-ui-button", "office-ui-checkbox", "office-ui-switch", "office-ui-select", "office-ui-ribbon-group", "office-ui-ribbon-stack", "office-ui-menu-item", "office-ui-menu-button", "office-ui-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-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-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, attachKeyTips, defineButton, defineCheckbox, defineCommandSearch, defineContextMenu, defineDialog, defineMenuButton, defineMenuItem, defineMenuSeparator, defineRibbonGroup, defineRibbonStack, defineSelect, defineStatusBar, defineStatusItem, defineSwitch, defineTabStrip, defineToolbar, defineZoomSlider, registerControls } from './chunk-
|
|
3
|
+
import { registerControls } from './chunk-TMSFX6TC.js';
|
|
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-TMSFX6TC.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';
|
|
@@ -29,6 +29,8 @@ var OFFICE_UI_TAGS = [
|
|
|
29
29
|
"office-ui-status-item",
|
|
30
30
|
"office-ui-zoom-slider",
|
|
31
31
|
"office-ui-tab-strip",
|
|
32
|
+
"office-ui-options-dialog",
|
|
33
|
+
"office-ui-account",
|
|
32
34
|
"office-ui-presence",
|
|
33
35
|
"office-ui-smartart"
|
|
34
36
|
];
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Office File > Options dialog. Products describe their categories as data; the element renders
|
|
3
|
+
* the category list, the pane and OK/Cancel, and reports the edited values. Generalised from
|
|
4
|
+
* pptx-viewer's `VIEWER_OPTIONS_SCHEMA` dialog (render/options) so every viewer shares one.
|
|
5
|
+
*/
|
|
6
|
+
export type OfficeOptionValue = boolean | number | string;
|
|
7
|
+
export type OfficeOptionValues = Record<string, OfficeOptionValue>;
|
|
8
|
+
export interface OfficeOptionChoice {
|
|
9
|
+
value: string;
|
|
10
|
+
label: string;
|
|
11
|
+
}
|
|
12
|
+
interface OptionBase {
|
|
13
|
+
/** Key into the values record. */
|
|
14
|
+
key: string;
|
|
15
|
+
label: string;
|
|
16
|
+
/** Optional "(i)" tooltip, as Office's info bubbles. */
|
|
17
|
+
info?: string;
|
|
18
|
+
/** Renders indented under the preceding control. */
|
|
19
|
+
indent?: boolean;
|
|
20
|
+
/** Shown disabled with this reason, for settings the product cannot honour yet. */
|
|
21
|
+
disabled?: string;
|
|
22
|
+
}
|
|
23
|
+
export type OfficeOptionControl = (OptionBase & {
|
|
24
|
+
kind: 'toggle';
|
|
25
|
+
}) | (OptionBase & {
|
|
26
|
+
kind: 'select';
|
|
27
|
+
choices: readonly OfficeOptionChoice[];
|
|
28
|
+
}) | (OptionBase & {
|
|
29
|
+
kind: 'number';
|
|
30
|
+
min: number;
|
|
31
|
+
max: number;
|
|
32
|
+
step?: number;
|
|
33
|
+
unit?: string;
|
|
34
|
+
}) | (OptionBase & {
|
|
35
|
+
kind: 'text';
|
|
36
|
+
maxLength?: number;
|
|
37
|
+
});
|
|
38
|
+
export interface OfficeOptionSection {
|
|
39
|
+
id: string;
|
|
40
|
+
title: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
controls: readonly OfficeOptionControl[];
|
|
43
|
+
}
|
|
44
|
+
export interface OfficeOptionCategory {
|
|
45
|
+
id: string;
|
|
46
|
+
label: string;
|
|
47
|
+
/** Headline at the top of the pane. */
|
|
48
|
+
description?: string;
|
|
49
|
+
sections: readonly OfficeOptionSection[];
|
|
50
|
+
/** The whole category is not available yet; the pane explains why. */
|
|
51
|
+
disabled?: string;
|
|
52
|
+
}
|
|
53
|
+
/** Emitted on OK with every value and the keys that changed. */
|
|
54
|
+
export type OfficeOptionsChangeEvent = CustomEvent<{
|
|
55
|
+
values: OfficeOptionValues;
|
|
56
|
+
changed: string[];
|
|
57
|
+
}>;
|
|
58
|
+
/** Clamp a number edit into range; `undefined` when it is not a finite number. */
|
|
59
|
+
export declare function clampOptionNumber(raw: string, min: number, max: number): number | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* `<office-ui-options-dialog>`: set `categories` and `values`, then `show()` (or the `open`
|
|
62
|
+
* attribute). Edits stay in a draft until OK, which emits `office-options-change` and closes;
|
|
63
|
+
* Cancel, Escape and the close button discard them. `heading` defaults to "Options".
|
|
64
|
+
*/
|
|
65
|
+
export declare const defineOptionsDialog: import("./registry.js").Definer;
|
|
66
|
+
export {};
|