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.
@@ -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 { DOT_RECTS as d, DOT_SPAN as f, vfDots as p, vfStripes as m } from "../styles/recipes/pattern.js";
8
- import { vfChromeFrame as h } from "../styles/recipes/surface.js";
9
- import { vfTitleBar as g, vfWindowWidgets as _ } from "../styles/recipes/title-bar.js";
10
- import { vfFocus as v } from "../styles/recipes/focus.js";
11
- import { TileRasterCache as y, patternOverride as b, tileGrid as x, vfTileGrid as S } from "../tile-grid.js";
12
- import { GridSnapController as C } from "../grid-snap.js";
13
- import { VfSized as w } from "../size.js";
14
- import { DragController as T } from "../drag.js";
15
- import { TitleCenterController as E, chromeTitleBar as D, closeBox as O, widgetLabel as k, zoomBox as A } from "../chrome.js";
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 j, css as M, html as N, nothing as P } from "lit";
18
- import { property as F, state as I } from "lit/decorators.js";
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 L = 80, R = 54, z = 24, B = 8, V = class extends w(c(j)) {
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 C(this), this.titleCenter = new E(this), this._dotsPattern = "", this.#e = new y(), this.#t = (e, t, n) => {
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, z - r), n.width - z),
26
- y: Math.min(Math.max(t, 0), Math.max(0, n.height - z))
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 T(this, {
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
- M`
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 = b(this, "--vf-dots-pattern"));
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 x({
290
- cols: Math.ceil(e / f),
289
+ if (this._dotsPattern) return S({
290
+ cols: Math.ceil(e / p),
291
291
  rows: 1,
292
- tile: f
292
+ tile: p
293
293
  });
294
- let t = Math.ceil((e + 2) / f) * f, n = B + 2;
295
- return N`<div
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(2, 2, d, t, n)}"
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(L, t.baseWidth + a(e.clientX - t.startX, this)), this), i = r(Math.max(R, t.baseHeight + a(e.clientY - t.startY, this)), this);
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 N`
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" : P}
369
+ aria-labelledby=${this.heading ? "title" : F}
370
370
  >
371
- ${D(this._drag, N`
372
- ${this.closable ? O(k("Close", this.heading), this._onCloseClick) : P}
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(k("Zoom", this.heading), this._onZoomClick) : P}
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 ? N`
377
+ ${this.scrollbars ? P`
378
378
  <vf-scroll-area
379
379
  class="edge-scroll"
380
380
  axis=${this.scrollbars}
381
- label=${this.heading || P}
381
+ label=${this.heading || F}
382
382
  exportparts="viewport"
383
383
  >
384
384
  <slot></slot>
385
385
  </vf-scroll-area>
386
- ` : N`<slot></slot>`}
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 ? N`
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
- ` : P}
401
+ ` : F}
402
402
  </div>
