vintage-frames 0.6.2 → 0.7.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.
@@ -1,6 +1,62 @@
1
1
  import { LitElement } from 'lit';
2
2
  /** Which member of the icon family paints — the two System 7 resource sizes. */
3
3
  export type VfIconSize = 'large' | 'small';
4
+ /**
5
+ * The detail of `vf-drag` and `vf-drop`: the pointer, for the page's hit
6
+ * test; the proposal in the icon's own container; and the outline's top-left
7
+ * in the viewport, for a drop that lands in another container (convert it
8
+ * with that container's `placementAt`).
9
+ */
10
+ export interface VfIconDragDetail {
11
+ /** The pointer, in viewport CSS px. */
12
+ clientX: number;
13
+ clientY: number;
14
+ /**
15
+ * The proposed origin in the icon's own container, whole system px on the
16
+ * placement lattice.
17
+ */
18
+ left: number;
19
+ top: number;
20
+ /**
21
+ * The outline's top-left — the icon's frame box translated by the delta —
22
+ * in viewport CSS px. The press offset is already inside it: an icon placed
23
+ * at `container.placementAt(x, y)` lands exactly where the outline was.
24
+ */
25
+ x: number;
26
+ y: number;
27
+ /**
28
+ * Every icon the drag carries: this one first, then the other selected
29
+ * movable icons of its field, in document order — the selection travels
30
+ * as one. Each follower's outline is its own box translated by the same
31
+ * delta, so a page filing the set converts each icon's own rect the way
32
+ * it converts `x`/`y`.
33
+ */
34
+ icons: VfIcon[];
35
+ }
36
+ /**
37
+ * A follower's handle in a group drag: what the dragged icon holds on each
38
+ * other selected icon of its field, so their outlines move as one and the
39
+ * drop writes each by the same delta. Internal to the kit's group drag.
40
+ */
41
+ export interface VfIconDragFollower {
42
+ icon: VfIcon;
43
+ /** The follower's seeded origin, system px in the shared container. */
44
+ origin: {
45
+ x: number;
46
+ y: number;
47
+ };
48
+ /** The follower's box, system px, for the group clamp. */
49
+ size: {
50
+ width: number;
51
+ height: number;
52
+ };
53
+ /** Move the follower's outline by a lattice delta. */
54
+ move(dx: number, dy: number): void;
55
+ /** Write the follower's origin plus the delta through `left`/`top`. */
56
+ drop(dx: number, dy: number): void;
57
+ /** Take the outline down. */
58
+ end(): void;
59
+ }
4
60
  declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfPositionedInterface) & typeof LitElement;
