vintage-frames 0.6.2 → 0.7.1

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,90 @@ 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 a black line, the composition
193
+ * QuickDraw's pattern pen gave — the checker's phase is taken from where
194
+ * the outline lands on the *screen* ({@link penPhase}), so its dots fall on
195
+ * the pixels the dither leaves white wherever it goes, and the dither's own
196
+ * ink fills in between them.
197
+ *
198
+ * It draws on the desktop's drag surface: a layer in the screen's shadow,
199
+ * over windows, palettes and the menu bar alike, clipped at the raster's
200
+ * edge like everything else, reached through the `vf-drag-surface-request`
201
+ * handshake (bubbles, non-composed — it travels up the slots the icon is
202
+ * assigned to, so it works from inside a window body). With no desktop the
203
+ * canvas lives in the icon's own frame instead, translated by the delta,
204
+ * clipped by whatever clips the icon; the gesture and its events are the
205
+ * same either way. Its origin is a whole count of system px from the
206
+ * surface's, written as a live `sysLength()`, so a scale change mid-gesture
207
+ * cannot smear it.
208
+ *
209
+ * ### The drag reports, the page files
210
+ *
211
+ * The kit ships no filing semantics — folders are the page's own catalog —
212
+ * so a drag is a stream of events and a cancelable commit, on the icon:
213
+ *
214
+ * - `vf-drag-start` `{ left, top }` on the first lattice step away from the
215
+ * press (a plain click never starts one, and never fires a drop);
216
+ * - `vf-drag` `{ clientX, clientY, left, top, x, y }` on every step that
217
+ * changed the snapped proposal;
218
+ * - `vf-drop`, the same shape at the release, **cancelable**: its default
219
+ * action is the move, the proposal written through `left`/`top` and
220
+ * clamped whole in the container measured at the press. `preventDefault()`
221
+ * writes nothing — the page re-parents or places the icon itself, the
222
+ * outline's origin converted with the destination's `placementAt`;
223
+ * - `vf-drag-cancel` `{}` on Escape or a `pointercancel`: nothing written.
224
+ *
225
+ * `left`/`top` in the detail are the *proposal*, unclamped — the origin plus
226
+ * the lattice-snapped delta — and only the default action clamps, so a page
227
+ * that cancels gets the raw gesture. `x`/`y` are the outline's top-left in
228
+ * viewport CSS px: the frame's box at the press translated by the delta,
229
+ * the press offset already inside it, so an icon placed at the
230
+ * destination's `placementAt(x, y)` lands exactly where the outline was.
231
+ *
232
+ * ### The selection travels
233
+ *
234
+ * A drag that begins on a *selected* icon takes every other selected,
235
+ * movable icon of its field with it — the Finder outlined the whole
236
+ * selection under a drag on any member. Each follower draws its own outline
237
+ * ({@link followDrag}), moved by the same lattice delta as the leader's, and
238
+ * the leader's events carry the set as `detail.icons`, itself first. The
239
+ * default action of the drop clamps the delta once for the whole group —
240
+ * the arrangement is kept, and the group stops when its outermost member
241
+ * meets the container's edge — then writes each member's origin plus that
242
+ * delta. A cancel takes every outline down and writes nothing. A press on
243
+ * an unselected icon makes it the selection first (the outside listeners
244
+ * clear the others), so it drags alone; a Shift press that deselects the
245
+ * pressed icon drags it alone too, the rest staying where they are.
246
+ *
247
+ * For the selection to travel, a plain press on one of its members must not
248
+ * collapse it: the other icons' outside-press listeners leave a selection
249
+ * alone when the press landed on an icon already selected in the same
250
+ * field. A *click* on such an icon — released with no drag — collapses the
251
+ * selection to it on the release, so a click still single-selects and the
252
+ * same press could have dragged them all.
253
+ *
254
+ * Escape is heard by a document listener scoped to the gesture rather than
255
+ * by the icon's own key handler, because a `movable`-only icon never takes
256
+ * focus — an addition in the kit's idiom (a pointer-only gesture with no way
257
+ * out is the kind of gap SPEC §1 closes), not a claim about the Finder.
258
+ *
259
+ * `target` is the destination highlight the page sets on the folder under a
260
+ * drag: the selected treatment of the art alone — inverted, or darkened
261
+ * under `color` — with none of `selected`'s semantics: no event, no outside
262
+ * listener, no `aria-selected`, the plate untouched.
263
+ *
124
264
  * Opening gets the same treatment. The double-click is the pointer gesture,
125
265
  * and its keyboard route is ⌘O / ⌘↓ — the System 7 Open shortcuts, with Ctrl
126
266
  * standing in for ⌘ off the Mac. Return is deliberately not one of them: the
@@ -160,21 +300,22 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
160
300
  * and true of what it is. Deliberately not `button`: that would promise Enter
161
301
  * and Space activate, and here Return *renames* while the open route is ⌘O / ⌘↓.
162
302
  *
163
- * Declaring the owner is one attribute on whatever already holds the field, and
303
+ * The owner is `vf-icon-field`, the container a field of icons sits in, and
164
304
  * it is what buys the selection state back:
165
305
  *
