vintage-frames 0.2.1 → 0.4.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.
@@ -17,6 +17,20 @@ declare const VfDesktop_base: (new (...args: any[]) => import("../position.js").
17
17
  * deactivates the active document window nor greys the palette, exactly as
18
18
  * System 7's floating windoids behaved while their application was frontmost.
19
19
  *
20
+ * **Deactivation.** On a real System 7 machine clicking the desktop clicked
21
+ * the *Finder* — the frontmost application's windows lost their stripes.
22
+ * {@link clearActive} is that gesture's handler: it clears `active` from
23
+ * the whole document tier, and **zero active windows is a legal state**,
24
+ * held until a press or keyboard focus re-enters a document window (or a
25
+ * new one is slotted, which activates it — opening a window brings its
26
+ * application forward). The desktop never takes this decision itself: its
27
+ * furniture is slotted light DOM (an icon layer, say), so only the page
28
+ * knows which of its children — or which presses on the bare dither — mean
29
+ * "the Finder", and it routes those through `clearActive()`. Left alone,
30
+ * the classic always-one-active behavior is unchanged. {@link activeWindow}
31
+ * reads the current holder, and every change of holder — including to and
32
+ * from none — fires `vf-activate`.
33
+ *
20
34
  * The desktop is a raster with an explicit size, always: **`width` and
21
35
  * `height`**, in system px, the way a WIND resource declared a window's —
22
36
  * the host box renders at the declared screen plus `2 × bezel` per axis, a
@@ -41,6 +55,11 @@ declare const VfDesktop_base: (new (...args: any[]) => import("../position.js").
41
55
  * cells (or with `none`).
42
56
  *
43
57
  * @slot - Default slot: menu bar, windows, anything.
58
+ * @fires vf-activate - The active document-tier window changed. Detail
59
+ * `{ window: HTMLElement | null }` — the new holder, or `null` when the
60
+ * document tier deactivated (a {@link clearActive} call, or the active
61
+ * window leaving the DOM with none behind it). Fired once per change of
62
+ * holder, never for a re-assertion of the same one.
44
63
  * @csspart desktop - The dithered screen surface — the whole-system-px
45
64
  * raster (inset by `bezel` when one is set).
46
65
  * @cssprop [--vf-desktop=#808080] - base color under the desktop dither —
@@ -108,6 +127,20 @@ export declare class VfDesktop extends VfDesktop_base {
108
127
  private _pattern;
109
128
  /** Monotonic z-index counter for window stacking. */
110
129
  private _zCounter;
130
+ /**
131
+ * The active document-tier window, or null when the tier is deactivated
132
+ * (or empty). The single change-tracked truth behind {@link activeWindow}
133
+ * and the `vf-activate` event — written only by {@link _setActive}.
134
+ */
135
+ private _activeWindow;
136
+ /**
137
+ * Whether the document tier was *deliberately* deactivated (a
138
+ * {@link clearActive} call) — as opposed to `_activeWindow` being null
139
+ * because nothing has activated yet. Slot changes preserve a deliberate
140
+ * deactivation instead of promoting a survivor; a newly slotted document
141
+ * window still activates (opening a window brings its application forward).
142
+ */
143
+ private _deactivated;
111
144
  /** Whether a one-shot post-upgrade re-normalization is already pending. */
112
145
  private _awaitingUpgrade;
113
146
  /** Whether a pointer gesture that began on the desktop is still in flight. */
@@ -143,6 +176,18 @@ export declare class VfDesktop extends VfDesktop_base {
143
176
  * draggable in the same gesture that raises it.
144
177
  */
145
178
  bringToFront(win: HTMLElement): void;
179
+ /** The active document-tier window, or null while the tier is deactivated
180
+ * (or has no windows). Utility windows are never the holder. */
181
+ get activeWindow(): HTMLElement | null;
182
+ /**
183
+ * Deactivate the whole document tier — clear `active` from every document
184
+ * window, leaving none the holder. Pages route "the user clicked the
185
+ * Finder" presses — on the bare dither, on their own desktop furniture
186
+ * (an icon layer) — through here; the deactivated state holds until a
187
+ * document window is pressed, focused, brought to front, or newly
188
+ * slotted.
189
+ */
190
+ clearActive(): void;
146
191
  /** The z/active half of a raise, shared by every path. */
147
192
  private _restack;
148
193
  /** Sync the DOM order now, or at gesture end if a pointer is down. */
@@ -199,9 +244,12 @@ export declare class VfDesktop extends VfDesktop_base {
199
244
  */
200
245
  private _normalizeAfterUpgrade;
201
246
  /** Set `active` on `win` only, clearing it on every other *document-tier*
202
- * window. Utility windows stand outside the invariant: a palette keeps
203
- * whatever `active` state it has (true by default, so its dither and
204
- * widgets stay drawn while document windows trade the highlight). */
247
+ * window (`null` clears the whole tier — the deactivated state). Utility
248
+ * windows stand outside the invariant: a palette keeps whatever `active`
249
+ * state it has (true by default, so its dither and widgets stay drawn
250
+ * while document windows trade the highlight). The one write site of
251
+ * {@link _activeWindow}, so `vf-activate` fires exactly on a change of
252
+ * holder — re-asserting the current holder is silent. */
205
253
  private _setActive;
206
254
  /**
207
255
  * Set a window's `active` state. Prefers the property (the source of truth
@@ -1,17 +1,18 @@
1
- import { vfElement as e } from "../define.js";
2
- import { ScaleController as t, effectiveScale as n, sysLength as r } from "../scale.js";
3
- import i from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
4
- import { VfPositioned as a } from "../position.js";
5
- import { vfBase as o } from "../styles/recipes/host.js";
6
- import { tileImage as s, tileRaster as c, tileRects as l, tileSpan as u, vfTileSize as d } from "../styles/recipes/tile.js";
7
- import { TileRasterCache as f, patternOverride as p, tileGrid as m, vfTileGrid as h } from "../tile-grid.js";
8
- import { GridSnapController as g } from "../grid-snap.js";
9
- import { DocumentListenersController as _ } from "../document-listeners.js";
10
- import { SCREEN_CORNER as v, steppedCornerClip as y } from "../pixel-frame.js";
11
- import { LitElement as b, css as x, html as S, unsafeCSS as C } from "lit";
12
- import { property as w, queryAssignedElements as T } from "lit/decorators.js";
1
+ import { emit as e } from "../events.js";
2
+ import { vfElement as t } from "../define.js";
3
+ import { ScaleController as n, effectiveScale as r, sysLength as i } from "../scale.js";
4
+ import a from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
5
+ import { VfPositioned as o } from "../position.js";
6
+ import { vfBase as s } from "../styles/recipes/host.js";
7
+ import { tileImage as c, tileRaster as l, tileRects as u, tileSpan as d, vfTileSize as f } from "../styles/recipes/tile.js";
8
+ import { TileRasterCache as p, patternOverride as m, tileGrid as h, vfTileGrid as g } from "../tile-grid.js";
9
+ import { GridSnapController as _ } from "../grid-snap.js";
10
+ import { DocumentListenersController as v } from "../document-listeners.js";
11
+ import { SCREEN_CORNER as y, steppedCornerClip as b } from "../pixel-frame.js";
12
+ import { LitElement as x, css as S, html as C, unsafeCSS as w } from "lit";
13
+ import { property as T, queryAssignedElements as E } from "lit/decorators.js";
13
14
  //#region src/components/vf-desktop.ts
14
- var E = 1e6, D = 512, O = 342, k = 2, A = [
15
+ var D = 1e6, O = 512, k = 342, A = 2, j = [
15
16
  [
16
17
  0,
17
18
  0,
@@ -33,9 +34,9 @@ var E = 1e6, D = 512, O = 342, k = 2, A = [
33
34
  1,
34
35
  "#000000"
35
36
  ]
36
- ], j = s(k, k, l(A)), M = c(k, k, A), N = u(k), P = class extends a(b) {
37
+ ], M = c(A, A, u(j)), N = l(A, A, j), P = d(A), F = class extends o(x) {
37
38
  constructor(...e) {
38
- super(...e), this.width = D, this.height = O, this.bezel = 0, this.scale = new t(this), this.gridSnap = new g(this), this._pattern = "", this.#e = new f(), this._zCounter = 0, this._awaitingUpgrade = !1, this._pointerGesture = !1, this._restoringFocus = !1, this._gestureEnd = new _(this, () => [[
39
+ super(...e), this.width = O, this.height = k, this.bezel = 0, this.scale = new n(this), this.gridSnap = new _(this), this._pattern = "", this.#e = new p(), this._zCounter = 0, this._activeWindow = null, this._deactivated = !1, this._awaitingUpgrade = !1, this._pointerGesture = !1, this._restoringFocus = !1, this._gestureEnd = new v(this, () => [[
39
40
  document,
40
41
  "pointerup",
41
42
  this._onGestureEnd,
@@ -59,9 +60,9 @@ var E = 1e6, D = 512, O = 342, k = 2, A = [
59
60
  }
60
61
  static {
61
62
  this.styles = [
62
- o,
63
- h,
64
- x`
63
+ s,
64
+ g,
65
+ S`
65
66
  :host {
66
67
  display: block;
67
68
  position: relative;
@@ -110,8 +111,8 @@ var E = 1e6, D = 512, O = 342, k = 2, A = [
110
111
  belt-and-braces paint beneath the (opaque) kit fill. Override the
111
112
  whole tile via --vf-desktop-pattern — the tile grid renders the
112
113
  same token at the same documented geometry. */
113
- background-image: var(--vf-desktop-pattern, ${C(j)});
114
- ${d(k)}
114
+ background-image: var(--vf-desktop-pattern, ${w(M)});
115
+ ${f(A)}
115
116
  /* Forced colors: the checker is opaque literal white-and-black (a
116
117
  preserved url() tile), which ignores a dark theme entirely. A
117
118
  backdrop is decoration, and high-contrast mode is a request for
@@ -148,7 +149,7 @@ var E = 1e6, D = 512, O = 342, k = 2, A = [
148
149
  .screen > .vf-tile-grid {
149
150
  position: absolute;
150
151
  inset: 0;
151
- --_vf-tile-image: var(--vf-desktop-pattern, ${C(M)});
152
+ --_vf-tile-image: var(--vf-desktop-pattern, ${w(N)});
152
153
  }
153
154
  /* Bezeled, the screen is inset by exactly one bezel width. The host
154
155
  is always the declared screen + 2×bezel (written in updated()), so
@@ -175,25 +176,25 @@ var E = 1e6, D = 512, O = 342, k = 2, A = [
175
176
  .corner {
176
177
  position: absolute;
177
178
  top: 0;
178
- width: calc(var(--vf-scale, 1) * ${v[0]}px);
179
- height: calc(var(--vf-scale, 1) * ${v.length}px);
179
+ width: calc(var(--vf-scale, 1) * ${y[0]}px);
180
+ height: calc(var(--vf-scale, 1) * ${y.length}px);
180
181
  background: var(--vf-black, #000);
181
182
  pointer-events: none;
182
183
  z-index: 2147483647;
183
184
  }
184
185
  .corner.tl {
185
186
  left: 0;
186
- clip-path: ${C(y(v, "left"))};
187
+ clip-path: ${w(b(y, "left"))};
187
188
  }
188
189
  .corner.tr {
189
190
  right: 0;
190
- clip-path: ${C(y(v, "right"))};
191
+ clip-path: ${w(b(y, "right"))};
191
192
  }
192
193
  `
193
194
  ];
194
195
  }
195
196
  fitWithin(e, t) {
196
- let r = n(this), i = (e) => Math.max(0, Math.floor(e / r + 1e-6) - 2 * this.bezel);
197
+ let n = r(this), i = (e) => Math.max(0, Math.floor(e / n + 1e-6) - 2 * this.bezel);
197
198
  return this.width = i(e), this.height = i(t), {
198
199
  width: this.width,
199
200
  height: this.height
@@ -212,9 +213,15 @@ var E = 1e6, D = 512, O = 342, k = 2, A = [
212
213
  bringToFront(e) {
213
214
  this._restack(e), this._requestDomSync();
214
215
  }
216
+ get activeWindow() {
217
+ return this._activeWindow;
218
+ }
219
+ clearActive() {
220
+ this._deactivated = !0, this._setActive(null);
221
+ }
215
222
  _restack(e) {
216
223
  let t = this._isUtility(e);
217
- e.style.zIndex = String(++this._zCounter + (t ? E : 0)), t || this._setActive(e);
224
+ e.style.zIndex = String(++this._zCounter + (t ? D : 0)), t || this._setActive(e);
218
225
  }
219
226
  _requestDomSync() {
220
227
  this._pointerGesture || this._syncDomOrder();
@@ -231,20 +238,22 @@ var E = 1e6, D = 512, O = 342, k = 2, A = [
231
238
  let e = this._windows, t = null;
232
239
  for (let n of e) if (!n.style.zIndex) {
233
240
  let e = this._isUtility(n);
234
- n.style.zIndex = String(++this._zCounter + (e ? E : 0)), e || (t = n);
241
+ n.style.zIndex = String(++this._zCounter + (e ? D : 0)), e || (t = n);
235
242
  }
236
- let n = t ?? this._topmost(e.filter((e) => !this._isUtility(e)));
237
- n && this._setActive(n), customElements.get("vf-window") || this._normalizeAfterUpgrade();
243
+ let n = e.filter((e) => !this._isUtility(e)), r = this._activeWindow && n.includes(this._activeWindow) ? this._activeWindow : null;
244
+ this._setActive(t ?? r ?? (this._deactivated ? null : this._topmost(n))), customElements.get("vf-window") || this._normalizeAfterUpgrade();
238
245
  }
239
246
  _normalizeAfterUpgrade() {
240
247
  this._awaitingUpgrade || (this._awaitingUpgrade = !0, customElements.whenDefined("vf-window").then(() => {
241
248
  if (this._awaitingUpgrade = !1, !this.isConnected) return;
242
- let e = this._topmost(this._windows.filter((e) => !this._isUtility(e)));
243
- e && this._setActive(e);
249
+ let e = this._windows.filter((e) => !this._isUtility(e)), t = this._activeWindow && e.includes(this._activeWindow) ? this._activeWindow : null;
250
+ this._setActive(t ?? (this._deactivated ? null : this._topmost(e)));
244
251
  }));
245
252
  }
246
- _setActive(e) {
247
- for (let t of this._windows) this._isUtility(t) || this._setWindowActive(t, t === e);
253
+ _setActive(t) {
254
+ t && (this._deactivated = !1);
255
+ for (let e of this._windows) this._isUtility(e) || this._setWindowActive(e, e === t);
256
+ t !== this._activeWindow && (this._activeWindow = t, e(this, "vf-activate", { window: t }));
248
257
  }
249
258
  _setWindowActive(e, t) {
250
259
  if ("active" in e) {
@@ -274,37 +283,37 @@ var E = 1e6, D = 512, O = 342, k = 2, A = [
274
283
  r && n instanceof HTMLElement && n.isConnected && this._deepActiveElement() !== n && (this._restoringFocus = !0, n.focus({ preventScroll: !0 }), this._restoringFocus = !1);
275
284
  }
276
285
  willUpdate(e) {
277
- super.willUpdate(e), this._pattern = p(this, "--vf-desktop-pattern");
286
+ super.willUpdate(e), this._pattern = m(this, "--vf-desktop-pattern");
278
287
  }
279
288
  updated(e) {
280
- if (e.has("bezel") && (this.bezel > 0 ? this.style.setProperty("--vf-desktop-bezel", r(this.bezel)) : this.style.removeProperty("--vf-desktop-bezel")), e.has("width") || e.has("height") || e.has("bezel")) {
281
- let e = this.width ?? D, t = this.height ?? O;
282
- this.style.width = r(e + 2 * this.bezel), this.style.height = r(t + 2 * this.bezel);
289
+ if (e.has("bezel") && (this.bezel > 0 ? this.style.setProperty("--vf-desktop-bezel", i(this.bezel)) : this.style.removeProperty("--vf-desktop-bezel")), e.has("width") || e.has("height") || e.has("bezel")) {
290
+ let e = this.width ?? O, t = this.height ?? k;
291
+ this.style.width = i(e + 2 * this.bezel), this.style.height = i(t + 2 * this.bezel);
283
292
  }
284
293
  }
285
294
  render() {
286
- let e = this.width ?? D, t = this.height ?? O, n = Math.ceil(e / N), i = Math.ceil(t / N), a = this._pattern ? S`<div class="vf-tile-grid">
287
- ${m({
295
+ let e = this.width ?? O, t = this.height ?? k, n = Math.ceil(e / P), r = Math.ceil(t / P), a = this._pattern ? C`<div class="vf-tile-grid">
296
+ ${h({
288
297
  cols: n,
289
- rows: i,
290
- tile: N
298
+ rows: r,
299
+ tile: P
291
300
  })}
292
- </div>` : S`<div
301
+ </div>` : C`<div
293
302
  class="vf-tile-raster"
294
- style="width:${r(n * N)};height:${r(i * N)};background-image:${this.#e.for(k, k, A, n * N, i * N)}"
303
+ style="width:${i(n * P)};height:${i(r * P)};background-image:${this.#e.for(A, A, j, n * P, r * P)}"
295
304
  ></div>`;
296
- return S`
305
+ return C`
297
306
  <div class=${this.bezel > 0 ? "desktop vf-snap bezeled" : "desktop vf-snap"}>
298
307
  <div class="screen${this._pattern ? " patterned" : ""}" part="desktop">
299
308
  ${a}
300
309
  <slot @slotchange=${this._onSlotChange}></slot>
301
- ${this.bezel > 0 ? S`<div class="corner tl"></div>
310
+ ${this.bezel > 0 ? C`<div class="corner tl"></div>
302
311
  <div class="corner tr"></div>` : null}
303
312
  </div>
304
313
  </div>
305
314
  `;
306
315
  }
307
316
  };
308
- i([w({ type: Number })], P.prototype, "width", void 0), i([w({ type: Number })], P.prototype, "height", void 0), i([w({ type: Number })], P.prototype, "bezel", void 0), i([T({ selector: "vf-window" })], P.prototype, "_windows", void 0), P = i([e("vf-desktop")], P);
317
+ a([T({ type: Number })], F.prototype, "width", void 0), a([T({ type: Number })], F.prototype, "height", void 0), a([T({ type: Number })], F.prototype, "bezel", void 0), a([E({ selector: "vf-window" })], F.prototype, "_windows", void 0), F = a([t("vf-desktop")], F);
309
318
  //#endregion
310
- export { P as VfDesktop };
319
+ export { F as VfDesktop };
@@ -71,10 +71,17 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
71
71
  * precisely an image plus its mask — so inverting it flips ink and fill and
72
72
  * leaves the surround alone, which is the whole of the classic selected
73
73
  * appearance. `filter: invert(1)` reproduces it exactly for 1-bit art. Color
74
- * art inverts too, into a photographic negative rather than the darkening
75
- * System 7 gave it; that is the case to revisit if the kit ever grows a
76
- * selected-state treatment of its own. The label plate inverts to the
77
- * `--vf-highlight` pair, sharing one selection color with `vf-list-item`.
74
+ * art would invert into a photographic negative, which was never what
75
+ * System 7 showed: declare `color` and selection **darkens** the art
76
+ * instead Icon Utilities' ttSelected transform, every color blended
77
+ * halfway toward black (`brightness(0.5)`), whites going gray, the
78
+ * transparent surround still untouched. The declaration is the consumer's
79
+ * because the component cannot tell color art from a mask by looking at a
80
+ * slotted image. It covers whatever the cell shows, the derived open ghost
81
+ * included, so a color icon has one selected treatment open or closed. The
82
+ * label plate inverts to the `--vf-highlight` pair either way, sharing one
83
+ * selection color with `vf-list-item` — the selected name was inverted
84
+ * whatever the art.
78
85
  *
79
86
  * ### Open is derived, not shipped
80
87
  *
@@ -265,6 +272,14 @@ export declare class VfIcon extends VfIcon_base {
265
272
  selectable: boolean;
266
273
  /** Whether the icon is selected: the art inverts and the plate goes black. */
267
274
  selected: boolean;
275
+ /**
276
+ * Declares the slotted art a **color icon**, so selection darkens it — the
277
+ * ttSelected transform, every color blended halfway toward black — instead
278
+ * of inverting it into a photographic negative (see the class doc). Yours
279
+ * to declare because the component cannot tell color art from a 1-bit mask
280
+ * by looking at a slotted image. The label plate inverts either way.
281
+ */
282
+ color: boolean;
268
283
  /**
269
284
  * The icon's window is on screen, so the art paints as the Finder's open
270
285
  * ghost — outline held, interior re-filled with the kit's loose dither —
@@ -1,14 +1,14 @@
1
- import { vfElement as e } from "../define.js";
2
- import { ScaleController as t, effectiveScale as n, toSysExact as r } from "../scale.js";
3
- import i from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
4
- import { PlacementController as a, VfPositioned as o, warnMovableContract as s } from "../position.js";
5
- import { vfBodyDecls as c } from "../styles/recipes/body-face.js";
6
- import { vfBase as l } from "../styles/recipes/host.js";
7
- import { vfFocusUnderline as u } from "../styles/recipes/focus.js";
8
- import { GridSnapController as d } from "../grid-snap.js";
9
- import { DocumentListenersController as f } from "../document-listeners.js";
10
- import { DragController as p } from "../drag.js";
11
- import { emit as m } from "../events.js";
1
+ import { emit as e } from "../events.js";
2
+ import { vfElement as t } from "../define.js";
3
+ import { ScaleController as n, effectiveScale as r, toSysExact as i } from "../scale.js";
4
+ import a from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
5
+ import { PlacementController as o, VfPositioned as s, warnMovableContract as c } from "../position.js";
6
+ import { vfBodyDecls as l } from "../styles/recipes/body-face.js";
7
+ import { vfBase as u } from "../styles/recipes/host.js";
8
+ import { vfFocusUnderline as d } from "../styles/recipes/focus.js";
9
+ import { GridSnapController as f } from "../grid-snap.js";
10
+ import { DocumentListenersController as p } from "../document-listeners.js";
11
+ import { DragController as m } from "../drag.js";
12
12
  import "../motion.js";
13
13
  import { FocusRuleController as h } from "../focus-modality.js";
14
14
  import { deriveOpenArt as g } from "../open-art.js";
@@ -18,20 +18,20 @@ import { property as x, state as S } from "lit/decorators.js";
18
18
  var C = {
19
19
  large: 32,
20
20
  small: 16
21
- }, w = 1, T = 8, E = (e, t) => t <= 0 ? Math.max(e, 0) : Math.min(Math.max(e, 0), t), D = class extends o(_) {
22
- constructor(...e) {
23
- super(...e), this.label = "", this.size = "large", this.selectable = !1, this.selected = !1, this.open = !1, this.movable = !1, this.editable = !1, this.maxlength = 31, this.scale = new t(this), this.gridSnap = new d(this), this.focusRule = new h(this), this._editing = !1, this._draft = "", this.#e = 0, this._ghost = null, this.#t = null, this.#n = this.attachInternals(), this.#i = "", this.#a = "", this.#o = 0, this.#s = -Infinity, this.#c = new f(this, () => [[
21
+ }, w = 1, T = 8, E = (e, t) => t <= 0 ? Math.max(e, 0) : Math.min(Math.max(e, 0), t), D = class extends s(_) {
22
+ constructor(...t) {
23
+ super(...t), this.label = "", this.size = "large", this.selectable = !1, this.selected = !1, this.color = !1, this.open = !1, this.movable = !1, this.editable = !1, this.maxlength = 31, this.scale = new n(this), this.gridSnap = new f(this), this.focusRule = new h(this), this._editing = !1, this._draft = "", this.#e = 0, this._ghost = null, this.#t = null, this.#n = this.attachInternals(), this.#i = "", this.#a = "", this.#o = 0, this.#s = -Infinity, this.#c = new p(this, () => [[
24
24
  document,
25
25
  "pointerdown",
26
26
  this.#A,
27
27
  !0
28
28
  ]]), this.#l = (e, t, n) => ({
29
- x: E(e, n.width - r(this.offsetWidth, this)),
30
- y: E(t, n.height - r(this.offsetHeight, this))
31
- }), this.#u = new a(this, (e, t, n) => this.#l(e, t, n)), this.#d = {
29
+ x: E(e, n.width - i(this.offsetWidth, this)),
30
+ y: E(t, n.height - i(this.offsetHeight, this))
31
+ }), this.#u = new o(this, (e, t, n) => this.#l(e, t, n)), this.#d = {
32
32
  x: 0,
33
33
  y: 0
34
- }, this.#f = new p(this, {
34
+ }, this.#f = new m(this, {
35
35
  onDragStart: (e) => !this.movable || e.button !== 0 || this._editing ? null : (this.#m(), this.#d = this.#u.seed()),
36
36
  onDrag: (e, t) => {
37
37
  (e !== this.#d.x || t !== this.#d.y) && this.#S(), this.#u.moveTo(e, t);
@@ -45,7 +45,7 @@ var C = {
45
45
  let t = e.composedPath().some((e) => e instanceof HTMLElement && e.classList.contains("label")), n = this.selected, r = e.timeStamp - this.#s < 800;
46
46
  this.#s = e.timeStamp, this.#S(), this.selectable && (e.shiftKey || e.metaKey ? this.#D(!this.selected) : this.#D(!0)), this.editable && t && n && !r && !e.shiftKey && !e.metaKey && this.#x(), this.#T && (this.focus({ preventScroll: !0 }), this.focusRule.suppress()), this.#f.onPointerDown(e);
47
47
  }, this.#k = () => {
48
- this._editing || m(this, "vf-open", {});
48
+ this._editing || e(this, "vf-open", {});
49
49
  }, this.#A = (e) => {
50
50
  e.composedPath().includes(this) || (this.#S(), !(e.shiftKey || e.metaKey) && this.#D(!1));
51
51
  }, this.#j = (e) => {
@@ -62,28 +62,28 @@ var C = {
62
62
  this._draft = t.value;
63
63
  }, this.#P = (e) => {
64
64
  e.key === "Enter" ? (e.preventDefault(), this.commitEditing(), this.focus()) : e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), this.cancelEditing(), this.focus());
65
- }, this.#F = (e) => {
66
- if (this.#S(), !(this._editing || e.defaultPrevented)) {
67
- if ((e.metaKey || e.ctrlKey) && !e.altKey && (e.key.toLowerCase() === "o" || e.key === "ArrowDown")) {
68
- e.preventDefault(), m(this, "vf-open", {});
65
+ }, this.#F = (t) => {
66
+ if (this.#S(), !(this._editing || t.defaultPrevented)) {
67
+ if ((t.metaKey || t.ctrlKey) && !t.altKey && (t.key.toLowerCase() === "o" || t.key === "ArrowDown")) {
68
+ t.preventDefault(), e(this, "vf-open", {});
69
69
  return;
70
70
  }
71
- switch (e.key) {
71
+ switch (t.key) {
72
72
  case "Enter":
73
73
  if (!this.editable) return;
74
- e.preventDefault(), this.startEditing();
74
+ t.preventDefault(), this.startEditing();
75
75
  return;
76
76
  case " ":
77
77
  if (!this.selectable) return;
78
- e.preventDefault(), this.focusRule.reveal(), this.#D(!this.selected);
78
+ t.preventDefault(), this.focusRule.reveal(), this.#D(!this.selected);
79
79
  return;
80
80
  case "ArrowLeft":
81
81
  case "ArrowRight":
82
82
  case "ArrowUp":
83
83
  case "ArrowDown": {
84
84
  if (!this.movable) return;
85
- e.preventDefault(), this.focusRule.reveal();
86
- let t = e.shiftKey ? T : w, n = e.key === "ArrowLeft" ? -t : e.key === "ArrowRight" ? t : 0, r = e.key === "ArrowUp" ? -t : e.key === "ArrowDown" ? t : 0;
85
+ t.preventDefault(), this.focusRule.reveal();
86
+ let e = t.shiftKey ? T : w, n = t.key === "ArrowLeft" ? -e : t.key === "ArrowRight" ? e : 0, r = t.key === "ArrowUp" ? -e : t.key === "ArrowDown" ? e : 0;
87
87
  this.#m();
88
88
  let i = this.#u.seed();
89
89
  this.#u.moveTo(i.x + n, i.y + r);
@@ -93,7 +93,7 @@ var C = {
93
93
  };
94
94
  }
95
95
  static {
96
- this.styles = [l, v`
96
+ this.styles = [u, v`
97
97
  :host {
98
98
  display: inline-block;
99
99
  cursor: var(--vf-cursor, default);
@@ -128,6 +128,13 @@ var C = {
128
128
  :host([selected]) .art {
129
129
  filter: invert(1);
130
130
  }
131
+ /* A color icon's selection darkens instead — ttSelected, colors
132
+ blended halfway toward black — since a photographic negative was
133
+ never what System 7 showed for color art (see the class doc). One
134
+ treatment for whatever the cell shows, the open ghost included. */
135
+ :host([selected][color]) .art {
136
+ filter: brightness(0.5);
137
+ }
131
138
  /* The open ghost replaces the slotted art while there is one — the
132
139
  slot stays in the tree (it is where the art loads and re-loads
133
140
  from) but paints nothing. Gated on the class, not :host([open]):
@@ -154,7 +161,7 @@ var C = {
154
161
  margin-top: calc(var(--vf-scale, 1) * var(--vf-icon-gap, 2px));
155
162
  }
156
163
  .label {
157
- ${c}
164
+ ${l}
158
165
  font-weight: var(--vf-font-weight, 700);
159
166
  /* Whole system px, never a ratio — layout contract rule 2. 12, not
160
167
  the face's 16px em: the Finder's plate is 12 system px tall, and
@@ -242,7 +249,7 @@ var C = {
242
249
  selection paint at this edge, which is the whole reason it has no
243
250
  border of its own (see .rename-box). */
244
251
  height: calc(var(--vf-scale, 1) * var(--vf-icon-label-height, 12px));
245
- ${c}
252
+ ${l}
246
253
  font-weight: var(--vf-font-weight, 700);
247
254
  line-height: calc(
248
255
  var(--vf-scale, 1) * var(--vf-icon-label-height, 12px)
@@ -285,12 +292,12 @@ var C = {
285
292
  as a visible focus (see focus-modality.ts). */
286
293
  .caption.focus-rule .label::after {
287
294
  --vf-focus-underline-offset: -2px;
288
- ${u}
295
+ ${d}
289
296
  }
290
297
  /* No name, no plate — the rule falls back to the art cell. */
291
298
  .art.focus-rule::after {
292
299
  --vf-focus-underline-offset: -2px;
293
- ${u}
300
+ ${d}
294
301
  }
295
302
  :host(:focus) {
296
303
  outline: none;
@@ -327,7 +334,7 @@ var C = {
327
334
  }
328
335
  #p;
329
336
  #m() {
330
- this.#p ||= s(this, `vf-icon${this.label ? ` ("${this.label}")` : ""}`, "<vf-icon movable label=\"Read Me\" width=\"64\" top=\"16\" left=\"16\">");
337
+ this.#p ||= c(this, `vf-icon${this.label ? ` ("${this.label}")` : ""}`, "<vf-icon movable label=\"Read Me\" width=\"64\" top=\"16\" left=\"16\">");
331
338
  }
332
339
  firstUpdated() {
333
340
  document.fonts.ready.then(() => this.#h());
@@ -343,7 +350,7 @@ var C = {
343
350
  let n = document.createRange();
344
351
  n.selectNodeContents(e), t = n.getBoundingClientRect().width, n.detach();
345
352
  }
346
- let r = t / n(this) + 2, i = Math.max(2, Math.ceil(r / 2) * 2);
353
+ let n = t / r(this) + 2, i = Math.max(2, Math.ceil(n / 2) * 2);
347
354
  this.#e = this._editing && t === 0 ? Math.max(i, C[this.size]) : i, e.style.width = this.#g;
348
355
  }
349
356
  get #g() {
@@ -392,18 +399,18 @@ var C = {
392
399
  commitEditing() {
393
400
  if (!this._editing) return;
394
401
  this._editing = !1;
395
- let e = this.#a, t = this._draft;
396
- if (t.trim() === "") {
397
- this._draft = e, t !== e && m(this, "vf-name-rejected", {
398
- attempted: t,
399
- kept: e,
402
+ let t = this.#a, n = this._draft;
403
+ if (n.trim() === "") {
404
+ this._draft = t, n !== t && e(this, "vf-name-rejected", {
405
+ attempted: n,
406
+ kept: t,
400
407
  reason: "empty"
401
408
  });
402
409
  return;
403
410
  }
404
- t !== e && (this.label = t, m(this, "vf-change", {
405
- label: t,
406
- previous: e
411
+ n !== t && (this.label = n, e(this, "vf-change", {
412
+ label: n,
413
+ previous: t
407
414
  }));
408
415
  }
409
416
  cancelEditing() {
@@ -469,39 +476,42 @@ var C = {
469
476
  #E() {
470
477
  this.hasAttribute("tabindex") || (this.#T ? this.tabIndex = 0 : this.removeAttribute("tabindex"));
471
478
  }
472
- #D(e) {
473
- e !== this.selected && (this.selected = e, m(this, "vf-select", { selected: e }));
479
+ #D(t) {
480
+ t !== this.selected && (this.selected = t, e(this, "vf-select", { selected: t }));
474
481
  }
475
482
  #O;
476
483
  #k;
477
484
  #A;
478
485
  #j;
479
486
  #M;
480
- #N(e) {
481
- m(this, "vf-name-too-long", {
482
- attempted: e,
483
- accepted: e.slice(0, this.maxlength),
487
+ #N(t) {
488
+ e(this, "vf-name-too-long", {
489
+ attempted: t,
490
+ accepted: t.slice(0, this.maxlength),
484
491
  limit: this.maxlength
485
492
  });
486
493
  }
487
494
  #P;
488
495
  #F;
489
496
  };
490
- i([x()], D.prototype, "label", void 0), i([x({ reflect: !0 })], D.prototype, "size", void 0), i([x({
497
+ a([x()], D.prototype, "label", void 0), a([x({ reflect: !0 })], D.prototype, "size", void 0), a([x({
498
+ type: Boolean,
499
+ reflect: !0
500
+ })], D.prototype, "selectable", void 0), a([x({
491
501
  type: Boolean,
492
502
  reflect: !0
493
- })], D.prototype, "selectable", void 0), i([x({
503
+ })], D.prototype, "selected", void 0), a([x({
494
504
  type: Boolean,
495
505
  reflect: !0
496
- })], D.prototype, "selected", void 0), i([x({
506
+ })], D.prototype, "color", void 0), a([x({
497
507
  type: Boolean,
498
508
  reflect: !0
499
- })], D.prototype, "open", void 0), i([x({
509
+ })], D.prototype, "open", void 0), a([x({
500
510
  type: Boolean,
501
511
  reflect: !0
502
- })], D.prototype, "movable", void 0), i([x({
512
+ })], D.prototype, "movable", void 0), a([x({
503
513
  type: Boolean,
504
514
  reflect: !0
505
- })], D.prototype, "editable", void 0), i([x({ type: Number })], D.prototype, "width", void 0), i([x({ type: Number })], D.prototype, "maxlength", void 0), i([S()], D.prototype, "_editing", void 0), i([S()], D.prototype, "_draft", void 0), i([S()], D.prototype, "_ghost", void 0), D = i([e("vf-icon")], D);
515
+ })], D.prototype, "editable", void 0), a([x({ type: Number })], D.prototype, "width", void 0), a([x({ type: Number })], D.prototype, "maxlength", void 0), a([S()], D.prototype, "_editing", void 0), a([S()], D.prototype, "_draft", void 0), a([S()], D.prototype, "_ghost", void 0), D = a([t("vf-icon")], D);
506
516
  //#endregion
507
517
  export { D as VfIcon };