vintage-frames 0.12.2 → 0.12.4

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.
@@ -1,58 +1,100 @@
1
1
  import { emit as e } from "../events.js";
2
2
  import { vfElement as t } from "../define.js";
3
- import { ScaleController as n, snapSys as r, sysLength as i, toSysExact as a } from "../scale.js";
4
- import o from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
5
- import { PlacementController as s, VfPositioned as c, placementIn as l, warnMovableContract as u } from "../position.js";
6
- import { vfBase as d } from "../styles/recipes/host.js";
7
- import { DOT_MOTIF as f, DOT_RECTS as p, DOT_SPAN as m, vfDots as h, vfStripes as g } from "../styles/recipes/pattern.js";
8
- import { vfChromeFrame as _ } from "../styles/recipes/surface.js";
9
- import { vfRule as v } from "../styles/recipes/rule.js";
10
- import { vfTitleBar as y, vfWindowWidgets as b } from "../styles/recipes/title-bar.js";
11
- import { vfFocus as x } from "../styles/recipes/focus.js";
12
- import { TileRasterCache as S, patternOverride as C, tileGrid as w, vfTileGrid as T } from "../tile-grid.js";
13
- import { GridSnapController as E } from "../grid-snap.js";
14
- import { VfSized as D } from "../size.js";
15
- import { DragController as O } from "../drag.js";
16
- import { TitleCenterController as k, chromeTitleBar as A, closeBox as j, widgetLabel as M, zoomBox as N } from "../chrome.js";
3
+ import { ScaleController as n, effectiveScale as r, snapSys as i, sysLength as a, toSysExact as o } from "../scale.js";
4
+ import s from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
5
+ import { PlacementController as c, VfPositioned as l, placementIn as u, warnMovableContract as d } from "../position.js";
6
+ import { vfBase as f } from "../styles/recipes/host.js";
7
+ import { DOT_MOTIF as p, DOT_RECTS as m, DOT_SPAN as h, vfDots as g, vfStripes as _ } from "../styles/recipes/pattern.js";
8
+ import { vfChromeFrame as v } from "../styles/recipes/surface.js";
9
+ import { vfRule as y } from "../styles/recipes/rule.js";
10
+ import { vfTitleBar as b, vfWindowWidgets as x } from "../styles/recipes/title-bar.js";
11
+ import { vfFocus as S } from "../styles/recipes/focus.js";
12
+ import { TileRasterCache as C, patternOverride as w, tileGrid as T, vfTileGrid as E } from "../tile-grid.js";
13
+ import { GridSnapController as D } from "../grid-snap.js";
14
+ import { DocumentListenersController as O } from "../document-listeners.js";
15
+ import { VfSized as k } from "../size.js";
16
+ import { DragController as A } from "../drag.js";
17
+ import { TitleCenterController as j, chromeTitleBar as M, closeBox as N, widgetLabel as P, zoomBox as F } from "../chrome.js";
18
+ import { prefersReducedMotion as I, windowRectFraction as L } from "../motion.js";
19
+ import { paintSelectionRect as R, penPhase as z, xorPenCanvas as B } from "../open-art.js";
17
20
  import "./vf-scroll-area.js";
18
- import { LitElement as P, css as F, html as I, nothing as L } from "lit";
19
- import { property as R, query as z, state as B } from "lit/decorators.js";
21
+ import { LitElement as V, css as H, html as U, nothing as W } from "lit";
22
+ import { property as G, query as K, state as q } from "lit/decorators.js";
20
23
  //#region src/components/vf-window.ts
21
- var V = 80, H = 54;
22
- function U(e, t, n) {
24
+ var J = 80, Y = 54;
25
+ function X(e, t, n) {
23
26
  let r = Math.max(t, e);
24
27
  return n == null ? r : Math.min(n, r);
25
28
  }
26
- var W = 24, G = 8, K = class extends D(c(P)) {
29
+ var Z = 24, Q = 8, $ = class extends k(l(V)) {
27
30
  constructor(...e) {
28
- super(...e), this.heading = "", this.active = !0, this.closable = !0, this.zoomable = !1, this.movable = !1, this.resizable = !1, this._hasHeader = !1, this._hasStatus = !1, this.scale = new n(this), this.gridSnap = new E(this), this.titleCenter = new k(this), this._dotsPattern = "", this.#e = new S(), this.#t = (e, t, n) => {
29
- let r = a(this.offsetWidth, this);
31
+ super(...e), this.heading = "", this.active = !0, this.closable = !0, this.zoomable = !1, this.movable = !1, this.outlineDrag = !1, this.resizable = !1, this._hasHeader = !1, this._hasStatus = !1, this.scale = new n(this), this.gridSnap = new D(this), this.titleCenter = new j(this), this._dotsPattern = "", this.#e = new C(), this.#t = (e, t, n) => {
32
+ let r = o(this.offsetWidth, this);
30
33
  return {
31
- x: Math.min(Math.max(e, W - r), n.width - W),
32
- y: Math.min(Math.max(t, 0), Math.max(0, n.height - W))
34
+ x: Math.min(Math.max(e, Z - r), n.width - Z),
35
+ y: Math.min(Math.max(t, 0), Math.max(0, n.height - Z))
33
36
  };
34
- }, this._placement = new s(this, (e, t, n) => this.#t(e, t, n)), this._drag = new O(this, {
35
- onDragStart: (e) => !this.movable || e.button !== 0 || e.composedPath().some((e) => e instanceof HTMLElement && e.classList.contains("box")) ? null : (this.#i(), this._placement.seed()),
36
- onDrag: (e, t) => this._placement.moveTo(e, t)
37
- }), this._resizeState = null, this.#n = !1, this.#r = !1;
37
+ }, this._placement = new c(this, (e, t, n) => this.#t(e, t, n)), this._drag = new A(this, {
38
+ onDragStart: (e) => {
39
+ if (!this.movable || e.button !== 0 || e.composedPath().some((e) => e instanceof HTMLElement && e.classList.contains("box"))) return null;
40
+ this.#S();
41
+ let t = this._placement.seed();
42
+ return this.#h(t), t;
43
+ },
44
+ onDrag: (e, t) => {
45
+ this.#f ? this.#g(e, t) : this._placement.moveTo(e, t);
46
+ },
47
+ onDragEnd: (e, t) => {
48
+ this.#y(t);
49
+ }
50
+ }), this._resizeState = null, this.#n = this.attachInternals(), this.#r = null, this.#i = new O(this, () => [[
51
+ document,
52
+ "pointerdown",
53
+ this.#a,
54
+ !0
55
+ ], [
56
+ document,
57
+ "keydown",
58
+ this.#o,
59
+ !0
60
+ ]]), this.#a = () => {
61
+ this.#s("finish");
62
+ }, this.#o = (e) => {
63
+ e.key !== "Escape" || !this.#r || (e.preventDefault(), e.stopPropagation(), this.#s("finish"));
64
+ }, this.#f = null, this.#p = new O(this, () => [[
65
+ document,
66
+ "keydown",
67
+ this.#m,
68
+ !0
69
+ ]]), this.#m = (e) => {
70
+ e.key !== "Escape" || !this.#f || (e.preventDefault(), e.stopPropagation(), this._drag.cancel());
71
+ }, this.#b = !1, this.#x = !1;
38
72
  }