403
403
  `;
404
404
  }
405
405
  };
406
- o([F({ reflect: !0 })], V.prototype, "variant", void 0), o([F()], V.prototype, "heading", void 0), o([F({
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
- })], V.prototype, "active", void 0), o([F({
409
+ })], H.prototype, "active", void 0), o([I({
410
410
  type: Boolean,
411
411
  reflect: !0
412
- })], V.prototype, "closable", void 0), o([F({
412
+ })], H.prototype, "closable", void 0), o([I({
413
413
  type: Boolean,
414
414
  reflect: !0
415
- })], V.prototype, "zoomable", void 0), o([F({
415
+ })], H.prototype, "zoomable", void 0), o([I({
416
416
  type: Boolean,
417
417
  reflect: !0
418
- })], V.prototype, "movable", void 0), o([F({
418
+ })], H.prototype, "movable", void 0), o([I({
419
419
  type: Boolean,
420
420
  reflect: !0
421
- })], V.prototype, "resizable", void 0), o([F({
421
+ })], H.prototype, "resizable", void 0), o([I({
422
422
  type: Boolean,
423
423
  reflect: !0
424
- })], V.prototype, "flush", void 0), o([F({ reflect: !0 })], V.prototype, "scrollbars", void 0), o([I()], V.prototype, "_hasStatus", void 0), V = o([t("vf-window")], V);
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 { V as VfWindow };
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 { vfDots as G, vfStripes as K } from "./styles/recipes/pattern.js";
15
- import { vfHardShadowDecls as q } from "./styles/recipes/shadow.js";
16
- import { vfChromeFrame as J, vfModalFrame as Y, vfPanel as X } from "./styles/recipes/surface.js";
17
- import { vfTitleBar as Z, vfWindowWidgets as Q } from "./styles/recipes/title-bar.js";
18
- import { vfFocus as $, vfFocusRing as ee, vfFocusUnderline as te } from "./styles/recipes/focus.js";
19
- import { vfToggle as ne } from "./styles/recipes/toggle.js";
20
- import { vfField as re } from "./styles/recipes/field.js";
21
- import { vfScrollRail as ie } from "./styles/recipes/scroll-rail.js";
22
- import { TileRasterCache as ae, patternOverride as oe, tileGrid as se, vfTileGrid as ce } from "./tile-grid.js";
23
- import { GridSnapController as le, requestGridSnap as ue } from "./grid-snap.js";
24
- import { DocumentListenersController as de } from "./document-listeners.js";
25
- import { BUTTON_FACE as fe, BUTTON_FRAME as pe, RING_FRAME as me, RING_HOLE as he, RING_INSET as ge, SCREEN_CORNER as _e, steppedCornerClip as ve, steppedRectClip as ye, steppedRingClip as be } from "./pixel-frame.js";
26
- import { VfDesktop as xe } from "./components/vf-desktop.js";
27
- import { VfSized as Se } from "./size.js";
28
- import { DragController as Ce } from "./drag.js";
29
- import { ScrollStateController as we } from "./scroll-state.js";
30
- import { BLINK_FLIPS as Te, BLINK_INTERVAL_MS as Ee, PRESS_HOLD_MS as De, RENAME_DELAY_MS as Oe, prefersReducedMotion as ke, runSelectionBlink as Ae } from "./motion.js";
31
- import { CARET_DOWN as je, CHECKBOX_X as Me, CHECKMARK as Ne, RADIO_DOT as Pe, RADIO_FACE as Fe, RADIO_RING as Ie, RADIO_RING_PRESSED as Le, SLIDER_THUMB as Re, SLIDER_THUMB_FACE as ze, STEPPER as Be, STEPPER_DOWN_FILL as Ve, STEPPER_UP_FILL as He, glyphSvg as Ue } from "./glyphs.js";
32
- import { ScrollRailController as We, renderScrollRail as Ge } from "./scroll-rail.js";
33
- import { VfScrollArea as Ke } from "./components/vf-scroll-area.js";
34
- import { VfWindow as qe } from "./components/vf-window.js";
35
- import { VfModalDialog as Je, modalDialogStyles as Ye } from "./modal-dialog.js";
36
- import { VfButtonGroup as Xe } from "./components/vf-button-group.js";
37
- import { VfDialog as Ze } from "./components/vf-dialog.js";
38
- import { VfSeparator as Qe } from "./components/vf-separator.js";
39
- import { VfFormControl as $e } from "./form-control.js";
40
- import { VfButton as et } from "./components/vf-button.js";
41
- import { VfSwatch as tt } from "./components/vf-swatch.js";
42
- import { VfToggleControl as nt } from "./toggle-control.js";
43
- import { VfCheckbox as rt } from "./components/vf-checkbox.js";
44
- import { VfRadio as it } from "./components/vf-radio.js";
45
- import { VfRadioGroup as at } from "./components/vf-radio-group.js";
46
- import { FocusRuleController as ot, focusModality as st, trackFocusModality as ct } from "./focus-modality.js";
47
- import { VfTextControlBase as lt } from "./text-control.js";
48
- import { VfTextField as ut } from "./components/vf-text-field.js";
49
- import { VfTextArea as dt } from "./components/vf-text-area.js";
50
- import { VfNumberField as ft } from "./components/vf-number-field.js";
51
- import { VfOption as pt } from "./components/vf-option.js";
52
- import { VfSelect as mt } from "./components/vf-select.js";
53
- import { TrackWidthController as ht } from "./track-width.js";
54
- import { VfProgressBar as gt } from "./components/vf-progress-bar.js";
55
- import { VfSlider as _t } from "./components/vf-slider.js";
56
- import { VfLabel as vt } from "./components/vf-label.js";
57
- import { VfParagraph as yt } from "./components/vf-paragraph.js";
58
- import { VfImg as bt } from "./components/vf-img.js";
59
- import { VfIcon as xt } from "./components/vf-icon.js";
60
- import { VfMenuBar as St } from "./components/vf-menu-bar.js";
61
- import { VfMenu as Ct } from "./components/vf-menu.js";
62
- import { VfMenuItem as wt } from "./components/vf-menu-item.js";
63
- import { VfList as Tt } from "./components/vf-list.js";
64
- import { VfListItem as Et } from "./components/vf-list-item.js";
65
- import { VfFieldset as Dt } from "./components/vf-fieldset.js";
66
- import { VfGrid as Ot } from "./components/vf-grid.js";
67
- import { VfStack as kt } from "./components/vf-stack.js";
68
- import { VfContainer as At } from "./components/vf-container.js";
69
- import { CURSOR_ARROW as jt, CURSOR_CROSSHAIR as Mt, CURSOR_I_BEAM as Nt, CURSOR_WAIT as Pt } from "./cursor-art.js";
70
- import { applyCursor as Ft } from "./cursor.js";
71
- export { Te as BLINK_FLIPS, Ee as BLINK_INTERVAL_MS, fe as BUTTON_FACE, pe as BUTTON_FRAME, je as CARET_DOWN, Me as CHECKBOX_X, Ne as CHECKMARK, r as CLASSIC_DPI, i as CSS_REFERENCE_DPI, jt as CURSOR_ARROW, Mt as CURSOR_CROSSHAIR, Nt as CURSOR_I_BEAM, Pt as CURSOR_WAIT, de as DocumentListenersController, Ce as DragController, ot as FocusRuleController, le as GridSnapController, D as PIXEL_GRID_METRICS, De as PRESS_HOLD_MS, T as PlacementController, Pe as RADIO_DOT, Fe as RADIO_FACE, Ie as RADIO_RING, Le as RADIO_RING_PRESSED, Oe as RENAME_DELAY_MS, me as RING_FRAME, he as RING_HOLE, ge as RING_INSET, _e as SCREEN_CORNER, Re as SLIDER_THUMB, ze as SLIDER_THUMB_FACE, Be as STEPPER, Ve as STEPPER_DOWN_FILL, He as STEPPER_UP_FILL, a as SYSTEM_PX_IN_CSS_PX, d as ScaleController, We as ScrollRailController, we as ScrollStateController, R as TILE_LATTICE, ae as TileRasterCache, ht as TrackWidthController, k as VF_BODY_FAMILY, M as VF_DISPLAY_FAMILY, et as VfButton, Xe as VfButtonGroup, rt as VfCheckbox, At as VfContainer, xe as VfDesktop, Ze as VfDialog, Dt as VfFieldset, $e as VfFormControl, Ot as VfGrid, xt as VfIcon, bt as VfImg, vt as VfLabel, Tt as VfList, Et as VfListItem, Ct as VfMenu, St as VfMenuBar, wt as VfMenuItem, Je as VfModalDialog, ft as VfNumberField, pt as VfOption, yt as VfParagraph, E as VfPositioned, gt as VfProgressBar, it as VfRadio, at as VfRadioGroup, Ke as VfScrollArea, mt as VfSelect, Qe as VfSeparator, Se as VfSized, _t as VfSlider, kt as VfStack, tt as VfSwatch, dt as VfTextArea, lt as VfTextControlBase, ut as VfTextField, nt as VfToggleControl, qe as VfWindow, Ft as applyCursor, f as applyScale, t as defineElement, o as devicePxPerSystemPx, p as effectiveScale, e as emit, st as focusModality, m as getScale, s as getZoom, Ue as glyphSvg, Ye as modalDialogStyles, h as onScaleChange, c as onZoomChange, oe as patternOverride, ke as prefersReducedMotion, A as registerBodyFace, N as registerDisplayFace, O as registerEmbeddedFont, Ge as renderScrollRail, ue as requestGridSnap, l as resetZoomBaseline, Ae as runSelectionBlink, g as snapSys, _ as snapToDevicePx, v as snapToSystemPx, ve as steppedCornerClip, ye as steppedRectClip, be as steppedRingClip, y as sys, b as sysLength, x as sysLengths, S as systemPxQuantum, se as tileGrid, z as tileImage, B as tileRaster, V as tileRects, H as tileSpan, C as toSys, w as toSysExact, ct as trackFocusModality, u as truePixelRatio, I as vfBase, j as vfBodyDecls, J as vfChromeFrame, P as vfDisplay, F as vfDisplayDecls, G as vfDots, n as vfElement, re as vfField, $ as vfFocus, ee as vfFocusRing, te as vfFocusUnderline, q as vfHardShadowDecls, Y as vfModalFrame, X as vfPanel, ie as vfScrollRail, L as vfStaticText, K as vfStripes, ce as vfTileGrid, U as vfTileMaskSize, W as vfTileSize, Z as vfTitleBar, ne as vfToggle, Q as vfWindowWidgets };
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[];