vintage-frames 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +348 -40
- package/dist/components/vf-button.d.ts +1 -1
- package/dist/components/vf-checkbox.d.ts +5 -0
- package/dist/components/vf-checkbox.js +18 -10
- package/dist/components/vf-container.d.ts +2 -2
- package/dist/components/vf-desktop.d.ts +1 -1
- package/dist/components/vf-fieldset.d.ts +1 -1
- package/dist/components/vf-fieldset.js +6 -1
- package/dist/components/vf-grid.d.ts +1 -1
- package/dist/components/vf-icon.d.ts +1 -1
- package/dist/components/vf-img.d.ts +1 -1
- package/dist/components/vf-label.d.ts +1 -1
- package/dist/components/vf-list-item.d.ts +9 -1
- package/dist/components/vf-list-item.js +15 -14
- package/dist/components/vf-list.d.ts +1 -1
- package/dist/components/vf-menu-bar.d.ts +1 -1
- package/dist/components/vf-menu-item.d.ts +10 -1
- package/dist/components/vf-menu-item.js +35 -34
- package/dist/components/vf-menu.d.ts +11 -2
- package/dist/components/vf-menu.js +33 -32
- package/dist/components/vf-option.d.ts +11 -1
- package/dist/components/vf-option.js +16 -15
- package/dist/components/vf-paragraph.d.ts +3 -3
- package/dist/components/vf-progress-bar.d.ts +1 -1
- package/dist/components/vf-radio.d.ts +5 -0
- package/dist/components/vf-radio.js +16 -11
- package/dist/components/vf-scroll-area.d.ts +1 -1
- package/dist/components/vf-select.d.ts +1 -1
- package/dist/components/vf-separator.d.ts +1 -1
- package/dist/components/vf-slider.d.ts +1 -1
- package/dist/components/vf-stack.d.ts +27 -9
- package/dist/components/vf-stack.js +30 -8
- package/dist/components/vf-swatch.d.ts +1 -1
- package/dist/components/vf-window.d.ts +1 -1
- package/dist/cross-center.d.ts +76 -0
- package/dist/cross-center.js +69 -0
- package/dist/define.d.ts +2 -2
- package/dist/define.js +1 -1
- package/dist/grid-snap.d.ts +2 -24
- package/dist/grid-snap.js +7 -33
- package/dist/index.d.ts +5 -5
- package/dist/index.js +50 -50
- package/dist/position.d.ts +11 -2
- package/dist/styles/recipes/host.js +14 -1
- package/dist/styles/recipes/toggle.js +24 -0
- package/dist/text-control.d.ts +1 -1
- package/docs/SPEC.md +10 -9
- package/editor/vscode.html-custom-data.json +50 -10
- package/editor/web-types.json +96 -16
- package/package.json +1 -3
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { vfElement as e } from "../define.js";
|
|
2
2
|
import { ScaleController as t } from "../scale.js";
|
|
3
3
|
import n from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
4
|
+
import { VfPositioned as r } from "../position.js";
|
|
5
|
+
import { vfDisplay as i } from "../styles/recipes/display-face.js";
|
|
6
|
+
import { vfBase as a } from "../styles/recipes/host.js";
|
|
7
|
+
import { vfPanel as o } from "../styles/recipes/surface.js";
|
|
8
|
+
import { vfFocusUnderline as s } from "../styles/recipes/focus.js";
|
|
9
|
+
import { GridSnapController as c } from "../grid-snap.js";
|
|
10
|
+
import { DocumentListenersController as l, releaseAfterGesture as u } from "../document-listeners.js";
|
|
11
|
+
import { deferActivation as d, emit as f } from "../events.js";
|
|
12
|
+
import { FocusRuleController as p } from "../focus-modality.js";
|
|
13
|
+
import { TypeAheadBuffer as m } from "../type-ahead.js";
|
|
14
|
+
import { MenuPressController as h } from "../menu-press.js";
|
|
15
|
+
import { LitElement as g, css as _, html as v, nothing as y } from "lit";
|
|
16
|
+
import { property as b, query as x, queryAssignedElements as S } from "lit/decorators.js";
|
|
16
17
|
//#region src/components/vf-menu.ts
|
|
17
|
-
var
|
|
18
|
+
var C = class extends r(g) {
|
|
18
19
|
constructor(...e) {
|
|
19
|
-
super(...e), this.scale = new t(this), this.gridSnap = new
|
|
20
|
+
super(...e), this.scale = new t(this), this.gridSnap = new c(this), this.#e = new p(this), this.label = "", this.open = !1, this.barTabIndex = 0, this.#t = new h(this, {
|
|
20
21
|
menus: () => [this],
|
|
21
22
|
open: (e) => {
|
|
22
23
|
e.open = !0;
|
|
@@ -24,7 +25,7 @@ var S = class extends h {
|
|
|
24
25
|
close: () => {
|
|
25
26
|
this.open = !1;
|
|
26
27
|
}
|
|
27
|
-
}), this.#r = this.attachInternals(), this.#i = new
|
|
28
|
+
}), this.#r = this.attachInternals(), this.#i = new m(), this.#a = !1, this.#o = () => {
|
|
28
29
|
this.#n || this.focus(), this.open = !1;
|
|
29
30
|
}, this.#s = (e) => {
|
|
30
31
|
e.composedPath().includes(this) || (this.open = !1);
|
|
@@ -58,7 +59,7 @@ var S = class extends h {
|
|
|
58
59
|
break;
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
|
-
}, this.#u = new
|
|
62
|
+
}, this.#u = new l(this, () => [[
|
|
62
63
|
document,
|
|
63
64
|
"pointerdown",
|
|
64
65
|
this.#s,
|
|
@@ -78,10 +79,10 @@ var S = class extends h {
|
|
|
78
79
|
}
|
|
79
80
|
static {
|
|
80
81
|
this.styles = [
|
|
81
|
-
i,
|
|
82
|
-
r,
|
|
83
82
|
a,
|
|
84
|
-
|
|
83
|
+
i,
|
|
84
|
+
o,
|
|
85
|
+
_`
|
|
85
86
|
:host {
|
|
86
87
|
display: inline-block;
|
|
87
88
|
position: relative;
|
|
@@ -168,7 +169,7 @@ var S = class extends h {
|
|
|
168
169
|
}
|
|
169
170
|
:host(:not([open])) .label.vf-focus-rule .title::after {
|
|
170
171
|
--vf-focus-underline-offset: -2px;
|
|
171
|
-
${
|
|
172
|
+
${s}
|
|
172
173
|
}
|
|
173
174
|
.panel {
|
|
174
175
|
position: absolute;
|
|
@@ -270,7 +271,7 @@ var S = class extends h {
|
|
|
270
271
|
this.focus();
|
|
271
272
|
}
|
|
272
273
|
render() {
|
|
273
|
-
return
|
|
274
|
+
return v`
|
|
274
275
|
<div
|
|
275
276
|
class="label vf-snap ${this.#e.marked ? "vf-focus-rule" : ""}"
|
|
276
277
|
part="label"
|
|
@@ -278,7 +279,7 @@ var S = class extends h {
|
|
|
278
279
|
tabindex=${this.barTabIndex}
|
|
279
280
|
aria-haspopup="menu"
|
|
280
281
|
aria-expanded=${this.open ? "true" : "false"}
|
|
281
|
-
aria-label=${this.label ||
|
|
282
|
+
aria-label=${this.label || y}
|
|
282
283
|
@pointerdown=${this.#h}
|
|
283
284
|
@click=${this.#g}
|
|
284
285
|
@pointerenter=${this.#_}
|
|
@@ -290,7 +291,7 @@ var S = class extends h {
|
|
|
290
291
|
class="panel vf-panel"
|
|
291
292
|
part="panel"
|
|
292
293
|
role="menu"
|
|
293
|
-
aria-label=${this.label ||
|
|
294
|
+
aria-label=${this.label || y}
|
|
294
295
|
>
|
|
295
296
|
<slot></slot>
|
|
296
297
|
</div>
|
|
@@ -301,13 +302,13 @@ var S = class extends h {
|
|
|
301
302
|
this.open = !this.open;
|
|
302
303
|
return;
|
|
303
304
|
}
|
|
304
|
-
|
|
305
|
+
f(this, "vf-menu-toggle-request", { menu: this }, {
|
|
305
306
|
cancelable: !0,
|
|
306
307
|
composed: !1
|
|
307
308
|
}) && (this.open = !this.open);
|
|
308
309
|
}
|
|
309
310
|
#h() {
|
|
310
|
-
this.#a = !0,
|
|
311
|
+
this.#a = !0, u(() => {
|
|
311
312
|
this.#a = !1;
|
|
312
313
|
});
|
|
313
314
|
}
|
|
@@ -316,10 +317,10 @@ var S = class extends h {
|
|
|
316
317
|
this.#a = !1;
|
|
317
318
|
return;
|
|
318
319
|
}
|
|
319
|
-
|
|
320
|
+
d(this, e, () => this.#m());
|
|
320
321
|
}
|
|
321
322
|
#_() {
|
|
322
|
-
|
|
323
|
+
f(this, "vf-menu-hover", { menu: this }, { composed: !1 });
|
|
323
324
|
}
|
|
324
325
|
#v(e) {
|
|
325
326
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -332,15 +333,15 @@ var S = class extends h {
|
|
|
332
333
|
await this.updateComplete, this.items[0]?.focus();
|
|
333
334
|
}
|
|
334
335
|
};
|
|
335
|
-
n([
|
|
336
|
+
n([b()], C.prototype, "label", void 0), n([b({
|
|
336
337
|
type: Boolean,
|
|
337
338
|
reflect: !0
|
|
338
|
-
})],
|
|
339
|
+
})], C.prototype, "open", void 0), n([b({
|
|
339
340
|
type: Number,
|
|
340
341
|
attribute: !1
|
|
341
|
-
})],
|
|
342
|
+
})], C.prototype, "barTabIndex", void 0), n([x(".label")], C.prototype, "_labelEl", void 0), n([S({
|
|
342
343
|
selector: "vf-menu-item",
|
|
343
344
|
flatten: !0
|
|
344
|
-
})],
|
|
345
|
+
})], C.prototype, "_assignedItems", void 0), C = n([e("vf-menu")], C);
|
|
345
346
|
//#endregion
|
|
346
|
-
export {
|
|
347
|
+
export { C as VfMenu };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import type { PropertyValues } from 'lit';
|
|
3
|
+
declare const VfOption_base: (new (...args: any[]) => import("../position.js").VfPositionedInterface) & typeof LitElement;
|
|
3
4
|
/**
|
|
4
5
|
* `<vf-option>` — a single choice inside a `<vf-select>` popup menu.
|
|
5
6
|
*
|
|
@@ -12,6 +13,14 @@ import type { PropertyValues } from 'lit';
|
|
|
12
13
|
*
|
|
13
14
|
* The host carries `role="option"` with `aria-selected`/`aria-disabled`.
|
|
14
15
|
*
|
|
16
|
+
* Takes `top`/`left` like every other element ({@link VfPositioned}), for the
|
|
17
|
+
* consumer who wants one somewhere other than a popup row. Inside its parent
|
|
18
|
+
* `<vf-select>` it is a row the panel measures and scrolls in flow, so stating
|
|
19
|
+
* an origin there takes it out of that measurement: the panel stops counting it
|
|
20
|
+
* toward its own width and its scroll clamp, and the rows below close the gap.
|
|
21
|
+
* That is the placement doing exactly what it says — not a bug — but it is not
|
|
22
|
+
* how a popup is laid out.
|
|
23
|
+
*
|
|
15
24
|
* @csspart check - The ✓ checkmark shown in the left gutter when selected.
|
|
16
25
|
* @cssprop [--vf-popup-height=18px] - `vf-select` pill (border box; its 1px
|
|
17
26
|
* hard shadow makes the sheet's 157×19 ink box)
|
|
@@ -19,7 +28,7 @@ import type { PropertyValues } from 'lit';
|
|
|
19
28
|
* / `vf-option` + `vf-menu-item` ✓ column (shared so the value doesn't shift
|
|
20
29
|
* on open)
|
|
21
30
|
*/
|
|
22
|
-
export declare class VfOption extends
|
|
31
|
+
export declare class VfOption extends VfOption_base {
|
|
23
32
|
#private;
|
|
24
33
|
static styles: import("lit").CSSResult[];
|
|
25
34
|
private readonly scale;
|
|
@@ -47,3 +56,4 @@ declare global {
|
|
|
47
56
|
'vf-option': VfOption;
|
|
48
57
|
}
|
|
49
58
|
}
|
|
59
|
+
export {};
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { vfElement as e } from "../define.js";
|
|
2
2
|
import { ScaleController as t } from "../scale.js";
|
|
3
3
|
import n from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { VfPositioned as r } from "../position.js";
|
|
5
|
+
import { vfDisplay as i } from "../styles/recipes/display-face.js";
|
|
6
|
+
import { vfBase as a } from "../styles/recipes/host.js";
|
|
7
|
+
import { CHECKMARK as o, glyphSvg as s } from "../glyphs.js";
|
|
8
|
+
import { LitElement as c, css as l, html as u } from "lit";
|
|
9
|
+
import { property as d } from "lit/decorators.js";
|
|
9
10
|
//#region src/components/vf-option.ts
|
|
10
|
-
var
|
|
11
|
+
var f = class extends r(c) {
|
|
11
12
|
static {
|
|
12
13
|
this.styles = [
|
|
14
|
+
a,
|
|
13
15
|
i,
|
|
14
|
-
|
|
15
|
-
c`
|
|
16
|
+
l`
|
|
16
17
|
:host {
|
|
17
18
|
position: relative;
|
|
18
19
|
display: flex;
|
|
@@ -97,23 +98,23 @@ var d = class extends s {
|
|
|
97
98
|
e.has("selected") && (this.#e.ariaSelected = this.selected ? "true" : "false"), e.has("disabled") && (this.#e.ariaDisabled = this.disabled ? "true" : null);
|
|
98
99
|
}
|
|
99
100
|
render() {
|
|
100
|
-
return
|
|
101
|
+
return u`
|
|
101
102
|
<span class="check" part="check" aria-hidden="true"
|
|
102
|
-
>${o
|
|
103
|
+
>${s(o, "checkmark")}</span
|
|
103
104
|
>
|
|
104
105
|
<slot></slot>
|
|
105
106
|
`;
|
|
106
107
|
}
|
|
107
108
|
};
|
|
108
|
-
n([
|
|
109
|
+
n([d()], f.prototype, "value", void 0), n([d({
|
|
109
110
|
type: Boolean,
|
|
110
111
|
reflect: !0
|
|
111
|
-
})],
|
|
112
|
+
})], f.prototype, "disabled", void 0), n([d({
|
|
112
113
|
type: Boolean,
|
|
113
114
|
reflect: !0
|
|
114
|
-
})],
|
|
115
|
+
})], f.prototype, "selected", void 0), n([d({
|
|
115
116
|
type: Boolean,
|
|
116
117
|
reflect: !0
|
|
117
|
-
})],
|
|
118
|
+
})], f.prototype, "active", void 0), f = n([e("vf-option")], f);
|
|
118
119
|
//#endregion
|
|
119
|
-
export {
|
|
120
|
+
export { f as VfOption };
|
|
@@ -19,8 +19,8 @@ declare const VfParagraph_base: (new (...args: any[]) => import("../size.js").Vf
|
|
|
19
19
|
* everything after it further off the device-pixel grid, smearing 1-bit
|
|
20
20
|
* borders and bitmap glyph stems (docs/SIZING.md rule 2). A
|
|
21
21
|
* whole-pixel line box accumulates whole offsets;
|
|
22
|
-
* - its own {@link GridSnapController}, so it holds its own origin
|
|
23
|
-
*
|
|
22
|
+
* - its own {@link GridSnapController}, so it holds its own origin
|
|
23
|
+
* wherever the page puts it;
|
|
24
24
|
* - a **declared box** when the layout wants one — `width`/`height` in whole
|
|
25
25
|
* system px ({@link VfSized}). In flow a paragraph takes its container's
|
|
26
26
|
* width, which is usually right; a *placed* one (`top`/`left`) shrink-wraps
|
|
@@ -52,7 +52,7 @@ export declare class VfParagraph extends VfParagraph_base {
|
|
|
52
52
|
static styles: import("lit").CSSResult[];
|
|
53
53
|
/** Default-on display scaling (true 72dpi size); see src/scale.ts. */
|
|
54
54
|
private readonly scale;
|
|
55
|
-
/** Device-pixel grid snapping
|
|
55
|
+
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
56
56
|
private readonly gridSnap;
|
|
57
57
|
/**
|
|
58
58
|
* Which embedded face to set the copy in — `'body'` (Geneva, the
|
|
@@ -28,7 +28,7 @@ export declare class VfProgressBar extends VfProgressBar_base {
|
|
|
28
28
|
#private;
|
|
29
29
|
static styles: import("lit").CSSResult[];
|
|
30
30
|
private readonly scale;
|
|
31
|
-
/** Device-pixel grid snapping
|
|
31
|
+
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
32
32
|
private readonly gridSnap;
|
|
33
33
|
/** Current progress, from 0 to `max`. Clamped for display and ARIA. */
|
|
34
34
|
value: number;
|
|
@@ -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,7 +30,7 @@ declare const VfScrollArea_base: (new (...args: any[]) => import("../position.js
|
|
|
30
30
|
*/
|
|
31
31
|
export declare class VfScrollArea extends VfScrollArea_base {
|
|
32
32
|
private readonly scale;
|
|
33
|
-
/** Device-pixel grid snapping
|
|
33
|
+
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
34
34
|
private readonly gridSnap;
|
|
35
35
|
/**
|
|
36
36
|
* Which scroll rails to reserve as permanent placeholders: `vertical`
|
|
@@ -116,7 +116,7 @@ export declare class VfSelect extends VfSelect_base {
|
|
|
116
116
|
private cachedOptions;
|
|
117
117
|
/** Default-on display scaling (true 72dpi size); see src/scale.ts. */
|
|
118
118
|
private readonly scale;
|
|
119
|
-
/** Device-pixel grid snapping
|
|
119
|
+
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
120
120
|
private readonly gridSnap;
|
|
121
121
|
/**
|
|
122
122
|
* Whether the closed pill wears the kit's dashed focus rule — keyboard focus
|
|
@@ -22,7 +22,7 @@ export declare class VfSeparator extends VfSeparator_base {
|
|
|
22
22
|
#private;
|
|
23
23
|
static styles: import("lit").CSSResult[];
|
|
24
24
|
private readonly scale;
|
|
25
|
-
/** Device-pixel grid snapping
|
|
25
|
+
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
26
26
|
private readonly gridSnap;
|
|
27
27
|
/** Render as a vertical rule (1px wide) instead of horizontal. */
|
|
28
28
|
vertical: boolean;
|
|
@@ -48,7 +48,7 @@ export declare class VfSlider extends VfSlider_base {
|
|
|
48
48
|
private readonly trackSize;
|
|
49
49
|
/** Default-on display scaling (true 72dpi size); see src/scale.ts. */
|
|
50
50
|
private readonly scale;
|
|
51
|
-
/** Device-pixel grid snapping
|
|
51
|
+
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
52
52
|
private readonly gridSnap;
|
|
53
53
|
/** True when this component owns the host `tabindex`. */
|
|
54
54
|
private selfManagedTabIndex;
|
|
@@ -93,12 +93,16 @@ declare const VfStack_base: (new (...args: any[]) => import("../size.js").VfSize
|
|
|
93
93
|
* and a layout box for *anything*, and consumer content inside it — a div, an
|
|
94
94
|
* `<img>`, a run of text — has no controller of its own. So the flex
|
|
95
95
|
* container, the placed-child anchor and the `vf-snap` class live on one
|
|
96
|
-
* shadow box, and
|
|
96
|
+
* shadow box, and the correction moves the stack's
|
|
97
97
|
* whole coordinate system; children (kit or not) ride it, and the sweep's
|
|
98
98
|
* outermost-first order means the kit children then find nothing left to
|
|
99
99
|
* correct. What this deliberately does not fix: a text-governed child width
|
|
100
100
|
* mid-row still shifts later siblings fractionally (their own controllers
|
|
101
|
-
* cover that)
|
|
101
|
+
* cover that).
|
|
102
|
+
*
|
|
103
|
+
* **Centering lands on whole system px as well** — halving an odd count of free
|
|
104
|
+
* system px gives a half, which no container can round in CSS. See
|
|
105
|
+
* {@link CrossCenterController}.
|
|
102
106
|
*
|
|
103
107
|
* It is also the kit's one **typographically transparent** component: `vfBase`'s
|
|
104
108
|
* chrome face, ratio line box, color and non-selectability are all reset to
|
|
@@ -148,18 +152,18 @@ export declare class VfStack extends VfStack_base {
|
|
|
148
152
|
* `text-align` on any element, so the cross-axis switch used to re-align every
|
|
149
153
|
* run of copy inside the stack (see the `text-align` reset above).
|
|
150
154
|
*
|
|
151
|
-
*
|
|
152
|
-
* 16px caption centered in a row set by the
|
|
153
|
-
* sits at 4.5
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
155
|
+
* Centering divides the free space in two, so an odd count of system px would
|
|
156
|
+
* land a child on a half — a 16px caption centered in a row set by the
|
|
157
|
+
* 25-system-px `vf-number-field` sits at 4.5. {@link CrossCenterController}
|
|
158
|
+
* steps that back onto whole system px, the exact half going toward the start
|
|
159
|
+
* the way QuickDraw's `div 2` did; `place="start"` is still the way to ask
|
|
160
|
+
* for no centering at all.
|
|
157
161
|
*/
|
|
158
162
|
place?: VfStackPlace;
|
|
159
163
|
/** Default-on display scaling (true 72dpi size); see src/scale.ts. */
|
|
160
164
|
private readonly scale;
|
|
161
165
|
/**
|
|
162
|
-
* Hold the box on the device-pixel grid
|
|
166
|
+
* Hold the box on the device-pixel grid — see the
|
|
163
167
|
* class doc for why the original no-controller decision was reversed. The
|
|
164
168
|
* host is what gets measured; `.box` (vf-snap) is where the correction
|
|
165
169
|
* lands, taking the whole coordinate system with it.
|
|
@@ -167,6 +171,20 @@ export declare class VfStack extends VfStack_base {
|
|
|
167
171
|
private readonly gridSnap;
|
|
168
172
|
/** The shadow flex box `gap`/`pad` write to; exists from the first render. */
|
|
169
173
|
private readonly box;
|
|
174
|
+
/** The slot the children arrive through. (`slot` itself is HTMLElement's.) */
|
|
175
|
+
private readonly childSlot;
|
|
176
|
+
/**
|
|
177
|
+
* Keeps cross-axis centering on whole system px (src/cross-center.ts).
|
|
178
|
+
* A null axis is the inert state — no observers, nothing held — which is
|
|
179
|
+
* every column that starts its children, i.e. the default.
|
|
180
|
+
*/
|
|
181
|
+
private readonly crossCenter;
|
|
182
|
+
/**
|
|
183
|
+
* Mirrors the stylesheet's alignment selectors: a row centers unless `place`
|
|
184
|
+
* names something else, a column only when it says `center`, and an
|
|
185
|
+
* unrecognized value lands on the direction's default in both places.
|
|
186
|
+
*/
|
|
187
|
+
private get centersChildren();
|
|
170
188
|
/**
|
|
171
189
|
* `gap` and `pad` go on the shadow box's inline style as
|
|
172
190
|
* `calc(var(--vf-scale, 1) * Npx)`, the way VfSized writes the declared
|
|
@@ -5,15 +5,20 @@ import { VfPositioned as a } from "../position.js";
|
|
|
5
5
|
import { vfBase as o } from "../styles/recipes/host.js";
|
|
6
6
|
import { GridSnapController as s } from "../grid-snap.js";
|
|
7
7
|
import { VfSized as c } from "../size.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { CrossCenterController as l } from "../cross-center.js";
|
|
9
|
+
import { LitElement as u, css as d, html as f } from "lit";
|
|
10
|
+
import { property as p, query as m } from "lit/decorators.js";
|
|
10
11
|
//#region src/components/vf-stack.ts
|
|
11
|
-
var
|
|
12
|
+
var h = class extends c(a(u)) {
|
|
12
13
|
constructor(...e) {
|
|
13
|
-
super(...e), this.direction = "column", this.gap = 0, this.scale = new t(this), this.gridSnap = new s(this)
|
|
14
|
+
super(...e), this.direction = "column", this.gap = 0, this.scale = new t(this), this.gridSnap = new s(this), this.crossCenter = new l(this, () => ({
|
|
15
|
+
box: this.box,
|
|
16
|
+
slot: this.childSlot,
|
|
17
|
+
axis: this.centersChildren ? this.direction === "row" ? "y" : "x" : null
|
|
18
|
+
}));
|
|
14
19
|
}
|
|
15
20
|
static {
|
|
16
|
-
this.styles = [o,
|
|
21
|
+
this.styles = [o, d`
|
|
17
22
|
:host {
|
|
18
23
|
/* Shrink to the content, but stay BLOCK-level while doing it: the stack
|
|
19
24
|
is exactly as big as what it holds, so it can't hand a size it never
|
|
@@ -126,6 +131,20 @@ var m = class extends c(a(l)) {
|
|
|
126
131
|
align-items: flex-end;
|
|
127
132
|
}
|
|
128
133
|
|
|
134
|
+
/* The centering tie: CrossCenterController steps a centered child onto
|
|
135
|
+
whole system px through these variables (src/cross-center.ts has the
|
|
136
|
+
why). Keyed off the marker because a ::slotted rule outranks a slotted
|
|
137
|
+
element's own :host — a blanket position would restyle vf-window and
|
|
138
|
+
vf-menu. */
|
|
139
|
+
:host(:not([direction='row'])) ::slotted([data-vf-tie]) {
|
|
140
|
+
position: relative;
|
|
141
|
+
left: var(--vf-stack-dx, 0px);
|
|
142
|
+
}
|
|
143
|
+
:host([direction='row']) ::slotted([data-vf-tie]) {
|
|
144
|
+
position: relative;
|
|
145
|
+
top: var(--vf-stack-dy, 0px);
|
|
146
|
+
}
|
|
147
|
+
|
|
129
148
|
/* --- Children ----------------------------------------------------- */
|
|
130
149
|
/* Neither grow nor shrink: the content governs the box, not the other way
|
|
131
150
|
round (see the class doc). A light-DOM declaration beats a ::slotted
|
|
@@ -156,13 +175,16 @@ var m = class extends c(a(l)) {
|
|
|
156
175
|
}
|
|
157
176
|
`];
|
|
158
177
|
}
|
|
178
|
+
get centersChildren() {
|
|
179
|
+
return this.place === "center" ? !0 : this.place === "start" || this.place === "end" ? !1 : this.direction === "row";
|
|
180
|
+
}
|
|
159
181
|
updated(e) {
|
|
160
182
|
e.has("gap") && (this.box.style.gap = n(this.gap)), e.has("pad") && (this.box.style.padding = r(this.pad));
|
|
161
183
|
}
|
|
162
184
|
render() {
|
|
163
|
-
return
|
|
185
|
+
return f`<div class="vf-snap box"><slot></slot></div>`;
|
|
164
186
|
}
|
|
165
187
|
};
|
|
166
|
-
i([
|
|
188
|
+
i([p({ reflect: !0 })], h.prototype, "direction", void 0), i([p({ type: Number })], h.prototype, "gap", void 0), i([p()], h.prototype, "pad", void 0), i([p({ reflect: !0 })], h.prototype, "place", void 0), i([m(".box")], h.prototype, "box", void 0), i([m("slot")], h.prototype, "childSlot", void 0), h = i([e("vf-stack")], h);
|
|
167
189
|
//#endregion
|
|
168
|
-
export {
|
|
190
|
+
export { h as VfStack };
|
|
@@ -79,7 +79,7 @@ export declare class VfSwatch extends VfSwatch_base {
|
|
|
79
79
|
disabled: boolean;
|
|
80
80
|
/** Default-on display scaling (true 72dpi size); see src/scale.ts. */
|
|
81
81
|
private readonly scale;
|
|
82
|
-
/** Device-pixel grid snapping
|
|
82
|
+
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
83
83
|
private readonly gridSnap;
|
|
84
84
|
/**
|
|
85
85
|
* The consumer's `--vf-swatch-checker` override, or `''` for the kit
|
|
@@ -92,7 +92,7 @@ export declare class VfWindow extends VfWindow_base {
|
|
|
92
92
|
scrollbars?: 'vertical' | 'horizontal' | 'both';
|
|
93
93
|
/** Default-on display scaling (true 72dpi size); see src/scale.ts. */
|
|
94
94
|
private readonly scale;
|
|
95
|
-
/** Device-pixel grid snapping
|
|
95
|
+
/** Device-pixel grid snapping; see src/grid-snap.ts. */
|
|
96
96
|
private readonly gridSnap;
|
|
97
97
|
/** Holds the centered title patch on the placement lattice (src/chrome.ts). */
|
|
98
98
|
private readonly titleCenter;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
/** The axis a container centers its children across — `null` when it doesn't. */
|
|
3
|
+
export type CrossAxis = 'x' | 'y' | null;
|
|
4
|
+
/** What {@link CrossCenterController} reads off its host before each measure. */
|
|
5
|
+
export interface CrossCenterParts {
|
|
6
|
+
/** The flex box the children are centered in. */
|
|
7
|
+
box: HTMLElement | null | undefined;
|
|
8
|
+
/** The slot they arrive through. */
|
|
9
|
+
slot: HTMLSlotElement | null | undefined;
|
|
10
|
+
/** Which axis that centering happens on, if it happens at all. */
|
|
11
|
+
axis: CrossAxis;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Marks a held child; the container's `::slotted()` rule keys off it. The
|
|
15
|
+
* container owns the correction, the child carries only the fact of it.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CENTER_TIE_ATTRIBUTE = "data-vf-tie";
|
|
18
|
+
/**
|
|
19
|
+
* Holds cross-axis centering on the system-pixel grid.
|
|
20
|
+
*
|
|
21
|
+
* Centering halves the free space, and half of an odd count of system px is a
|
|
22
|
+
* half: a 71-system-px child centered in 200 sits at 64.5 — half a *system*
|
|
23
|
+
* px, so the child's whole 1-bit interior misses the device grid at every
|
|
24
|
+
* density. CSS can't round it: no rule can say "half my child's width,
|
|
25
|
+
* floored", and a fractional transform leaves the composite-time fringe
|
|
26
|
+
* grid-snap.ts measured. So the offset is measured here and corrected through
|
|
27
|
+
* layout: each centered child steps to the nearest whole system px, the exact
|
|
28
|
+
* half going toward the start as QuickDraw's `div 2` did.
|
|
29
|
+
*
|
|
30
|
+
* It measures where flexbox actually put each child rather than deriving from
|
|
31
|
+
* the two widths — a stack holds anything, including a child whose width isn't
|
|
32
|
+
* whole system px (`vf-select` is 87⅓ at 1.5×), and deriving would move such a
|
|
33
|
+
* child *off* a grid position it already held. Everything is relative to the
|
|
34
|
+
* box, so a stack the page put on a fractional origin is untouched: that stays
|
|
35
|
+
* the page's fault, or the grid snapper's to absorb (src/grid-snap.ts).
|
|
36
|
+
*
|
|
37
|
+
* The correction lands as {@link CENTER_TIE_ATTRIBUTE} plus a length in
|
|
38
|
+
* `--vf-stack-dx` / `--vf-stack-dy`, applied by the container's own
|
|
39
|
+
* `::slotted([data-vf-tie])` rule (see vf-stack.ts). A marker plus a variable
|
|
40
|
+
* is the weakest channel available — any inline style or page rule beats it —
|
|
41
|
+
* and the marker matters because a `::slotted` rule outranks a slotted
|
|
42
|
+
* element's own `:host` (measured): a blanket `position` would restyle
|
|
43
|
+
* `vf-window` and `vf-menu`.
|
|
44
|
+
*
|
|
45
|
+
* Re-measures after every host render and on any resize of the box or a child
|
|
46
|
+
* — a density change, a late-registering face, an edited label. A relative
|
|
47
|
+
* offset changes no box's size, so the measurement stays stable: the applied
|
|
48
|
+
* correction is subtracted back out before the next one is derived, and a
|
|
49
|
+
* child already on the grid is left exactly as it is.
|
|
50
|
+
*/
|
|
51
|
+
export declare class CrossCenterController implements ReactiveController {
|
|
52
|
+
private readonly host;
|
|
53
|
+
private readonly read;
|
|
54
|
+
private observer?;
|
|
55
|
+
private observed;
|
|
56
|
+
private slot?;
|
|
57
|
+
private readonly held;
|
|
58
|
+
constructor(host: ReactiveControllerHost & HTMLElement, read: () => CrossCenterParts);
|
|
59
|
+
hostConnected(): void;
|
|
60
|
+
hostUpdated(): void;
|
|
61
|
+
hostDisconnected(): void;
|
|
62
|
+
/** Re-attach to the current box, slot and children, then re-measure. */
|
|
63
|
+
private readonly sync;
|
|
64
|
+
/**
|
|
65
|
+
* Detach from everything and give every held child its box back. Keeps the
|
|
66
|
+
* observer instance, so a re-parented stack doesn't allocate a fresh one.
|
|
67
|
+
*/
|
|
68
|
+
private rest;
|
|
69
|
+
/** Observe the box and every child, once per distinct set. */
|
|
70
|
+
private watch;
|
|
71
|
+
/** Put every centered child on the nearest whole system px, ties to the start. */
|
|
72
|
+
private hold;
|
|
73
|
+
private apply;
|
|
74
|
+
/** Give a child back exactly the box it arrived with. */
|
|
75
|
+
private clear;
|
|
76
|
+
}
|