vintage-frames 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +210 -4
- package/dist/components/vf-icon-field.d.ts +29 -1
- package/dist/components/vf-icon-field.js +93 -34
- package/dist/components/vf-icon.d.ts +48 -1
- package/dist/components/vf-icon.js +204 -161
- package/dist/index.d.ts +3 -2
- package/dist/index.js +42 -42
- package/dist/motion.d.ts +31 -0
- package/dist/motion.js +15 -1
- package/dist/position.d.ts +10 -0
- package/dist/position.js +8 -1
- package/docs/SPEC.md +5 -3
- package/editor/vscode.html-custom-data.json +2 -2
- package/editor/web-types.json +3 -3
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ import { VfPositioned as a } from "../position.js";
|
|
|
6
6
|
import { vfBase as o } from "../styles/recipes/host.js";
|
|
7
7
|
import { DocumentListenersController as s } from "../document-listeners.js";
|
|
8
8
|
import { VfSized as c } from "../size.js";
|
|
9
|
+
import "../motion.js";
|
|
9
10
|
import { paintSelectionRect as l, penPhase as u } from "../open-art.js";
|
|
10
11
|
import { LitElement as d, css as f, html as p } from "lit";
|
|
11
12
|
import { property as m } from "lit/decorators.js";
|
|
@@ -48,34 +49,52 @@ var h = (e, t, n) => Math.min(Math.max(e, t), n), g = class extends c(a(d)) {
|
|
|
48
49
|
#e;
|
|
49
50
|
#t;
|
|
50
51
|
#n;
|
|
52
|
+
#r;
|
|
53
|
+
#i;
|
|
54
|
+
#a;
|
|
55
|
+
#o;
|
|
51
56
|
constructor() {
|
|
52
57
|
super(), this.label = "", this.scale = new n(this), this.#e = this.attachInternals(), this.#t = null, this.#n = new s(this, () => [[
|
|
53
58
|
document,
|
|
54
59
|
"keydown",
|
|
55
|
-
this.#
|
|
60
|
+
this.#p,
|
|
61
|
+
!0
|
|
62
|
+
]]), this.#r = null, this.#i = new s(this, () => [[
|
|
63
|
+
document,
|
|
64
|
+
"pointerdown",
|
|
65
|
+
this.#a,
|
|
66
|
+
!0
|
|
67
|
+
], [
|
|
68
|
+
document,
|
|
69
|
+
"keydown",
|
|
70
|
+
this.#o,
|
|
56
71
|
!0
|
|
57
|
-
]]), this.#
|
|
58
|
-
this.#
|
|
72
|
+
]]), this.#a = () => {
|
|
73
|
+
this.#S();
|
|
59
74
|
}, this.#o = (e) => {
|
|
75
|
+
e.key !== "Escape" || !this.#r || (e.preventDefault(), e.stopPropagation(), this.#S());
|
|
76
|
+
}, this.#s = () => {
|
|
77
|
+
this.#c();
|
|
78
|
+
}, this.#u = (e) => {
|
|
60
79
|
if (this.#t || e.button !== 0 || e.target !== this) return;
|
|
61
80
|
let t = this.getBoundingClientRect();
|
|
62
81
|
if (t.width <= 0 || t.height <= 0) return;
|
|
63
|
-
let n = r(this), i = this.#
|
|
82
|
+
let n = r(this), i = this.#g(t, n);
|
|
64
83
|
this.#t = {
|
|
65
84
|
pointerId: e.pointerId,
|
|
66
85
|
box: t,
|
|
67
86
|
reach: i,
|
|
68
|
-
origin: this.#
|
|
69
|
-
screen: this.#
|
|
70
|
-
anchor: new Set(this.#
|
|
87
|
+
origin: this.#h(e, t, n, i),
|
|
88
|
+
screen: this.#_(t, n),
|
|
89
|
+
anchor: new Set(this.#l().filter((e) => e.selected)),
|
|
71
90
|
rect: null,
|
|
72
91
|
canvas: null,
|
|
73
92
|
phase: -1
|
|
74
93
|
}, this.setPointerCapture(e.pointerId), e.preventDefault();
|
|
75
|
-
}, this.#
|
|
94
|
+
}, this.#d = (e) => {
|
|
76
95
|
let t = this.#t;
|
|
77
96
|
if (!t || e.pointerId !== t.pointerId) return;
|
|
78
|
-
let n = r(this), i = this.#
|
|
97
|
+
let n = r(this), i = this.#h(e, t.box, n, t.reach);
|
|
79
98
|
if (!t.rect && i.x === t.origin.x && i.y === t.origin.y) return;
|
|
80
99
|
let a = {
|
|
81
100
|
x: Math.min(t.origin.x, i.x),
|
|
@@ -83,46 +102,46 @@ var h = (e, t, n) => Math.min(Math.max(e, t), n), g = class extends c(a(d)) {
|
|
|
83
102
|
width: Math.abs(i.x - t.origin.x),
|
|
84
103
|
height: Math.abs(i.y - t.origin.y)
|
|
85
104
|
}, o = t.rect;
|
|
86
|
-
o && o.x === a.x && o.y === a.y && o.width === a.width && o.height === a.height || (o || (this.#n.attach(), t.canvas = this.#
|
|
87
|
-
}, this.#
|
|
105
|
+
o && o.x === a.x && o.y === a.y && o.width === a.width && o.height === a.height || (o || (this.#n.attach(), t.canvas = this.#v(), this.renderRoot.append(t.canvas)), t.rect = a, this.#y(t, n), this.#b(t, n));
|
|
106
|
+
}, this.#f = (e) => {
|
|
88
107
|
let t = this.#t;
|
|
89
|
-
!t || e.pointerId !== t.pointerId || this.#
|
|
90
|
-
}, this.#
|
|
91
|
-
e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), this.#
|
|
92
|
-
}, this.#e.role = "listbox", this.#e.ariaMultiSelectable = "true", this.addEventListener("pointerdown", this.#
|
|
108
|
+
!t || e.pointerId !== t.pointerId || this.#m(e.type === "pointercancel");
|
|
109
|
+
}, this.#p = (e) => {
|
|
110
|
+
e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), this.#m(!0));
|
|
111
|
+
}, this.#e.role = "listbox", this.#e.ariaMultiSelectable = "true", this.addEventListener("pointerdown", this.#u), this.addEventListener("pointermove", this.#d), this.addEventListener("pointerup", this.#f), this.addEventListener("pointercancel", this.#f);
|
|
93
112
|
}
|
|
94
113
|
disconnectedCallback() {
|
|
95
|
-
super.disconnectedCallback(), this.#t?.canvas?.remove(), this.#t = null;
|
|
114
|
+
super.disconnectedCallback(), this.#t?.canvas?.remove(), this.#t = null, this.#S();
|
|
96
115
|
}
|
|
97
116
|
updated(e) {
|
|
98
|
-
e.has("label") && (this.#e.ariaLabel = this.label || null), e.has("size") && this.#
|
|
117
|
+
e.has("label") && (this.#e.ariaLabel = this.label || null), e.has("size") && this.#c();
|
|
99
118
|
}
|
|
100
|
-
#
|
|
101
|
-
#
|
|
119
|
+
#s;
|
|
120
|
+
#c() {
|
|
102
121
|
let e = this.size;
|
|
103
122
|
if (e != null) for (let t of this.querySelectorAll("vf-icon")) t.size !== e && (t.size = e);
|
|
104
123
|
}
|
|
105
|
-
#
|
|
124
|
+
#l() {
|
|
106
125
|
return [...this.querySelectorAll("vf-icon")].filter((e) => e.selectable);
|
|
107
126
|
}
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
#
|
|
127
|
+
#u;
|
|
128
|
+
#d;
|
|
129
|
+
#f;
|
|
130
|
+
#p;
|
|
131
|
+
#m(e) {
|
|
113
132
|
let t = this.#t;
|
|
114
|
-
if (t && (this.#t = null, this.hasPointerCapture(t.pointerId) && this.releasePointerCapture(t.pointerId), t.rect && (this.#n.detach(), t.canvas?.remove(), e))) for (let e of this.#
|
|
133
|
+
if (t && (this.#t = null, this.hasPointerCapture(t.pointerId) && this.releasePointerCapture(t.pointerId), t.rect && (this.#n.detach(), t.canvas?.remove(), e))) for (let e of this.#l()) {
|
|
115
134
|
let n = t.anchor.has(e);
|
|
116
135
|
e.selected !== n && e.setSelected(n);
|
|
117
136
|
}
|
|
118
137
|
}
|
|
119
|
-
#
|
|
138
|
+
#h(e, t, n, r) {
|
|
120
139
|
return {
|
|
121
140
|
x: h(Math.round((e.clientX - t.left) / n), r.minX, r.maxX),
|
|
122
141
|
y: h(Math.round((e.clientY - t.top) / n), r.minY, r.maxY)
|
|
123
142
|
};
|
|
124
143
|
}
|
|
125
|
-
#
|
|
144
|
+
#g(e, t) {
|
|
126
145
|
let n = e.left, r = e.top, i = e.right, a = e.bottom, o = this.assignedSlot ?? this.parentNode;
|
|
127
146
|
for (; o;) if (o instanceof Element) {
|
|
128
147
|
let e = getComputedStyle(o);
|
|
@@ -140,7 +159,7 @@ var h = (e, t, n) => Math.min(Math.max(e, t), n), g = class extends c(a(d)) {
|
|
|
140
159
|
maxY: Math.max(0, Math.floor(s((a - e.top) / t)))
|
|
141
160
|
};
|
|
142
161
|
}
|
|
143
|
-
#
|
|
162
|
+
#_(t, n) {
|
|
144
163
|
let r = { surface: null };
|
|
145
164
|
if (e(this, "vf-drag-surface-request", r, { composed: !1 }), !r.surface) return {
|
|
146
165
|
x: 0,
|
|
@@ -152,19 +171,19 @@ var h = (e, t, n) => Math.min(Math.max(e, t), n), g = class extends c(a(d)) {
|
|
|
152
171
|
y: Math.round((t.top - i.top) / n)
|
|
153
172
|
};
|
|
154
173
|
}
|
|
155
|
-
#
|
|
174
|
+
#v() {
|
|
156
175
|
let e = document.createElement("canvas");
|
|
157
176
|
e.className = "selection-rect";
|
|
158
177
|
let t = e.style;
|
|
159
178
|
return t.position = "fixed", t.display = "block", t.pointerEvents = "none", t.filter = "invert(1)", t.mixBlendMode = "difference", t.imageRendering = "pixelated", e;
|
|
160
179
|
}
|
|
161
|
-
#
|
|
180
|
+
#y(e, t) {
|
|
162
181
|
let { rect: n, canvas: r } = e;
|
|
163
182
|
if (!n || !r) return;
|
|
164
183
|
let i = Math.max(1, n.width), a = Math.max(1, n.height), o = u(e.screen.x + n.x, e.screen.y + n.y);
|
|
165
184
|
l(r, i, a, o), e.phase = o, r.style.left = `${e.box.left + n.x * t}px`, r.style.top = `${e.box.top + n.y * t}px`, r.style.width = `${i * t}px`, r.style.height = `${a * t}px`;
|
|
166
185
|
}
|
|
167
|
-
#
|
|
186
|
+
#b(e, t) {
|
|
168
187
|
let { rect: n } = e;
|
|
169
188
|
if (!n) return;
|
|
170
189
|
let r = {
|
|
@@ -173,13 +192,53 @@ var h = (e, t, n) => Math.min(Math.max(e, t), n), g = class extends c(a(d)) {
|
|
|
173
192
|
right: e.box.left + (n.x + Math.max(1, n.width)) * t,
|
|
174
193
|
bottom: e.box.top + (n.y + Math.max(1, n.height)) * t
|
|
175
194
|
};
|
|
176
|
-
for (let t of this.#
|
|
195
|
+
for (let t of this.#l()) {
|
|
177
196
|
let n = e.anchor.has(t) !== t.touches(r);
|
|
178
197
|
t.selected !== n && t.setSelected(n);
|
|
179
198
|
}
|
|
180
199
|
}
|
|
200
|
+
dragIcons(e) {
|
|
201
|
+
this.#S();
|
|
202
|
+
let t = {
|
|
203
|
+
queue: [...e],
|
|
204
|
+
beat: null,
|
|
205
|
+
finished: !1,
|
|
206
|
+
settle: () => {}
|
|
207
|
+
}, n = new Promise((e) => {
|
|
208
|
+
t.settle = e;
|
|
209
|
+
});
|
|
210
|
+
return this.#r = t, this.#i.attach(), this.#x(t), n;
|
|
211
|
+
}
|
|
212
|
+
async #x(e) {
|
|
213
|
+
for (; !e.finished && e.queue.length > 0;) {
|
|
214
|
+
let t = e.queue[0];
|
|
215
|
+
if (!t) break;
|
|
216
|
+
let { icon: n, left: r, top: i } = t, a = n.isConnected ? await n.dragTo(r, i) : !1;
|
|
217
|
+
if (e.finished) return;
|
|
218
|
+
e.queue.shift(), !(!a || e.queue.length === 0) && await new Promise((t) => {
|
|
219
|
+
let n = window.setTimeout(() => {
|
|
220
|
+
e.beat = null, t();
|
|
221
|
+
}, 50);
|
|
222
|
+
e.beat = () => {
|
|
223
|
+
window.clearTimeout(n), e.beat = null, t();
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
this.#C(e);
|
|
228
|
+
}
|
|
229
|
+
#S() {
|
|
230
|
+
let e = this.#r;
|
|
231
|
+
if (e) {
|
|
232
|
+
e.beat?.();
|
|
233
|
+
for (let { icon: t, left: n, top: r } of e.queue) t.isConnected && t.moveTo(n, r);
|
|
234
|
+
e.queue.length = 0, this.#C(e);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
#C(e) {
|
|
238
|
+
e.finished || (e.finished = !0, this.#r === e && (this.#r = null, this.#i.detach()), e.settle());
|
|
239
|
+
}
|
|
181
240
|
render() {
|
|
182
|
-
return p`<slot @slotchange=${this.#
|
|
241
|
+
return p`<slot @slotchange=${this.#s}></slot>`;
|
|
183
242
|
}
|
|
184
243
|
};
|
|
185
244
|
i([m()], g.prototype, "label", void 0), i([m({ reflect: !0 })], g.prototype, "size", void 0), g = i([t("vf-icon-field")], g);
|
|
@@ -226,7 +226,8 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
|
|
|
226
226
|
* changed the snapped proposal;
|
|
227
227
|
* - `vf-drop`, the same shape at the release, **cancelable**: its default
|
|
228
228
|
* action is the move, the proposal written through `left`/`top` and
|
|
229
|
-
* clamped whole in the container measured at the press
|
|
229
|
+
* clamped whole in the container measured at the press — held at the
|
|
230
|
+
* origin only in a scrolling plane, whose rails reach the rest. `preventDefault()`
|
|
230
231
|
* writes nothing — the page re-parents or places the icon itself, the
|
|
231
232
|
* outline's origin converted with the destination's `placementAt`;
|
|
232
233
|
* - `vf-drag-cancel` `{}` on Escape or a `pointercancel`: nothing written.
|
|
@@ -270,6 +271,33 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
|
|
|
270
271
|
* under `color` — with none of `selected`'s semantics: no event, no outside
|
|
271
272
|
* listener, no `aria-selected`, the plate untouched.
|
|
272
273
|
*
|
|
274
|
+
* ### The page drags it too
|
|
275
|
+
*
|
|
276
|
+
* The Finder's Clean Up walked a container's icons one at a time, each
|
|
277
|
+
* icon's outline travelling from where it sat to its cell and the icon
|
|
278
|
+
* landing when the outline arrived — the drag's own vocabulary, with the
|
|
279
|
+
* Finder for a hand. {@link dragTo} is that move for one icon: the outline
|
|
280
|
+
* built and placed as a drag's is, on the desktop's surface or in the frame,
|
|
281
|
+
* stepped to the landing at the walk's cadence ({@link runOutlineTravel},
|
|
282
|
+
* src/motion.ts — the kit's, no knobs), then the outline down and the icon
|
|
283
|
+
* written where a drop would write it. The landing is resolved before the
|
|
284
|
+
* outline sets off, so the outline goes where the icon will land rather
|
|
285
|
+
* than where a pair past the container's edge pointed. {@link moveTo} is
|
|
286
|
+
* that write alone: the drop's clamp and snap, one `vf-placement-change` —
|
|
287
|
+
* where a property set is the authored pair, unclamped. Neither fires a
|
|
288
|
+
* drag event (the page is the mover and already knows) and neither needs
|
|
289
|
+
* `movable`, which says the hand may drag: the page may always place its
|
|
290
|
+
* icon. `vf-icon-field.dragIcons` walks a set through `dragTo` with the
|
|
291
|
+
* Finder's beat between landings.
|
|
292
|
+
*
|
|
293
|
+
* A walk is finished, never cancelled: a press anywhere, or Escape, lands
|
|
294
|
+
* the icon at once — the user wants the machine back, and the move was the
|
|
295
|
+
* page's to make. A second `dragTo`, or a `moveTo`, finishes the one in
|
|
296
|
+
* flight the same way; leaving the DOM takes the outline down and writes
|
|
297
|
+
* nothing. Under `prefers-reduced-motion` the icon lands at once with no
|
|
298
|
+
* outline, the blink's posture — as does one being renamed, or one under
|
|
299
|
+
* the hand's own press.
|
|
300
|
+
*
|
|
273
301
|
* Opening gets the same treatment. The double-click is the pointer gesture,
|
|
274
302
|
* and its keyboard route is ⌘O / ⌘↓ — the System 7 Open shortcuts, with Ctrl
|
|
275
303
|
* standing in for ⌘ off the Mac. Return is deliberately not one of them: the
|
|
@@ -564,6 +592,25 @@ export declare class VfIcon extends VfIcon_base {
|
|
|
564
592
|
right: number;
|
|
565
593
|
bottom: number;
|
|
566
594
|
}): boolean;
|
|
595
|
+
/**
|
|
596
|
+
* Place the icon as a drop would: the stated pair — the origin point
|
|
597
|
+
* under an `origin`, the corner without one — clamped whole in the
|
|
598
|
+
* container measured now (held at the origin only in a scrolling plane),
|
|
599
|
+
* snapped onto the lattice, announced as one `vf-placement-change`. A
|
|
600
|
+
* `left`/`top` write is the authored pair, unclamped; this is the
|
|
601
|
+
* gesture's. Finishes a walk in flight first.
|
|
602
|
+
*/
|
|
603
|
+
moveTo(left: number, top: number): void;
|
|
604
|
+
/**
|
|
605
|
+
* Move the icon the way a drag moves it (see the class doc): its outline
|
|
606
|
+
* travels from where it sits to where it will land, and the icon lands
|
|
607
|
+
* when the outline arrives, written as {@link moveTo} writes. Resolves
|
|
608
|
+
* once it has landed — to whether the outline travelled; false when the
|
|
609
|
+
* icon landed at once: already there, `prefers-reduced-motion`, nothing
|
|
610
|
+
* to draw the outline with, or not in the DOM (nothing written then).
|
|
611
|
+
* Fires no drag event. A walk already in flight here is finished first.
|
|
612
|
+
*/
|
|
613
|
+
dragTo(left: number, top: number): Promise<boolean>;
|
|
567
614
|
}
|
|
568
615
|
declare global {
|
|
569
616
|
interface HTMLElementTagNameMap {
|