vintage-frames 0.4.0 → 0.5.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 +134 -30
- package/dist/components/vf-container.d.ts +37 -3
- package/dist/components/vf-container.js +32 -10
- package/dist/components/vf-desktop.d.ts +52 -19
- package/dist/components/vf-desktop.js +74 -104
- package/dist/components/vf-dialog.d.ts +19 -15
- package/dist/components/vf-dialog.js +45 -53
- package/dist/components/vf-progress-bar.js +3 -3
- package/dist/components/vf-slider.js +11 -11
- package/dist/components/vf-window.js +47 -47
- package/dist/index.d.ts +14 -0
- package/dist/index.js +60 -58
- package/dist/pattern-fill.d.ts +91 -0
- package/dist/pattern-fill.js +74 -0
- package/dist/patterns.d.ts +80 -0
- package/dist/patterns.js +477 -0
- package/dist/scroll-rail.js +37 -37
- package/dist/styles/recipes/pattern.d.ts +2 -12
- package/dist/styles/recipes/pattern.js +11 -15
- package/dist/styles/recipes/scroll-rail.d.ts +3 -12
- package/dist/styles/recipes/scroll-rail.js +7 -15
- package/dist/styles/recipes/surface.d.ts +18 -7
- package/dist/styles/recipes/surface.js +15 -0
- package/dist/tile-grid.d.ts +4 -2
- package/dist/tile-grid.js +3 -3
- package/dist/track-width.d.ts +7 -0
- package/dist/track-width.js +6 -3
- package/docs/SPEC.md +11 -9
- package/editor/vscode.html-custom-data.json +14 -4
- package/editor/web-types.json +29 -6
- package/package.json +2 -1
|
@@ -4,28 +4,28 @@ import { ScaleController as n, snapSys as r, sysLength as i, toSysExact as a } f
|
|
|
4
4
|
import o from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
|
|
5
5
|
import { PlacementController as s, VfPositioned as c, warnMovableContract as l } from "../position.js";
|
|
6
6
|
import { vfBase as u } from "../styles/recipes/host.js";
|
|
7
|
-
import {
|
|
8
|
-
import { vfChromeFrame as
|
|
9
|
-
import { vfTitleBar as
|
|
10
|
-
import { vfFocus as
|
|
11
|
-
import { TileRasterCache as
|
|
12
|
-
import { GridSnapController as
|
|
13
|
-
import { VfSized as
|
|
14
|
-
import { DragController as
|
|
15
|
-
import { TitleCenterController as
|
|
7
|
+
import { DOT_MOTIF as d, DOT_RECTS as f, DOT_SPAN as p, vfDots as m, vfStripes as h } from "../styles/recipes/pattern.js";
|
|
8
|
+
import { vfChromeFrame as g } from "../styles/recipes/surface.js";
|
|
9
|
+
import { vfTitleBar as _, vfWindowWidgets as v } from "../styles/recipes/title-bar.js";
|
|
10
|
+
import { vfFocus as y } from "../styles/recipes/focus.js";
|
|
11
|
+
import { TileRasterCache as b, patternOverride as x, tileGrid as S, vfTileGrid as C } from "../tile-grid.js";
|
|
12
|
+
import { GridSnapController as w } from "../grid-snap.js";
|
|
13
|
+
import { VfSized as T } from "../size.js";
|
|
14
|
+
import { DragController as E } from "../drag.js";
|
|
15
|
+
import { TitleCenterController as D, chromeTitleBar as O, closeBox as k, widgetLabel as A, zoomBox as j } from "../chrome.js";
|
|
16
16
|
import "./vf-scroll-area.js";
|
|
17
|
-
import { LitElement as
|
|
18
|
-
import { property as
|
|
17
|
+
import { LitElement as M, css as N, html as P, nothing as F } from "lit";
|
|
18
|
+
import { property as I, state as L } from "lit/decorators.js";
|
|
19
19
|
//#region src/components/vf-window.ts
|
|
20
|
-
var
|
|
20
|
+
var R = 80, z = 54, B = 24, V = 8, H = class extends T(c(M)) {
|
|
21
21
|
constructor(...e) {
|
|
22
|
-
super(...e), this.heading = "", this.active = !0, this.closable = !0, this.zoomable = !1, this.movable = !1, this.resizable = !1, this.flush = !1, this._hasStatus = !1, this.scale = new n(this), this.gridSnap = new
|
|
22
|
+
super(...e), this.heading = "", this.active = !0, this.closable = !0, this.zoomable = !1, this.movable = !1, this.resizable = !1, this.flush = !1, this._hasStatus = !1, this.scale = new n(this), this.gridSnap = new w(this), this.titleCenter = new D(this), this._dotsPattern = "", this.#e = new b(), this.#t = (e, t, n) => {
|
|
23
23
|
let r = a(this.offsetWidth, this);
|
|
24
24
|
return {
|
|
25
|
-
x: Math.min(Math.max(e,
|
|
26
|
-
y: Math.min(Math.max(t, 0), Math.max(0, n.height -
|
|
25
|
+
x: Math.min(Math.max(e, B - r), n.width - B),
|
|
26
|
+
y: Math.min(Math.max(t, 0), Math.max(0, n.height - B))
|
|
27
27
|
};
|
|
28
|
-
}, this._placement = new s(this, (e, t, n) => this.#t(e, t, n)), this._drag = new
|
|
28
|
+
}, this._placement = new s(this, (e, t, n) => this.#t(e, t, n)), this._drag = new E(this, {
|
|
29
29
|
onDragStart: (e) => !this.movable || e.button !== 0 || e.composedPath().some((e) => e instanceof HTMLElement && e.classList.contains("box")) ? null : (this.#i(), this._placement.seed()),
|
|
30
30
|
onDrag: (e, t) => this._placement.moveTo(e, t)
|
|
31
31
|
}), this._resizeState = null, this.#n = !1, this.#r = !1;
|
|
@@ -33,14 +33,14 @@ var L = 80, R = 54, z = 24, B = 8, V = class extends w(c(j)) {
|
|
|
33
33
|
static {
|
|
34
34
|
this.styles = [
|
|
35
35
|
u,
|
|
36
|
-
m,
|
|
37
|
-
p,
|
|
38
|
-
S,
|
|
39
|
-
v,
|
|
40
36
|
h,
|
|
37
|
+
m,
|
|
38
|
+
C,
|
|
39
|
+
y,
|
|
41
40
|
g,
|
|
42
41
|
_,
|
|
43
|
-
|
|
42
|
+
v,
|
|
43
|
+
N`
|
|
44
44
|
:host {
|
|
45
45
|
display: block;
|
|
46
46
|
position: relative;
|
|
@@ -281,20 +281,20 @@ var L = 80, R = 54, z = 24, B = 8, V = class extends w(c(j)) {
|
|
|
281
281
|
}
|
|
282
282
|
#e;
|
|
283
283
|
willUpdate(e) {
|
|
284
|
-
super.willUpdate(e), this.variant === "utility" && (this._dotsPattern =
|
|
284
|
+
super.willUpdate(e), this.variant === "utility" && (this._dotsPattern = x(this, "--vf-dots-pattern"));
|
|
285
285
|
}
|
|
286
286
|
_dotsTexture() {
|
|
287
287
|
if (this.width == null) return;
|
|
288
288
|
let e = Math.max(1, this.width - 2);
|
|
289
|
-
if (this._dotsPattern) return
|
|
290
|
-
cols: Math.ceil(e /
|
|
289
|
+
if (this._dotsPattern) return S({
|
|
290
|
+
cols: Math.ceil(e / p),
|
|
291
291
|
rows: 1,
|
|
292
|
-
tile:
|
|
292
|
+
tile: p
|
|
293
293
|
});
|
|
294
|
-
let t = Math.ceil((e +
|
|
295
|
-
return
|
|
294
|
+
let t = Math.ceil((e + d) / p) * p, n = V + d;
|
|
295
|
+
return P`<div
|
|
296
296
|
class="vf-tile-raster"
|
|
297
|
-
style="width:${i(t)};height:${i(n)};background-image:${this.#e.for(
|
|
297
|
+
style="width:${i(t)};height:${i(n)};background-image:${this.#e.for(d, d, f, t, n)}"
|
|
298
298
|
></div>`;
|
|
299
299
|
}
|
|
300
300
|
#t;
|
|
@@ -346,7 +346,7 @@ var L = 80, R = 54, z = 24, B = 8, V = class extends w(c(j)) {
|
|
|
346
346
|
_onGrowPointerMove(e) {
|
|
347
347
|
let t = this._resizeState;
|
|
348
348
|
if (!t || e.pointerId !== t.pointerId) return;
|
|
349
|
-
let n = r(Math.max(
|
|
349
|
+
let n = r(Math.max(R, t.baseWidth + a(e.clientX - t.startX, this)), this), i = r(Math.max(z, t.baseHeight + a(e.clientY - t.startY, this)), this);
|
|
350
350
|
(n !== this.width || i !== this.height) && (t.emitPending = !0, t.resized = !0), this.width = n, this.height = i;
|
|
351
351
|
}
|
|
352
352
|
_onGrowPointerEnd(t) {
|
|
@@ -361,34 +361,34 @@ var L = 80, R = 54, z = 24, B = 8, V = class extends w(c(j)) {
|
|
|
361
361
|
});
|
|
362
362
|
}
|
|
363
363
|
render() {
|
|
364
|
-
return
|
|
364
|
+
return P`
|
|
365
365
|
<div
|
|
366
366
|
class="vf-frame vf-snap"
|
|
367
367
|
part="frame"
|
|
368
368
|
role="group"
|
|
369
|
-
aria-labelledby=${this.heading ? "title" :
|
|
369
|
+
aria-labelledby=${this.heading ? "title" : F}
|
|
370
370
|
>
|
|
371
|
-
${
|
|
372
|
-
${this.closable ?
|
|
371
|
+
${O(this._drag, P`
|
|
372
|
+
${this.closable ? k(A("Close", this.heading), this._onCloseClick) : F}
|
|
373
373
|
<span class="vf-title" part="title" id="title">${this.heading}</span>
|
|
374
|
-
${this.zoomable ? A(
|
|
374
|
+
${this.zoomable ? j(A("Zoom", this.heading), this._onZoomClick) : F}
|
|
375
375
|
`, this.variant === "utility" ? "vf-dots" : "vf-stripes", this.variant === "utility" ? this._dotsTexture() : void 0)}
|
|
376
376
|
<div class="body" part="body">
|
|
377
|
-
${this.scrollbars ?
|
|
377
|
+
${this.scrollbars ? P`
|
|
378
378
|
<vf-scroll-area
|
|
379
379
|
class="edge-scroll"
|
|
380
380
|
axis=${this.scrollbars}
|
|
381
|
-
label=${this.heading ||
|
|
381
|
+
label=${this.heading || F}
|
|
382
382
|
exportparts="viewport"
|
|
383
383
|
>
|
|
384
384
|
<slot></slot>
|
|
385
385
|
</vf-scroll-area>
|
|
386
|
-
` :
|
|
386
|
+
` : P`<slot></slot>`}
|
|
387
387
|
</div>
|
|
388
388
|
<div class="status ${this._hasStatus ? "" : "empty"}" part="status-bar">
|
|
389
389
|
<slot name="status" @slotchange=${this._onStatusSlotChange}></slot>
|
|
390
390
|
</div>
|
|
391
|
-
${this.resizable ?
|
|
391
|
+
${this.resizable ? P`
|
|
392
392
|
<div
|
|
393
393
|
class="grow"
|
|
394
394
|
part="grow-box"
|
|
@@ -398,29 +398,29 @@ var L = 80, R = 54, z = 24, B = 8, V = class extends w(c(j)) {
|
|
|
398
398
|
@pointercancel=${this._onGrowPointerEnd}
|
|
399
399
|
@lostpointercapture=${this._onGrowPointerEnd}
|
|
400
400
|
></div>
|
|
401
|
-
` :
|
|
401
|
+
` : F}
|
|
402
402
|
</div>
|
|
403
403
|
`;
|
|
404
404
|
}
|
|
405
405
|
};
|
|
406
|
-
o([
|
|
406
|
+
o([I({ reflect: !0 })], H.prototype, "variant", void 0), o([I()], H.prototype, "heading", void 0), o([I({
|
|
407
407
|
type: Boolean,
|
|
408
408
|
reflect: !0
|
|
409
|
-
})],
|
|
409
|
+
})], H.prototype, "active", void 0), o([I({
|
|
410
410
|
type: Boolean,
|
|
411
411
|
reflect: !0
|
|
412
|
-
})],
|
|
412
|
+
})], H.prototype, "closable", void 0), o([I({
|
|
413
413
|
type: Boolean,
|
|
414
414
|
reflect: !0
|
|
415
|
-
})],
|
|
415
|
+
})], H.prototype, "zoomable", void 0), o([I({
|
|
416
416
|
type: Boolean,
|
|
417
417
|
reflect: !0
|
|
418
|
-
})],
|
|
418
|
+
})], H.prototype, "movable", void 0), o([I({
|
|
419
419
|
type: Boolean,
|
|
420
420
|
reflect: !0
|
|
421
|
-
})],
|
|
421
|
+
})], H.prototype, "resizable", void 0), o([I({
|
|
422
422
|
type: Boolean,
|
|
423
423
|
reflect: !0
|
|
424
|
-
})],
|
|
424
|
+
})], H.prototype, "flush", void 0), o([I({ reflect: !0 })], H.prototype, "scrollbars", void 0), o([L()], H.prototype, "_hasStatus", void 0), H = o([t("vf-window")], H);
|
|
425
425
|
//#endregion
|
|
426
|
-
export {
|
|
426
|
+
export { H as VfWindow };
|
package/dist/index.d.ts
CHANGED
|
@@ -101,6 +101,20 @@ export type { TileRect } from './styles/base.js';
|
|
|
101
101
|
* memoizes the encoded raster against its size.
|
|
102
102
|
*/
|
|
103
103
|
export { vfTileGrid, tileGrid, patternOverride, TileRasterCache } from './tile-grid.js';
|
|
104
|
+
/**
|
|
105
|
+
* The standard pattern set — the 38 MacPaint fills as 8-byte QuickDraw
|
|
106
|
+
* patterns (`PATTERNS`, named; `PATTERN_NAMES` in palette order), the
|
|
107
|
+
* attribute grammar (`parsePattern` reads a name or sixteen hex digits,
|
|
108
|
+
* `patternHex` writes one back), and the adapters onto the tile machinery
|
|
109
|
+
* (`patternMotif` on the minimal cell, `patternRects` on the full 8×8). The
|
|
110
|
+
* fill itself is `PatternFillController` + `vfPatternFill`: a pattern
|
|
111
|
+
* painted as a box's own background, exact at every density and zoom — what
|
|
112
|
+
* `vf-container pattern="…"` does.
|
|
113
|
+
*/
|
|
114
|
+
export { PATTERNS, PATTERN_NAMES, PATTERN_SIZE, parsePattern, patternHex, patternMotif, patternRects, } from './patterns.js';
|
|
115
|
+
export type { Pattern, PatternMotif, PatternName } from './patterns.js';
|
|
116
|
+
export { PatternFillController, vfPatternFill } from './pattern-fill.js';
|
|
117
|
+
export type { PatternFillOptions } from './pattern-fill.js';
|
|
104
118
|
/** Glyph sprites (`glyphSvg(CHECKMARK, 'check')`) and their pixel geometry. */
|
|
105
119
|
export { glyphSvg, CHECKBOX_X, RADIO_FACE, RADIO_RING, RADIO_RING_PRESSED, RADIO_DOT, CHECKMARK, CARET_DOWN, STEPPER, STEPPER_UP_FILL, STEPPER_DOWN_FILL, SLIDER_THUMB, SLIDER_THUMB_FACE, } from './glyphs.js';
|
|
106
120
|
export type { Glyph } from './glyphs.js';
|
package/dist/index.js
CHANGED
|
@@ -11,61 +11,63 @@ import { vfDisplay as P, vfDisplayDecls as F } from "./styles/recipes/display-fa
|
|
|
11
11
|
import { vfBase as I } from "./styles/recipes/host.js";
|
|
12
12
|
import { vfStaticText as L } from "./styles/recipes/static-text.js";
|
|
13
13
|
import { TILE_LATTICE as R, tileImage as z, tileRaster as B, tileRects as V, tileSpan as H, vfTileMaskSize as U, vfTileSize as W } from "./styles/recipes/tile.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
import {
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import {
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
64
|
-
import {
|
|
65
|
-
import {
|
|
66
|
-
import {
|
|
67
|
-
import {
|
|
68
|
-
import {
|
|
69
|
-
import {
|
|
70
|
-
import {
|
|
71
|
-
|
|
14
|
+
import { PATTERNS as G, PATTERN_NAMES as K, PATTERN_SIZE as q, parsePattern as J, patternHex as Y, patternMotif as X, patternRects as Z } from "./patterns.js";
|
|
15
|
+
import { vfDots as Q, vfStripes as $ } from "./styles/recipes/pattern.js";
|
|
16
|
+
import { vfHardShadowDecls as ee } from "./styles/recipes/shadow.js";
|
|
17
|
+
import { vfChromeFrame as te, vfModalFrame as ne, vfPanel as re } from "./styles/recipes/surface.js";
|
|
18
|
+
import { vfTitleBar as ie, vfWindowWidgets as ae } from "./styles/recipes/title-bar.js";
|
|
19
|
+
import { vfFocus as oe, vfFocusRing as se, vfFocusUnderline as ce } from "./styles/recipes/focus.js";
|
|
20
|
+
import { vfToggle as le } from "./styles/recipes/toggle.js";
|
|
21
|
+
import { vfField as ue } from "./styles/recipes/field.js";
|
|
22
|
+
import { vfScrollRail as de } from "./styles/recipes/scroll-rail.js";
|
|
23
|
+
import { TileRasterCache as fe, patternOverride as pe, tileGrid as me, vfTileGrid as he } from "./tile-grid.js";
|
|
24
|
+
import { TrackWidthController as ge } from "./track-width.js";
|
|
25
|
+
import { PatternFillController as _e, vfPatternFill as ve } from "./pattern-fill.js";
|
|
26
|
+
import { GridSnapController as ye, requestGridSnap as be } from "./grid-snap.js";
|
|
27
|
+
import { DocumentListenersController as xe } from "./document-listeners.js";
|
|
28
|
+
import { BUTTON_FACE as Se, BUTTON_FRAME as Ce, RING_FRAME as we, RING_HOLE as Te, RING_INSET as Ee, SCREEN_CORNER as De, steppedCornerClip as Oe, steppedRectClip as ke, steppedRingClip as Ae } from "./pixel-frame.js";
|
|
29
|
+
import { VfDesktop as je } from "./components/vf-desktop.js";
|
|
30
|
+
import { VfSized as Me } from "./size.js";
|
|
31
|
+
import { DragController as Ne } from "./drag.js";
|
|
32
|
+
import { ScrollStateController as Pe } from "./scroll-state.js";
|
|
33
|
+
import { BLINK_FLIPS as Fe, BLINK_INTERVAL_MS as Ie, PRESS_HOLD_MS as Le, RENAME_DELAY_MS as Re, prefersReducedMotion as ze, runSelectionBlink as Be } from "./motion.js";
|
|
34
|
+
import { CARET_DOWN as Ve, CHECKBOX_X as He, CHECKMARK as Ue, RADIO_DOT as We, RADIO_FACE as Ge, RADIO_RING as Ke, RADIO_RING_PRESSED as qe, SLIDER_THUMB as Je, SLIDER_THUMB_FACE as Ye, STEPPER as Xe, STEPPER_DOWN_FILL as Ze, STEPPER_UP_FILL as Qe, glyphSvg as $e } from "./glyphs.js";
|
|
35
|
+
import { ScrollRailController as et, renderScrollRail as tt } from "./scroll-rail.js";
|
|
36
|
+
import { VfScrollArea as nt } from "./components/vf-scroll-area.js";
|
|
37
|
+
import { VfWindow as rt } from "./components/vf-window.js";
|
|
38
|
+
import { VfModalDialog as it, modalDialogStyles as at } from "./modal-dialog.js";
|
|
39
|
+
import { VfButtonGroup as ot } from "./components/vf-button-group.js";
|
|
40
|
+
import { VfDialog as st } from "./components/vf-dialog.js";
|
|
41
|
+
import { VfSeparator as ct } from "./components/vf-separator.js";
|
|
42
|
+
import { VfFormControl as lt } from "./form-control.js";
|
|
43
|
+
import { VfButton as ut } from "./components/vf-button.js";
|
|
44
|
+
import { VfSwatch as dt } from "./components/vf-swatch.js";
|
|
45
|
+
import { VfToggleControl as ft } from "./toggle-control.js";
|
|
46
|
+
import { VfCheckbox as pt } from "./components/vf-checkbox.js";
|
|
47
|
+
import { VfRadio as mt } from "./components/vf-radio.js";
|
|
48
|
+
import { VfRadioGroup as ht } from "./components/vf-radio-group.js";
|
|
49
|
+
import { FocusRuleController as gt, focusModality as _t, trackFocusModality as vt } from "./focus-modality.js";
|
|
50
|
+
import { VfTextControlBase as yt } from "./text-control.js";
|
|
51
|
+
import { VfTextField as bt } from "./components/vf-text-field.js";
|
|
52
|
+
import { VfTextArea as xt } from "./components/vf-text-area.js";
|
|
53
|
+
import { VfNumberField as St } from "./components/vf-number-field.js";
|
|
54
|
+
import { VfOption as Ct } from "./components/vf-option.js";
|
|
55
|
+
import { VfSelect as wt } from "./components/vf-select.js";
|
|
56
|
+
import { VfProgressBar as Tt } from "./components/vf-progress-bar.js";
|
|
57
|
+
import { VfSlider as Et } from "./components/vf-slider.js";
|
|
58
|
+
import { VfLabel as Dt } from "./components/vf-label.js";
|
|
59
|
+
import { VfParagraph as Ot } from "./components/vf-paragraph.js";
|
|
60
|
+
import { VfImg as kt } from "./components/vf-img.js";
|
|
61
|
+
import { VfIcon as At } from "./components/vf-icon.js";
|
|
62
|
+
import { VfMenuBar as jt } from "./components/vf-menu-bar.js";
|
|
63
|
+
import { VfMenu as Mt } from "./components/vf-menu.js";
|
|
64
|
+
import { VfMenuItem as Nt } from "./components/vf-menu-item.js";
|
|
65
|
+
import { VfList as Pt } from "./components/vf-list.js";
|
|
66
|
+
import { VfListItem as Ft } from "./components/vf-list-item.js";
|
|
67
|
+
import { VfFieldset as It } from "./components/vf-fieldset.js";
|
|
68
|
+
import { VfGrid as Lt } from "./components/vf-grid.js";
|
|
69
|
+
import { VfStack as Rt } from "./components/vf-stack.js";
|
|
70
|
+
import { VfContainer as zt } from "./components/vf-container.js";
|
|
71
|
+
import { CURSOR_ARROW as Bt, CURSOR_CROSSHAIR as Vt, CURSOR_I_BEAM as Ht, CURSOR_WAIT as Ut } from "./cursor-art.js";
|
|
72
|
+
import { applyCursor as Wt } from "./cursor.js";
|
|
73
|
+
export { Fe as BLINK_FLIPS, Ie as BLINK_INTERVAL_MS, Se as BUTTON_FACE, Ce as BUTTON_FRAME, Ve as CARET_DOWN, He as CHECKBOX_X, Ue as CHECKMARK, r as CLASSIC_DPI, i as CSS_REFERENCE_DPI, Bt as CURSOR_ARROW, Vt as CURSOR_CROSSHAIR, Ht as CURSOR_I_BEAM, Ut as CURSOR_WAIT, xe as DocumentListenersController, Ne as DragController, gt as FocusRuleController, ye as GridSnapController, G as PATTERNS, K as PATTERN_NAMES, q as PATTERN_SIZE, D as PIXEL_GRID_METRICS, Le as PRESS_HOLD_MS, _e as PatternFillController, T as PlacementController, We as RADIO_DOT, Ge as RADIO_FACE, Ke as RADIO_RING, qe as RADIO_RING_PRESSED, Re as RENAME_DELAY_MS, we as RING_FRAME, Te as RING_HOLE, Ee as RING_INSET, De as SCREEN_CORNER, Je as SLIDER_THUMB, Ye as SLIDER_THUMB_FACE, Xe as STEPPER, Ze as STEPPER_DOWN_FILL, Qe as STEPPER_UP_FILL, a as SYSTEM_PX_IN_CSS_PX, d as ScaleController, et as ScrollRailController, Pe as ScrollStateController, R as TILE_LATTICE, fe as TileRasterCache, ge as TrackWidthController, k as VF_BODY_FAMILY, M as VF_DISPLAY_FAMILY, ut as VfButton, ot as VfButtonGroup, pt as VfCheckbox, zt as VfContainer, je as VfDesktop, st as VfDialog, It as VfFieldset, lt as VfFormControl, Lt as VfGrid, At as VfIcon, kt as VfImg, Dt as VfLabel, Pt as VfList, Ft as VfListItem, Mt as VfMenu, jt as VfMenuBar, Nt as VfMenuItem, it as VfModalDialog, St as VfNumberField, Ct as VfOption, Ot as VfParagraph, E as VfPositioned, Tt as VfProgressBar, mt as VfRadio, ht as VfRadioGroup, nt as VfScrollArea, wt as VfSelect, ct as VfSeparator, Me as VfSized, Et as VfSlider, Rt as VfStack, dt as VfSwatch, xt as VfTextArea, yt as VfTextControlBase, bt as VfTextField, ft as VfToggleControl, rt as VfWindow, Wt as applyCursor, f as applyScale, t as defineElement, o as devicePxPerSystemPx, p as effectiveScale, e as emit, _t as focusModality, m as getScale, s as getZoom, $e as glyphSvg, at as modalDialogStyles, h as onScaleChange, c as onZoomChange, J as parsePattern, Y as patternHex, X as patternMotif, pe as patternOverride, Z as patternRects, ze as prefersReducedMotion, A as registerBodyFace, N as registerDisplayFace, O as registerEmbeddedFont, tt as renderScrollRail, be as requestGridSnap, l as resetZoomBaseline, Be as runSelectionBlink, g as snapSys, _ as snapToDevicePx, v as snapToSystemPx, Oe as steppedCornerClip, ke as steppedRectClip, Ae as steppedRingClip, y as sys, b as sysLength, x as sysLengths, S as systemPxQuantum, me as tileGrid, z as tileImage, B as tileRaster, V as tileRects, H as tileSpan, C as toSys, w as toSysExact, vt as trackFocusModality, u as truePixelRatio, I as vfBase, j as vfBodyDecls, te as vfChromeFrame, P as vfDisplay, F as vfDisplayDecls, Q as vfDots, n as vfElement, ue as vfField, oe as vfFocus, se as vfFocusRing, ce as vfFocusUnderline, ee as vfHardShadowDecls, ne as vfModalFrame, re as vfPanel, ve as vfPatternFill, de as vfScrollRail, L as vfStaticText, $ as vfStripes, he as vfTileGrid, U as vfTileMaskSize, W as vfTileSize, ie as vfTitleBar, le as vfToggle, ae as vfWindowWidgets };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type CSSResult, type ReactiveController, type ReactiveControllerHost } from 'lit';
|
|
2
|
+
import { type Pattern } from './patterns.js';
|
|
3
|
+
/** What a component hands the controller. */
|
|
4
|
+
export interface PatternFillOptions {
|
|
5
|
+
/** The element whose background the pattern paints — a component's own
|
|
6
|
+
* snapped box, so the fill rides the grid-snap correction with it. */
|
|
7
|
+
getBox: () => HTMLElement | null | undefined;
|
|
8
|
+
/** The resolved pattern, or null to paint nothing ({@link parsePattern}
|
|
9
|
+
* turns an attribute value into one). */
|
|
10
|
+
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
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Paints a {@link Pattern} as a box's own background — the fill behind
|
|
24
|
+
* `vf-container pattern="…"` and `vf-desktop pattern="…"`.
|
|
25
|
+
*
|
|
26
|
+
* It is the exact-fill idiom (src/tile-grid.ts) in its background form: the
|
|
27
|
+
* motif is encoded as one raster at one image px per system px
|
|
28
|
+
* (`tileRaster`, cached by pattern and size), sized in system px to the box
|
|
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.
|
|
36
|
+
*
|
|
37
|
+
* A background rather than a child element, on purpose: it paints below all
|
|
38
|
+
* content by definition — no `isolation: isolate` + `z-index: -1`, so a
|
|
39
|
+
* patterned box never becomes a stacking context that traps a slotted
|
|
40
|
+
* control's drop-open panel under a later sibling — and it clips itself, so
|
|
41
|
+
* the box keeps `overflow: visible` (a container's outgrowing content
|
|
42
|
+
* overflows by contract). The one thing a background costs is that
|
|
43
|
+
* `image-rendering` is an inherited property: {@link vfPatternFill} sets it
|
|
44
|
+
* on the box only while patterned and hands `auto` back to the slot, so
|
|
45
|
+
* slotted content renders as it did.
|
|
46
|
+
*
|
|
47
|
+
* What it writes, all on the box's inline style and removed together the
|
|
48
|
+
* moment there is nothing to paint: `--_vf-pattern-image` (the raster) and
|
|
49
|
+
* `--_vf-pattern-size` (two live `sysLength`s). Custom-property channels,
|
|
50
|
+
* not `background-image` itself, so the recipe's forced-colors rule can
|
|
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`.
|
|
56
|
+
*
|
|
57
|
+
* Phase is anchored at the box's top-left — where the desktop, trough and
|
|
58
|
+
* swatch anchor theirs. Two same-pattern boxes meeting at an offset that is
|
|
59
|
+
* not a multiple of 8 show a phase seam; a port-anchored phase would be a
|
|
60
|
+
* contained follow-up, not a change here.
|
|
61
|
+
*/
|
|
62
|
+
export declare class PatternFillController implements ReactiveController {
|
|
63
|
+
#private;
|
|
64
|
+
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
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The rules behind {@link PatternFillController}, for the box it paints:
|
|
75
|
+
* give the box the `vf-pattern-fill` class always, and `vf-patterned` while
|
|
76
|
+
* a pattern is resolved (the component's template knows).
|
|
77
|
+
*
|
|
78
|
+
* Painting: the raster the controller wrote, at the size it stated, once
|
|
79
|
+
* (`no-repeat` — the overdraw is the repeat), nearest-neighbor. The paper
|
|
80
|
+
* and the pixelation ride the `vf-patterned` state so an unpatterned box
|
|
81
|
+
* paints exactly nothing and inherits nothing new. `image-rendering`
|
|
82
|
+
* inherits, so the slot hands `auto` back to slotted content: a consumer's
|
|
83
|
+
* own `<img>` renders as it would anywhere else, and a kit element that
|
|
84
|
+
* wants nearest-neighbor (`vf-img`, a `vf-icon`) says so itself. A page
|
|
85
|
+
* that set `pixelated` on an ancestor gets `auto` inside a patterned box —
|
|
86
|
+
* its own declaration on the child still wins, as everywhere.
|
|
87
|
+
*
|
|
88
|
+
* Forced colors: the image goes, the paper is the remapped Canvas — the
|
|
89
|
+
* desktop's posture, a backdrop being decoration.
|
|
90
|
+
*/
|
|
91
|
+
export declare const vfPatternFill: CSSResult;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { sysLength as e, toSys as t } from "./scale.js";
|
|
2
|
+
import { patternHex as n, patternMotif as r } from "./patterns.js";
|
|
3
|
+
import { TileRasterCache as i } from "./tile-grid.js";
|
|
4
|
+
import { TrackWidthController as a } from "./track-width.js";
|
|
5
|
+
import { css as o } from "lit";
|
|
6
|
+
//#region src/pattern-fill.ts
|
|
7
|
+
var s = class {
|
|
8
|
+
#e;
|
|
9
|
+
#t;
|
|
10
|
+
#n = new i();
|
|
11
|
+
#r;
|
|
12
|
+
#i = null;
|
|
13
|
+
#a = "";
|
|
14
|
+
#o = "";
|
|
15
|
+
#s = null;
|
|
16
|
+
constructor(e, t) {
|
|
17
|
+
this.#e = e, this.#t = t, this.#r = new a(e, () => {
|
|
18
|
+
if (!t.getPattern()) return null;
|
|
19
|
+
let e = t.getSize?.();
|
|
20
|
+
return e == null || e.width == null || e.height == null ? t.getBox() : null;
|
|
21
|
+
}), e.addController(this);
|
|
22
|
+
}
|
|
23
|
+
get size() {
|
|
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`
|
|
55
|
+
.vf-pattern-fill {
|
|
56
|
+
background-image: var(--_vf-pattern-image, none);
|
|
57
|
+
background-size: var(--_vf-pattern-size, auto);
|
|
58
|
+
background-repeat: no-repeat;
|
|
59
|
+
}
|
|
60
|
+
.vf-pattern-fill.vf-patterned {
|
|
61
|
+
background-color: var(--vf-white, #fff);
|
|
62
|
+
image-rendering: pixelated;
|
|
63
|
+
}
|
|
64
|
+
.vf-pattern-fill.vf-patterned > slot {
|
|
65
|
+
image-rendering: auto;
|
|
66
|
+
}
|
|
67
|
+
@media (forced-colors: active) {
|
|
68
|
+
.vf-pattern-fill {
|
|
69
|
+
background-image: none;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
//#endregion
|
|
74
|
+
export { s as PatternFillController, l as vfPatternFill };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { TileRect } from './styles/recipes/tile.js';
|
|
2
|
+
/**
|
|
3
|
+
* The standard Macintosh pattern set — the 38 fills of MacPaint's pattern
|
|
4
|
+
* bar and the System file's `PAT#` 0 — as 8-byte bitmaps, with the helpers
|
|
5
|
+
* that turn one into the art the kit's exact-fill machinery draws
|
|
6
|
+
* (src/pattern-fill.ts paints one as a box's background; src/tile-grid.ts
|
|
7
|
+
* is the raster mechanism under it).
|
|
8
|
+
*
|
|
9
|
+
* A {@link Pattern} is the QuickDraw type: eight rows, top row first, each a
|
|
10
|
+
* byte whose bit 7 is the leftmost pixel and whose set bits are ink. That is
|
|
11
|
+
* also what a `pattern` attribute spells as a custom value — sixteen hex
|
|
12
|
+
* digits, the way a PAT resource read in ResEdit — so the library, the
|
|
13
|
+
* attribute and the data model are one representation.
|
|
14
|
+
*
|
|
15
|
+
* Transcribed 2026-08-22 from a 2× capture of the tear-off pattern palette
|
|
16
|
+
* (a windoid over a 5×8 grid of 19×16 cells on a 20×17 pitch, the first two
|
|
17
|
+
* merged into the current-pattern well; native pixel (x, y) at image
|
|
18
|
+
* (2x+1, 2y+1), cell (c, r) at (5 + 20c, 15 + 17r)) and normalized to the
|
|
19
|
+
* palette window's port origin (5, 4) — the phase QuickDraw drew them at.
|
|
20
|
+
* Under it the three toolbox constants come out byte-for-byte (`gray` AA55,
|
|
21
|
+
* `ltGray` 8822, `dkGray` DD77), and so do the kit's own desktop dither,
|
|
22
|
+
* scroll trough and windoid dots, which are those three patterns. Designed
|
|
23
|
+
* at Apple for MacPaint and the System; stated here as data, the way
|
|
24
|
+
* `fonts/VF-*.glyphs.txt` states the strikes. The capture is not in the
|
|
25
|
+
* repo. docs/PATTERNS.md is the consumer table.
|
|
26
|
+
*/
|
|
27
|
+
export type Pattern = readonly [
|
|
28
|
+
number,
|
|
29
|
+
number,
|
|
30
|
+
number,
|
|
31
|
+
number,
|
|
32
|
+
number,
|
|
33
|
+
number,
|
|
34
|
+
number,
|
|
35
|
+
number
|
|
36
|
+
];
|
|
37
|
+
/** The library's names, in palette order. */
|
|
38
|
+
export type PatternName = 'black' | 'gray-50' | 'white' | 'gray-88' | 'gray-75' | 'gray-75-striped' | 'gray-75-diagonal' | 'dots' | 'pinpoint' | 'dots-sparse' | 'speckle' | 'gray-12' | 'gray-25' | 'stripes-vertical' | 'stripes-horizontal' | 'diagonal' | 'grid' | 'weave' | 'lines-vertical' | 'lines-horizontal' | 'diagonal-wide' | 'grid-wide' | 'zigzag' | 'arrows' | 'chevrons' | 'shingles' | 'dotted-grid' | 'birds' | 'waves' | 'bricks' | 'scales' | 'basket-weave' | 'lattice' | 'twigs' | 'hexagons' | 'pyramids' | 'mesh' | 'stones';
|
|
39
|
+
/**
|
|
40
|
+
* The 38 standard patterns, in palette order (row-major from the cell after
|
|
41
|
+
* the well — insertion order is the order). The ordered-dither ramp is named
|
|
42
|
+
* `gray-N` by ink percentage; everything else for what it reads as.
|
|
43
|
+
*/
|
|
44
|
+
export declare const PATTERNS: Readonly<Record<PatternName, Pattern>>;
|
|
45
|
+
/** The names in palette order — a chooser's iteration order. */
|
|
46
|
+
export declare const PATTERN_NAMES: readonly PatternName[];
|
|
47
|
+
/** A pattern's side in system px — what a custom literal states. */
|
|
48
|
+
export declare const PATTERN_SIZE = 8;
|
|
49
|
+
/**
|
|
50
|
+
* The value a `pattern` attribute takes, resolved: a library name, or
|
|
51
|
+
* sixteen hex digits (two per row, top row first; whitespace between bytes
|
|
52
|
+
* and either case allowed — `"DD 77 DD 77 DD 77 DD 77"`). Anything else,
|
|
53
|
+
* including an empty string, is `null`: the caller paints nothing.
|
|
54
|
+
*/
|
|
55
|
+
export declare function parsePattern(value: string | null | undefined): Pattern | null;
|
|
56
|
+
/** The attribute form of a pattern: sixteen upper-case hex digits, no spaces. */
|
|
57
|
+
export declare function patternHex(pattern: Pattern): string;
|
|
58
|
+
/**
|
|
59
|
+
* A pattern's art as the rect data the tile machinery takes
|
|
60
|
+
* (`tileRaster`, `tileImage` via `tileRects`): `width × height` is the cell
|
|
61
|
+
* the rects cover and tile at.
|
|
62
|
+
*/
|
|
63
|
+
export interface PatternMotif {
|
|
64
|
+
readonly width: number;
|
|
65
|
+
readonly height: number;
|
|
66
|
+
readonly rects: readonly TileRect[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* A pattern's art on its **minimal** cell — the smallest period along each
|
|
70
|
+
* axis — as ink runs over a transparent ground, or over an opaque `paper`
|
|
71
|
+
* rect when one is given. This is how the kit's own surfaces state their
|
|
72
|
+
* dithers from the library: `gray-50` comes back as the 2×2 cell with two
|
|
73
|
+
* black pixels the desktop always had.
|
|
74
|
+
*/
|
|
75
|
+
export declare function patternMotif(pattern: Pattern, ink?: string, paper?: string): PatternMotif;
|
|
76
|
+
/**
|
|
77
|
+
* A pattern's art on the full 8×8 cell, as {@link patternMotif}'s rects —
|
|
78
|
+
* for a caller that wants the literal QuickDraw cell regardless of period.
|
|
79
|
+
*/
|
|
80
|
+
export declare function patternRects(pattern: Pattern, ink?: string, paper?: string): TileRect[];
|