166
306
  * ```html
167
- * <div role="listbox" aria-label="Desktop" aria-multiselectable="true">
307
+ * <vf-icon-field label="Desktop">
168
308
  * <vf-icon label="Macintosh HD" selectable movable editable>…</vf-icon>
169
309
  * <vf-icon label="Trash" selectable movable editable>…</vf-icon>
170
- * </div>
310
+ * </vf-icon-field>
171
311
  * ```
172
312
  *
173
313
  * A `vf-desktop` cannot be that container itself: it also holds windows and a
174
314
  * 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
315
+ * orphaned option was. The field is layout-neutral — placed icons anchor to
316
+ * the nearest *positioned* ancestor, which is still the desktop's raster. An
317
+ * element of your own carrying `role="listbox"` still owns an icon the same
318
+ * way. One divergence from the APG listbox is deliberate: its options share
178
319
  * a single roving tab stop, while these stay one stop each, the way a Finder
179
320
  * icon is reached on its own.
180
321
  *
@@ -250,6 +391,19 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
250
391
  * edit was dropped and the old name put back.
251
392
  * `detail: { attempted, kept, reason: 'empty' }`. A `vf-change` is *not*
252
393
  * fired alongside it — nothing changed.
394
+ * @fires vf-drag-start - A drag began: the first lattice step away from the
395
+ * press. `detail: { left, top, icons }` — the origin, whole system px in
396
+ * the icon's container, and every icon the drag carries (this one first).
397
+ * @fires vf-drag - A step that changed the proposal. `detail: { clientX,
398
+ * clientY, left, top, x, y, icons }` — the pointer in viewport CSS px, the
399
+ * proposed origin in the container (whole system px on the lattice), the
400
+ * outline's top-left in viewport CSS px, and the icons travelling.
401
+ * @fires vf-drop - The release; cancelable. The same detail as `vf-drag`.
402
+ * Its default action writes the proposal through `left`/`top` — every
403
+ * icon in `icons` by the same delta, clamped whole in the container as a
404
+ * group; `preventDefault()` writes nothing.
405
+ * @fires vf-drag-cancel - The drag was abandoned — Escape, or a
406
+ * `pointercancel` — and nothing was written. `detail: {}`.
253
407
  */
254
408
  export declare class VfIcon extends VfIcon_base {
255
409
  #private;
@@ -272,6 +426,15 @@ export declare class VfIcon extends VfIcon_base {
272
426
  selectable: boolean;
273
427
  /** Whether the icon is selected: the art inverts and the plate goes black. */
274
428
  selected: boolean;
429
+ /**
430
+ * The destination highlight: this icon is the folder under a drag, and its
431
+ * art paints the selected treatment — inverted, or darkened under
432
+ * {@link color} — with none of `selected`'s semantics: no `vf-select`, no
433
+ * outside-press listener, no `aria-selected`, the plate untouched. The page
434
+ * sets it on the folder a `vf-drag` reports the pointer over and clears it
435
+ * when the pointer leaves or the drop lands.
436
+ */
437
+ target: boolean;
275
438
  /**
276
439
  * Declares the slotted art a **color icon**, so selection darkens it — the
277
440
  * ttSelected transform, every color blended halfway toward black — instead
@@ -339,6 +502,14 @@ export declare class VfIcon extends VfIcon_base {
339
502
  private _draft;
340
503
  /** The derived open ghost, or null while there is nothing to derive from. */
341
504
  private _ghost;
505
+ /**
506
+ * Join another icon's drag as a follower (see the class doc): seed the
507
+ * origin the drop will add the delta to, draw this icon's own outline on
508
+ * `surface` (the desktop's, as the leader's handshake found it) or in its
509
+ * own frame, and hand back the handle the leader moves, drops and ends.
510
+ * Null when this icon cannot move. Internal to the kit's group drag.
511
+ */
512
+ followDrag(surface: HTMLElement | null): VfIconDragFollower | null;
342
513
  connectedCallback(): void;
343
514
  disconnectedCallback(): void;
344
515
  protected updated(changed: Map<PropertyKey, unknown>): void;
@@ -362,6 +533,27 @@ export declare class VfIcon extends VfIcon_base {
362
533
  /** Put the previous name back and close the field. */
363
534
  cancelEditing(): void;
364
535
  protected render(): import("lit-html").TemplateResult<1>;
536
+ /**
537
+ * Select or deselect as a press would: the state changes and `vf-select`
538
+ * reports it. A `selected` write from code is silent, the way a value set
539
+ * fires no `vf-change`; this is the route for a gesture a container runs
540
+ * on the icon's behalf — `vf-icon-field`'s rubber band. A no-op when the
541
+ * state already matches.
542
+ */
543
+ setSelected(next: boolean): void;
544
+ /**
545
+ * Whether a viewport box (CSS px) touches the icon the way the Finder's
546
+ * selection rectangle asked: its art cell or its name plate. The empty
547
+ * cell around narrower art and the frame's margin beside the plate count
548
+ * for nothing — a rectangle dragged through the gap between two icons
549
+ * selects neither. `vf-icon-field`'s rubber band reads it.
550
+ */
551
+ touches(box: {
552
+ left: number;
553
+ top: number;
554
+ right: number;
555
+ bottom: number;
556
+ }): boolean;
365
557
  }
366
558
  declare global {
367
559
  interface HTMLElementTagNameMap {