39
73
  static {
40
74
  this.styles = [
41
- d,
42
- g,
43
- h,
44
- T,
45
- x,
75
+ f,
46
76
  _,
77
+ g,
78
+ E,
79
+ S,
47
80
  v,
48
81
  y,
49
82
  b,
50
- F`
83
+ x,
84
+ H`
51
85
  :host {
52
86
  display: block;
53
87
  position: relative;
54
88
  --vf-surface: var(--vf-white, #ffffff);
55
89
  }
90
+ /* Opening from a rect (show): laid out, focusable and a hit target,
91
+ painting nothing until the rects have drained. Opacity rather than
92
+ visibility, which would drop focus and hand a press to whatever is
93
+ under the window. A rule of its own, never in an :is() list: an
94
+ engine that cannot parse :state() drops the whole list. */
95
+ :host(:state(opening)) {
96
+ opacity: 0;
97
+ }
56
98
  /* Skin from vfChromeFrame; the layout is the window's own — a full-size
57
99
  flex column so the body takes the slack the title bar and grow box
58
100
  don't. */
@@ -312,32 +354,152 @@ var W = 24, G = 8, K = class extends D(c(P)) {
312
354
  }
313
355
  #e;
314
356
  willUpdate(e) {
315
- super.willUpdate(e), this.variant === "utility" && (this._dotsPattern = C(this, "--vf-dots-pattern"));
357
+ super.willUpdate(e), this.variant === "utility" && (this._dotsPattern = w(this, "--vf-dots-pattern"));
316
358
  }
317
359
  _dotsTexture() {
318
360
  if (this.width == null) return;
319
361
  let e = Math.max(1, this.width - 2);
320
- if (this._dotsPattern) return w({
321
- cols: Math.ceil(e / m),
362
+ if (this._dotsPattern) return T({
363
+ cols: Math.ceil(e / h),
322
364
  rows: 1,
323
- tile: m
365
+ tile: h
324
366
  });
325
- let t = Math.ceil((e + f) / m) * m, n = G + f;
326
- return I`<div
367
+ let t = Math.ceil((e + p) / h) * h, n = Q + p;
368
+ return U`<div
327
369
  class="vf-tile-raster"
328
- style="width:${i(t)};height:${i(n)};background-image:${this.#e.for(f, f, p, t, n)}"
370
+ style="width:${a(t)};height:${a(n)};background-image:${this.#e.for(p, p, m, t, n)}"
329
371
  ></div>`;
330
372
  }
331
373
  #t;
332
374
  placementAt(e, t, n) {
333
375
  let r = this.scrollArea;
334
- return r ? r.placementAt(e, t, n) : l(this.body ?? this, e, t, this, n);
376
+ return r ? r.placementAt(e, t, n) : u(this.body ?? this, e, t, this, n);
335
377
  }
336
378
  measure() {
337
379
  this.scrollArea?.measure();
338
380
  }
381
+ async show(e = {}) {
382
+ this.#s("finish"), this.hidden = !1;
383
+ let t = e.from;
384
+ if (!t || I()) return !1;
385
+ let n = {
386
+ closing: !1,
387
+ animations: []
388
+ };
389
+ this.#r = n, this.#n.states?.add("opening"), this.#i.attach();
390
+ do
391
+ await this.updateComplete;
392
+ while (this.isUpdatePending && this.#r === n);
393
+ if (this.#r !== n) return !1;
394
+ let r = this.isConnected ? this.#u(t, this.getBoundingClientRect(), !1) : null;
395
+ return r ? (n.animations = r.animations, this.#l(n, r)) : (this.#c(), !1);
396
+ }
397
+ async hide(e = {}) {
398
+ let t = this.#r?.closing === !1, n = !this.hidden && !t;
399
+ this.#s(t ? "cancel" : "finish");
400
+ let r = e.to, i = r && n && this.isConnected && !I() ? this.#u(r, this.getBoundingClientRect(), !0) : null;
401
+ if (this.hidden = !0, !i) return !1;
402
+ let a = {
403
+ closing: !0,
404
+ animations: i.animations
405
+ };
406
+ return this.#r = a, this.#i.attach(), this.#l(a, i);
407
+ }
408
+ #n;
409
+ #r;
410
+ #i;
411
+ #a;
412
+ #o;
413
+ #s(e) {
414
+ let t = this.#r;
415
+ if (t) {
416
+ this.#c();
417
+ for (let n of t.animations) n[e]();
418
+ }
419
+ }
420
+ #c() {
421
+ this.#r = null, this.#n.states?.delete("opening"), this.#i.detach();
422
+ }
423
+ async #l(e, t) {
424
+ let n = await Promise.all(t.animations.map((e) => e.finished)).then(() => !0, () => !1);
425
+ for (let e of t.canvases) e.remove();
426
+ return this.#r === e && this.#c(), n;
427
+ }
428
+ #u(e, t, n) {
429
+ let i = this.#d();
430
+ if (!i) return null;
431
+ let o = r(this), s = i.getBoundingClientRect(), c = (e) => ({
432
+ left: Math.round((e.left - s.left) / o),
433
+ top: Math.round((e.top - s.top) / o),
434
+ right: Math.round((e.right - s.left) / o),
435
+ bottom: Math.round((e.bottom - s.top) / o)
436
+ }), l = c(e), u = c(t);
437
+ if (Math.max(l.right, u.right) <= 0 || Math.max(l.bottom, u.bottom) <= 0 || Math.min(l.left, u.left) >= Math.round(s.width / o) || Math.min(l.top, u.top) >= Math.round(s.height / o)) return null;
438
+ let d = {
439
+ canvases: [],
440
+ animations: []
441
+ };
442
+ for (let e = 0; e < 14; e++) {
443
+ let t = L(e), r = (e, n) => e + Math.trunc((n - e) * t), o = r(l.left, u.left), s = r(l.top, u.top), c = Math.max(1, r(l.right, u.right) - o), f = Math.max(1, r(l.bottom, u.bottom) - s), p = B("window-rect"), m = p.style;
444
+ m.position = "absolute", m.left = a(o), m.top = a(s), m.width = a(c), m.height = a(f), m.visibility = "hidden", R(p, c, f, z(o, s)), i.append(p), d.canvases.push(p);
445
+ let h = n ? 13 - e : e;
446
+ d.animations.push(p.animate([{ visibility: "visible" }, { visibility: "visible" }], {
447
+ delay: h * 17,
448
+ duration: 68,
449
+ endDelay: (14 - h) * 17
450
+ }));
451
+ }
452
+ return d;
453
+ }
454
+ #d() {
455
+ let t = { surface: null };
456
+ return e(this, "vf-drag-surface-request", t, { composed: !1 }), t.surface;
457
+ }
458
+ #f;
459
+ #p;
460
+ #m;
461
+ #h(e) {
462
+ if (this.#y(!0), !this.outlineDrag) return;
463
+ let t = this.#v(this.getBoundingClientRect());
464
+ t && (this.#f = {
465
+ origin: e,
466
+ outline: t,
467
+ landing: null
468
+ }, this.#_(t, 0, 0), this.#p.attach());
469
+ }
470
+ #g(e, t) {
471
+ let n = this.#f;
472
+ if (!n) return;
473
+ let r = this._placement.resolve(e, t);
474
+ n.landing = r, this.#_(n.outline, r.x - n.origin.x, r.y - n.origin.y);
475
+ }
476
+ #_(e, t, n) {
477
+ let r = e.base.x + t, i = e.base.y + n;
478
+ e.canvas.style.left = a(r), e.canvas.style.top = a(i);
479
+ let o = z(r, i);
480
+ o !== e.phase && (e.phase = o, R(e.canvas, e.width, e.height, o));
481
+ }
482
+ #v(e) {
483
+ let t = this.#d();
484
+ if (!t) return null;
485
+ let n = r(this), i = t.getBoundingClientRect(), o = Math.max(1, Math.round(e.width / n)), s = Math.max(1, Math.round(e.height / n)), c = B("drag-outline"), l = c.style;
486
+ return l.position = "absolute", l.width = a(o), l.height = a(s), t.append(c), {
487
+ canvas: c,
488
+ base: {
489
+ x: Math.round((e.left - i.left) / n),
490
+ y: Math.round((e.top - i.top) / n)
491
+ },
492
+ width: o,
493
+ height: s,
494
+ phase: -1
495
+ };
496
+ }
497
+ #y(e) {
498
+ let t = this.#f;
499
+ this.#f = null, t && (this.#p.detach(), t.outline.canvas.remove(), !e && t.landing && this._placement.moveTo(t.landing.x, t.landing.y));
500
+ }
339
501
  updated() {
340
- this.#a();
502
+ this.#C();
341
503
  let t = this._resizeState;
342
504
  t?.emitPending && (t.emitPending = !1, e(this, "vf-resize", {
343
505
  width: this.width,
@@ -345,18 +507,23 @@ var W = 24, G = 8, K = class extends D(c(P)) {
345
507
  commit: !1
346
508
  }));
347
509
  }
348
- #n;
349
- #r;
350
- #i() {
351
- this.#r ||= u(this, `vf-window${this.heading ? ` ("${this.heading}")` : ""}`, "<vf-window movable top=\"30\" left=\"40\" width=\"240\" height=\"176\">");
510
+ #b;
511
+ #x;
512
+ #S() {
513
+ this.#x ||= d(this, `vf-window${this.heading ? ` ("${this.heading}")` : ""}`, "<vf-window movable top=\"30\" left=\"40\" width=\"240\" height=\"176\">");
352
514
  }
353
- #a() {
354
- if (this.#n) return;
515
+ #C() {
516
+ if (this.#b) return;
355
517
  let e = [];
356
- this.width == null && this.style.width === "" && e.push("width (falling back to block layout)"), this.height == null && this.style.height === "" && e.push("height (falling back to the content)"), e.length !== 0 && (this.#n = !0, console.warn(`vf-window${this.heading ? ` ("${this.heading}")` : ""}: no ${e.join(", no ")}. A window owns its whole box — declare both in system px: <vf-window width="240" height="176">.`));
518
+ this.width == null && this.style.width === "" && e.push("width (falling back to block layout)"), this.height == null && this.style.height === "" && e.push("height (falling back to the content)"), e.length !== 0 && (this.#b = !0, console.warn(`vf-window${this.heading ? ` ("${this.heading}")` : ""}: no ${e.join(", no ")}. A window owns its whole box — declare both in system px: <vf-window width="240" height="176">.`));
519
+ }
520
+ connectedCallback() {
521
+ super.connectedCallback(), this.#r && this.#i.attach();
357
522
  }
358
523
  disconnectedCallback() {
359
- super.disconnectedCallback(), this._resizeState = null;
524
+ super.disconnectedCallback(), this._resizeState = null, this.#f?.outline.canvas.remove(), this.#f = null, this.#r && !this.#r.closing && queueMicrotask(() => {
525
+ !this.isConnected && this.#r?.closing === !1 && this.#s("cancel");
526
+ });
360
527
  }
361
528
  _onStatusSlotChange(e) {
362
529
  let t = e.target;
@@ -379,8 +546,8 @@ var W = 24, G = 8, K = class extends D(c(P)) {
379
546
  pointerId: e.pointerId,
380
547
  startX: e.clientX,
381
548
  startY: e.clientY,
382
- baseWidth: a(t.width, this),
383
- baseHeight: a(t.height, this),
549
+ baseWidth: o(t.width, this),
550
+ baseHeight: o(t.height, this),
384
551
  emitPending: !1,
385
552
  resized: !1
386
553
  }, e.currentTarget.setPointerCapture(e.pointerId), e.preventDefault();
@@ -388,8 +555,8 @@ var W = 24, G = 8, K = class extends D(c(P)) {
388
555
  _onGrowPointerMove(e) {
389
556
  let t = this._resizeState;
390
557
  if (!t || e.pointerId !== t.pointerId) return;
391
- let n = U(r(t.baseWidth + a(e.clientX - t.startX, this), this), this.minWidth ?? V, this.maxWidth), i = U(r(t.baseHeight + a(e.clientY - t.startY, this), this), this.minHeight ?? H, this.maxHeight);
392
- (n !== this.width || i !== this.height) && (t.emitPending = !0, t.resized = !0), this.width = n, this.height = i;
558
+ let n = X(i(t.baseWidth + o(e.clientX - t.startX, this), this), this.minWidth ?? J, this.maxWidth), r = X(i(t.baseHeight + o(e.clientY - t.startY, this), this), this.minHeight ?? Y, this.maxHeight);
559
+ (n !== this.width || r !== this.height) && (t.emitPending = !0, t.resized = !0), this.width = n, this.height = r;
393
560
  }
394
561
  _onGrowPointerEnd(t) {
395
562
  let n = this._resizeState;
@@ -403,42 +570,42 @@ var W = 24, G = 8, K = class extends D(c(P)) {
403
570
  });
404
571
  }
405
572
  render() {
406
- return I`
573
+ return U`
407
574
  <div
408
575
  class="vf-frame vf-snap"
409
576
  part="frame"
410
577
  role="group"
411
- aria-labelledby=${this.heading ? "title" : L}
578
+ aria-labelledby=${this.heading ? "title" : W}
412
579
  >
413
- ${A(this._drag, I`
414
- ${this.closable ? j(M("Close", this.heading), this._onCloseClick) : L}
580
+ ${M(this._drag, U`
581
+ ${this.closable ? N(P("Close", this.heading), this._onCloseClick) : W}
415
582
  <span class="vf-title" part="title" id="title">${this.heading}</span>
416
- ${this.zoomable ? N(M("Zoom", this.heading), this._onZoomClick) : L}
583
+ ${this.zoomable ? F(P("Zoom", this.heading), this._onZoomClick) : W}
417
584
  `, this.variant === "utility" ? "vf-dots" : "vf-stripes", this.variant === "utility" ? this._dotsTexture() : void 0)}
418
585
  <div
419
586
  class="header vf-rule-bottom ${this._hasHeader ? "" : "empty"}"
420
587
  part="header"
421
- style=${this.headerHeight == null ? L : `height:${i(this.headerHeight)}`}
588
+ style=${this.headerHeight == null ? W : `height:${a(this.headerHeight)}`}
422
589
  >
423
590
  <slot name="header" @slotchange=${this._onHeaderSlotChange}></slot>
424
591
  </div>
425
592
  <div class="body" part="body">
426
- ${this.scrollbars ? I`
593
+ ${this.scrollbars ? U`
427
594
  <vf-scroll-area
428
595
  class="edge-scroll"
429
596
  axis=${this.scrollbars}
430
597
  ?corner=${this.resizable && !this._hasStatus}
431
- label=${this.heading || L}
598
+ label=${this.heading || W}
432
599
  exportparts="viewport"
433
600
  >
434
601
  <slot></slot>
435
602
  </vf-scroll-area>
436
- ` : I`<slot></slot>`}
603
+ ` : U`<slot></slot>`}
437
604
  </div>
438
605
  <div class="status vf-rule-top ${this._hasStatus ? "" : "empty"}" part="status-bar">
439
606
  <slot name="status" @slotchange=${this._onStatusSlotChange}></slot>
440
607
  </div>
441
- ${this.resizable ? I`
608
+ ${this.resizable ? U`
442
609
  <div
443
610
  class="grow"
444
611
  part="grow-box"
@@ -448,41 +615,45 @@ var W = 24, G = 8, K = class extends D(c(P)) {
448
615
  @pointercancel=${this._onGrowPointerEnd}
449
616
  @lostpointercapture=${this._onGrowPointerEnd}
450
617
  ></div>
451
- ` : L}
618
+ ` : W}
452
619
  </div>
453
620
  `;
454
621
  }
455
622
  };
456
- o([R({ reflect: !0 })], K.prototype, "variant", void 0), o([R()], K.prototype, "heading", void 0), o([R({
623
+ s([G({ reflect: !0 })], $.prototype, "variant", void 0), s([G()], $.prototype, "heading", void 0), s([G({
457
624
  type: Boolean,
458
625
  reflect: !0
459
- })], K.prototype, "active", void 0), o([R({
626
+ })], $.prototype, "active", void 0), s([G({
460
627
  type: Boolean,
461
628
  reflect: !0
462
- })], K.prototype, "closable", void 0), o([R({
629
+ })], $.prototype, "closable", void 0), s([G({
463
630
  type: Boolean,
464
631
  reflect: !0
465
- })], K.prototype, "zoomable", void 0), o([R({
632
+ })], $.prototype, "zoomable", void 0), s([G({
466
633
  type: Boolean,
467
634
  reflect: !0
468
- })], K.prototype, "movable", void 0), o([R({
635
+ })], $.prototype, "movable", void 0), s([G({
636
+ type: Boolean,
637
+ reflect: !0,
638
+ attribute: "outline-drag"
639
+ })], $.prototype, "outlineDrag", void 0), s([G({
469
640
  type: Boolean,
470
641
  reflect: !0
471
- })], K.prototype, "resizable", void 0), o([R({
642
+ })], $.prototype, "resizable", void 0), s([G({
472
643
  type: Number,
473
644
  attribute: "min-width"
474
- })], K.prototype, "minWidth", void 0), o([R({
645
+ })], $.prototype, "minWidth", void 0), s([G({
475
646
  type: Number,
476
647
  attribute: "min-height"
477
- })], K.prototype, "minHeight", void 0), o([R({
648
+ })], $.prototype, "minHeight", void 0), s([G({
478
649
  type: Number,
479
650
  attribute: "max-width"
480
- })], K.prototype, "maxWidth", void 0), o([R({
651
+ })], $.prototype, "maxWidth", void 0), s([G({
481
652
  type: Number,
482
653
  attribute: "max-height"
483
- })], K.prototype, "maxHeight", void 0), o([R({ reflect: !0 })], K.prototype, "scrollbars", void 0), o([R({
654
+ })], $.prototype, "maxHeight", void 0), s([G({ reflect: !0 })], $.prototype, "scrollbars", void 0), s([G({
484
655
  type: Number,
485
656
  attribute: "header-height"
486
- })], K.prototype, "headerHeight", void 0), o([B()], K.prototype, "_hasHeader", void 0), o([B()], K.prototype, "_hasStatus", void 0), o([z(".body")], K.prototype, "body", void 0), o([z("vf-scroll-area")], K.prototype, "scrollArea", void 0), K = o([t("vf-window")], K);
657
+ })], $.prototype, "headerHeight", void 0), s([q()], $.prototype, "_hasHeader", void 0), s([q()], $.prototype, "_hasStatus", void 0), s([K(".body")], $.prototype, "body", void 0), s([K("vf-scroll-area")], $.prototype, "scrollArea", void 0), $ = s([t("vf-window")], $);
487
658
  //#endregion
488
- export { K as VfWindow };
659
+ export { $ as VfWindow };
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@
12
12
  */
13
13
  export { VfDesktop } from './components/vf-desktop.js';
14
14
  export { VfWindow } from './components/vf-window.js';
15
+ export type { VfViewportBox, VfWindowHideOptions, VfWindowShowOptions, } from './components/vf-window.js';
15
16
  export { VfDialog } from './components/vf-dialog.js';
16
17
  export { VfSeparator } from './components/vf-separator.js';
17
18
  export { VfButton } from './components/vf-button.js';
@@ -143,7 +144,7 @@ export type { DocumentListenerSpec } from './document-listeners.js';
143
144
  export { focusModality, trackFocusModality, FocusRuleController } from './focus-modality.js';
144
145
  export type { FocusModality } from './focus-modality.js';
145
146
  export { emit } from './events.js';
146
- export { prefersReducedMotion, runSelectionBlink, runOutlineTravel, BLINK_INTERVAL_MS, BLINK_FLIPS, PRESS_HOLD_MS, RENAME_DELAY_MS, TAP_PAIR_MS, TAP_PAIR_SLOP_PX, DRAG_SLOP_PX, DRAG_SLOP_COARSE_PX, dragSlop, WALK_STEP_PX, WALK_STEP_MS, WALK_BEAT_MS, } from './motion.js';
147
+ export { prefersReducedMotion, runSelectionBlink, runOutlineTravel, BLINK_INTERVAL_MS, BLINK_FLIPS, PRESS_HOLD_MS, RENAME_DELAY_MS, TAP_PAIR_MS, TAP_PAIR_SLOP_PX, DRAG_SLOP_PX, DRAG_SLOP_COARSE_PX, dragSlop, WALK_STEP_PX, WALK_STEP_MS, WALK_BEAT_MS, windowRectFraction, WINDOW_RECT_STEPS, WINDOW_RECTS_VISIBLE, WINDOW_RECT_RATIO, WINDOW_RECT_STEP_MS, } from './motion.js';
147
148
  export type { BlinkHandle, TravelHandle } from './motion.js';
148
149
  /**
149
150
  * Element registration. `vfElement` is the kit's `@customElement`: it registers
package/dist/index.js CHANGED
@@ -30,46 +30,46 @@ import { BUTTON_FACE as Ee, BUTTON_FRAME as De, RING_FRAME as Oe, RING_HOLE as k
30
30
  import { VfDesktop as Fe } from "./components/vf-desktop.js";
31
31
  import { VfSized as Ie } from "./size.js";
32
32
  import { DragController as Le } from "./drag.js";
33
- import { ScrollStateController as Re } from "./scroll-state.js";
34
- import { BLINK_FLIPS as ze, BLINK_INTERVAL_MS as Be, DRAG_SLOP_COARSE_PX as Ve, DRAG_SLOP_PX as He, PRESS_HOLD_MS as Ue, RENAME_DELAY_MS as We, TAP_PAIR_MS as Ge, TAP_PAIR_SLOP_PX as Ke, WALK_BEAT_MS as qe, WALK_STEP_MS as Je, WALK_STEP_PX as Ye, dragSlop as Xe, prefersReducedMotion as Ze, runOutlineTravel as Qe, runSelectionBlink as $e } from "./motion.js";
35
- import { CARET_DOWN as et, CARET_DOWN_SMALL as tt, CHECKBOX_X as nt, CHECKMARK as rt, RADIO_DOT as it, RADIO_FACE as at, RADIO_RING as ot, RADIO_RING_PRESSED as st, SLIDER_THUMB as ct, SLIDER_THUMB_FACE as lt, STEPPER as ut, STEPPER_DOWN_FILL as dt, STEPPER_UP_FILL as ft, glyphSvg as pt } from "./glyphs.js";
36
- import { ScrollRailController as mt, renderScrollRail as ht } from "./scroll-rail.js";
37
- import { VfScrollArea as gt } from "./components/vf-scroll-area.js";
38
- import { VfWindow as _t } from "./components/vf-window.js";
39
- import { VfModalDialog as vt, modalDialogStyles as yt } from "./modal-dialog.js";
40
- import { VfDialog as bt } from "./components/vf-dialog.js";
41
- import { VfSeparator as xt } from "./components/vf-separator.js";
42
- import { VfFormControl as St } from "./form-control.js";
43
- import { VfButton as Ct } from "./components/vf-button.js";
44
- import { VfButtonGroup as wt } from "./components/vf-button-group.js";
45
- import { VfSwatch as Tt } from "./components/vf-swatch.js";
46
- import { VfToggleControl as Et } from "./toggle-control.js";
47
- import { VfCheckbox as Dt } from "./components/vf-checkbox.js";
48
- import { VfRadio as Ot } from "./components/vf-radio.js";
49
- import { VfRadioGroup as kt } from "./components/vf-radio-group.js";
50
- import { FocusRuleController as At, focusModality as jt, trackFocusModality as Mt } from "./focus-modality.js";
51
- import { VfTextControlBase as Nt } from "./text-control.js";
52
- import { VfTextField as Pt } from "./components/vf-text-field.js";
53
- import { VfTextArea as Ft } from "./components/vf-text-area.js";
54
- import { VfNumberField as It } from "./components/vf-number-field.js";
55
- import { VfOption as Lt } from "./components/vf-option.js";
56
- import { VfSelect as Rt } from "./components/vf-select.js";
57
- import { VfProgressBar as zt } from "./components/vf-progress-bar.js";
58
- import { VfSlider as Bt } from "./components/vf-slider.js";
59
- import { VfLabel as Vt } from "./components/vf-label.js";
60
- import { VfParagraph as Ht } from "./components/vf-paragraph.js";
61
- import { VfImg as Ut } from "./components/vf-img.js";
62
- import { VfIcon as Wt } from "./components/vf-icon.js";
63
- import { VfIconField as Gt } from "./components/vf-icon-field.js";
64
- import { VfMenuBar as Kt } from "./components/vf-menu-bar.js";
65
- import { VfMenu as qt } from "./components/vf-menu.js";
66
- import { VfMenuItem as Jt } from "./components/vf-menu-item.js";
67
- import { VfList as Yt } from "./components/vf-list.js";
68
- import { VfListItem as Xt } from "./components/vf-list-item.js";
69
- import { VfFieldset as Zt } from "./components/vf-fieldset.js";
70
- import { VfGrid as Qt } from "./components/vf-grid.js";
71
- import { VfStack as $t } from "./components/vf-stack.js";
72
- import { VfContainer as en } from "./components/vf-container.js";
73
- import { CURSOR_ARROW as tn, CURSOR_CROSSHAIR as nn, CURSOR_I_BEAM as rn, CURSOR_WAIT as an } from "./cursor-art.js";
74
- import { applyCursor as on } from "./cursor.js";
75
- export { ze as BLINK_FLIPS, Be as BLINK_INTERVAL_MS, Ee as BUTTON_FACE, De as BUTTON_FRAME, et as CARET_DOWN, tt as CARET_DOWN_SMALL, nt as CHECKBOX_X, rt as CHECKMARK, r as CLASSIC_DPI, i as CSS_REFERENCE_DPI, tn as CURSOR_ARROW, nn as CURSOR_CROSSHAIR, rn as CURSOR_I_BEAM, an as CURSOR_WAIT, Ve as DRAG_SLOP_COARSE_PX, He as DRAG_SLOP_PX, Te as DocumentListenersController, Le as DragController, At as FocusRuleController, Ce as GridSnapController, G as PATTERNS, K as PATTERN_NAMES, q as PATTERN_SIZE, D as PIXEL_GRID_METRICS, Ue as PRESS_HOLD_MS, xe as PatternFillController, T as PlacementController, it as RADIO_DOT, at as RADIO_FACE, ot as RADIO_RING, st as RADIO_RING_PRESSED, We as RENAME_DELAY_MS, Oe as RING_FRAME, ke as RING_HOLE, Ae as RING_INSET, ie as RULE_EDGES, je as SCREEN_CORNER, ct as SLIDER_THUMB, lt as SLIDER_THUMB_FACE, ut as STEPPER, dt as STEPPER_DOWN_FILL, ft as STEPPER_UP_FILL, a as SYSTEM_PX_IN_CSS_PX, d as ScaleController, mt as ScrollRailController, Re as ScrollStateController, Ge as TAP_PAIR_MS, Ke as TAP_PAIR_SLOP_PX, R as TILE_LATTICE, ge as TileRasterCache, be as TrackWidthController, k as VF_BODY_FAMILY, M as VF_DISPLAY_FAMILY, Ct as VfButton, wt as VfButtonGroup, Dt as VfCheckbox, en as VfContainer, Fe as VfDesktop, bt as VfDialog, Zt as VfFieldset, St as VfFormControl, Qt as VfGrid, Wt as VfIcon, Gt as VfIconField, Ut as VfImg, Vt as VfLabel, Yt as VfList, Xt as VfListItem, qt as VfMenu, Kt as VfMenuBar, Jt as VfMenuItem, vt as VfModalDialog, It as VfNumberField, Lt as VfOption, Ht as VfParagraph, E as VfPositioned, zt as VfProgressBar, Ot as VfRadio, kt as VfRadioGroup, gt as VfScrollArea, Rt as VfSelect, xt as VfSeparator, Ie as VfSized, Bt as VfSlider, $t as VfStack, Tt as VfSwatch, Ft as VfTextArea, Nt as VfTextControlBase, Pt as VfTextField, Et as VfToggleControl, _t as VfWindow, qe as WALK_BEAT_MS, Je as WALK_STEP_MS, Ye as WALK_STEP_PX, on as applyCursor, f as applyScale, t as defineElement, o as devicePxPerSystemPx, Xe as dragSlop, p as effectiveScale, e as emit, jt as focusModality, m as getScale, s as getZoom, pt as glyphSvg, yt as modalDialogStyles, h as onScaleChange, c as onZoomChange, J as parsePattern, ae as parseRule, Y as patternHex, X as patternMotif, _e as patternOverride, Z as patternRects, Ze as prefersReducedMotion, A as registerBodyFace, N as registerDisplayFace, O as registerEmbeddedFont, ht as renderScrollRail, we as requestGridSnap, l as resetZoomBaseline, oe as ruleClasses, Qe as runOutlineTravel, $e as runSelectionBlink, g as snapSys, _ as snapToDevicePx, v as snapToSystemPx, Me as steppedCornerClip, Ne as steppedRectClip, Pe as steppedRingClip, y as sys, b as sysLength, x as sysLengths, S as systemPxQuantum, ve as tileGrid, z as tileImage, B as tileRaster, V as tileRects, H as tileSpan, C as toSys, w as toSysExact, Mt 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, me as vfField, ue as vfFocus, de as vfFocusRing, fe as vfFocusUnderline, ee as vfHardShadowDecls, ne as vfModalFrame, re as vfPanel, Se as vfPatternFill, se as vfRule, he as vfScrollRail, L as vfStaticText, $ as vfStripes, ye as vfTileGrid, U as vfTileMaskSize, W as vfTileSize, ce as vfTitleBar, pe as vfToggle, le as vfWindowWidgets };
33
+ import { BLINK_FLIPS as Re, BLINK_INTERVAL_MS as ze, DRAG_SLOP_COARSE_PX as Be, DRAG_SLOP_PX as Ve, PRESS_HOLD_MS as He, RENAME_DELAY_MS as Ue, TAP_PAIR_MS as We, TAP_PAIR_SLOP_PX as Ge, WALK_BEAT_MS as Ke, WALK_STEP_MS as qe, WALK_STEP_PX as Je, WINDOW_RECTS_VISIBLE as Ye, WINDOW_RECT_RATIO as Xe, WINDOW_RECT_STEPS as Ze, WINDOW_RECT_STEP_MS as Qe, dragSlop as $e, prefersReducedMotion as et, runOutlineTravel as tt, runSelectionBlink as nt, windowRectFraction as rt } from "./motion.js";
34
+ import { ScrollStateController as it } from "./scroll-state.js";
35
+ import { CARET_DOWN as at, CARET_DOWN_SMALL as ot, CHECKBOX_X as st, CHECKMARK as ct, RADIO_DOT as lt, RADIO_FACE as ut, RADIO_RING as dt, RADIO_RING_PRESSED as ft, SLIDER_THUMB as pt, SLIDER_THUMB_FACE as mt, STEPPER as ht, STEPPER_DOWN_FILL as gt, STEPPER_UP_FILL as _t, glyphSvg as vt } from "./glyphs.js";
36
+ import { ScrollRailController as yt, renderScrollRail as bt } from "./scroll-rail.js";
37
+ import { VfScrollArea as xt } from "./components/vf-scroll-area.js";
38
+ import { VfWindow as St } from "./components/vf-window.js";
39
+ import { VfModalDialog as Ct, modalDialogStyles as wt } from "./modal-dialog.js";
40
+ import { VfDialog as Tt } from "./components/vf-dialog.js";
41
+ import { VfSeparator as Et } from "./components/vf-separator.js";
42
+ import { VfFormControl as Dt } from "./form-control.js";
43
+ import { VfButton as Ot } from "./components/vf-button.js";
44
+ import { VfButtonGroup as kt } from "./components/vf-button-group.js";
45
+ import { VfSwatch as At } from "./components/vf-swatch.js";
46
+ import { VfToggleControl as jt } from "./toggle-control.js";
47
+ import { VfCheckbox as Mt } from "./components/vf-checkbox.js";
48
+ import { VfRadio as Nt } from "./components/vf-radio.js";
49
+ import { VfRadioGroup as Pt } from "./components/vf-radio-group.js";
50
+ import { FocusRuleController as Ft, focusModality as It, trackFocusModality as Lt } from "./focus-modality.js";
51
+ import { VfTextControlBase as Rt } from "./text-control.js";
52
+ import { VfTextField as zt } from "./components/vf-text-field.js";
53
+ import { VfTextArea as Bt } from "./components/vf-text-area.js";
54
+ import { VfNumberField as Vt } from "./components/vf-number-field.js";
55
+ import { VfOption as Ht } from "./components/vf-option.js";
56
+ import { VfSelect as Ut } from "./components/vf-select.js";
57
+ import { VfProgressBar as Wt } from "./components/vf-progress-bar.js";
58
+ import { VfSlider as Gt } from "./components/vf-slider.js";
59
+ import { VfLabel as Kt } from "./components/vf-label.js";
60
+ import { VfParagraph as qt } from "./components/vf-paragraph.js";
61
+ import { VfImg as Jt } from "./components/vf-img.js";
62
+ import { VfIcon as Yt } from "./components/vf-icon.js";
63
+ import { VfIconField as Xt } from "./components/vf-icon-field.js";
64
+ import { VfMenuBar as Zt } from "./components/vf-menu-bar.js";
65
+ import { VfMenu as Qt } from "./components/vf-menu.js";
66
+ import { VfMenuItem as $t } from "./components/vf-menu-item.js";
67
+ import { VfList as en } from "./components/vf-list.js";
68
+ import { VfListItem as tn } from "./components/vf-list-item.js";
69
+ import { VfFieldset as nn } from "./components/vf-fieldset.js";
70
+ import { VfGrid as rn } from "./components/vf-grid.js";
71
+ import { VfStack as an } from "./components/vf-stack.js";
72
+ import { VfContainer as on } from "./components/vf-container.js";
73
+ import { CURSOR_ARROW as sn, CURSOR_CROSSHAIR as cn, CURSOR_I_BEAM as ln, CURSOR_WAIT as un } from "./cursor-art.js";
74
+ import { applyCursor as dn } from "./cursor.js";
75
+ export { Re as BLINK_FLIPS, ze as BLINK_INTERVAL_MS, Ee as BUTTON_FACE, De as BUTTON_FRAME, at as CARET_DOWN, ot as CARET_DOWN_SMALL, st as CHECKBOX_X, ct as CHECKMARK, r as CLASSIC_DPI, i as CSS_REFERENCE_DPI, sn as CURSOR_ARROW, cn as CURSOR_CROSSHAIR, ln as CURSOR_I_BEAM, un as CURSOR_WAIT, Be as DRAG_SLOP_COARSE_PX, Ve as DRAG_SLOP_PX, Te as DocumentListenersController, Le as DragController, Ft as FocusRuleController, Ce as GridSnapController, G as PATTERNS, K as PATTERN_NAMES, q as PATTERN_SIZE, D as PIXEL_GRID_METRICS, He as PRESS_HOLD_MS, xe as PatternFillController, T as PlacementController, lt as RADIO_DOT, ut as RADIO_FACE, dt as RADIO_RING, ft as RADIO_RING_PRESSED, Ue as RENAME_DELAY_MS, Oe as RING_FRAME, ke as RING_HOLE, Ae as RING_INSET, ie as RULE_EDGES, je as SCREEN_CORNER, pt as SLIDER_THUMB, mt as SLIDER_THUMB_FACE, ht as STEPPER, gt as STEPPER_DOWN_FILL, _t as STEPPER_UP_FILL, a as SYSTEM_PX_IN_CSS_PX, d as ScaleController, yt as ScrollRailController, it as ScrollStateController, We as TAP_PAIR_MS, Ge as TAP_PAIR_SLOP_PX, R as TILE_LATTICE, ge as TileRasterCache, be as TrackWidthController, k as VF_BODY_FAMILY, M as VF_DISPLAY_FAMILY, Ot as VfButton, kt as VfButtonGroup, Mt as VfCheckbox, on as VfContainer, Fe as VfDesktop, Tt as VfDialog, nn as VfFieldset, Dt as VfFormControl, rn as VfGrid, Yt as VfIcon, Xt as VfIconField, Jt as VfImg, Kt as VfLabel, en as VfList, tn as VfListItem, Qt as VfMenu, Zt as VfMenuBar, $t as VfMenuItem, Ct as VfModalDialog, Vt as VfNumberField, Ht as VfOption, qt as VfParagraph, E as VfPositioned, Wt as VfProgressBar, Nt as VfRadio, Pt as VfRadioGroup, xt as VfScrollArea, Ut as VfSelect, Et as VfSeparator, Ie as VfSized, Gt as VfSlider, an as VfStack, At as VfSwatch, Bt as VfTextArea, Rt as VfTextControlBase, zt as VfTextField, jt as VfToggleControl, St as VfWindow, Ke as WALK_BEAT_MS, qe as WALK_STEP_MS, Je as WALK_STEP_PX, Ye as WINDOW_RECTS_VISIBLE, Xe as WINDOW_RECT_RATIO, Ze as WINDOW_RECT_STEPS, Qe as WINDOW_RECT_STEP_MS, dn as applyCursor, f as applyScale, t as defineElement, o as devicePxPerSystemPx, $e as dragSlop, p as effectiveScale, e as emit, It as focusModality, m as getScale, s as getZoom, vt as glyphSvg, wt as modalDialogStyles, h as onScaleChange, c as onZoomChange, J as parsePattern, ae as parseRule, Y as patternHex, X as patternMotif, _e as patternOverride, Z as patternRects, et as prefersReducedMotion, A as registerBodyFace, N as registerDisplayFace, O as registerEmbeddedFont, bt as renderScrollRail, we as requestGridSnap, l as resetZoomBaseline, oe as ruleClasses, tt as runOutlineTravel, nt as runSelectionBlink, g as snapSys, _ as snapToDevicePx, v as snapToSystemPx, Me as steppedCornerClip, Ne as steppedRectClip, Pe as steppedRingClip, y as sys, b as sysLength, x as sysLengths, S as systemPxQuantum, ve as tileGrid, z as tileImage, B as tileRaster, V as tileRects, H as tileSpan, C as toSys, w as toSysExact, Lt 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, me as vfField, ue as vfFocus, de as vfFocusRing, fe as vfFocusUnderline, ee as vfHardShadowDecls, ne as vfModalFrame, re as vfPanel, Se as vfPatternFill, se as vfRule, he as vfScrollRail, L as vfStaticText, $ as vfStripes, ye as vfTileGrid, U as vfTileMaskSize, W as vfTileSize, ce as vfTitleBar, pe as vfToggle, le as vfWindowWidgets, rt as windowRectFraction };
package/dist/motion.d.ts CHANGED
@@ -124,3 +124,24 @@ export interface TravelHandle {
124
124
  * `prefers-reduced-motion`, where it runs at once and the handle is a no-op.
125
125
  */
126
126
  export declare function runOutlineTravel(distance: number, setProgress: (t: number) => void, onDone: () => void): TravelHandle;
127
+ /**
128
+ * The zoom rects a window opens with (`vf-window.show({ from })`): how many
129
+ * rects are drawn, how many are on screen at once, the ratio between the
130
+ * fractions of the way consecutive rects sit, and the milliseconds a step
131
+ * lasts. A fixed count rather than the walk's constant speed: every
132
+ * distance takes the same eighteen steps — one per rect, then four as the
133
+ * trail drains. Provisional. verify:window computes its expected frames
134
+ * from the first three; nothing asserts the step's length.
135
+ */
136
+ export declare const WINDOW_RECT_STEPS = 14;
137
+ export declare const WINDOW_RECTS_VISIBLE = 4;
138
+ export declare const WINDOW_RECT_RATIO = 0.7;
139
+ export declare const WINDOW_RECT_STEP_MS = 17;
140
+ /**
141
+ * How far window rect `k` (0 … {@link WINDOW_RECT_STEPS} − 1) sits from the
142
+ * small rect toward the big one, as a fraction of the way:
143
+ * `WINDOW_RECT_RATIO ** (WINDOW_RECT_STEPS − k)`, 0.007 for the first and
144
+ * 0.7 for the last. The rects bunch at the small rect and open out toward
145
+ * the big one, and the last stops seven tenths of the way.
146
+ */
147
+ export declare function windowRectFraction(k: number): number;
package/dist/motion.js CHANGED
@@ -36,5 +36,9 @@ function m(t, n, r) {
36
36
  };
37
37
  return s = window.setTimeout(l, 25), { finish: c };
38
38
  }
39
+ var h = 14, g = 4, _ = .7, v = 17;
40
+ function y(e) {
41
+ return _ ** (14 - e);
42
+ }
39
43
  //#endregion
40
- export { l as BLINK_FLIPS, c as BLINK_INTERVAL_MS, o as DRAG_SLOP_COARSE_PX, a as DRAG_SLOP_PX, t as PRESS_HOLD_MS, n as RENAME_DELAY_MS, r as TAP_PAIR_MS, i as TAP_PAIR_SLOP_PX, p as WALK_BEAT_MS, f as WALK_STEP_MS, d as WALK_STEP_PX, s as dragSlop, e as prefersReducedMotion, m as runOutlineTravel, u as runSelectionBlink };
44
+ export { l as BLINK_FLIPS, c as BLINK_INTERVAL_MS, o as DRAG_SLOP_COARSE_PX, a as DRAG_SLOP_PX, t as PRESS_HOLD_MS, n as RENAME_DELAY_MS, r as TAP_PAIR_MS, i as TAP_PAIR_SLOP_PX, p as WALK_BEAT_MS, f as WALK_STEP_MS, d as WALK_STEP_PX, g as WINDOW_RECTS_VISIBLE, _ as WINDOW_RECT_RATIO, h as WINDOW_RECT_STEPS, v as WINDOW_RECT_STEP_MS, s as dragSlop, e as prefersReducedMotion, m as runOutlineTravel, u as runSelectionBlink, y as windowRectFraction };