vintage-frames 0.2.0 → 0.3.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/custom-elements.json +214 -6
- package/dist/components/vf-checkbox.d.ts +5 -0
- package/dist/components/vf-checkbox.js +18 -10
- package/dist/components/vf-icon.d.ts +19 -4
- package/dist/components/vf-icon.js +11 -1
- package/dist/components/vf-menu-bar.d.ts +8 -0
- package/dist/components/vf-menu-bar.js +5 -2
- package/dist/components/vf-menu-item.d.ts +12 -6
- package/dist/components/vf-menu-item.js +32 -14
- package/dist/components/vf-menu.d.ts +14 -1
- package/dist/components/vf-menu.js +68 -48
- package/dist/components/vf-radio.d.ts +5 -0
- package/dist/components/vf-radio.js +16 -11
- package/dist/components/vf-window.d.ts +26 -0
- package/dist/components/vf-window.js +67 -18
- package/dist/styles/recipes/toggle.js +8 -0
- package/docs/SPEC.md +13 -10
- package/editor/vscode.html-custom-data.json +21 -6
- package/editor/web-types.json +53 -11
- package/package.json +3 -1
|
@@ -62,12 +62,18 @@ export declare class VfMenuItem extends VfMenuItem_base {
|
|
|
62
62
|
*/
|
|
63
63
|
checkable: boolean;
|
|
64
64
|
/**
|
|
65
|
-
* Keyboard shortcut
|
|
66
|
-
* shared shortcut column.
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
65
|
+
* Keyboard shortcut, e.g. `"⌘H"`, drawn left-aligned in the panel's
|
|
66
|
+
* shared shortcut column. The span is `aria-hidden` so the glyphs never
|
|
67
|
+
* concatenate into the item's accessible name ("Print… place of interest
|
|
68
|
+
* sign P") — the host mirrors it as `aria-keyshortcuts` ("Meta+H") instead,
|
|
69
|
+
* so AT announces it *as* a shortcut. A consumer's own `aria-keyshortcuts`
|
|
70
|
+
* wins.
|
|
71
|
+
*
|
|
72
|
+
* Inside a `vf-menu`/`vf-menu-bar` that declares `shortcuts`, this is a
|
|
73
|
+
* LIVE key equivalent, not a legend: a matching keydown anywhere on the
|
|
74
|
+
* page activates the item — menu open or not — claiming the stroke with
|
|
75
|
+
* `preventDefault()` (see the document keydown handler below for the full
|
|
76
|
+
* contract).
|
|
71
77
|
*/
|
|
72
78
|
shortcut: string;
|
|
73
79
|
/**
|
|
@@ -24,7 +24,20 @@ function b(e) {
|
|
|
24
24
|
let r = t.join("");
|
|
25
25
|
return r ? [...n, r].join("+") : "";
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
function x(e, t) {
|
|
28
|
+
let n = [...t.trim()], r = {
|
|
29
|
+
Meta: !1,
|
|
30
|
+
Control: !1,
|
|
31
|
+
Alt: !1,
|
|
32
|
+
Shift: !1
|
|
33
|
+
};
|
|
34
|
+
for (; n.length > 0 && y.has(n[0]);) r[y.get(n.shift())] = !0;
|
|
35
|
+
let i = n.join("");
|
|
36
|
+
if (!i || !r.Meta && !r.Control && !r.Alt && [...i].length === 1) return !1;
|
|
37
|
+
let a = r.Meta ? e.metaKey || e.ctrlKey : !e.metaKey, o = r.Control ? e.ctrlKey : r.Meta || !e.ctrlKey;
|
|
38
|
+
return a && o && e.altKey === r.Alt && e.shiftKey === r.Shift && e.key.toLowerCase() === i.toLowerCase();
|
|
39
|
+
}
|
|
40
|
+
var S = class extends r(f) {
|
|
28
41
|
static {
|
|
29
42
|
this.styles = [
|
|
30
43
|
a,
|
|
@@ -161,19 +174,21 @@ var x = class extends r(f) {
|
|
|
161
174
|
#r;
|
|
162
175
|
#i;
|
|
163
176
|
constructor() {
|
|
164
|
-
super(), this.scale = new t(this), this.disabled = !1, this.checked = !1, this.active = !1, this.checkable = !1, this.shortcut = "", this._blinkPhase = null, this.#t = !1, this.#n = !1, this.#r = this.attachInternals(), this.#i = !1, this
|
|
177
|
+
super(), this.scale = new t(this), this.disabled = !1, this.checked = !1, this.active = !1, this.checkable = !1, this.shortcut = "", this._blinkPhase = null, this.#t = !1, this.#n = !1, this.#r = this.attachInternals(), this.#i = !1, this.#d = (e) => {
|
|
178
|
+
e.defaultPrevented || e.isComposing || this.disabled || !this.shortcut || this.closest("vf-menu[shortcuts], vf-menu-bar[shortcuts]") && x(e, this.shortcut) && (e.preventDefault(), !(e.repeat || this.#t) && (c(this, "vf-menu-flash-request", { item: this }, { composed: !1 }), this.activate()));
|
|
179
|
+
}, this.addEventListener("keydown", this.#u), this.addEventListener("pointerdown", this.#c), this.addEventListener("click", this.#l);
|
|
165
180
|
}
|
|
166
181
|
get #a() {
|
|
167
182
|
return this.checkable || this.#n;
|
|
168
183
|
}
|
|
169
184
|
connectedCallback() {
|
|
170
|
-
super.connectedCallback(), this.#s(), this.#o(), this.hasAttribute("tabindex") || (this.tabIndex = -1);
|
|
185
|
+
super.connectedCallback(), this.#s(), this.#o(), this.hasAttribute("tabindex") || (this.tabIndex = -1), document.addEventListener("keydown", this.#d);
|
|
171
186
|
}
|
|
172
187
|
disconnectedCallback() {
|
|
173
|
-
super.disconnectedCallback(), this.#d();
|
|
188
|
+
super.disconnectedCallback(), document.removeEventListener("keydown", this.#d), this.#f();
|
|
174
189
|
}
|
|
175
190
|
updated(e) {
|
|
176
|
-
e.has("disabled") && (this.#r.ariaDisabled = this.disabled ? "true" : null, this.disabled && this.#
|
|
191
|
+
e.has("disabled") && (this.#r.ariaDisabled = this.disabled ? "true" : null, this.disabled && this.#f()), e.has("checked") && this.checked && (this.#n = !0), (e.has("checked") || e.has("checkable")) && this.#s(), e.has("shortcut") && this.#o();
|
|
177
192
|
}
|
|
178
193
|
#o() {
|
|
179
194
|
this.#r.ariaKeyShortcuts = b(this.shortcut) || null;
|
|
@@ -215,39 +230,42 @@ var x = class extends r(f) {
|
|
|
215
230
|
#u(e) {
|
|
216
231
|
(e.key === "Enter" || e.key === " ") && (e.preventDefault(), e.stopPropagation(), this.activate());
|
|
217
232
|
}
|
|
233
|
+
#d;
|
|
218
234
|
activate() {
|
|
219
235
|
if (this.disabled || this.#t) return;
|
|
220
236
|
this.#t = !0;
|
|
221
237
|
let e = l((e) => {
|
|
222
238
|
this._blinkPhase = e ? "on" : "off";
|
|
223
239
|
}, () => {
|
|
224
|
-
this._blinkPhase = null, this.#t = !1, this.#e = void 0, this.#
|
|
240
|
+
this._blinkPhase = null, this.#t = !1, this.#e = void 0, this.#p();
|
|
225
241
|
});
|
|
226
242
|
this.#t && (this.#e = e);
|
|
227
243
|
}
|
|
228
|
-
#
|
|
244
|
+
#f() {
|
|
229
245
|
this.#t && (this.#e?.cancel(), this.#e = void 0, this.#t = !1, this._blinkPhase = null);
|
|
230
246
|
}
|
|
231
|
-
#
|
|
247
|
+
#p() {
|
|
232
248
|
let e = this.value ?? (this.textContent ?? "").trim();
|
|
233
249
|
c(this, "vf-menu-select", {
|
|
234
250
|
value: e,
|
|
235
251
|
item: this
|
|
236
|
-
})
|
|
252
|
+
});
|
|
253
|
+
let t = this.closest("vf-menu");
|
|
254
|
+
(!t || t.hasAttribute("open")) && c(this, "vf-menu-close-request", { item: this }, { composed: !1 });
|
|
237
255
|
}
|
|
238
256
|
};
|
|
239
257
|
n([g({
|
|
240
258
|
type: Boolean,
|
|
241
259
|
reflect: !0
|
|
242
|
-
})],
|
|
260
|
+
})], S.prototype, "disabled", void 0), n([g({
|
|
243
261
|
type: Boolean,
|
|
244
262
|
reflect: !0
|
|
245
|
-
})],
|
|
263
|
+
})], S.prototype, "checked", void 0), n([g({
|
|
246
264
|
type: Boolean,
|
|
247
265
|
reflect: !0
|
|
248
|
-
})],
|
|
266
|
+
})], S.prototype, "active", void 0), n([g({
|
|
249
267
|
type: Boolean,
|
|
250
268
|
reflect: !0
|
|
251
|
-
})],
|
|
269
|
+
})], S.prototype, "checkable", void 0), n([g()], S.prototype, "shortcut", void 0), n([g()], S.prototype, "value", void 0), n([_()], S.prototype, "_blinkPhase", void 0), S = n([e("vf-menu-item")], S);
|
|
252
270
|
//#endregion
|
|
253
|
-
export {
|
|
271
|
+
export { S as VfMenuItem };
|
|
@@ -29,7 +29,8 @@ declare const VfMenu_base: (new (...args: any[]) => import("../position.js").VfP
|
|
|
29
29
|
* icon for the Apple menu. Keep the `label` attribute set too: it stays the
|
|
30
30
|
* menu's accessible name (the bar item's `aria-label` and the panel's) when
|
|
31
31
|
* the visible title is an image.
|
|
32
|
-
* @csspart label - The menu title in the bar (inverts while open
|
|
32
|
+
* @csspart label - The menu title in the bar (inverts while open; flashes
|
|
33
|
+
* when a closed menu's item is activated by its key equivalent).
|
|
33
34
|
* @csspart panel - The dropped `.vf-panel` containing the items.
|
|
34
35
|
* @cssprop [--vf-menubar-height=20px] - `vf-menu-bar`
|
|
35
36
|
* @cssprop [--vf-menu-row-height=16px] - `vf-menu-item` row pitch; the panel
|
|
@@ -53,6 +54,16 @@ export declare class VfMenu extends VfMenu_base {
|
|
|
53
54
|
* `vf-menu-bar` when present, otherwise by the menu itself.
|
|
54
55
|
*/
|
|
55
56
|
open: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Makes the items' `shortcut`s live key equivalents: a matching keydown
|
|
59
|
+
* anywhere on the page activates the item — menu open or not — and a
|
|
60
|
+
* closed menu answers by flashing its bar title, MenuKey's acknowledgment.
|
|
61
|
+
* Off by default because key equivalents are page-global and a page may
|
|
62
|
+
* hold several menus of which only one is *the* menu bar; on a bar, declare
|
|
63
|
+
* it there once for every menu in it. The full claim contract lives on
|
|
64
|
+
* `vf-menu-item.shortcut`.
|
|
65
|
+
*/
|
|
66
|
+
shortcuts: boolean;
|
|
56
67
|
/**
|
|
57
68
|
* The bar label's tabindex. A parent `vf-menu-bar` owns a roving tabindex
|
|
58
69
|
* across its menus and sets this to 0 on the active menu, -1 on the rest,
|
|
@@ -77,6 +88,8 @@ export declare class VfMenu extends VfMenu_base {
|
|
|
77
88
|
* src/menu-press.ts), so it wants the box, not the element.
|
|
78
89
|
*/
|
|
79
90
|
get labelRect(): DOMRect | null;
|
|
91
|
+
/** `true` while the key-equivalent flash paints the title inverted. */
|
|
92
|
+
private _flashOn;
|
|
80
93
|
connectedCallback(): void;
|
|
81
94
|
disconnectedCallback(): void;
|
|
82
95
|
protected updated(changed: Map<PropertyKey, unknown>): void;
|
|
@@ -9,15 +9,16 @@ import { vfFocusUnderline as s } from "../styles/recipes/focus.js";
|
|
|
9
9
|
import { GridSnapController as c } from "../grid-snap.js";
|
|
10
10
|
import { DocumentListenersController as l, releaseAfterGesture as u } from "../document-listeners.js";
|
|
11
11
|
import { deferActivation as d, emit as f } from "../events.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
12
|
+
import { runSelectionBlink as p } from "../motion.js";
|
|
13
|
+
import { FocusRuleController as m } from "../focus-modality.js";
|
|
14
|
+
import { TypeAheadBuffer as h } from "../type-ahead.js";
|
|
15
|
+
import { MenuPressController as g } from "../menu-press.js";
|
|
16
|
+
import { LitElement as _, css as v, html as y, nothing as b } from "lit";
|
|
17
|
+
import { property as x, query as S, queryAssignedElements as C, state as w } from "lit/decorators.js";
|
|
17
18
|
//#region src/components/vf-menu.ts
|
|
18
|
-
var
|
|
19
|
+
var T = class extends r(_) {
|
|
19
20
|
constructor(...e) {
|
|
20
|
-
super(...e), this.scale = new t(this), this.gridSnap = new c(this), this.#e = new
|
|
21
|
+
super(...e), this.scale = new t(this), this.gridSnap = new c(this), this.#e = new m(this), this.label = "", this.open = !1, this.shortcuts = !1, this.barTabIndex = 0, this.#t = new g(this, {
|
|
21
22
|
menus: () => [this],
|
|
22
23
|
open: (e) => {
|
|
23
24
|
e.open = !0;
|
|
@@ -25,11 +26,17 @@ var C = class extends r(g) {
|
|
|
25
26
|
close: () => {
|
|
26
27
|
this.open = !1;
|
|
27
28
|
}
|
|
28
|
-
}), this.#r = this.attachInternals(), this.#i = new
|
|
29
|
+
}), this.#r = this.attachInternals(), this.#i = new h(), this.#a = !1, this.#o = () => {
|
|
29
30
|
this.#n || this.focus(), this.open = !1;
|
|
30
|
-
}, this.#
|
|
31
|
+
}, this._flashOn = !1, this.#c = () => {
|
|
32
|
+
this.open || (this.#l(), this.#s = p((e) => {
|
|
33
|
+
this._flashOn = e;
|
|
34
|
+
}, () => {
|
|
35
|
+
this._flashOn = !1, this.#s = void 0;
|
|
36
|
+
}));
|
|
37
|
+
}, this.#u = (e) => {
|
|
31
38
|
e.composedPath().includes(this) || (this.open = !1);
|
|
32
|
-
}, this.#
|
|
39
|
+
}, this.#d = (e) => {
|
|
33
40
|
if (!e.defaultPrevented) switch (e.key) {
|
|
34
41
|
case "Escape":
|
|
35
42
|
e.preventDefault(), this.open = !1, this.focus();
|
|
@@ -39,7 +46,7 @@ var C = class extends r(g) {
|
|
|
39
46
|
break;
|
|
40
47
|
case "ArrowDown":
|
|
41
48
|
case "ArrowUp":
|
|
42
|
-
e.preventDefault(), this.#
|
|
49
|
+
e.preventDefault(), this.#f(e.key === "ArrowDown" ? 1 : -1);
|
|
43
50
|
break;
|
|
44
51
|
case "Home":
|
|
45
52
|
case "End": {
|
|
@@ -59,21 +66,21 @@ var C = class extends r(g) {
|
|
|
59
66
|
break;
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
|
-
}, this.#
|
|
69
|
+
}, this.#p = new l(this, () => [[
|
|
63
70
|
document,
|
|
64
71
|
"pointerdown",
|
|
65
|
-
this.#
|
|
72
|
+
this.#u,
|
|
66
73
|
!0
|
|
67
74
|
], [
|
|
68
75
|
document,
|
|
69
76
|
"keydown",
|
|
70
|
-
this.#
|
|
77
|
+
this.#d,
|
|
71
78
|
!0
|
|
72
|
-
]]), this.#
|
|
79
|
+
]]), this.#h = (e) => {
|
|
73
80
|
if (!this.open || this.#n) return;
|
|
74
81
|
let t = e.relatedTarget;
|
|
75
82
|
t instanceof Node && (this.contains(t) || this.renderRoot.contains(t)) || (this.open = !1);
|
|
76
|
-
}, this.#
|
|
83
|
+
}, this.#g = (e) => {
|
|
77
84
|
this.#e.suppress(), !this.#n && this.#t.onPointerDown(e);
|
|
78
85
|
};
|
|
79
86
|
}
|
|
@@ -82,7 +89,7 @@ var C = class extends r(g) {
|
|
|
82
89
|
a,
|
|
83
90
|
i,
|
|
84
91
|
o,
|
|
85
|
-
|
|
92
|
+
v`
|
|
86
93
|
:host {
|
|
87
94
|
display: inline-block;
|
|
88
95
|
position: relative;
|
|
@@ -105,7 +112,12 @@ var C = class extends r(g) {
|
|
|
105
112
|
touch-action: none;
|
|
106
113
|
cursor: var(--vf-cursor, default);
|
|
107
114
|
}
|
|
108
|
-
|
|
115
|
+
/* .flash-on: the key-equivalent acknowledgment — a closed menu whose
|
|
116
|
+
item was activated by its shortcut flashes the title on the item
|
|
117
|
+
blink's own cadence, the way MenuKey() flashed the bar. Shares the
|
|
118
|
+
open inversion so the two can't drift apart. */
|
|
119
|
+
:host([open]) .label,
|
|
120
|
+
.label.flash-on {
|
|
109
121
|
/* Forced colors: exempt the inverted title from the mode's text
|
|
110
122
|
backplate, which would land a Canvas slab on the highlight bar —
|
|
111
123
|
see vf-list-item's forced-colors note. The pair is already the
|
|
@@ -240,30 +252,35 @@ var C = class extends r(g) {
|
|
|
240
252
|
#o;
|
|
241
253
|
#s;
|
|
242
254
|
#c;
|
|
243
|
-
#l(
|
|
255
|
+
#l() {
|
|
256
|
+
this.#s?.cancel(), this.#s = void 0, this._flashOn = !1;
|
|
257
|
+
}
|
|
258
|
+
#u;
|
|
259
|
+
#d;
|
|
260
|
+
#f(e) {
|
|
244
261
|
let t = this.items;
|
|
245
262
|
if (t.length === 0) return;
|
|
246
263
|
let n = t.indexOf(document.activeElement), r;
|
|
247
264
|
r = n < 0 ? e === 1 ? 0 : t.length - 1 : (n + e + t.length) % t.length, t[r]?.focus();
|
|
248
265
|
}
|
|
249
|
-
#
|
|
266
|
+
#p;
|
|
250
267
|
connectedCallback() {
|
|
251
|
-
super.connectedCallback(), this.#
|
|
268
|
+
super.connectedCallback(), this.#m(), this.requestUpdate(), this.addEventListener("vf-menu-close-request", this.#o), this.addEventListener("vf-menu-flash-request", this.#c), this.addEventListener("pointerdown", this.#g), this.addEventListener("focusout", this.#h);
|
|
252
269
|
}
|
|
253
|
-
#
|
|
270
|
+
#m() {
|
|
254
271
|
this.#r.role = this.#n ? "none" : null;
|
|
255
272
|
}
|
|
256
273
|
disconnectedCallback() {
|
|
257
|
-
super.disconnectedCallback(), this.removeEventListener("vf-menu-close-request", this.#o), this.removeEventListener("pointerdown", this.#
|
|
274
|
+
super.disconnectedCallback(), this.removeEventListener("vf-menu-close-request", this.#o), this.removeEventListener("vf-menu-flash-request", this.#c), this.removeEventListener("pointerdown", this.#g), this.removeEventListener("focusout", this.#h), this.#l();
|
|
258
275
|
}
|
|
259
|
-
#
|
|
276
|
+
#h;
|
|
260
277
|
updated(e) {
|
|
261
278
|
if (e.has("open")) {
|
|
262
|
-
if (this.open && !this.#n ? this.#
|
|
279
|
+
if (this.open && this.#l(), this.open && !this.#n ? this.#p.attach() : this.#p.detach(), !this.open) for (let e of this.allItems) e.active = !1;
|
|
263
280
|
this.open || this.#i.reset();
|
|
264
281
|
}
|
|
265
282
|
}
|
|
266
|
-
#
|
|
283
|
+
#g;
|
|
267
284
|
focus(e) {
|
|
268
285
|
this._labelEl?.focus(e);
|
|
269
286
|
}
|
|
@@ -271,19 +288,19 @@ var C = class extends r(g) {
|
|
|
271
288
|
this.focus();
|
|
272
289
|
}
|
|
273
290
|
render() {
|
|
274
|
-
return
|
|
291
|
+
return y`
|
|
275
292
|
<div
|
|
276
|
-
class="label vf-snap ${this.#e.marked ? "vf-focus-rule" : ""}"
|
|
293
|
+
class="label vf-snap ${this.#e.marked ? "vf-focus-rule" : ""} ${this._flashOn ? "flash-on" : ""}"
|
|
277
294
|
part="label"
|
|
278
295
|
role=${this.#n ? "menuitem" : "button"}
|
|
279
296
|
tabindex=${this.barTabIndex}
|
|
280
297
|
aria-haspopup="menu"
|
|
281
298
|
aria-expanded=${this.open ? "true" : "false"}
|
|
282
|
-
aria-label=${this.label ||
|
|
283
|
-
@pointerdown=${this.#
|
|
284
|
-
@click=${this.#
|
|
285
|
-
@pointerenter=${this.#
|
|
286
|
-
@keydown=${this.#
|
|
299
|
+
aria-label=${this.label || b}
|
|
300
|
+
@pointerdown=${this.#v}
|
|
301
|
+
@click=${this.#y}
|
|
302
|
+
@pointerenter=${this.#b}
|
|
303
|
+
@keydown=${this.#x}
|
|
287
304
|
>
|
|
288
305
|
<span class="title"><slot name="label">${this.label}</slot></span>
|
|
289
306
|
</div>
|
|
@@ -291,13 +308,13 @@ var C = class extends r(g) {
|
|
|
291
308
|
class="panel vf-panel"
|
|
292
309
|
part="panel"
|
|
293
310
|
role="menu"
|
|
294
|
-
aria-label=${this.label ||
|
|
311
|
+
aria-label=${this.label || b}
|
|
295
312
|
>
|
|
296
313
|
<slot></slot>
|
|
297
314
|
</div>
|
|
298
315
|
`;
|
|
299
316
|
}
|
|
300
|
-
#
|
|
317
|
+
#_() {
|
|
301
318
|
if (!this.#n) {
|
|
302
319
|
this.open = !this.open;
|
|
303
320
|
return;
|
|
@@ -307,41 +324,44 @@ var C = class extends r(g) {
|
|
|
307
324
|
composed: !1
|
|
308
325
|
}) && (this.open = !this.open);
|
|
309
326
|
}
|
|
310
|
-
#
|
|
327
|
+
#v() {
|
|
311
328
|
this.#a = !0, u(() => {
|
|
312
329
|
this.#a = !1;
|
|
313
330
|
});
|
|
314
331
|
}
|
|
315
|
-
#
|
|
332
|
+
#y(e) {
|
|
316
333
|
if (this.#a) {
|
|
317
334
|
this.#a = !1;
|
|
318
335
|
return;
|
|
319
336
|
}
|
|
320
|
-
d(this, e, () => this.#
|
|
337
|
+
d(this, e, () => this.#_());
|
|
321
338
|
}
|
|
322
|
-
#
|
|
339
|
+
#b() {
|
|
323
340
|
f(this, "vf-menu-hover", { menu: this }, { composed: !1 });
|
|
324
341
|
}
|
|
325
|
-
#
|
|
342
|
+
#x(e) {
|
|
326
343
|
if (e.key === "Enter" || e.key === " ") {
|
|
327
344
|
e.preventDefault();
|
|
328
345
|
let t = this.open;
|
|
329
|
-
this.#
|
|
330
|
-
} else e.key === "ArrowDown" && !this.open && (e.preventDefault(), this.#
|
|
346
|
+
this.#_(), !t && this.open && this.#S();
|
|
347
|
+
} else e.key === "ArrowDown" && !this.open && (e.preventDefault(), this.#_(), this.open && this.#S());
|
|
331
348
|
}
|
|
332
|
-
async #
|
|
349
|
+
async #S() {
|
|
333
350
|
await this.updateComplete, this.items[0]?.focus();
|
|
334
351
|
}
|
|
335
352
|
};
|
|
336
|
-
n([
|
|
353
|
+
n([x()], T.prototype, "label", void 0), n([x({
|
|
354
|
+
type: Boolean,
|
|
355
|
+
reflect: !0
|
|
356
|
+
})], T.prototype, "open", void 0), n([x({
|
|
337
357
|
type: Boolean,
|
|
338
358
|
reflect: !0
|
|
339
|
-
})],
|
|
359
|
+
})], T.prototype, "shortcuts", void 0), n([x({
|
|
340
360
|
type: Number,
|
|
341
361
|
attribute: !1
|
|
342
|
-
})],
|
|
362
|
+
})], T.prototype, "barTabIndex", void 0), n([S(".label")], T.prototype, "_labelEl", void 0), n([C({
|
|
343
363
|
selector: "vf-menu-item",
|
|
344
364
|
flatten: !0
|
|
345
|
-
})],
|
|
365
|
+
})], T.prototype, "_assignedItems", void 0), n([w()], T.prototype, "_flashOn", void 0), T = n([e("vf-menu")], T);
|
|
346
366
|
//#endregion
|
|
347
|
-
export {
|
|
367
|
+
export { T as VfMenu };
|
|
@@ -13,11 +13,14 @@ declare const VfRadio_base: (new (...args: any[]) => import("../position.js").Vf
|
|
|
13
13
|
* unselects its siblings.
|
|
14
14
|
*
|
|
15
15
|
* @slot - The label, rendered to the right of the circle with a 6px gap.
|
|
16
|
+
* Left empty, the label and its gap collapse: the control is the bare
|
|
17
|
+
* 13×13 circle.
|
|
16
18
|
* @csspart circle - The 13×13 radio circle.
|
|
17
19
|
* @csspart label - The label wrapper around the slot.
|
|
18
20
|
* @fires vf-change - When selected by user interaction. `detail: { value: string }`.
|
|
19
21
|
*/
|
|
20
22
|
export declare class VfRadio extends VfRadio_base {
|
|
23
|
+
#private;
|
|
21
24
|
static styles: import("lit").CSSResult[];
|
|
22
25
|
/** Whether this radio is selected. Managed by the containing group. */
|
|
23
26
|
checked: boolean;
|
|
@@ -30,6 +33,8 @@ export declare class VfRadio extends VfRadio_base {
|
|
|
30
33
|
* group — not intended to be set by consumers.
|
|
31
34
|
*/
|
|
32
35
|
groupDisabled: boolean;
|
|
36
|
+
/** Whether the slot holds non-whitespace content; gates the label row. */
|
|
37
|
+
private _hasLabel;
|
|
33
38
|
private readonly internals;
|
|
34
39
|
constructor();
|
|
35
40
|
/**
|
|
@@ -9,10 +9,10 @@ import { emit as s } from "../events.js";
|
|
|
9
9
|
import { RADIO_DOT as c, RADIO_FACE as l, RADIO_RING as u, RADIO_RING_PRESSED as d } from "../glyphs.js";
|
|
10
10
|
import { VfToggleControl as f } from "../toggle-control.js";
|
|
11
11
|
import { LitElement as p, css as m, html as h } from "lit";
|
|
12
|
-
import { property as g } from "lit/decorators.js";
|
|
13
|
-
import { classMap as
|
|
12
|
+
import { property as g, state as _ } from "lit/decorators.js";
|
|
13
|
+
import { classMap as v } from "lit/directives/class-map.js";
|
|
14
14
|
//#region src/components/vf-radio.ts
|
|
15
|
-
var
|
|
15
|
+
var y = class extends n(f(p)) {
|
|
16
16
|
static {
|
|
17
17
|
this.styles = [
|
|
18
18
|
i,
|
|
@@ -82,7 +82,7 @@ var v = class extends n(f(p)) {
|
|
|
82
82
|
];
|
|
83
83
|
}
|
|
84
84
|
constructor() {
|
|
85
|
-
super(), this.checked = !1, this.disabled = !1, this.value = "", this.groupDisabled = !1, this.internals = this.attachInternals(), this.internals.role = "radio";
|
|
85
|
+
super(), this.checked = !1, this.disabled = !1, this.value = "", this.groupDisabled = !1, this._hasLabel = !1, this.internals = this.attachInternals(), this.internals.role = "radio";
|
|
86
86
|
}
|
|
87
87
|
get toggleInternals() {
|
|
88
88
|
return this.internals;
|
|
@@ -97,7 +97,7 @@ var v = class extends n(f(p)) {
|
|
|
97
97
|
let e = this.toggleDisabled;
|
|
98
98
|
return h`
|
|
99
99
|
<span
|
|
100
|
-
class=${
|
|
100
|
+
class=${v({
|
|
101
101
|
circle: !0,
|
|
102
102
|
dim: e,
|
|
103
103
|
"vf-snap": !0
|
|
@@ -112,14 +112,19 @@ var v = class extends n(f(p)) {
|
|
|
112
112
|
<path class="dot" d=${c.d}></path>
|
|
113
113
|
</svg>
|
|
114
114
|
</span>
|
|
115
|
-
<span class=${
|
|
115
|
+
<span class=${v({
|
|
116
116
|
label: !0,
|
|
117
|
-
dim: e
|
|
117
|
+
dim: e,
|
|
118
|
+
empty: !this._hasLabel
|
|
118
119
|
})} part="label">
|
|
119
|
-
<slot></slot>
|
|
120
|
+
<slot @slotchange=${this.#e}></slot>
|
|
120
121
|
</span>
|
|
121
122
|
`;
|
|
122
123
|
}
|
|
124
|
+
#e(e) {
|
|
125
|
+
let t = e.target;
|
|
126
|
+
this._hasLabel = t.assignedNodes({ flatten: !0 }).some((e) => e.nodeType === Node.ELEMENT_NODE || !!e.textContent?.trim());
|
|
127
|
+
}
|
|
123
128
|
activate() {
|
|
124
129
|
this.checked || (this.externallyCoordinated || (this.checked = !0), this.focus(), s(this, "vf-change", { value: this.value }));
|
|
125
130
|
}
|
|
@@ -127,9 +132,9 @@ var v = class extends n(f(p)) {
|
|
|
127
132
|
t([g({
|
|
128
133
|
type: Boolean,
|
|
129
134
|
reflect: !0
|
|
130
|
-
})],
|
|
135
|
+
})], y.prototype, "checked", void 0), t([g({
|
|
131
136
|
type: Boolean,
|
|
132
137
|
reflect: !0
|
|
133
|
-
})],
|
|
138
|
+
})], y.prototype, "disabled", void 0), t([g()], y.prototype, "value", void 0), t([g({ attribute: !1 })], y.prototype, "groupDisabled", void 0), t([_()], y.prototype, "_hasLabel", void 0), y = t([e("vf-radio")], y);
|
|
134
139
|
//#endregion
|
|
135
|
-
export {
|
|
140
|
+
export { y as VfRadio };
|
|
@@ -30,12 +30,18 @@ declare const VfWindow_base: (new (...args: any[]) => import("../size.js").VfSiz
|
|
|
30
30
|
* says so once in the console.
|
|
31
31
|
*
|
|
32
32
|
* @slot - Default slot: window body content.
|
|
33
|
+
* @slot status - Optional status-bar content — the classic bottom readout
|
|
34
|
+
* strip ("40px x 40px"): a 1px rule over a 15px white band under the body,
|
|
35
|
+
* body-face text on its native line. Takes no space until populated; a
|
|
36
|
+
* `resizable` window's grow box sits flush in its right end.
|
|
33
37
|
* @csspart frame - The outer chrome frame.
|
|
34
38
|
* @csspart title-bar - The striped (or dithered) title bar.
|
|
35
39
|
* @csspart title - The centered title patch (hidden on the utility bar).
|
|
36
40
|
* @csspart close-box - The close widget (left).
|
|
37
41
|
* @csspart zoom-box - The zoom widget (right).
|
|
38
42
|
* @csspart body - The content area.
|
|
43
|
+
* @csspart status-bar - The bottom status strip (when the `status` slot is
|
|
44
|
+
* populated).
|
|
39
45
|
* @csspart grow-box - The resize widget (bottom-right, when `resizable`).
|
|
40
46
|
* @csspart viewport - The built-in scroll area's viewport (when `scrollbars`;
|
|
41
47
|
* re-exported from vf-scroll-area).
|
|
@@ -43,6 +49,13 @@ declare const VfWindow_base: (new (...args: any[]) => import("../size.js").VfSiz
|
|
|
43
49
|
* compatible with vf-dialog's `vf-close`). The window does NOT
|
|
44
50
|
* remove itself; the consumer decides what closing means.
|
|
45
51
|
* @fires vf-zoom - Zoom box clicked. Detail `{}`.
|
|
52
|
+
* @fires vf-resize - The grow box resized the window. Detail `{ width,
|
|
53
|
+
* height, commit }`, sizes in whole system px: one event per size the drag
|
|
54
|
+
* writes (`commit: false`), fired after the new box is applied so a handler
|
|
55
|
+
* that measures reads the resized layout, then a final `commit: true` as
|
|
56
|
+
* the gesture settles — only when it changed the size. Fired by the gesture
|
|
57
|
+
* alone: a programmatic `width`/`height` write fires nothing, the way a
|
|
58
|
+
* value set fires no `vf-change`.
|
|
46
59
|
* @cssprop --vf-dots-pattern - the windoid bar's dot-grid dither — a 2×2 motif,
|
|
47
60
|
* one black pixel at its origin, on a 30-system-px tile (`vfDots`; override
|
|
48
61
|
* the whole tile like `--vf-desktop-pattern` — consumer art renders as a
|
|
@@ -51,6 +64,10 @@ declare const VfWindow_base: (new (...args: any[]) => import("../size.js").VfSiz
|
|
|
51
64
|
* @cssprop [--vf-titlebar-height-utility=12px] - the slim
|
|
52
65
|
* `vf-window[variant="utility"]` (windoid) bar — 11px interior + 1px bottom
|
|
53
66
|
* rule, traced from `Windows/utility-window.png`
|
|
67
|
+
* @cssprop [--vf-status-bar-height=15px] - the status strip: 1px rule + 14px
|
|
68
|
+
* interior — the grow box's own height, so the two compose flush
|
|
69
|
+
* @cssprop [--vf-line-height=12px] - the body face's native line, which the
|
|
70
|
+
* status strip's text rides (whole-pixel centered in the 14px interior)
|
|
54
71
|
*/
|
|
55
72
|
export declare class VfWindow extends VfWindow_base {
|
|
56
73
|
#private;
|
|
@@ -90,6 +107,8 @@ export declare class VfWindow extends VfWindow_base {
|
|
|
90
107
|
* vf-scroll-area) still works for windows that want an inset well instead.
|
|
91
108
|
*/
|
|
92
109
|
scrollbars?: 'vertical' | 'horizontal' | 'both';
|
|
110
|
+
/** Whether the `status` slot has assigned content (drives the strip). */
|
|
111
|
+
private _hasStatus;
|
|
93
112
|
/** Default-on display scaling (true 72dpi size); see src/scale.ts. */
|
|
94
113
|
private readonly scale;
|
|
95
114
|
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
@@ -134,9 +153,16 @@ export declare class VfWindow extends VfWindow_base {
|
|
|
134
153
|
* are the same declaration and neither can be re-asserted over the other.
|
|
135
154
|
* Controllers run before this hook, so the inline style the warning reads is
|
|
136
155
|
* already written.
|
|
156
|
+
*
|
|
157
|
+
* The stream half of `vf-resize` also fires here, not from the pointermove
|
|
158
|
+
* that wrote the size: by this hook the controller has applied the box, so
|
|
159
|
+
* a handler that measures reads the resized layout — the contract that lets
|
|
160
|
+
* window content follow the grow box without a ResizeObserver.
|
|
137
161
|
*/
|
|
138
162
|
protected updated(): void;
|
|
139
163
|
disconnectedCallback(): void;
|
|
164
|
+
/** The `.empty` gate: the strip renders only while the slot is populated. */
|
|
165
|
+
private _onStatusSlotChange;
|
|
140
166
|
private _onCloseClick;
|
|
141
167
|
private _onZoomClick;
|
|
142
168
|
private _onGrowPointerDown;
|