ooxml-ui 0.19.0 → 0.21.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 +82 -36
- package/dist/base.d.ts +118 -0
- package/dist/{account.d.ts → chrome/account-profile.d.ts} +0 -6
- package/dist/chrome/account.d.ts +17 -0
- package/dist/chrome/backstage.d.ts +78 -0
- package/dist/chrome/find-bar.d.ts +111 -0
- package/dist/chrome/print-preview.d.ts +39 -0
- package/dist/chrome/ruler.d.ts +43 -0
- package/dist/chrome/status-bar.d.ts +80 -0
- package/dist/chrome/status-item.d.ts +40 -0
- package/dist/chrome/tab-strip.d.ts +88 -0
- package/dist/chrome/title-bar-types.d.ts +75 -0
- package/dist/chrome/title-bar.d.ts +81 -0
- package/dist/{chunk-5L3NYLAW.js → chunk-2X6QYQ3Q.js} +10 -1
- package/dist/{chunk-OAGGHX23.js → chunk-3MDKXKKQ.js} +53 -65
- package/dist/chunk-5A4REH6T.js +259 -0
- package/dist/chunk-E47762NY.js +90 -0
- package/dist/chunk-HNGJI5EZ.js +834 -0
- package/dist/{chunk-A3QNC6VS.js → chunk-HSJH6SUW.js} +41 -1
- package/dist/{chunk-GWAPPX66.js → chunk-HZ422LTR.js} +1 -49
- package/dist/chunk-UTLCJKYC.js +4527 -0
- package/dist/controls.d.ts +58 -46
- package/dist/controls.js +5 -5
- package/dist/dialog/dialog-footer.d.ts +40 -0
- package/dist/dialog/dialog.d.ts +52 -0
- package/dist/{options.d.ts → dialog/options-dialog.d.ts} +46 -1
- package/dist/form/checkable.d.ts +49 -0
- package/dist/form/checkbox.d.ts +8 -0
- package/dist/form/radio.d.ts +68 -0
- package/dist/form/search-field.d.ts +54 -0
- package/dist/{select-menu.d.ts → form/select-menu.d.ts} +3 -13
- package/dist/form/select.d.ts +115 -0
- package/dist/form/switch.d.ts +11 -0
- package/dist/form/zoom-slider.d.ts +61 -0
- package/dist/glyph.d.ts +2 -0
- package/dist/icon.d.ts +19 -0
- package/dist/icons.d.ts +0 -3
- package/dist/icons.js +1 -3
- package/dist/index.d.ts +4 -1
- package/dist/index.js +17 -12
- package/dist/menu/command-search.d.ts +74 -0
- package/dist/menu/context-menu.d.ts +89 -0
- package/dist/menu/menu-button.d.ts +77 -0
- package/dist/menu/menu-item.d.ts +52 -0
- package/dist/menu/menu-separator.d.ts +7 -0
- package/dist/notices/paste-options.d.ts +41 -0
- package/dist/notices/read-only-banner.d.ts +53 -0
- package/dist/notices/toasts.d.ts +40 -0
- package/dist/presence/presence.d.ts +53 -0
- package/dist/presence.d.ts +1 -31
- package/dist/presence.js +3 -3
- package/dist/ribbon/button.d.ts +60 -0
- package/dist/ribbon/gallery-styles.d.ts +2 -0
- package/dist/ribbon/gallery.d.ts +97 -0
- package/dist/ribbon/ribbon-group.d.ts +35 -0
- package/dist/{ribbon-section.d.ts → ribbon/ribbon-section.d.ts} +14 -1
- package/dist/ribbon/ribbon-stack.d.ts +10 -0
- package/dist/ribbon/ribbon-tabs.d.ts +82 -0
- package/dist/ribbon/ribbon-toggle.d.ts +49 -0
- package/dist/ribbon/ribbon-toolbar.d.ts +15 -0
- package/dist/ribbon/safe-svg.d.ts +1 -0
- package/dist/smartart/smartart.d.ts +43 -0
- package/dist/smartart.d.ts +1 -14
- package/dist/smartart.js +3 -3
- package/dist/styles.d.ts +1 -4
- package/dist/teams/app-rail.d.ts +29 -0
- package/dist/teams/avatar.d.ts +39 -0
- package/dist/teams/base.d.ts +17 -0
- package/dist/teams/call-controls.d.ts +61 -0
- package/dist/teams/call-grid.d.ts +33 -0
- package/dist/teams/channel-list.d.ts +40 -0
- package/dist/teams/chat-composer.d.ts +60 -0
- package/dist/teams/chat-list.d.ts +51 -0
- package/dist/teams/icons.d.ts +3 -0
- package/dist/teams/index.d.ts +14 -0
- package/dist/teams/prejoin.d.ts +40 -0
- package/dist/teams.js +5 -0
- package/dist/theme.js +2 -2
- package/dist/tokens.d.ts +245 -207
- package/package.json +12 -6
- package/dist/backstage.d.ts +0 -28
- package/dist/button.d.ts +0 -14
- package/dist/checkable.d.ts +0 -4
- package/dist/chrome-controls.d.ts +0 -52
- package/dist/chunk-6DZC4M2H.js +0 -5562
- package/dist/chunk-DECL6RNI.js +0 -119
- package/dist/chunk-UYPH4ESZ.js +0 -78
- package/dist/command-search.d.ts +0 -18
- package/dist/context-menu.d.ts +0 -20
- package/dist/dialog.d.ts +0 -13
- package/dist/document-notices.d.ts +0 -55
- package/dist/find-bar.d.ts +0 -15
- package/dist/menu.d.ts +0 -15
- package/dist/print-preview.d.ts +0 -11
- package/dist/radio.d.ts +0 -1
- package/dist/ribbon-tabs.d.ts +0 -14
- package/dist/ribbon-toggle.d.ts +0 -1
- package/dist/ribbon.d.ts +0 -24
- package/dist/ruler.d.ts +0 -10
- package/dist/search-field.d.ts +0 -1
- package/dist/select-styles.d.ts +0 -6
- package/dist/select.d.ts +0 -19
- package/dist/status-bar-view.d.ts +0 -50
- package/dist/status-bar.d.ts +0 -19
- package/dist/tab-strip.d.ts +0 -20
- package/dist/title-bar-search.d.ts +0 -43
- package/dist/title-bar-strip.d.ts +0 -20
- package/dist/title-bar.d.ts +0 -49
- package/dist/zoom-slider.d.ts +0 -9
- /package/dist/{menu-model.d.ts → menu/menu-model.d.ts} +0 -0
- /package/dist/{smartart-svg.d.ts → smartart/smartart-svg.d.ts} +0 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { TOUCH, tok, OFFICE_TOKENS } from './chunk-HSJH6SUW.js';
|
|
2
|
+
import { unsafeCSS, LitElement } from 'lit';
|
|
3
|
+
|
|
4
|
+
// src/registry.ts
|
|
5
|
+
var CONTRACT_REVISION = 1;
|
|
6
|
+
var CONTRACT_KEY = /* @__PURE__ */ Symbol.for("office-ui.web-control-contract");
|
|
7
|
+
function assertContract(registry, tag) {
|
|
8
|
+
const revision = registry.get(tag)?.[CONTRACT_KEY];
|
|
9
|
+
if (revision !== void 0 && revision !== CONTRACT_REVISION) {
|
|
10
|
+
throw new Error(
|
|
11
|
+
`Incompatible ${tag} contract (${revision}; expected ${CONTRACT_REVISION}). Load one version of ooxml-ui per window.`
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function defineOnce(registry, tag, make) {
|
|
16
|
+
assertContract(registry, tag);
|
|
17
|
+
if (registry.get(tag)) return;
|
|
18
|
+
const ctor = make();
|
|
19
|
+
Object.defineProperty(ctor, CONTRACT_KEY, { value: CONTRACT_REVISION });
|
|
20
|
+
registry.define(tag, ctor);
|
|
21
|
+
}
|
|
22
|
+
function browserRegistry() {
|
|
23
|
+
return typeof window === "undefined" ? void 0 : window.customElements;
|
|
24
|
+
}
|
|
25
|
+
function definer(tag, make) {
|
|
26
|
+
const define = (registry = browserRegistry()) => {
|
|
27
|
+
if (registry) defineOnce(registry, tag, make);
|
|
28
|
+
};
|
|
29
|
+
return Object.assign(define, { tag });
|
|
30
|
+
}
|
|
31
|
+
function emit(host, type, detail, cancelable = false) {
|
|
32
|
+
return host.dispatchEvent(
|
|
33
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable })
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function present(value) {
|
|
37
|
+
return value === "" || Boolean(value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/styles.ts
|
|
41
|
+
var COMMON_CONTROL_CSS = `
|
|
42
|
+
:host([hidden]) { display: none !important; }
|
|
43
|
+
@media ${TOUCH} {
|
|
44
|
+
:host { --office-target-size: ${tok("--office-target-size-touch")}; }
|
|
45
|
+
}
|
|
46
|
+
@media (forced-colors: active) {
|
|
47
|
+
:host(:focus-visible), :focus-visible { outline: ${tok("--office-focus-width")} solid Highlight; outline-offset: ${tok("--office-focus-offset")}; }
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
// src/base.ts
|
|
52
|
+
function withTokens(css) {
|
|
53
|
+
return css.replace(
|
|
54
|
+
/var\((--office-[\w-]+)\)/g,
|
|
55
|
+
(whole, name) => name in OFFICE_TOKENS ? `var(${name}, ${OFFICE_TOKENS[name]})` : whole
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
var controlStyles = (...sheets) => [
|
|
59
|
+
unsafeCSS(COMMON_CONTROL_CSS),
|
|
60
|
+
...sheets.map((sheet) => unsafeCSS(withTokens(sheet)))
|
|
61
|
+
];
|
|
62
|
+
var flag = {
|
|
63
|
+
type: Boolean,
|
|
64
|
+
reflect: true,
|
|
65
|
+
converter: {
|
|
66
|
+
fromAttribute: (value) => value !== null,
|
|
67
|
+
toAttribute: (value) => present(value) ? "" : null
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var readFlag = {
|
|
71
|
+
type: Boolean,
|
|
72
|
+
converter: {
|
|
73
|
+
fromAttribute: (value) => value !== null && value !== "false"
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var triState = {
|
|
77
|
+
reflect: true,
|
|
78
|
+
converter: {
|
|
79
|
+
fromAttribute: (value) => value === null ? void 0 : value !== "false",
|
|
80
|
+
toAttribute: (value) => value === void 0 ? null : String(value)
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var valueOn = {
|
|
84
|
+
type: String,
|
|
85
|
+
converter: { fromAttribute: (value) => value ?? "on" }
|
|
86
|
+
};
|
|
87
|
+
var OfficeElement = class extends LitElement {
|
|
88
|
+
static syncUpdates = true;
|
|
89
|
+
_rendering;
|
|
90
|
+
_ready;
|
|
91
|
+
constructor() {
|
|
92
|
+
super();
|
|
93
|
+
this.renderRoot = this.createRenderRoot();
|
|
94
|
+
this._ready = true;
|
|
95
|
+
if (this.constructor.syncUpdates)
|
|
96
|
+
queueMicrotask(() => {
|
|
97
|
+
if (this.isConnected) this.ensureRendered();
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Render now if the element has never rendered; a no-op afterwards or while rendering. A
|
|
102
|
+
* disconnected element may be rendered here from inside a constructor (a subclass reading
|
|
103
|
+
* `shadowRoot`), and a constructor may not add host attributes, so while it renders its host
|
|
104
|
+
* writes are queued and applied before the next write or update, or on connection.
|
|
105
|
+
*/
|
|
106
|
+
ensureRendered() {
|
|
107
|
+
if (!this._ready || this._rendering || this.hasUpdated || !this.isUpdatePending || !this.constructor.syncUpdates)
|
|
108
|
+
return;
|
|
109
|
+
this._deferring = !this.isConnected;
|
|
110
|
+
this._detachedRender ||= this._deferring;
|
|
111
|
+
try {
|
|
112
|
+
this.performUpdate();
|
|
113
|
+
} finally {
|
|
114
|
+
this._deferring = false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
_detachedRender;
|
|
118
|
+
/** True while a detached first render runs (inside a constructor, maybe): no children may be added. */
|
|
119
|
+
get detachedFirstRender() {
|
|
120
|
+
return this._deferring === true;
|
|
121
|
+
}
|
|
122
|
+
_queue;
|
|
123
|
+
_deferring;
|
|
124
|
+
/** Write to the host element: queued (and dropped) during a detached first render, else applied at once. */
|
|
125
|
+
hostWrite(write) {
|
|
126
|
+
if (this._deferring) (this._queue ??= []).push(write);
|
|
127
|
+
else {
|
|
128
|
+
this.flushHost();
|
|
129
|
+
write();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Forget the host writes a detached first render queued. They are stale by the time anything
|
|
134
|
+
* else happens (replaying one would fire an attribute change that overwrites a newer property),
|
|
135
|
+
* and the render that follows connecting recomputes every host write from the current state.
|
|
136
|
+
*/
|
|
137
|
+
flushHost() {
|
|
138
|
+
this._queue = void 0;
|
|
139
|
+
}
|
|
140
|
+
setAttribute(name, value) {
|
|
141
|
+
this.hostWrite(() => super.setAttribute(name, value));
|
|
142
|
+
}
|
|
143
|
+
removeAttribute(name) {
|
|
144
|
+
this.hostWrite(() => super.removeAttribute(name));
|
|
145
|
+
}
|
|
146
|
+
toggleAttribute(name, force) {
|
|
147
|
+
if (!this._deferring) {
|
|
148
|
+
this.flushHost();
|
|
149
|
+
return super.toggleAttribute(name, force);
|
|
150
|
+
}
|
|
151
|
+
const on = force ?? !this.hasAttribute(name);
|
|
152
|
+
this.hostWrite(() => super.toggleAttribute(name, on));
|
|
153
|
+
return on;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Reflecting properties write their attribute as soon as they are set, even before the element
|
|
157
|
+
* connects (Lit alone reflects during an update). A `flag` property also stores a real
|
|
158
|
+
* boolean whatever it is given, so a framework writing `''` (the attribute idiom for
|
|
159
|
+
* "present") reads back `true`.
|
|
160
|
+
*/
|
|
161
|
+
static createProperty(name, options = {}) {
|
|
162
|
+
if (!options.reflect || options.noAccessor || options.state)
|
|
163
|
+
return super.createProperty(name, options);
|
|
164
|
+
const quiet = { ...options, reflect: false };
|
|
165
|
+
super.createProperty(name, { ...quiet, noAccessor: true });
|
|
166
|
+
const store = Symbol(String(name));
|
|
167
|
+
const attribute = typeof options.attribute === "string" ? options.attribute : String(name).toLowerCase();
|
|
168
|
+
const isFlag = options.converter === flag.converter;
|
|
169
|
+
Object.defineProperty(this.prototype, name, {
|
|
170
|
+
configurable: true,
|
|
171
|
+
enumerable: true,
|
|
172
|
+
get() {
|
|
173
|
+
return this[store];
|
|
174
|
+
},
|
|
175
|
+
set(value) {
|
|
176
|
+
const old = this[store];
|
|
177
|
+
const next = isFlag ? present(value) : value;
|
|
178
|
+
this[store] = next;
|
|
179
|
+
const deferred = old === void 0;
|
|
180
|
+
if (!deferred) this.reflectAttribute(attribute, next, options);
|
|
181
|
+
this.requestUpdate(name, old, deferred ? options : quiet);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Attributes the element reads straight from the DOM, without a property of the same name: a
|
|
187
|
+
* product subclass reads them too, and a framework that assigns properties it finds (React 19)
|
|
188
|
+
* must write the attribute instead. Changing one redraws the element.
|
|
189
|
+
*/
|
|
190
|
+
static watched = [];
|
|
191
|
+
static get observedAttributes() {
|
|
192
|
+
return [...super.observedAttributes, ...this.watched];
|
|
193
|
+
}
|
|
194
|
+
fromAttribute;
|
|
195
|
+
attributeChangedCallback(name, old, value) {
|
|
196
|
+
this.fromAttribute = name;
|
|
197
|
+
try {
|
|
198
|
+
super.attributeChangedCallback(name, old, value);
|
|
199
|
+
} finally {
|
|
200
|
+
this.fromAttribute = void 0;
|
|
201
|
+
}
|
|
202
|
+
if (this.constructor.watched.includes(name)) this.requestUpdate();
|
|
203
|
+
}
|
|
204
|
+
/** Write a property's value to its attribute now, unless the attribute is where it came from. */
|
|
205
|
+
reflectAttribute(attribute, value, options) {
|
|
206
|
+
if (this.fromAttribute === attribute) return;
|
|
207
|
+
const converter = options.converter;
|
|
208
|
+
const text = converter && typeof converter === "object" && converter.toAttribute ? converter.toAttribute(value, options.type) : options.type === Boolean ? value ? "" : null : value === null || value === void 0 ? null : String(value);
|
|
209
|
+
if (this.getAttribute(attribute) === text) return;
|
|
210
|
+
if (text === null || text === void 0) this.removeAttribute(attribute);
|
|
211
|
+
else this.setAttribute(attribute, String(text));
|
|
212
|
+
}
|
|
213
|
+
/** Dispatch a bubbling, composed event with `detail`. */
|
|
214
|
+
fire(type, detail, cancelable = false) {
|
|
215
|
+
return emit(this, type, detail, cancelable);
|
|
216
|
+
}
|
|
217
|
+
get immediate() {
|
|
218
|
+
return this.constructor.syncUpdates;
|
|
219
|
+
}
|
|
220
|
+
connectedCallback() {
|
|
221
|
+
this.flushHost();
|
|
222
|
+
super.connectedCallback();
|
|
223
|
+
if (this._detachedRender) {
|
|
224
|
+
this._detachedRender = false;
|
|
225
|
+
this.requestUpdate();
|
|
226
|
+
}
|
|
227
|
+
if (this.immediate && !this.hasUpdated && this.isUpdatePending) this.performUpdate();
|
|
228
|
+
}
|
|
229
|
+
performUpdate() {
|
|
230
|
+
if (!this._deferring) this.flushHost();
|
|
231
|
+
this._rendering = true;
|
|
232
|
+
try {
|
|
233
|
+
return super.performUpdate();
|
|
234
|
+
} finally {
|
|
235
|
+
this._rendering = false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
requestUpdate(name, oldValue, options) {
|
|
239
|
+
super.requestUpdate(name, oldValue, options);
|
|
240
|
+
if (this._ready && this.immediate && this.hasUpdated && !this._rendering && this.isUpdatePending)
|
|
241
|
+
this.performUpdate();
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
function inheritedShadowRoot() {
|
|
245
|
+
for (let proto = Object.getPrototypeOf(OfficeElement.prototype); proto; proto = Object.getPrototypeOf(proto)) {
|
|
246
|
+
const getter = Object.getOwnPropertyDescriptor(proto, "shadowRoot")?.get;
|
|
247
|
+
if (getter) return getter;
|
|
248
|
+
}
|
|
249
|
+
return void 0;
|
|
250
|
+
}
|
|
251
|
+
Object.defineProperty(OfficeElement.prototype, "shadowRoot", {
|
|
252
|
+
configurable: true,
|
|
253
|
+
get() {
|
|
254
|
+
this.ensureRendered();
|
|
255
|
+
return inheritedShadowRoot()?.call(this) ?? null;
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
export { CONTRACT_REVISION, OfficeElement, controlStyles, definer, flag, present, readFlag, triState, valueOn, withTokens };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { OfficeElement, controlStyles, definer } from './chunk-5A4REH6T.js';
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
|
|
4
|
+
// raw-css:/home/runner/work/ooxml/ooxml/packages/ui/src/presence/presence.css?raw
|
|
5
|
+
var presence_default = ":host {\n display: inline-flex;\n align-items: center;\n}\nul {\n display: flex;\n margin: 0;\n padding: 0;\n list-style: none;\n}\nli {\n margin-inline-start: calc(-1 * var(--office-space-1-5));\n}\nli:first-child {\n margin-inline-start: 0;\n}\nbutton,\n.more {\n box-sizing: border-box;\n display: inline-grid;\n place-items: center;\n width: var(--office-target-size);\n height: var(--office-target-size);\n padding: 0;\n border-radius: 50%;\n border: var(--office-border-width-thick) solid var(--office-avatar-color);\n background: var(--office-surface);\n color: var(--office-foreground);\n font: 600 var(--office-font-size-xs) var(--office-font);\n cursor: pointer;\n}\n.more {\n cursor: default;\n border-color: var(--office-border);\n}\nbutton:focus-visible {\n outline: var(--office-focus-width) solid var(--office-ring);\n outline-offset: calc(var(--office-focus-offset) / 2);\n z-index: 1;\n}\nbutton[data-status='idle'] {\n opacity: 0.7;\n}\nbutton[data-status='away'] {\n opacity: 0.45;\n border-style: dashed;\n}\n@media (forced-colors: active) {\n button,\n .more {\n border-color: CanvasText;\n background: Canvas;\n color: CanvasText;\n }\n button:focus-visible {\n outline-color: Highlight;\n }\n}\n";
|
|
6
|
+
|
|
7
|
+
// src/presence/presence.ts
|
|
8
|
+
function participantsFromAwareness(states, selfId) {
|
|
9
|
+
const out = [];
|
|
10
|
+
for (const state of states) {
|
|
11
|
+
const user = state?.user;
|
|
12
|
+
const id = String(user?.id ?? state?.clientId ?? "");
|
|
13
|
+
if (!id || !user?.name) continue;
|
|
14
|
+
out.push({
|
|
15
|
+
id,
|
|
16
|
+
name: user.name,
|
|
17
|
+
...user.color ? { color: user.color } : {},
|
|
18
|
+
...user.status ? { status: user.status } : {},
|
|
19
|
+
...id === selfId || user.self ? { self: true } : {}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
var initialsOf = (name) => {
|
|
25
|
+
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
26
|
+
if (parts.length === 0) return "?";
|
|
27
|
+
const first = [...parts[0] ?? ""][0] ?? "?";
|
|
28
|
+
const last = parts.length > 1 ? [...parts[parts.length - 1] ?? ""][0] ?? "" : "";
|
|
29
|
+
return (first + last).toUpperCase();
|
|
30
|
+
};
|
|
31
|
+
var OfficeUiPresence = class extends OfficeElement {
|
|
32
|
+
static styles = controlStyles(presence_default);
|
|
33
|
+
static properties = {
|
|
34
|
+
// `participants` keeps the local user first, so it has an accessor.
|
|
35
|
+
max: { type: String },
|
|
36
|
+
label: { type: String }
|
|
37
|
+
};
|
|
38
|
+
people = [];
|
|
39
|
+
constructor() {
|
|
40
|
+
super();
|
|
41
|
+
this.max = null;
|
|
42
|
+
this.label = null;
|
|
43
|
+
}
|
|
44
|
+
get participants() {
|
|
45
|
+
return this.people;
|
|
46
|
+
}
|
|
47
|
+
set participants(next) {
|
|
48
|
+
this.people = [...next].sort((a, b) => Number(Boolean(b.self)) - Number(Boolean(a.self)));
|
|
49
|
+
this.requestUpdate("participants");
|
|
50
|
+
}
|
|
51
|
+
get visible() {
|
|
52
|
+
const n = Number(this.max ?? 4);
|
|
53
|
+
return Number.isFinite(n) && n >= 1 ? Math.floor(n) : 4;
|
|
54
|
+
}
|
|
55
|
+
willUpdate() {
|
|
56
|
+
this.setAttribute("role", "group");
|
|
57
|
+
this.setAttribute("aria-label", this.label ?? `${this.people.length} collaborators`);
|
|
58
|
+
}
|
|
59
|
+
person(person) {
|
|
60
|
+
const status = person.status && person.status !== "active" ? `, ${person.status}` : "";
|
|
61
|
+
return html`<li>
|
|
62
|
+
<button
|
|
63
|
+
type="button"
|
|
64
|
+
data-id=${person.id}
|
|
65
|
+
data-status=${person.status ?? "active"}
|
|
66
|
+
style=${person.color ? `--office-avatar-color:${person.color}` : ""}
|
|
67
|
+
aria-label="${person.name}${person.self ? " (you)" : ""}${status}"
|
|
68
|
+
title=${person.name}
|
|
69
|
+
@click=${() => this.fire("office-presence-select", { id: person.id })}
|
|
70
|
+
>${initialsOf(person.name)}</button
|
|
71
|
+
>
|
|
72
|
+
</li>`;
|
|
73
|
+
}
|
|
74
|
+
render() {
|
|
75
|
+
const shown = this.people.slice(0, this.visible);
|
|
76
|
+
const hidden = this.people.length - shown.length;
|
|
77
|
+
const names = this.people.slice(shown.length).map((p) => p.name).join(", ");
|
|
78
|
+
return html`<ul role="list">
|
|
79
|
+
${shown.map((person) => this.person(person))}
|
|
80
|
+
${hidden > 0 ? html`<li>
|
|
81
|
+
<span class="more" title=${names} aria-label="${hidden} more: ${names}"
|
|
82
|
+
>+${hidden}</span
|
|
83
|
+
>
|
|
84
|
+
</li>` : ""}
|
|
85
|
+
</ul>`;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var definePresence = definer("office-ui-presence", () => OfficeUiPresence);
|
|
89
|
+
|
|
90
|
+
export { OfficeUiPresence, definePresence, initialsOf, participantsFromAwareness };
|