vintage-frames 0.12.8 → 0.14.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 +26 -26
- package/dist/chrome.d.ts +1 -1
- package/dist/components/vf-checkbox.d.ts +6 -5
- package/dist/components/vf-checkbox.js +41 -37
- package/dist/components/vf-container.d.ts +16 -20
- package/dist/components/vf-container.js +25 -17
- package/dist/components/vf-desktop.d.ts +4 -5
- package/dist/components/vf-desktop.js +13 -18
- package/dist/components/vf-fieldset.js +30 -22
- package/dist/components/vf-icon.js +55 -55
- package/dist/components/vf-list.js +30 -29
- package/dist/components/vf-menu.js +24 -22
- package/dist/components/vf-number-field.js +32 -30
- package/dist/components/vf-progress-bar.d.ts +2 -2
- package/dist/components/vf-progress-bar.js +65 -52
- package/dist/components/vf-radio.js +3 -4
- package/dist/components/vf-scroll-area.js +27 -26
- package/dist/components/vf-select.js +108 -90
- package/dist/components/vf-separator.d.ts +5 -5
- package/dist/components/vf-separator.js +36 -10
- package/dist/components/vf-slider.js +11 -11
- package/dist/components/vf-swatch.d.ts +2 -2
- package/dist/components/vf-swatch.js +73 -72
- package/dist/components/vf-text-area.js +37 -35
- package/dist/components/vf-text-field.js +20 -18
- package/dist/components/vf-window.d.ts +6 -9
- package/dist/components/vf-window.js +106 -87
- package/dist/index.d.ts +20 -10
- package/dist/index.js +63 -62
- package/dist/pattern-fill.d.ts +21 -50
- package/dist/pattern-fill.js +19 -54
- package/dist/scroll-rail.d.ts +6 -6
- package/dist/scroll-rail.js +24 -29
- package/dist/styles/base.d.ts +3 -1
- package/dist/styles/recipes/field.d.ts +10 -6
- package/dist/styles/recipes/field.js +8 -7
- package/dist/styles/recipes/focus.d.ts +7 -3
- package/dist/styles/recipes/pattern.d.ts +19 -10
- package/dist/styles/recipes/pattern.js +27 -18
- package/dist/styles/recipes/rule.d.ts +11 -8
- package/dist/styles/recipes/rule.js +31 -13
- package/dist/styles/recipes/scroll-rail.d.ts +21 -13
- package/dist/styles/recipes/scroll-rail.js +27 -37
- package/dist/styles/recipes/shadow.d.ts +10 -6
- package/dist/styles/recipes/shadow.js +4 -2
- package/dist/styles/recipes/stroke.d.ts +85 -0
- package/dist/styles/recipes/stroke.js +53 -0
- package/dist/styles/recipes/surface.d.ts +8 -4
- package/dist/styles/recipes/surface.js +23 -17
- package/dist/styles/recipes/tile.d.ts +11 -3
- package/dist/styles/recipes/tile.js +12 -12
- package/dist/styles/recipes/title-bar.d.ts +7 -0
- package/dist/styles/recipes/title-bar.js +25 -22
- package/dist/styles/recipes/toggle.js +3 -3
- package/dist/tile-grid.d.ts +98 -64
- package/dist/tile-grid.js +63 -30
- package/dist/track-width.d.ts +1 -2
- package/dist/zoom.d.ts +9 -9
- package/docs/SPEC.md +33 -32
- package/editor/vscode.html-custom-data.json +5 -5
- package/editor/web-types.json +8 -8
- package/package.json +1 -1
package/dist/pattern-fill.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type CSSResult, type
|
|
1
|
+
import { type CSSResult, type ReactiveControllerHost } from 'lit';
|
|
2
|
+
import { RepeatTileController } from './tile-grid.js';
|
|
2
3
|
import { type Pattern } from './patterns.js';
|
|
3
4
|
/** What a component hands the controller. */
|
|
4
5
|
export interface PatternFillOptions {
|
|
@@ -8,31 +9,14 @@ export interface PatternFillOptions {
|
|
|
8
9
|
/** The resolved pattern, or null to paint nothing ({@link parsePattern}
|
|
9
10
|
* turns an attribute value into one). */
|
|
10
11
|
getPattern: () => Pattern | null | undefined;
|
|
11
|
-
/**
|
|
12
|
-
* The box's declared size in system px, per axis. A declared axis is used
|
|
13
|
-
* as it is — exact, and free of any measurement; an axis left `null` or
|
|
14
|
-
* `undefined` is measured off the box instead (a `ResizeObserver`,
|
|
15
|
-
* `toSys`-rounded). Omit the whole option to measure both.
|
|
16
|
-
*/
|
|
17
|
-
getSize?: () => {
|
|
18
|
-
width?: number | null;
|
|
19
|
-
height?: number | null;
|
|
20
|
-
} | null | undefined;
|
|
21
12
|
}
|
|
22
13
|
/**
|
|
23
14
|
* Paints a {@link Pattern} as a box's own background — the fill behind
|
|
24
|
-
* `vf-container pattern="…"` and `vf-desktop pattern="…"
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* ceiled up to whole pattern cells plus one cell of overdraw, and stretched
|
|
30
|
-
* onto that stated size under `image-rendering: pixelated`. Nearest-neighbor
|
|
31
|
-
* sampling can only emit source colors and one image has no interior seams,
|
|
32
|
-
* so the fill is 1-bit at every density and zoom — the same argument the
|
|
33
|
-
* desktop dither rests on. A `background-size` stated in system px is one
|
|
34
|
-
* stored length quantized once over the whole image (≤ 1/128 CSS px), not a
|
|
35
|
-
* repeat, and the box's background painting area crops the overdraw.
|
|
15
|
+
* `vf-container pattern="…"` and `vf-desktop pattern="…"`: the pattern's
|
|
16
|
+
* motif as a repeating tile drawn at the display's resolution
|
|
17
|
+
* ({@link RepeatTileController}, src/tile-grid.ts), 1-bit at every density
|
|
18
|
+
* and zoom, and the same cost for a box of any size — a resize encodes
|
|
19
|
+
* nothing.
|
|
36
20
|
*
|
|
37
21
|
* A background rather than a child element, on purpose: it paints below all
|
|
38
22
|
* content by definition — no `isolation: isolate` + `z-index: -1`, so a
|
|
@@ -44,46 +28,33 @@ export interface PatternFillOptions {
|
|
|
44
28
|
* on the box only while patterned and hands `auto` back to the slot, so
|
|
45
29
|
* slotted content renders as it did.
|
|
46
30
|
*
|
|
47
|
-
* What it writes,
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* out-cascade them without `!important` — an inline `background-image`
|
|
52
|
-
* could not be overridden from a stylesheet. The paper is the recipe's, a
|
|
53
|
-
* token: `var(--vf-white)` behind ink that is literal black, like every kit
|
|
54
|
-
* raster. Density and zoom re-encode nothing: the raster is keyed on system
|
|
55
|
-
* px, and the stated lengths are live against `--vf-scale`.
|
|
31
|
+
* What it writes, on the box's inline style and removed the moment there is
|
|
32
|
+
* nothing to paint: `--_vf-pattern-image`, the tile. The paper is the
|
|
33
|
+
* recipe's, a token: `var(--vf-white)` behind ink that is literal black,
|
|
34
|
+
* like every kit raster.
|
|
56
35
|
*
|
|
57
36
|
* Phase is anchored at the box's top-left — where the desktop, trough and
|
|
58
37
|
* swatch anchor theirs. Two same-pattern boxes meeting at an offset that is
|
|
59
38
|
* not a multiple of 8 show a phase seam; a port-anchored phase would be a
|
|
60
39
|
* contained follow-up, not a change here.
|
|
61
40
|
*/
|
|
62
|
-
export declare class PatternFillController
|
|
63
|
-
#private;
|
|
41
|
+
export declare class PatternFillController extends RepeatTileController {
|
|
64
42
|
constructor(host: ReactiveControllerHost & HTMLElement, opts: PatternFillOptions);
|
|
65
|
-
/** The raster's current box in system px (overdraw included), or null
|
|
66
|
-
* while nothing is painted. */
|
|
67
|
-
get size(): {
|
|
68
|
-
width: number;
|
|
69
|
-
height: number;
|
|
70
|
-
} | null;
|
|
71
|
-
hostUpdated(): void;
|
|
72
43
|
}
|
|
73
44
|
/**
|
|
74
45
|
* The rules behind {@link PatternFillController}, for the box it paints:
|
|
75
46
|
* give the box the `vf-pattern-fill` class always, and `vf-patterned` while
|
|
76
47
|
* a pattern is resolved (the component's template knows).
|
|
77
48
|
*
|
|
78
|
-
* Painting: the
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
49
|
+
* Painting: the tile the controller wrote, repeated from the padding box's
|
|
50
|
+
* corner at {@link vfRepeatTileSize}, nearest-neighbor. The paper and the
|
|
51
|
+
* pixelation ride the `vf-patterned` state so an unpatterned box paints
|
|
52
|
+
* exactly nothing and inherits nothing new. `image-rendering` inherits, so
|
|
53
|
+
* the slot hands `auto` back to slotted content: a consumer's own `<img>`
|
|
54
|
+
* renders as it would anywhere else, and a kit element that wants
|
|
55
|
+
* nearest-neighbor (`vf-img`, a `vf-icon`) says so itself. A page that set
|
|
56
|
+
* `pixelated` on an ancestor gets `auto` inside a patterned box — its own
|
|
57
|
+
* declaration on the child still wins, as everywhere.
|
|
87
58
|
*
|
|
88
59
|
* Forced colors: the image goes, the paper is the remapped Canvas — the
|
|
89
60
|
* desktop's posture, a backdrop being decoration.
|
package/dist/pattern-fill.js
CHANGED
|
@@ -1,61 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { TrackWidthController as a } from "./track-width.js";
|
|
5
|
-
import { css as o } from "lit";
|
|
1
|
+
import { RepeatTileController as e, vfRepeatTileSize as t } from "./tile-grid.js";
|
|
2
|
+
import { patternMotif as n } from "./patterns.js";
|
|
3
|
+
import { css as r } from "lit";
|
|
6
4
|
//#region src/pattern-fill.ts
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
#r;
|
|
12
|
-
#i = null;
|
|
13
|
-
#a = "";
|
|
14
|
-
#o = "";
|
|
15
|
-
#s = null;
|
|
5
|
+
var i = /* @__PURE__ */ new WeakMap(), a = (e) => {
|
|
6
|
+
let t = i.get(e);
|
|
7
|
+
return t || (t = n(e), i.set(e, t)), t;
|
|
8
|
+
}, o = class extends e {
|
|
16
9
|
constructor(e, t) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
super(e, {
|
|
11
|
+
getBox: t.getBox,
|
|
12
|
+
getArt: () => {
|
|
13
|
+
let e = t.getPattern();
|
|
14
|
+
return e ? a(e) : null;
|
|
15
|
+
},
|
|
16
|
+
property: "--_vf-pattern-image"
|
|
17
|
+
});
|
|
22
18
|
}
|
|
23
|
-
|
|
24
|
-
return this.#s;
|
|
25
|
-
}
|
|
26
|
-
hostUpdated() {
|
|
27
|
-
this.#c();
|
|
28
|
-
}
|
|
29
|
-
#c() {
|
|
30
|
-
let t = this.#t.getBox() ?? null;
|
|
31
|
-
t !== this.#i && (this.#u(), this.#i = t);
|
|
32
|
-
let i = this.#t.getPattern() ?? null;
|
|
33
|
-
if (!t || !i) {
|
|
34
|
-
this.#u();
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
let a = this.#t.getSize?.() ?? null, o = c(a?.width) ?? this.#l(this.#r.width), s = c(a?.height) ?? this.#l(this.#r.height);
|
|
38
|
-
if (!o || !s) {
|
|
39
|
-
this.#u();
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
let l = (e) => Math.ceil((e + 8) / 8) * 8, u = l(o), d = l(s), f = r(i), p = this.#n.for(f.width, f.height, f.rects, u, d, n(i)), m = `${e(u)} ${e(d)}`;
|
|
43
|
-
this.#s = {
|
|
44
|
-
width: u,
|
|
45
|
-
height: d
|
|
46
|
-
}, (p !== this.#a || m !== this.#o) && (this.#a = p, this.#o = m, t.style.setProperty("--_vf-pattern-image", p), t.style.setProperty("--_vf-pattern-size", m));
|
|
47
|
-
}
|
|
48
|
-
#l(e) {
|
|
49
|
-
return e > 0 ? t(e, this.#e) : 0;
|
|
50
|
-
}
|
|
51
|
-
#u() {
|
|
52
|
-
this.#s = null, !(!this.#a && !this.#o) && (this.#a = "", this.#o = "", this.#i?.style.removeProperty("--_vf-pattern-image"), this.#i?.style.removeProperty("--_vf-pattern-size"));
|
|
53
|
-
}
|
|
54
|
-
}, c = (e) => typeof e == "number" && Number.isFinite(e) && e > 0 ? Math.trunc(e) : null, l = o`
|
|
19
|
+
}, s = r`
|
|
55
20
|
.vf-pattern-fill {
|
|
56
21
|
background-image: var(--_vf-pattern-image, none);
|
|
57
|
-
|
|
58
|
-
background-repeat:
|
|
22
|
+
${t}
|
|
23
|
+
background-repeat: repeat;
|
|
59
24
|
}
|
|
60
25
|
.vf-pattern-fill.vf-patterned {
|
|
61
26
|
background-color: var(--vf-white, #fff);
|
|
@@ -71,4 +36,4 @@ var s = class {
|
|
|
71
36
|
}
|
|
72
37
|
`;
|
|
73
38
|
//#endregion
|
|
74
|
-
export {
|
|
39
|
+
export { o as PatternFillController, s as vfPatternFill };
|
package/dist/scroll-rail.d.ts
CHANGED
|
@@ -30,9 +30,10 @@ export interface ScrollRailOptions {
|
|
|
30
30
|
* whole-system-px translate, so the art is crisp mid-scroll; accepts the
|
|
31
31
|
* ≤1-frame lag behind compositor wheel scrolling every scripted scrollbar
|
|
32
32
|
* has (at 1-bit there is no smooth motion to betray it — no rAF loop, no
|
|
33
|
-
* polling). The same pass
|
|
34
|
-
*
|
|
35
|
-
* state the recipe's
|
|
33
|
+
* polling). The same pass writes the trough's repeating dither tile for
|
|
34
|
+
* the density at the rail (`repeatTile`, src/tile-grid.ts — again on a
|
|
35
|
+
* zoom or display change) and the degenerate-track state the recipe's
|
|
36
|
+
* decision table styles.
|
|
36
37
|
* - **Thumb drag** — pointer-captured and axis-locked, live scrolling (the
|
|
37
38
|
* modern expectation; System 7's dotted-outline drag is a possible later
|
|
38
39
|
* opt-in). The thumb's paint position always snaps to whole system px.
|
|
@@ -59,8 +60,7 @@ export declare class ScrollRailController implements ReactiveController {
|
|
|
59
60
|
private press;
|
|
60
61
|
private holdTimer;
|
|
61
62
|
private repeatTimer;
|
|
62
|
-
|
|
63
|
-
private readonly troughCache;
|
|
63
|
+
private stopScale?;
|
|
64
64
|
constructor(host: ReactiveControllerHost & HTMLElement & {
|
|
65
65
|
readonly renderRoot: HTMLElement | DocumentFragment;
|
|
66
66
|
}, opts: ScrollRailOptions);
|
|
@@ -81,7 +81,7 @@ export declare class ScrollRailController implements ReactiveController {
|
|
|
81
81
|
private unwire;
|
|
82
82
|
private readonly onScroll;
|
|
83
83
|
/**
|
|
84
|
-
* Re-derive every measured output: thumb position, trough
|
|
84
|
+
* Re-derive every measured output: thumb position, trough tile,
|
|
85
85
|
* degenerate state. Safe to call any time; components hit it imperatively
|
|
86
86
|
* when content changes without a box resize (a `<textarea>` on input —
|
|
87
87
|
* the same moments they call `ScrollStateController.measure()`).
|
package/dist/scroll-rail.js
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import { effectiveScale as e,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { effectiveScale as e, onScaleChange as t, sysLength as n } from "./scale.js";
|
|
2
|
+
import { devicePxAt as r, repeatTile as i } from "./tile-grid.js";
|
|
3
|
+
import { TROUGH as a } from "./styles/recipes/scroll-rail.js";
|
|
4
4
|
import "./motion.js";
|
|
5
5
|
import { SCROLL_ARROW_DOWN as o, SCROLL_ARROW_DOWN_FILL as s, SCROLL_ARROW_LEFT as c, SCROLL_ARROW_LEFT_FILL as l, SCROLL_ARROW_RIGHT as u, SCROLL_ARROW_RIGHT_FILL as d, SCROLL_ARROW_UP as f, SCROLL_ARROW_UP_FILL as p } from "./glyphs.js";
|
|
6
6
|
import { html as m } from "lit";
|
|
7
7
|
//#region src/scroll-rail.ts
|
|
8
|
-
var h = 16, g = 16, _ =
|
|
8
|
+
var h = 16, g = 16, _ = 66, v = class {
|
|
9
9
|
constructor(t, n) {
|
|
10
|
-
this.host = t, this.opts = n, this.scroller = null, this.press = null, this.
|
|
11
|
-
vertical: new a(),
|
|
12
|
-
horizontal: new a()
|
|
13
|
-
}, this.onScroll = () => this.sync(), this.onPointerDown = (t) => {
|
|
10
|
+
this.host = t, this.opts = n, this.scroller = null, this.press = null, this.onScroll = () => this.sync(), this.onPointerDown = (t) => {
|
|
14
11
|
if (t.button !== 0 || this.press !== null) return;
|
|
15
12
|
let n = t.currentTarget, r = this.opts.getScroll();
|
|
16
13
|
if (!r) return;
|
|
17
|
-
let i =
|
|
14
|
+
let i = y(n), a = i === "vertical" ? "data-overflow-y" : "data-overflow-x";
|
|
18
15
|
if (r.getAttribute(a) === "false" || r.hasAttribute("data-window-inactive") || n.getAttribute("data-degenerate") === "rail") return;
|
|
19
16
|
let o = t.target, s = i === "vertical" ? t.clientY : t.clientX, c = e(this.host) || 1, l = o.closest(".vf-rail-thumb"), u = o.closest(".vf-rail-button--decrement"), d = o.closest(".vf-rail-button--increment");
|
|
20
17
|
if (l) {
|
|
@@ -78,13 +75,13 @@ var h = 16, g = 16, _ = 14, v = 66, y = class {
|
|
|
78
75
|
}, t.addController(this);
|
|
79
76
|
}
|
|
80
77
|
hostConnected() {
|
|
81
|
-
this.wire(), this.sync();
|
|
78
|
+
this.wire(), this.sync(), this.stopScale = t(() => this.sync());
|
|
82
79
|
}
|
|
83
80
|
hostUpdated() {
|
|
84
81
|
this.wire(), this.sync();
|
|
85
82
|
}
|
|
86
83
|
hostDisconnected() {
|
|
87
|
-
this.clearRepeat(), this.press = null, this.unwire();
|
|
84
|
+
this.clearRepeat(), this.press = null, this.unwire(), this.stopScale?.(), this.stopScale = void 0;
|
|
88
85
|
}
|
|
89
86
|
wire() {
|
|
90
87
|
let e = this.opts.getScroll() ?? null;
|
|
@@ -101,17 +98,17 @@ var h = 16, g = 16, _ = 14, v = 66, y = class {
|
|
|
101
98
|
let e = this.scroller ?? this.opts.getScroll(), t = this.host.renderRoot;
|
|
102
99
|
if (!(!e || !t)) for (let n of t.querySelectorAll(".vf-rail")) this.syncRail(n, e);
|
|
103
100
|
}
|
|
104
|
-
syncRail(
|
|
105
|
-
let s =
|
|
101
|
+
syncRail(t, o) {
|
|
102
|
+
let s = y(t), c = t.querySelector(".vf-rail-track"), l = t.querySelector(".vf-rail-thumb");
|
|
106
103
|
if (!c || !l) return;
|
|
107
104
|
let u = e(this.host) || 1, d = c.getBoundingClientRect(), f = (s === "vertical" ? d.height : d.width) / u, p = f < 1 ? "rail" : f < g ? "thumb" : null;
|
|
108
|
-
if (p ?
|
|
109
|
-
let m = this.scrollRange(o, s), h = s === "vertical" ? o.scrollTop : o.scrollLeft,
|
|
110
|
-
l.style.translate = s === "vertical" ? `0 ${
|
|
111
|
-
let
|
|
112
|
-
if (
|
|
113
|
-
let e =
|
|
114
|
-
|
|
105
|
+
if (p ? t.setAttribute("data-degenerate", p) : t.removeAttribute("data-degenerate"), p === "rail") return;
|
|
106
|
+
let m = this.scrollRange(o, s), h = s === "vertical" ? o.scrollTop : o.scrollLeft, _ = f - g, v = m > 0 && _ > 0 ? Math.max(0, Math.min(Math.floor(_), Math.round(h / m * _))) : 0;
|
|
107
|
+
l.style.translate = s === "vertical" ? `0 ${n(v)}` : `${n(v)} 0`;
|
|
108
|
+
let b = t.querySelector(".vf-rail-trough");
|
|
109
|
+
if (b) {
|
|
110
|
+
let e = i(a, r(b));
|
|
111
|
+
b.style.getPropertyValue("--_vf-trough-tile") !== e && b.style.setProperty("--_vf-trough-tile", e);
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
114
|
scrollRange(e, t) {
|
|
@@ -141,13 +138,13 @@ var h = 16, g = 16, _ = 14, v = 66, y = class {
|
|
|
141
138
|
}
|
|
142
139
|
armRepeat(e) {
|
|
143
140
|
this.clearRepeat(), this.holdTimer = window.setTimeout(() => {
|
|
144
|
-
this.repeatTimer = window.setInterval(e,
|
|
141
|
+
this.repeatTimer = window.setInterval(e, _);
|
|
145
142
|
}, 200);
|
|
146
143
|
}
|
|
147
144
|
clearRepeat() {
|
|
148
145
|
this.holdTimer !== void 0 && window.clearTimeout(this.holdTimer), this.repeatTimer !== void 0 && window.clearInterval(this.repeatTimer), this.holdTimer = void 0, this.repeatTimer = void 0;
|
|
149
146
|
}
|
|
150
|
-
},
|
|
147
|
+
}, y = (e) => e.classList.contains("vf-rail--horizontal") ? "horizontal" : "vertical", b = (e, t) => m`<svg
|
|
151
148
|
class="vf-rail-arrow vf-rail-arrow--${t}"
|
|
152
149
|
viewBox="1 1 14 14"
|
|
153
150
|
fill="currentColor"
|
|
@@ -156,7 +153,7 @@ var h = 16, g = 16, _ = 14, v = 66, y = class {
|
|
|
156
153
|
>
|
|
157
154
|
<path d=${e.d}></path>
|
|
158
155
|
</svg>`;
|
|
159
|
-
function
|
|
156
|
+
function x(e, t) {
|
|
160
157
|
let [n, r, i, a] = t === "vertical" ? [
|
|
161
158
|
f,
|
|
162
159
|
p,
|
|
@@ -179,19 +176,17 @@ function S(e, t) {
|
|
|
179
176
|
@lostpointercapture=${e.onPointerUp}
|
|
180
177
|
>
|
|
181
178
|
<div class="vf-rail-button vf-rail-button--decrement">
|
|
182
|
-
${
|
|
179
|
+
${b(n, "rest")}${b(r, "fill")}
|
|
183
180
|
</div>
|
|
184
181
|
<div class="vf-rail-track">
|
|
185
|
-
<div class="vf-rail-trough">
|
|
186
|
-
<div class="vf-rail-trough-art"></div>
|
|
187
|
-
</div>
|
|
182
|
+
<div class="vf-rail-trough"></div>
|
|
188
183
|
<div class="vf-rail-thumb"></div>
|
|
189
184
|
</div>
|
|
190
185
|
<div class="vf-rail-button vf-rail-button--increment">
|
|
191
|
-
${
|
|
186
|
+
${b(i, "rest")}${b(a, "fill")}
|
|
192
187
|
</div>
|
|
193
188
|
</div>
|
|
194
189
|
`;
|
|
195
190
|
}
|
|
196
191
|
//#endregion
|
|
197
|
-
export {
|
|
192
|
+
export { v as ScrollRailController, x as renderScrollRail };
|
package/dist/styles/base.d.ts
CHANGED
|
@@ -27,7 +27,9 @@ export { vfDisplay, vfDisplayDecls } from './recipes/display-face.js';
|
|
|
27
27
|
export { vfBase } from './recipes/host.js';
|
|
28
28
|
export { vfStaticText } from './recipes/static-text.js';
|
|
29
29
|
export { vfDots, vfStripes } from './recipes/pattern.js';
|
|
30
|
-
export { vfHardShadowDecls } from './recipes/shadow.js';
|
|
30
|
+
export { vfHardShadow, vfHardShadowDecls } from './recipes/shadow.js';
|
|
31
|
+
export { vfStrokeDecls, vfStrokeInset, vfStrokeShadow } from './recipes/stroke.js';
|
|
32
|
+
export type { VfStrokeOptions } from './recipes/stroke.js';
|
|
31
33
|
export { vfChromeFrame, vfModalFrame, vfPanel } from './recipes/surface.js';
|
|
32
34
|
export { RULE_EDGES, parseRule, ruleClasses, vfRule } from './recipes/rule.js';
|
|
33
35
|
export type { RuleEdge } from './recipes/rule.js';
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The System 7 editable-field skin (SPEC §1/§5): a white well with a 1px black
|
|
3
|
-
*
|
|
3
|
+
* frame, no corner radius, Chicago-style display type, and the kit's dashed
|
|
4
4
|
* keyboard-focus rule under the well (no dotted ring). Add the `vf-field`
|
|
5
5
|
* class to the inner native `<input>`/`<textarea>` and wrap it in a
|
|
6
|
-
* `.vf-field-well` element; the host supplies layout (width, height
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* `.vf-field-well` element; the host supplies layout (width, height) around
|
|
7
|
+
* it, and `VfTextControlBase` supplies the `.vf-focus-rule` class that turns
|
|
8
|
+
* the rule on. Shared by vf-text-field, vf-text-area and vf-number-field so
|
|
9
|
+
* the well, focus and disabled treatment stay identical across all three.
|
|
10
|
+
*
|
|
11
|
+
* The frame is a stroke ({@link vfStrokeDecls}), so the recipe owns the
|
|
12
|
+
* input's padding and box-shadow: a host that insets the text restates the
|
|
13
|
+
* padding with `vfStrokeInset` (`padding: ${vfStrokeInset(0)}
|
|
14
|
+
* ${vfStrokeInset(6)}`) in a rule that outranks `.vf-field`.
|
|
11
15
|
*
|
|
12
16
|
* Why the wrapper: the rule is a pseudo-element, and a replaced element
|
|
13
17
|
* generates none — neither `<input>` nor `<textarea>` can draw its own
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { vfDisplayDecls as e } from "./display-face.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { vfStrokeDecls as t } from "./stroke.js";
|
|
3
|
+
import { vfFocusUnderline as n } from "./focus.js";
|
|
4
|
+
import { css as r } from "lit";
|
|
4
5
|
//#region src/styles/recipes/field.ts
|
|
5
|
-
var
|
|
6
|
+
var i = r`
|
|
6
7
|
.vf-field {
|
|
7
8
|
background: var(--vf-white, #fff);
|
|
8
|
-
|
|
9
|
+
${t()}
|
|
9
10
|
border-radius: 0;
|
|
10
11
|
/* Editable text is set in the Chicago-style display face. */
|
|
11
12
|
${e}
|
|
@@ -36,7 +37,7 @@ var r = n`
|
|
|
36
37
|
VfTextControlBase adds .vf-focus-rule for a keyboard focus only. */
|
|
37
38
|
.vf-field-well.vf-focus-rule::after {
|
|
38
39
|
--vf-focus-underline-offset: -2px;
|
|
39
|
-
${
|
|
40
|
+
${n}
|
|
40
41
|
}
|
|
41
42
|
/* Its own token, deliberately not --vf-disabled: the disabled rule below is
|
|
42
43
|
an inactive control and exempt from contrast requirements, but a
|
|
@@ -50,7 +51,7 @@ var r = n`
|
|
|
50
51
|
font-weight: inherit;
|
|
51
52
|
opacity: 1;
|
|
52
53
|
}
|
|
53
|
-
/* Disabled: the text dims to gray; the solid black
|
|
54
|
+
/* Disabled: the text dims to gray; the solid black frame stays. The
|
|
54
55
|
cursor returns to the arrow — a well that can't take input isn't text. */
|
|
55
56
|
.vf-field:disabled {
|
|
56
57
|
color: var(--vf-disabled, #c0c0c0);
|
|
@@ -65,4 +66,4 @@ var r = n`
|
|
|
65
66
|
}
|
|
66
67
|
`;
|
|
67
68
|
//#endregion
|
|
68
|
-
export {
|
|
69
|
+
export { i as vfField };
|
|
@@ -64,13 +64,17 @@ export declare const vfFocus: import("lit").CSSResult;
|
|
|
64
64
|
* the box continues 6px past it (2px half-leading from vfBase's 1.25 line box
|
|
65
65
|
* over the 16px em, plus the face's 4px descent): 6 − 2 = 4.
|
|
66
66
|
* - `-2px` is a well whose ink runs to its own bottom edge — the radio's circle,
|
|
67
|
-
* a field's wrapper
|
|
68
|
-
*
|
|
67
|
+
* a field's wrapper, a box framed by a stroke (vf-checkbox), whose line is
|
|
68
|
+
* inside the padding box — putting the rule in the second row below it.
|
|
69
69
|
* - past that, the rule also clears a hard shadow, which is ink no box the
|
|
70
|
-
* pseudo-element can size to contains: `-
|
|
70
|
+
* pseudo-element can size to contains: `-3px` for vf-select's 1px one, and
|
|
71
71
|
* for vf-swatch an offset that composes `--vf-shadow-offset` rather than
|
|
72
72
|
* hard-coding a depth its consumer can retheme.
|
|
73
73
|
*
|
|
74
|
+
* Under forced colors a stroke is a border again and the padding box sits
|
|
75
|
+
* inside it, so a stroked carrier states its offset and sides with
|
|
76
|
+
* `vfStrokeInset`, which adds the stroke back there.
|
|
77
|
+
*
|
|
74
78
|
* Drawn in `currentColor`, so it inverts with the label on a pressed face.
|
|
75
79
|
*/
|
|
76
80
|
export declare const vfFocusUnderline: import("lit").CSSResult;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The windoid bar's dither is the library's `dots` on its minimal cell: a
|
|
3
|
+
* 2-system-px motif with a single black pixel at its origin. Transparent
|
|
4
|
+
* ground, because the layer floats over the bar and the same art doubles as
|
|
5
|
+
* the forced-colors mask, where the ground would be opacity rather than
|
|
6
|
+
* paint. `vf-window` keeps the layer's repeating tile drawn from this motif
|
|
7
|
+
* (src/tile-grid.ts); the SVG tile below is the forced-colors mask and the
|
|
8
|
+
* consumer token's documented geometry.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DOTS: import("../../patterns.js").PatternMotif;
|
|
3
11
|
/** The dots' tile size in system px (30) — the consumer token's documented box. */
|
|
4
12
|
export declare const DOT_SPAN: number;
|
|
5
13
|
/**
|
|
@@ -58,13 +66,14 @@ export declare const vfStripes: import("lit").CSSResult;
|
|
|
58
66
|
* runs the dots all the way into the side borders (the Windows/ sheet hand-
|
|
59
67
|
* insets them 2px, which the close-up shows is not the bar's own geometry).
|
|
60
68
|
*
|
|
61
|
-
* The layer's own
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
+
* The kit dots are the layer's own background: the repeating tile
|
|
70
|
+
* `vf-window` writes as `--_vf-dots-tile` (src/tile-grid.ts), at any window
|
|
71
|
+
* width. A consumer `--vf-dots-pattern` takes over in one of two ways. A
|
|
72
|
+
* window that knows its width renders the token's placed tile grid INTO the
|
|
73
|
+
* layer and marks it `vf-tile-grid`, which switches the layer's background
|
|
74
|
+
* off: the dot art is transparent-grounded, so a drifting CSS-repeated copy
|
|
75
|
+
* underneath would show through between the exactly placed dots. A window
|
|
76
|
+
* with no declared width marks the layer `vf-dots-token`, and the token
|
|
77
|
+
* repeats in CSS on its documented 30-system-px span.
|
|
69
78
|
*/
|
|
70
79
|
export declare const vfDots: import("lit").CSSResult;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { tileImage as e, tileRects as t, tileSpan as n, vfTileMaskSize as r, vfTileSize as i } from "./tile.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { vfRepeatTileSize as a } from "../../tile-grid.js";
|
|
3
|
+
import { PATTERNS as o, patternMotif as s } from "../../patterns.js";
|
|
4
|
+
import { css as c, unsafeCSS as l } from "lit";
|
|
4
5
|
//#region src/styles/recipes/pattern.ts
|
|
5
|
-
var
|
|
6
|
+
var u = s(o.dots), d = u.width, f = e(d, d, t(u.rects)), p = n(d), m = c`
|
|
6
7
|
.vf-stripes {
|
|
7
8
|
position: absolute;
|
|
8
9
|
inset: calc(var(--vf-scale, 1) * 3px) calc(var(--vf-scale, 1) * 1px);
|
|
@@ -40,15 +41,21 @@ var l = o(a.dots), u = l.width, d = l.rects, f = e(u, u, t(d)), p = n(u), m = s`
|
|
|
40
41
|
background: var(--vf-black, #000000);
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
`, h =
|
|
44
|
+
`, h = c`
|
|
44
45
|
.vf-dots {
|
|
45
46
|
position: absolute;
|
|
46
47
|
inset: calc(var(--vf-scale, 1) * 2px) 0;
|
|
47
|
-
background-image: var(--
|
|
48
|
-
${
|
|
48
|
+
background-image: var(--_vf-dots-tile, none);
|
|
49
|
+
${a}
|
|
50
|
+
image-rendering: pixelated;
|
|
49
51
|
pointer-events: none;
|
|
50
52
|
/* The consumer-token art channel for the placed tile grid. */
|
|
51
|
-
--_vf-tile-image: var(--vf-dots-pattern, ${
|
|
53
|
+
--_vf-tile-image: var(--vf-dots-pattern, ${l(f)});
|
|
54
|
+
}
|
|
55
|
+
.vf-dots.vf-dots-token {
|
|
56
|
+
background-image: var(--vf-dots-pattern);
|
|
57
|
+
${i(d)}
|
|
58
|
+
image-rendering: auto;
|
|
52
59
|
}
|
|
53
60
|
.vf-dots.vf-tile-grid {
|
|
54
61
|
background-image: none;
|
|
@@ -56,23 +63,25 @@ var l = o(a.dots), u = l.width, d = l.rects, f = e(u, u, t(d)), p = n(u), m = s`
|
|
|
56
63
|
/* Forced colors preserves url() tiles verbatim, so the dots would stay
|
|
57
64
|
literal black — invisible on a dark high-contrast theme. Repainted as the
|
|
58
65
|
ink token through the same tile as a mask (the vf-grid rules idiom), so
|
|
59
|
-
the windoid bar's signature follows the user's palette. The
|
|
60
|
-
|
|
61
|
-
rasterizes exactly at a zoom-minted scale anyway
|
|
62
|
-
not reach masks), so forced
|
|
63
|
-
caveat
|
|
66
|
+
the windoid bar's signature follows the user's palette. The tile and the
|
|
67
|
+
token's placed tiles hide here and the span mask takes over — no mask
|
|
68
|
+
pipeline rasterizes exactly at a zoom-minted scale anyway
|
|
69
|
+
(image-rendering does not reach masks), so forced colors keeps the span
|
|
70
|
+
approach and its zoom caveat. */
|
|
64
71
|
@media (forced-colors: active) {
|
|
65
|
-
.vf-dots
|
|
72
|
+
.vf-dots,
|
|
73
|
+
.vf-dots.vf-dots-token {
|
|
66
74
|
background-image: none;
|
|
75
|
+
}
|
|
76
|
+
.vf-dots {
|
|
67
77
|
background-color: var(--vf-black, #000);
|
|
68
|
-
mask-image: var(--vf-dots-pattern, ${
|
|
69
|
-
${r(
|
|
78
|
+
mask-image: var(--vf-dots-pattern, ${l(f)});
|
|
79
|
+
${r(d)}
|
|
70
80
|
}
|
|
71
|
-
.vf-dots .vf-tile
|
|
72
|
-
.vf-dots .vf-tile-raster {
|
|
81
|
+
.vf-dots .vf-tile {
|
|
73
82
|
display: none;
|
|
74
83
|
}
|
|
75
84
|
}
|
|
76
85
|
`;
|
|
77
86
|
//#endregion
|
|
78
|
-
export { u as
|
|
87
|
+
export { u as DOTS, p as DOT_SPAN, h as vfDots, m as vfStripes };
|
|
@@ -9,15 +9,18 @@ export type RuleEdge = (typeof RULE_EDGES)[number];
|
|
|
9
9
|
* floor is `.vf-rule-bottom`, a window's status strip's ceiling is
|
|
10
10
|
* `.vf-rule-top`, and `vf-container rule="…"` takes the edges by name.
|
|
11
11
|
*
|
|
12
|
-
* A
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
12
|
+
* A stroke (see {@link vfStrokeDecls}), inside the box's own `border-box`
|
|
13
|
+
* size (vfBase): the rule's row is padding and an inset shadow paints it
|
|
14
|
+
* black, so it is one system px at every density and zoom, and in-flow
|
|
15
|
+
* content begins inside it. Children placed against the box, and percentage
|
|
16
|
+
* fills, measure from the box's outer edge; a component whose contract puts
|
|
17
|
+
* them inside the rule gives them an inner box to lay out in (vf-container
|
|
18
|
+
* uses its slot). Paints in `--vf-black`, and under forced colors turns back
|
|
19
|
+
* into a border, so it remaps with the rest of the ink.
|
|
18
20
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
+
* The classes compose on one element: each edge's shadow goes through its
|
|
22
|
+
* own private property and one rule paints all four, so the classes own the
|
|
23
|
+
* element's `box-shadow`, and its padding on their edges.
|
|
21
24
|
*
|
|
22
25
|
* `npm run verify:rule` asserts a container's rule against the menu bar's.
|
|
23
26
|
*/
|