5
61
  /**
6
62
  * `<vf-icon>` — a Finder icon: pixel art in a reserved cell with its name on a
@@ -121,6 +177,88 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
121
177
  * Shift. Focus is what `selectable` grants, so the keyboard half of `movable`
122
178
  * and `editable` presupposes it — see the role section below.
123
179
  *
180
+ * ### The drag is an outline; the icon stays put
181
+ *
182
+ * The Finder dragged an icon as a dotted outline — the mask's boundary and
183
+ * the name's rectangle — drawn over everything with the XOR pen, the icon
184
+ * itself staying put until the drop. The kit draws it from what it already
185
+ * has: {@link deriveDragOutline} finds the ring the way the open ghost does
186
+ * (the silhouette from the art's alpha, eroded by one pixel, the ring the
187
+ * erosion removes), adds the plate's rectangle, and {@link dotOutline} dots
188
+ * it against a 2×2 checker — compositing only, so cross-origin art derives
189
+ * too, and art the pipeline cannot draw falls back to the cell's rectangle.
190
+ * The canvas paints with the cursor's XOR recipe, `filter: invert(1)` under
191
+ * `mix-blend-mode: difference`: a dotted black line over a white window
192
+ * body, and over the desktop dither the composition QuickDraw's pattern pen
193
+ * gave, because the checker's phase is taken from where the outline lands
194
+ * on the *screen* — its dots share the dither's own phase wherever it goes.
195
+ *
196
+ * It draws on the desktop's drag surface: a layer in the screen's shadow,
197
+ * over windows, palettes and the menu bar alike, clipped at the raster's
198
+ * edge like everything else, reached through the `vf-drag-surface-request`
199
+ * handshake (bubbles, non-composed — it travels up the slots the icon is
200
+ * assigned to, so it works from inside a window body). With no desktop the
201
+ * canvas lives in the icon's own frame instead, translated by the delta,
202
+ * clipped by whatever clips the icon; the gesture and its events are the
203
+ * same either way. Its origin is a whole count of system px from the
204
+ * surface's, written as a live `sysLength()`, so a scale change mid-gesture
205
+ * cannot smear it.
206
+ *
207
+ * ### The drag reports, the page files
208
+ *
209
+ * The kit ships no filing semantics — folders are the page's own catalog —
210
+ * so a drag is a stream of events and a cancelable commit, on the icon:
211
+ *
212
+ * - `vf-drag-start` `{ left, top }` on the first lattice step away from the
213
+ * press (a plain click never starts one, and never fires a drop);
214
+ * - `vf-drag` `{ clientX, clientY, left, top, x, y }` on every step that
215
+ * changed the snapped proposal;
216
+ * - `vf-drop`, the same shape at the release, **cancelable**: its default
217
+ * action is the move, the proposal written through `left`/`top` and
218
+ * clamped whole in the container measured at the press. `preventDefault()`
219
+ * writes nothing — the page re-parents or places the icon itself, the
220
+ * outline's origin converted with the destination's `placementAt`;
221
+ * - `vf-drag-cancel` `{}` on Escape or a `pointercancel`: nothing written.
222
+ *
223
+ * `left`/`top` in the detail are the *proposal*, unclamped — the origin plus
224
+ * the lattice-snapped delta — and only the default action clamps, so a page
225
+ * that cancels gets the raw gesture. `x`/`y` are the outline's top-left in
226
+ * viewport CSS px: the frame's box at the press translated by the delta,
227
+ * the press offset already inside it, so an icon placed at the
228
+ * destination's `placementAt(x, y)` lands exactly where the outline was.
229
+ *
230
+ * ### The selection travels
231
+ *
232
+ * A drag that begins on a *selected* icon takes every other selected,
233
+ * movable icon of its field with it — the Finder outlined the whole
234
+ * selection under a drag on any member. Each follower draws its own outline
235
+ * ({@link followDrag}), moved by the same lattice delta as the leader's, and
236
+ * the leader's events carry the set as `detail.icons`, itself first. The
237
+ * default action of the drop clamps the delta once for the whole group —
238
+ * the arrangement is kept, and the group stops when its outermost member
239
+ * meets the container's edge — then writes each member's origin plus that
240
+ * delta. A cancel takes every outline down and writes nothing. A press on
241
+ * an unselected icon makes it the selection first (the outside listeners
242
+ * clear the others), so it drags alone; a Shift press that deselects the
243
+ * pressed icon drags it alone too, the rest staying where they are.
244
+ *
245
+ * For the selection to travel, a plain press on one of its members must not
246
+ * collapse it: the other icons' outside-press listeners leave a selection
247
+ * alone when the press landed on an icon already selected in the same
248
+ * field. A *click* on such an icon — released with no drag — collapses the
249
+ * selection to it on the release, so a click still single-selects and the
250
+ * same press could have dragged them all.
251
+ *
252
+ * Escape is heard by a document listener scoped to the gesture rather than
253
+ * by the icon's own key handler, because a `movable`-only icon never takes
254
+ * focus — an addition in the kit's idiom (a pointer-only gesture with no way
255
+ * out is the kind of gap SPEC §1 closes), not a claim about the Finder.
256
+ *
257
+ * `target` is the destination highlight the page sets on the folder under a
258
+ * drag: the selected treatment of the art alone — inverted, or darkened
259
+ * under `color` — with none of `selected`'s semantics: no event, no outside
260
+ * listener, no `aria-selected`, the plate untouched.
261
+ *
124
262
  * Opening gets the same treatment. The double-click is the pointer gesture,
125
263
  * and its keyboard route is ⌘O / ⌘↓ — the System 7 Open shortcuts, with Ctrl
126
264
  * standing in for ⌘ off the Mac. Return is deliberately not one of them: the
@@ -160,21 +298,22 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
160
298
  * and true of what it is. Deliberately not `button`: that would promise Enter
161
299
  * and Space activate, and here Return *renames* while the open route is ⌘O / ⌘↓.
162
300
  *
163
- * Declaring the owner is one attribute on whatever already holds the field, and
301
+ * The owner is `vf-icon-field`, the container a field of icons sits in, and
164
302
  * it is what buys the selection state back:
165
303
  *
166
304
  * ```html
167
- * <div role="listbox" aria-label="Desktop" aria-multiselectable="true">
305
+ * <vf-icon-field label="Desktop">
168
306
  * <vf-icon label="Macintosh HD" selectable movable editable>…</vf-icon>
169
307
  * <vf-icon label="Trash" selectable movable editable>…</vf-icon>
170
- * </div>
308
+ * </vf-icon-field>
171
309
  * ```
172
310
  *
173
311
  * A `vf-desktop` cannot be that container itself: it also holds windows and a
174
312
  * menu bar, and a non-`option` child of a listbox is invalid the same way the
175
- * orphaned option was. The plain wrapper above is layout-neutral — placed icons
176
- * anchor to the nearest *positioned* ancestor, which is still the desktop's
177
- * raster. One divergence from the APG listbox is deliberate: its options share
313
+ * orphaned option was. The field is layout-neutral — placed icons anchor to
314
+ * the nearest *positioned* ancestor, which is still the desktop's raster. An
315
+ * element of your own carrying `role="listbox"` still owns an icon the same
316
+ * way. One divergence from the APG listbox is deliberate: its options share
178
317
  * a single roving tab stop, while these stay one stop each, the way a Finder
179
318
  * icon is reached on its own.
180
319
  *
@@ -250,6 +389,19 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
250
389
  * edit was dropped and the old name put back.
251
390
  * `detail: { attempted, kept, reason: 'empty' }`. A `vf-change` is *not*
252
391
  * fired alongside it — nothing changed.
392
+ * @fires vf-drag-start - A drag began: the first lattice step away from the
393
+ * press. `detail: { left, top, icons }` — the origin, whole system px in
394
+ * the icon's container, and every icon the drag carries (this one first).
395
+ * @fires vf-drag - A step that changed the proposal. `detail: { clientX,
396
+ * clientY, left, top, x, y, icons }` — the pointer in viewport CSS px, the
397
+ * proposed origin in the container (whole system px on the lattice), the
398
+ * outline's top-left in viewport CSS px, and the icons travelling.
399
+ * @fires vf-drop - The release; cancelable. The same detail as `vf-drag`.
400
+ * Its default action writes the proposal through `left`/`top` — every
401
+ * icon in `icons` by the same delta, clamped whole in the container as a
402
+ * group; `preventDefault()` writes nothing.
403
+ * @fires vf-drag-cancel - The drag was abandoned — Escape, or a
404
+ * `pointercancel` — and nothing was written. `detail: {}`.
253
405
  */
