@unofficialbox/box-open-elements 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/dist/components/actions/menu-item.d.ts +2 -0
- package/dist/components/actions/menu-item.js +4 -0
- package/dist/components/collections/card.js +6 -0
- package/dist/components/collections/check-list.d.ts +10 -0
- package/dist/components/collections/check-list.js +8 -0
- package/dist/components/collections/document-list.d.ts +10 -0
- package/dist/components/collections/document-list.js +8 -0
- package/dist/components/collections/fact-list.d.ts +10 -0
- package/dist/components/collections/fact-list.js +8 -0
- package/dist/components/collections/result-blocks.d.ts +54 -0
- package/dist/components/collections/result-blocks.js +74 -0
- package/dist/components/feedback/alert.d.ts +2 -0
- package/dist/components/feedback/alert.js +17 -13
- package/dist/components/feedback/progress-bar.d.ts +9 -0
- package/dist/components/feedback/progress-bar.js +29 -3
- package/dist/components/feedback/status-icon.d.ts +10 -0
- package/dist/components/feedback/status-icon.js +26 -0
- package/dist/components/feedback/toast.d.ts +10 -1
- package/dist/components/feedback/toast.js +69 -27
- package/dist/components/forms/number-input.d.ts +1 -0
- package/dist/components/forms/number-input.js +9 -6
- package/dist/components/forms/search-field.js +16 -0
- package/dist/components/overlays/context-menu.d.ts +2 -0
- package/dist/components/overlays/context-menu.js +7 -0
- package/dist/components/overlays/dialog.js +19 -3
- package/dist/components/overlays/popover.js +6 -1
- package/dist/element-maps.d.ts +49 -19
- package/dist/entries/agent-workspace.d.ts +1 -0
- package/dist/entries/agent-workspace.js +1 -0
- package/dist/entries/call-console.d.ts +1 -0
- package/dist/entries/call-console.js +1 -0
- package/dist/entries/check-list.d.ts +1 -0
- package/dist/entries/check-list.js +1 -0
- package/dist/entries/document-list.d.ts +1 -0
- package/dist/entries/document-list.js +1 -0
- package/dist/entries/fact-list.d.ts +1 -0
- package/dist/entries/fact-list.js +1 -0
- package/dist/entries/result-blocks.d.ts +1 -0
- package/dist/entries/result-blocks.js +1 -0
- package/dist/entries/run-summary.d.ts +1 -0
- package/dist/entries/run-summary.js +1 -0
- package/dist/entries/status-icon.d.ts +1 -0
- package/dist/entries/status-icon.js +1 -0
- package/dist/foundations/a11y/announcer.d.ts +12 -0
- package/dist/foundations/a11y/announcer.js +75 -0
- package/dist/foundations/a11y/focus.js +46 -25
- package/dist/foundations/a11y/index.d.ts +2 -0
- package/dist/foundations/a11y/index.js +1 -0
- package/dist/foundations/icons/box-iconography.d.ts +472 -472
- package/dist/foundations/icons/box-iconography.generated.d.ts +1151 -679
- package/dist/foundations/icons/box-iconography.generated.js +1006 -3588
- package/dist/foundations/icons/glyphs/index.d.ts +1 -0
- package/dist/foundations/icons/glyphs/index.js +2 -0
- package/dist/foundations/icons/glyphs/package.json +1 -0
- package/dist/foundations/motion/behaviors.d.ts +8 -0
- package/dist/foundations/motion/behaviors.js +24 -0
- package/dist/foundations/motion/index.d.ts +2 -0
- package/dist/foundations/motion/index.js +2 -0
- package/dist/foundations/motion/scroll-pin.d.ts +19 -0
- package/dist/foundations/motion/scroll-pin.js +60 -0
- package/dist/foundations/motion/tokens.d.ts +2 -0
- package/dist/foundations/motion/tokens.js +2 -0
- package/dist/foundations/overlay/positioning.js +7 -0
- package/dist/foundations/profiles/registry.d.ts +3 -0
- package/dist/foundations/profiles/registry.js +3 -0
- package/dist/foundations/profiles/types.d.ts +3 -0
- package/dist/foundations/status/index.d.ts +6 -0
- package/dist/foundations/status/index.js +35 -0
- package/dist/foundations/tokens/box-dark.js +4 -1
- package/dist/foundations/tokens/box-defaults.js +3 -0
- package/dist/foundations/tokens/registry.d.ts +3 -0
- package/dist/foundations/tokens/registry.js +3 -0
- package/dist/foundations/tokens/types.d.ts +3 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/patterns/agent-chat/agent-chat.d.ts +9 -0
- package/dist/patterns/agent-chat/agent-chat.js +146 -24
- package/dist/patterns/agent-chat/controller.d.ts +3 -1
- package/dist/patterns/agent-chat/controller.js +92 -16
- package/dist/patterns/agent-chat/index.d.ts +1 -0
- package/dist/patterns/agent-chat/index.js +1 -0
- package/dist/patterns/agent-chat/ndjson.d.ts +5 -0
- package/dist/patterns/agent-chat/ndjson.js +41 -0
- package/dist/patterns/agent-chat/types.d.ts +44 -1
- package/dist/patterns/agent-workspace/agent-workspace.d.ts +28 -0
- package/dist/patterns/agent-workspace/agent-workspace.js +215 -0
- package/dist/patterns/agent-workspace/controller.d.ts +38 -0
- package/dist/patterns/agent-workspace/controller.js +65 -0
- package/dist/patterns/agent-workspace/index.d.ts +2 -0
- package/dist/patterns/agent-workspace/index.js +2 -0
- package/dist/patterns/call-console/call-console.d.ts +20 -0
- package/dist/patterns/call-console/call-console.js +201 -0
- package/dist/patterns/call-console/controller.d.ts +23 -0
- package/dist/patterns/call-console/controller.js +50 -0
- package/dist/patterns/call-console/http-transport.d.ts +3 -0
- package/dist/patterns/call-console/http-transport.js +26 -0
- package/dist/patterns/call-console/index.d.ts +4 -0
- package/dist/patterns/call-console/index.js +4 -0
- package/dist/patterns/call-console/types.d.ts +32 -0
- package/dist/patterns/call-console/types.js +8 -0
- package/dist/patterns/content-explorer/adapters/action-menu.js +7 -5
- package/dist/patterns/content-explorer/adapters/toolbar.js +6 -2
- package/dist/patterns/content-uploader/content-uploader.js +2 -1
- package/dist/patterns/file-request/file-request-builder.js +3 -0
- package/dist/patterns/flow-builder/flow-builder.d.ts +48 -0
- package/dist/patterns/flow-builder/flow-builder.js +200 -0
- package/dist/patterns/flow-builder/index.d.ts +3 -0
- package/dist/patterns/flow-builder/index.js +3 -0
- package/dist/patterns/flow-builder/model.d.ts +33 -0
- package/dist/patterns/flow-builder/model.js +28 -0
- package/dist/patterns/flow-builder/primitives.d.ts +47 -0
- package/dist/patterns/flow-builder/primitives.js +192 -0
- package/dist/patterns/lineage/lineage-graph.js +26 -6
- package/dist/patterns/notifications/notification-inbox.js +19 -3
- package/dist/patterns/preview/annotation-inspector.js +2 -2
- package/dist/patterns/run/index.d.ts +2 -0
- package/dist/patterns/run/index.js +2 -0
- package/dist/patterns/run/progress.d.ts +24 -0
- package/dist/patterns/run/progress.js +32 -0
- package/dist/patterns/run/run-summary.d.ts +21 -0
- package/dist/patterns/run/run-summary.js +82 -0
- package/dist/patterns/run/run-trace.d.ts +1 -0
- package/dist/patterns/run/run-trace.js +14 -3
- package/dist/patterns/undo/index.d.ts +19 -0
- package/dist/patterns/undo/index.js +106 -0
- package/package.json +23 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseElement } from "../../core/index.js";
|
|
2
|
+
import { FeedbackAnnouncement } from "../../foundations/a11y/announcer.js";
|
|
2
3
|
import { toneAccessibleLabel, toneIcon } from "./tone.js";
|
|
3
4
|
import { boeRadius, boeSpace } from "../../foundations/geometry/index.js";
|
|
4
5
|
import { boeFocusVisibleStyles } from "../../foundations/tokens/index.js";
|
|
@@ -21,18 +22,8 @@ const toastStyles = `
|
|
|
21
22
|
display: none !important;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
/*
|
|
25
|
-
|
|
26
|
-
derived from the tone accent. The --toast-accent property exists only to
|
|
27
|
-
colour the status glyph, which upstream has no equivalent for, so adding it
|
|
28
|
-
costs no conformance.
|
|
29
|
-
|
|
30
|
-
There is no border. Upstream .notification has one, and box-open-elements
|
|
31
|
-
matched it until the outline was judged too heavy; the claim that pinned it
|
|
32
|
-
was retired rather than left describing something no longer painted. Tone
|
|
33
|
-
survives that in three places — the tinted fill, the full-strength glyph,
|
|
34
|
-
and the visually-hidden tone label — so it was never carried by the border
|
|
35
|
-
alone. */
|
|
25
|
+
/* Preserve upstream light tints while deriving dark fills from the active
|
|
26
|
+
surface. Status ink, tinted fill and a text label communicate the tone. */
|
|
36
27
|
[part="toast"] {
|
|
37
28
|
--toast-accent: var(--boe-token-text-text, #222222);
|
|
38
29
|
|
|
@@ -57,19 +48,19 @@ const toastStyles = `
|
|
|
57
48
|
}
|
|
58
49
|
|
|
59
50
|
[part="toast"][data-tone="success"] {
|
|
60
|
-
--toast-accent: var(--boe-token-
|
|
61
|
-
background: color-mix(in srgb, var(--boe-token-surface-status-surface-success, #26c281) 20%, #
|
|
51
|
+
--toast-accent: var(--boe-token-text-status-text-success, #187657);
|
|
52
|
+
background: color-mix(in srgb, var(--boe-token-surface-status-surface-success, #26c281) 20%, var(--boe-token-surface-surface, #ffffff));
|
|
62
53
|
}
|
|
63
54
|
|
|
64
55
|
[part="toast"][data-tone="error"] {
|
|
65
|
-
--toast-accent: var(--boe-token-
|
|
66
|
-
background: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 20%, #
|
|
56
|
+
--toast-accent: var(--boe-token-text-status-text-error, #b92340);
|
|
57
|
+
background: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 20%, var(--boe-token-surface-surface, #ffffff));
|
|
67
58
|
}
|
|
68
59
|
|
|
69
60
|
[part="toast"][data-tone="warning"],
|
|
70
61
|
[part="toast"][data-tone="inprogress"] {
|
|
71
|
-
--toast-accent: var(--boe-token-
|
|
72
|
-
background: color-mix(in srgb, var(--boe-token-surface-status-surface-inprogress, #f5b31b) 20%, #
|
|
62
|
+
--toast-accent: var(--boe-token-text-status-text-warning, #805600);
|
|
63
|
+
background: color-mix(in srgb, var(--boe-token-surface-status-surface-inprogress, #f5b31b) 20%, var(--boe-token-surface-surface, #ffffff));
|
|
73
64
|
}
|
|
74
65
|
|
|
75
66
|
.sr-only {
|
|
@@ -88,8 +79,7 @@ const toastStyles = `
|
|
|
88
79
|
flex: 0 0 auto;
|
|
89
80
|
inline-size: 20px;
|
|
90
81
|
block-size: 20px;
|
|
91
|
-
/*
|
|
92
|
-
read as the status colour rather than a darkened version of it. */
|
|
82
|
+
/* Readable status ink is separate from the decorative fill colour. */
|
|
93
83
|
color: var(--toast-accent);
|
|
94
84
|
}
|
|
95
85
|
|
|
@@ -205,6 +195,10 @@ export class Toast extends BaseElement {
|
|
|
205
195
|
}
|
|
206
196
|
openValue = false;
|
|
207
197
|
timeoutId = null;
|
|
198
|
+
remaining = 0;
|
|
199
|
+
deadline = 0;
|
|
200
|
+
holds = new Set();
|
|
201
|
+
announcement = new FeedbackAnnouncement();
|
|
208
202
|
toastEl;
|
|
209
203
|
iconEl;
|
|
210
204
|
headingEl;
|
|
@@ -255,11 +249,36 @@ export class Toast extends BaseElement {
|
|
|
255
249
|
clearTimeout(this.timeoutId);
|
|
256
250
|
this.timeoutId = null;
|
|
257
251
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
252
|
+
this.remaining = Number.isFinite(duration) ? Math.max(0, duration) : 0;
|
|
253
|
+
this.resumeTimer();
|
|
254
|
+
}
|
|
255
|
+
resumeTimer() {
|
|
256
|
+
if (!this.isConnected || !this.open || this.holds.size || this.remaining <= 0 || this.mode === "sticky" || this.tone === "error")
|
|
257
|
+
return;
|
|
258
|
+
this.deadline = Date.now() + this.remaining;
|
|
259
|
+
this.timeoutId = setTimeout(() => {
|
|
260
|
+
this.timeoutId = null;
|
|
261
|
+
this.remaining = 0;
|
|
262
|
+
this.dismiss("timeout");
|
|
263
|
+
}, this.remaining);
|
|
264
|
+
}
|
|
265
|
+
hold(reason, active) {
|
|
266
|
+
if (active) {
|
|
267
|
+
this.holds.add(reason);
|
|
268
|
+
if (this.timeoutId !== null) {
|
|
269
|
+
this.remaining = Math.max(0, this.deadline - Date.now());
|
|
270
|
+
clearTimeout(this.timeoutId);
|
|
271
|
+
this.timeoutId = null;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else if (this.holds.delete(reason) && !this.holds.size) {
|
|
275
|
+
this.resumeTimer();
|
|
261
276
|
}
|
|
262
277
|
}
|
|
278
|
+
dismiss(source) {
|
|
279
|
+
this.hide();
|
|
280
|
+
this.dispatchEvent(new CustomEvent("dismiss", { bubbles: true, composed: true, detail: { source } }));
|
|
281
|
+
}
|
|
263
282
|
get message() {
|
|
264
283
|
return this.getAttribute("message") ?? "";
|
|
265
284
|
}
|
|
@@ -308,16 +327,26 @@ export class Toast extends BaseElement {
|
|
|
308
327
|
this.setAttribute("tone", value);
|
|
309
328
|
}
|
|
310
329
|
disconnectedCallback() {
|
|
330
|
+
this.announcement.reset();
|
|
331
|
+
this.holds.clear();
|
|
311
332
|
if (this.timeoutId) {
|
|
333
|
+
this.remaining = Math.max(0, this.deadline - Date.now());
|
|
312
334
|
clearTimeout(this.timeoutId);
|
|
313
335
|
this.timeoutId = null;
|
|
314
336
|
}
|
|
315
337
|
}
|
|
338
|
+
connectedCallback() {
|
|
339
|
+
super.connectedCallback();
|
|
340
|
+
this.resumeTimer();
|
|
341
|
+
}
|
|
316
342
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
317
343
|
if (name === "open") {
|
|
318
344
|
this.openValue = this.hasAttribute("open");
|
|
319
345
|
}
|
|
320
346
|
super.attributeChangedCallback(name, oldValue, newValue);
|
|
347
|
+
if (oldValue !== newValue && ["open", "duration", "mode", "tone"].includes(name)) {
|
|
348
|
+
this.scheduleAutoDismiss(this.open ? this.duration : 0);
|
|
349
|
+
}
|
|
321
350
|
}
|
|
322
351
|
show(message, options) {
|
|
323
352
|
if (typeof message === "string") {
|
|
@@ -328,8 +357,12 @@ export class Toast extends BaseElement {
|
|
|
328
357
|
}
|
|
329
358
|
this.open = true;
|
|
330
359
|
// options.duration wins; else a declarative `duration` attribute; else 2500.
|
|
331
|
-
const duration = options?.duration ?? (this.duration
|
|
360
|
+
const duration = options?.duration ?? (this.hasAttribute("duration") ? this.duration : 2500);
|
|
332
361
|
this.scheduleAutoDismiss(duration);
|
|
362
|
+
// Re-showing the same text is a new feedback event, even when already open.
|
|
363
|
+
this.announcement.reset();
|
|
364
|
+
if (this.isRendered)
|
|
365
|
+
this.update();
|
|
333
366
|
}
|
|
334
367
|
hide() {
|
|
335
368
|
this.open = false;
|
|
@@ -340,7 +373,7 @@ export class Toast extends BaseElement {
|
|
|
340
373
|
}
|
|
341
374
|
this.shadowRoot.innerHTML = `
|
|
342
375
|
<style>${toastStyles}</style>
|
|
343
|
-
<div part="toast" role="
|
|
376
|
+
<div part="toast" role="group" aria-label="Notification">
|
|
344
377
|
<span part="icon" aria-hidden="true"></span>
|
|
345
378
|
<div part="content">
|
|
346
379
|
<span part="tone-label" class="sr-only"></span>
|
|
@@ -360,9 +393,17 @@ export class Toast extends BaseElement {
|
|
|
360
393
|
this.dismissEl = this.shadowRoot.querySelector('[part="dismiss"]');
|
|
361
394
|
}
|
|
362
395
|
setupListeners() {
|
|
396
|
+
this.addEventListener("pointerenter", () => this.hold("pointer", true));
|
|
397
|
+
this.addEventListener("pointerleave", () => this.hold("pointer", false));
|
|
398
|
+
this.addEventListener("focusin", () => this.hold("focus", true));
|
|
399
|
+
this.addEventListener("focusout", event => {
|
|
400
|
+
const target = event.relatedTarget;
|
|
401
|
+
if (target instanceof Node && (this.contains(target) || this.shadowRoot?.contains(target)))
|
|
402
|
+
return;
|
|
403
|
+
this.hold("focus", false);
|
|
404
|
+
});
|
|
363
405
|
this.dismissEl.addEventListener("click", () => {
|
|
364
|
-
this.
|
|
365
|
-
this.hide();
|
|
406
|
+
this.dismiss("close-button");
|
|
366
407
|
});
|
|
367
408
|
this.actionSlot.addEventListener("slotchange", () => {
|
|
368
409
|
const hasContent = this.actionSlot.assignedNodes({ flatten: true }).length > 0;
|
|
@@ -375,6 +416,7 @@ export class Toast extends BaseElement {
|
|
|
375
416
|
}
|
|
376
417
|
const visible = this.openValue && Boolean(this.message);
|
|
377
418
|
this.hidden = !visible;
|
|
419
|
+
this.announcement.update(this, visible ? [toneAccessibleLabel(this.tone), this.heading, this.message].filter(Boolean).join(": ") : "", this.tone === "error" ? "assertive" : "polite");
|
|
378
420
|
if (!visible) {
|
|
379
421
|
return;
|
|
380
422
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { FormAssociatedElement, boeFormFieldErrorStyles, formErrorMessageMarkup, } from "../../core/index.js";
|
|
1
|
+
import { FormAssociatedElement, boeFormFieldErrorStyles, boeFormFieldSupportStyles, formDescriptionMarkup, formErrorMessageMarkup, } from "../../core/index.js";
|
|
2
2
|
import { boeNeutralInteractiveStyles } from "../../foundations/tokens/index.js";
|
|
3
3
|
import { boeMotionDuration, boeMotionEasing } from "../../foundations/motion/index.js";
|
|
4
|
-
import { boeRadius } from "../../foundations/geometry/index.js";
|
|
4
|
+
import { boeControl, boeRadius } from "../../foundations/geometry/index.js";
|
|
5
5
|
const DEFAULT_TAG_NAME = "box-number-input";
|
|
6
6
|
const parseNumber = (value, fallback) => {
|
|
7
7
|
if (value == null || value === "") {
|
|
@@ -29,11 +29,9 @@ const numberInputStyles = `
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
[part="label"] {
|
|
32
|
-
font-size:
|
|
32
|
+
font-size: ${boeControl.fontSize};
|
|
33
33
|
font-weight: 700;
|
|
34
|
-
|
|
35
|
-
text-transform: uppercase;
|
|
36
|
-
color: var(--boe-token-text-text-secondary, #6f6f6f);
|
|
34
|
+
color: var(--boe-token-text-text, #222222);
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
[part="input"] {
|
|
@@ -60,6 +58,7 @@ const numberInputStyles = `
|
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
${boeFormFieldErrorStyles}
|
|
61
|
+
${boeFormFieldSupportStyles}
|
|
63
62
|
`;
|
|
64
63
|
export class NumberInput extends FormAssociatedElement {
|
|
65
64
|
static tagName = DEFAULT_TAG_NAME;
|
|
@@ -79,6 +78,7 @@ export class NumberInput extends FormAssociatedElement {
|
|
|
79
78
|
inputEl;
|
|
80
79
|
labelEl;
|
|
81
80
|
errorEl;
|
|
81
|
+
descriptionEl;
|
|
82
82
|
get disabled() {
|
|
83
83
|
return this.hasAttribute("disabled");
|
|
84
84
|
}
|
|
@@ -194,6 +194,7 @@ export class NumberInput extends FormAssociatedElement {
|
|
|
194
194
|
<style>${numberInputStyles}</style>
|
|
195
195
|
<label part="field">
|
|
196
196
|
<span part="label"></span>
|
|
197
|
+
${formDescriptionMarkup()}
|
|
197
198
|
<input type="number" part="input" />
|
|
198
199
|
${formErrorMessageMarkup()}
|
|
199
200
|
</label>
|
|
@@ -201,6 +202,7 @@ export class NumberInput extends FormAssociatedElement {
|
|
|
201
202
|
this.labelEl = this.shadowRoot.querySelector('[part="label"]');
|
|
202
203
|
this.inputEl = this.shadowRoot.querySelector('[part="input"]');
|
|
203
204
|
this.errorEl = this.shadowRoot.querySelector('[part="error-message"]');
|
|
205
|
+
this.descriptionEl = this.shadowRoot.querySelector('[part="description"]');
|
|
204
206
|
}
|
|
205
207
|
setupListeners() {
|
|
206
208
|
this.inputEl.addEventListener("input", event => {
|
|
@@ -239,6 +241,7 @@ export class NumberInput extends FormAssociatedElement {
|
|
|
239
241
|
else {
|
|
240
242
|
this.inputEl.removeAttribute("disabled");
|
|
241
243
|
}
|
|
244
|
+
this.applyFieldSupport(this.labelEl, this.inputEl, this.descriptionEl);
|
|
242
245
|
this.applyInvalidState(this.inputEl, this.errorEl);
|
|
243
246
|
}
|
|
244
247
|
}
|
|
@@ -6,6 +6,11 @@ const searchSpinnerMarkup = '<span part="spinner" aria-hidden="true"></span>';
|
|
|
6
6
|
const searchFieldStyles = `
|
|
7
7
|
:host {
|
|
8
8
|
display: block;
|
|
9
|
+
min-inline-size: 0;
|
|
10
|
+
container: boe-search-field / inline-size;
|
|
11
|
+
/* Inline-size containment otherwise contributes zero intrinsic width in
|
|
12
|
+
content-sized flex/grid rows. Explicit parent widths still take priority. */
|
|
13
|
+
contain-intrinsic-inline-size: 20rem;
|
|
9
14
|
color: inherit;
|
|
10
15
|
font: inherit;
|
|
11
16
|
}
|
|
@@ -18,6 +23,7 @@ const searchFieldStyles = `
|
|
|
18
23
|
|
|
19
24
|
[part="field"] {
|
|
20
25
|
display: grid;
|
|
26
|
+
grid-template-columns: minmax(0, 1fr);
|
|
21
27
|
gap: 0.45rem;
|
|
22
28
|
}
|
|
23
29
|
|
|
@@ -116,6 +122,16 @@ const searchFieldStyles = `
|
|
|
116
122
|
background: var(--boe-token-surface-surface-hover, #f4f4f4);
|
|
117
123
|
}
|
|
118
124
|
|
|
125
|
+
@container boe-search-field (max-width: 22rem) {
|
|
126
|
+
[part="input-shell"] {
|
|
127
|
+
flex-wrap: wrap;
|
|
128
|
+
border-radius: ${boeRadius.control};
|
|
129
|
+
}
|
|
130
|
+
[part="input"] {
|
|
131
|
+
flex-basis: 100%;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
119
135
|
[part="submit"]:focus-visible,
|
|
120
136
|
[part="clear"]:focus-visible {
|
|
121
137
|
outline: none;
|
|
@@ -27,6 +27,8 @@ export declare class ContextMenu extends BaseElement {
|
|
|
27
27
|
get disabled(): boolean;
|
|
28
28
|
set disabled(value: boolean);
|
|
29
29
|
get open(): boolean;
|
|
30
|
+
/** Open from an explicit keyboard/touch trigger without a synthetic event. */
|
|
31
|
+
show(): void;
|
|
30
32
|
disconnectedCallback(): void;
|
|
31
33
|
protected renderTemplate(): void;
|
|
32
34
|
protected setupListeners(): void;
|
|
@@ -139,6 +139,13 @@ export class ContextMenu extends BaseElement {
|
|
|
139
139
|
get open() {
|
|
140
140
|
return this.openValue;
|
|
141
141
|
}
|
|
142
|
+
/** Open from an explicit keyboard/touch trigger without a synthetic event. */
|
|
143
|
+
show() {
|
|
144
|
+
if (!this.isConnected || !this.surfaceEl || this.disabled || !this.items.length || this.open)
|
|
145
|
+
return;
|
|
146
|
+
const rect = this.getBoundingClientRect();
|
|
147
|
+
this.openAt(rect.left, rect.bottom);
|
|
148
|
+
}
|
|
142
149
|
disconnectedCallback() {
|
|
143
150
|
this.unbindDocument();
|
|
144
151
|
}
|
|
@@ -17,11 +17,13 @@ const dialogStyles = `
|
|
|
17
17
|
max-* are reset because this element is the full-viewport scrim rather
|
|
18
18
|
than a centred card. */
|
|
19
19
|
[part="backdrop"] {
|
|
20
|
+
box-sizing: border-box;
|
|
20
21
|
position: fixed;
|
|
21
22
|
inset: 0;
|
|
22
23
|
z-index: 1200;
|
|
23
24
|
background: ${boeOverlay.modalBackdrop};
|
|
24
25
|
display: grid;
|
|
26
|
+
grid-template-columns: minmax(0, 1fr);
|
|
25
27
|
place-items: center;
|
|
26
28
|
padding: ${boeOverlay.modalPadding};
|
|
27
29
|
border: 0;
|
|
@@ -45,13 +47,18 @@ const dialogStyles = `
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
[part="dialog"] {
|
|
50
|
+
box-sizing: border-box;
|
|
51
|
+
min-width: 0;
|
|
52
|
+
max-width: 100%;
|
|
53
|
+
max-height: calc(100dvh - ${boeOverlay.modalPadding} - ${boeOverlay.modalPadding});
|
|
48
54
|
width: min(${boeOverlay.modalWidth}, calc(100vw - 3rem));
|
|
49
55
|
background: var(--boe-token-surface-surface, #ffffff);
|
|
50
56
|
border: 0;
|
|
51
57
|
border-radius: ${boeOverlay.modalRadius};
|
|
52
58
|
box-shadow: ${boeOverlay.modalShadow};
|
|
53
59
|
padding: ${boeOverlay.modalPadding};
|
|
54
|
-
display:
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
55
62
|
gap: ${boeSpace[5]};
|
|
56
63
|
color: var(--boe-token-text-text, #222222);
|
|
57
64
|
}
|
|
@@ -62,7 +69,7 @@ const dialogStyles = `
|
|
|
62
69
|
[part="dialog"][data-size="fullscreen"] {
|
|
63
70
|
width: calc(100vw - 2rem);
|
|
64
71
|
height: calc(100vh - 2rem);
|
|
65
|
-
max-width:
|
|
72
|
+
max-width: 100%;
|
|
66
73
|
border-radius: ${boeRadius.large};
|
|
67
74
|
}
|
|
68
75
|
|
|
@@ -86,6 +93,9 @@ const dialogStyles = `
|
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
[part="body"] {
|
|
96
|
+
min-height: 0;
|
|
97
|
+
overflow: auto;
|
|
98
|
+
overflow-wrap: anywhere;
|
|
89
99
|
color: var(--boe-token-text-text, #222222);
|
|
90
100
|
font-size: 14px;
|
|
91
101
|
line-height: 20px;
|
|
@@ -93,6 +103,8 @@ const dialogStyles = `
|
|
|
93
103
|
|
|
94
104
|
[part="footer"] {
|
|
95
105
|
display: flex;
|
|
106
|
+
flex-shrink: 0;
|
|
107
|
+
flex-wrap: wrap;
|
|
96
108
|
justify-content: end;
|
|
97
109
|
gap: ${boeSpace[2]};
|
|
98
110
|
margin-top: ${boeSpace[2]};
|
|
@@ -246,7 +258,11 @@ export class Dialog extends BaseElement {
|
|
|
246
258
|
});
|
|
247
259
|
this.hostEl.addEventListener("keydown", event => {
|
|
248
260
|
const keyboardEvent = event;
|
|
249
|
-
|
|
261
|
+
if (keyboardEvent.defaultPrevented)
|
|
262
|
+
return;
|
|
263
|
+
// Slotted controls are not DOM descendants of the surface; their event
|
|
264
|
+
// path still crosses it. closest() misses keyboard events from slots.
|
|
265
|
+
const dialog = keyboardEvent.composedPath().find(node => node instanceof HTMLElement && node.getAttribute("part") === "dialog");
|
|
250
266
|
if (!dialog || !this.hostEl.contains(dialog)) {
|
|
251
267
|
return;
|
|
252
268
|
}
|
|
@@ -64,13 +64,18 @@ const popoverStyles = `
|
|
|
64
64
|
unavailable or fails, the surface still renders exactly as before and only
|
|
65
65
|
the top-layer promotion is lost — see foundations/overlay/top-layer.ts. */
|
|
66
66
|
[part="surface"] {
|
|
67
|
+
box-sizing: border-box;
|
|
68
|
+
margin: 0;
|
|
69
|
+
inset: auto;
|
|
67
70
|
display: block;
|
|
68
71
|
position: fixed;
|
|
69
72
|
z-index: 30;
|
|
70
73
|
inset-block-start: 0;
|
|
71
74
|
inset-inline-start: 0;
|
|
72
75
|
width: min(360px, calc(100vw - 5rem));
|
|
73
|
-
min-width: 200px;
|
|
76
|
+
min-width: min(200px, calc(100vw - 1rem));
|
|
77
|
+
max-height: calc(100dvh - 1rem);
|
|
78
|
+
overflow: auto;
|
|
74
79
|
padding: ${boeOverlay.padding};
|
|
75
80
|
border: ${boeOverlay.border};
|
|
76
81
|
border-radius: ${boeOverlay.radius};
|