vintage-frames 0.12.1 → 0.12.3
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 +402 -11
- package/dist/components/vf-desktop.d.ts +9 -5
- package/dist/components/vf-icon-field.js +12 -14
- package/dist/components/vf-icon.d.ts +55 -10
- package/dist/components/vf-icon.js +216 -182
- package/dist/components/vf-window.d.ts +90 -0
- package/dist/components/vf-window.js +248 -77
- package/dist/index.d.ts +2 -1
- package/dist/index.js +43 -43
- package/dist/motion.d.ts +44 -0
- package/dist/motion.js +13 -5
- package/dist/open-art.d.ts +17 -4
- package/dist/open-art.js +12 -6
- package/docs/SPEC.md +9 -9
- package/editor/vscode.html-custom-data.json +8 -3
- package/editor/web-types.json +18 -8
- package/package.json +1 -1
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import { LitElement, type PropertyValues } from 'lit';
|
|
2
2
|
import './vf-scroll-area.js';
|
|
3
|
+
/** A box in viewport CSS px. A `DOMRect` is one; a zero-size box is a point. */
|
|
4
|
+
export interface VfViewportBox {
|
|
5
|
+
left: number;
|
|
6
|
+
top: number;
|
|
7
|
+
right: number;
|
|
8
|
+
bottom: number;
|
|
9
|
+
}
|
|
10
|
+
/** The options of {@link VfWindow.show}. */
|
|
11
|
+
export interface VfWindowShowOptions {
|
|
12
|
+
/**
|
|
13
|
+
* The box the window opens from, in viewport CSS px — an icon's
|
|
14
|
+
* `cellRect()`, a button's `getBoundingClientRect()`, any rect. Unset, the
|
|
15
|
+
* window shows at once.
|
|
16
|
+
*/
|
|
17
|
+
from?: VfViewportBox | null;
|
|
18
|
+
}
|
|
19
|
+
/** The options of {@link VfWindow.hide}. */
|
|
20
|
+
export interface VfWindowHideOptions {
|
|
21
|
+
/**
|
|
22
|
+
* The box the window closes to, in viewport CSS px — an icon's
|
|
23
|
+
* `cellRect()`, a button's `getBoundingClientRect()`, any rect. Unset, the
|
|
24
|
+
* window hides at once.
|
|
25
|
+
*/
|
|
26
|
+
to?: VfViewportBox | null;
|
|
27
|
+
}
|
|
3
28
|
declare const VfWindow_base: (new (...args: any[]) => import("../size.js").VfSizedInterface) & (new (...args: any[]) => import("../position.js").VfPositionedInterface) & typeof LitElement;
|
|
4
29
|
/**
|
|
5
30
|
* `<vf-window>` — the System 7 desktop-window shell.
|
|
@@ -29,6 +54,32 @@ declare const VfWindow_base: (new (...args: any[]) => import("../size.js").VfSiz
|
|
|
29
54
|
* Unset, the window still renders — normal block layout, as before — and
|
|
30
55
|
* says so once in the console.
|
|
31
56
|
*
|
|
57
|
+
* **Opening from a rect.** {@link show} clears `hidden`, and given `from` — a
|
|
58
|
+
* box in viewport CSS px, an icon's `cellRect()` or a button's rect — opens
|
|
59
|
+
* the window from it: dotted rectangles grow from that box toward the
|
|
60
|
+
* window's frame, four on screen at a time, bunched at the box and opening
|
|
61
|
+
* out toward the window, drawn with the icon drag outline's XOR pen on the
|
|
62
|
+
* desktop's drag surface; the window draws once they have drained, eighteen
|
|
63
|
+
* steps later. Until then it matches `:state(opening)` and paints nothing —
|
|
64
|
+
* still laid out, focusable and a hit target, so a page can place it, raise
|
|
65
|
+
* it and focus into it at once, and a press finishes the rects and lands on
|
|
66
|
+
* the window. Under `prefers-reduced-motion`, with no `vf-desktop` on its
|
|
67
|
+
* path, or without `from`, the window shows at once.
|
|
68
|
+
*
|
|
69
|
+
* **Closing to a rect.** {@link hide} sets `hidden`, and given `to` closes
|
|
70
|
+
* the window to it: the same rectangles run the other way, from where the
|
|
71
|
+
* frame was in toward the box, the window gone from the first step. A press
|
|
72
|
+
* finishes them, and removing the window leaves them running. Under
|
|
73
|
+
* `prefers-reduced-motion`, with no `vf-desktop` on its path, or without
|
|
74
|
+
* `to`, the window hides at once. The window knows nothing about icons:
|
|
75
|
+
* `from` and `to` are any rect.
|
|
76
|
+
*
|
|
77
|
+
* **Dragging as an outline.** A `movable` window moves live under the
|
|
78
|
+
* pointer. With `outline-drag` a press on the title bar draws a dotted
|
|
79
|
+
* outline around the window on the desktop's drag surface instead, with the
|
|
80
|
+
* same pen; the drag moves the outline, held where the window can land, and
|
|
81
|
+
* the window moves there on the release. Escape cancels.
|
|
82
|
+
*
|
|
32
83
|
* @slot - Default slot: window body content.
|
|
33
84
|
* @slot header - Optional header content — a band between the title bar and
|
|
34
85
|
* the body, the full width of the window (the Finder window's header
|
|
@@ -101,6 +152,16 @@ export declare class VfWindow extends VfWindow_base {
|
|
|
101
152
|
zoomable: boolean;
|
|
102
153
|
/** Allow dragging the window by its title bar. */
|
|
103
154
|
movable: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Drag by the title bar as an outline: a press draws a dotted one-pixel
|
|
157
|
+
* rectangle around the window on the desktop's drag surface, with the
|
|
158
|
+
* icon drag outline's pen; the drag moves it, held where the window can
|
|
159
|
+
* land, and the window moves there on the release, in one write. Escape
|
|
160
|
+
* cancels and writes nothing, as does a release that never moved it.
|
|
161
|
+
* Unset, the window moves live under the pointer; with no `vf-desktop` on
|
|
162
|
+
* its path it moves live either way. Only matters with `movable`.
|
|
163
|
+
*/
|
|
164
|
+
outlineDrag: boolean;
|
|
104
165
|
/**
|
|
105
166
|
* Show a grow box at the bottom-right corner for resizing. The drag is
|
|
106
167
|
* bounded per axis by the sizeRect below.
|
|
@@ -217,6 +278,34 @@ export declare class VfWindow extends VfWindow_base {
|
|
|
217
278
|
* `vf-scroll-area.measure()` is.
|
|
218
279
|
*/
|
|
219
280
|
measure(): void;
|
|
281
|
+
/**
|
|
282
|
+
* Show the window: `hidden` cleared, and with `from` the window opens from
|
|
283
|
+
* that box — the zoom rects, grown from it toward the frame at the cadence
|
|
284
|
+
* in src/motion.ts (`WINDOW_RECT_*`), the window drawn once they have
|
|
285
|
+
* drained (see the class doc). A run in flight, a `show()` or a `hide()`,
|
|
286
|
+
* is finished first; a press anywhere or Escape finishes this one, and
|
|
287
|
+
* removing the window or a `hide()` takes it down. Resolves once the
|
|
288
|
+
* window draws: `true` when the rects ran, `false` when it showed at once
|
|
289
|
+
* — no `from`, `prefers-reduced-motion`, no `vf-desktop` on its path,
|
|
290
|
+
* nothing of the rects on the screen, or not in the DOM — or never drew.
|
|
291
|
+
* It raises and activates nothing: stacking stays the page's
|
|
292
|
+
* (`vf-desktop.bringToFront`).
|
|
293
|
+
*/
|
|
294
|
+
show(options?: VfWindowShowOptions): Promise<boolean>;
|
|
295
|
+
/**
|
|
296
|
+
* Hide the window: `hidden` set, and with `to` the window closes to that
|
|
297
|
+
* box — the rects of {@link show} run the other way, from where the frame
|
|
298
|
+
* is drawn at the call in toward the box, the window gone from their first
|
|
299
|
+
* step. A `show()` still opening is taken down and says `false`; a second
|
|
300
|
+
* `hide()` finishes the first; a press anywhere or Escape finishes the
|
|
301
|
+
* rects; removing the window leaves them running, so a page can remove a
|
|
302
|
+
* window as it closes it. Resolves once the rects are done: `true` when
|
|
303
|
+
* they ran, `false` when the window hid at once — no `to`,
|
|
304
|
+
* `prefers-reduced-motion`, no `vf-desktop` on its path, nothing of the
|
|
305
|
+
* rects on the screen, not in the DOM, or no frame to close from: already
|
|
306
|
+
* hidden, or still opening.
|
|
307
|
+
*/
|
|
308
|
+
hide(options?: VfWindowHideOptions): Promise<boolean>;
|
|
220
309
|
/**
|
|
221
310
|
* Say something the first time a window is opened without a width. The size
|
|
222
311
|
* itself is written by VfSized's controller, from `width`/`height` — which
|
|
@@ -231,6 +320,7 @@ export declare class VfWindow extends VfWindow_base {
|
|
|
231
320
|
* window content follow the grow box without a ResizeObserver.
|
|
232
321
|
*/
|
|
233
322
|
protected updated(): void;
|
|
323
|
+
connectedCallback(): void;
|
|
234
324
|
disconnectedCallback(): void;
|
|
235
325
|
/** The `.empty` gate: the strip renders only while the slot is populated. */
|
|
236
326
|
private _onStatusSlotChange;
|
|
@@ -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,
|
|
4
|
-
import
|
|
5
|
-
import { PlacementController as
|
|
6
|
-
import { vfBase as
|
|
7
|
-
import { DOT_MOTIF as
|
|
8
|
-
import { vfChromeFrame as
|
|
9
|
-
import { vfRule as
|
|
10
|
-
import { vfTitleBar as
|
|
11
|
-
import { vfFocus as
|
|
12
|
-
import { TileRasterCache as
|
|
13
|
-
import { GridSnapController as
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
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
|
|
19
|
-
import { property as
|
|
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
|
|
22
|
-
function
|
|
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
|
|
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
|
|
29
|
-
let r =
|
|
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,
|
|
32
|
-
y: Math.min(Math.max(t, 0), Math.max(0, n.height -
|
|
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
|
|
35
|
-
onDragStart: (e) =>
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
321
|
-
cols: Math.ceil(e /
|
|
362
|
+
if (this._dotsPattern) return T({
|
|
363
|
+
cols: Math.ceil(e / h),
|
|
322
364
|
rows: 1,
|
|
323
|
-
tile:
|
|
365
|
+
tile: h
|
|
324
366
|
});
|
|
325
|
-
let t = Math.ceil((e +
|
|
326
|
-
return
|
|
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:${
|
|
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) :
|
|
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.#
|
|
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
|
-
#
|
|
349
|
-
#
|
|
350
|
-
#
|
|
351
|
-
this.#
|
|
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
|
-
#
|
|
354
|
-
if (this.#
|
|
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.#
|
|
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:
|
|
383
|
-
baseHeight:
|
|
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 =
|
|
392
|
-
(n !== this.width ||
|
|
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
|
|
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" :
|
|
578
|
+
aria-labelledby=${this.heading ? "title" : W}
|
|
412
579
|
>
|
|
413
|
-
${
|
|
414
|
-
${this.closable ?
|
|
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 ?
|
|
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 ?
|
|
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 ?
|
|
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 ||
|
|
598
|
+
label=${this.heading || W}
|
|
432
599
|
exportparts="viewport"
|
|
433
600
|
>
|
|
434
601
|
<slot></slot>
|
|
435
602
|
</vf-scroll-area>
|
|
436
|
-
` :
|
|
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 ?
|
|
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
|
-
` :
|
|
618
|
+
` : W}
|
|
452
619
|
</div>
|
|
453
620
|
`;
|
|
454
621
|
}
|
|
455
622
|
};
|
|
456
|
-
|
|
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
|
-
})],
|
|
626
|
+
})], $.prototype, "active", void 0), s([G({
|
|
460
627
|
type: Boolean,
|
|
461
628
|
reflect: !0
|
|
462
|
-
})],
|
|
629
|
+
})], $.prototype, "closable", void 0), s([G({
|
|
463
630
|
type: Boolean,
|
|
464
631
|
reflect: !0
|
|
465
|
-
})],
|
|
632
|
+
})], $.prototype, "zoomable", void 0), s([G({
|
|
466
633
|
type: Boolean,
|
|
467
634
|
reflect: !0
|
|
468
|
-
})],
|
|
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
|
-
})],
|
|
642
|
+
})], $.prototype, "resizable", void 0), s([G({
|
|
472
643
|
type: Number,
|
|
473
644
|
attribute: "min-width"
|
|
474
|
-
})],
|
|
645
|
+
})], $.prototype, "minWidth", void 0), s([G({
|
|
475
646
|
type: Number,
|
|
476
647
|
attribute: "min-height"
|
|
477
|
-
})],
|
|
648
|
+
})], $.prototype, "minHeight", void 0), s([G({
|
|
478
649
|
type: Number,
|
|
479
650
|
attribute: "max-width"
|
|
480
|
-
})],
|
|
651
|
+
})], $.prototype, "maxWidth", void 0), s([G({
|
|
481
652
|
type: Number,
|
|
482
653
|
attribute: "max-height"
|
|
483
|
-
})],
|
|
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
|
-
})],
|
|
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 {
|
|
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, 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
|