254
406
  export declare class VfIcon extends VfIcon_base {
255
407
  #private;
@@ -272,6 +424,15 @@ export declare class VfIcon extends VfIcon_base {
272
424
  selectable: boolean;
273
425
  /** Whether the icon is selected: the art inverts and the plate goes black. */
274
426
  selected: boolean;
427
+ /**
428
+ * The destination highlight: this icon is the folder under a drag, and its
429
+ * art paints the selected treatment — inverted, or darkened under
430
+ * {@link color} — with none of `selected`'s semantics: no `vf-select`, no
431
+ * outside-press listener, no `aria-selected`, the plate untouched. The page
432
+ * sets it on the folder a `vf-drag` reports the pointer over and clears it
433
+ * when the pointer leaves or the drop lands.
434
+ */
435
+ target: boolean;
275
436
  /**
276
437
  * Declares the slotted art a **color icon**, so selection darkens it — the
277
438
  * ttSelected transform, every color blended halfway toward black — instead
@@ -339,6 +500,14 @@ export declare class VfIcon extends VfIcon_base {
339
500
  private _draft;
340
501
  /** The derived open ghost, or null while there is nothing to derive from. */
341
502
  private _ghost;
503
+ /**
504
+ * Join another icon's drag as a follower (see the class doc): seed the
505
+ * origin the drop will add the delta to, draw this icon's own outline on
506
+ * `surface` (the desktop's, as the leader's handshake found it) or in its
507
+ * own frame, and hand back the handle the leader moves, drops and ends.
508
+ * Null when this icon cannot move. Internal to the kit's group drag.
509
+ */
510
+ followDrag(surface: HTMLElement | null): VfIconDragFollower | null;
342
511
  connectedCallback(): void;
343
512
  disconnectedCallback(): void;
344
513
  protected updated(changed: Map<PropertyKey, unknown>): void;
@@ -362,6 +531,27 @@ export declare class VfIcon extends VfIcon_base {
362
531
  /** Put the previous name back and close the field. */
363
532
  cancelEditing(): void;
364
533
  protected render(): import("lit-html").TemplateResult<1>;
534
+ /**
535
+ * Select or deselect as a press would: the state changes and `vf-select`
536
+ * reports it. A `selected` write from code is silent, the way a value set
537
+ * fires no `vf-change`; this is the route for a gesture a container runs
538
+ * on the icon's behalf — `vf-icon-field`'s rubber band. A no-op when the
539
+ * state already matches.
540
+ */
541
+ setSelected(next: boolean): void;
542
+ /**
543
+ * Whether a viewport box (CSS px) touches the icon the way the Finder's
544
+ * selection rectangle asked: its art cell or its name plate. The empty
545
+ * cell around narrower art and the frame's margin beside the plate count
546
+ * for nothing — a rectangle dragged through the gap between two icons
547
+ * selects neither. `vf-icon-field`'s rubber band reads it.
548
+ */
549
+ touches(box: {
550
+ left: number;
551
+ top: number;
552
+ right: number;
553
+ bottom: number;
554
+ }): boolean;
365
555
  }
366
556
  declare global {
367
557
  interface HTMLElementTagNameMap {