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.
- package/custom-elements.json +204 -7
- package/dist/components/vf-button.js +25 -25
- package/dist/components/vf-checkbox.js +15 -15
- package/dist/components/vf-desktop.d.ts +51 -3
- package/dist/components/vf-desktop.js +57 -48
- package/dist/components/vf-icon.d.ts +19 -4
- package/dist/components/vf-icon.js +65 -55
- package/dist/components/vf-list-item.js +16 -16
- package/dist/components/vf-list.js +26 -26
- package/dist/components/vf-menu-bar.d.ts +8 -0
- package/dist/components/vf-menu-bar.js +5 -2
- package/dist/components/vf-menu-item.d.ts +12 -6
- package/dist/components/vf-menu-item.js +47 -29
- package/dist/components/vf-menu.d.ts +14 -1
- package/dist/components/vf-menu.js +85 -65
- package/dist/components/vf-number-field.js +17 -17
- package/dist/components/vf-radio-group.js +13 -13
- package/dist/components/vf-radio.js +16 -16
- package/dist/components/vf-select.js +27 -27
- package/dist/components/vf-slider.js +24 -24
- package/dist/components/vf-window.d.ts +26 -0
- package/dist/components/vf-window.js +105 -56
- package/dist/index.js +29 -29
- package/dist/modal-dialog.js +21 -21
- package/dist/text-control.js +11 -11
- package/dist/toggle-control.js +5 -5
- package/docs/SPEC.md +16 -11
- package/editor/vscode.html-custom-data.json +20 -5
- package/editor/web-types.json +67 -10
- package/package.json +4 -1
|
@@ -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
|
|
203
|
-
*
|
|
204
|
-
*
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import i from "../
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
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
|
|
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
|
-
],
|
|
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 =
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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, ${
|
|
114
|
-
${
|
|
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, ${
|
|
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) * ${
|
|
179
|
-
height: calc(var(--vf-scale, 1) * ${
|
|
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: ${
|
|
187
|
+
clip-path: ${w(b(y, "left"))};
|
|
187
188
|
}
|
|
188
189
|
.corner.tr {
|
|
189
190
|
right: 0;
|
|
190
|
-
clip-path: ${
|
|
191
|
+
clip-path: ${w(b(y, "right"))};
|
|
191
192
|
}
|
|
192
193
|
`
|
|
193
194
|
];
|
|
194
195
|
}
|
|
195
196
|
fitWithin(e, t) {
|
|
196
|
-
let
|
|
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 ?
|
|
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 ?
|
|
241
|
+
n.style.zIndex = String(++this._zCounter + (e ? D : 0)), e || (t = n);
|
|
235
242
|
}
|
|
236
|
-
let n =
|
|
237
|
-
|
|
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.
|
|
243
|
-
|
|
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(
|
|
247
|
-
|
|
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 =
|
|
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",
|
|
281
|
-
let e = this.width ??
|
|
282
|
-
this.style.width =
|
|
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 ??
|
|
287
|
-
${
|
|
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:
|
|
290
|
-
tile:
|
|
298
|
+
rows: r,
|
|
299
|
+
tile: P
|
|
291
300
|
})}
|
|
292
|
-
</div>` :
|
|
301
|
+
</div>` : C`<div
|
|
293
302
|
class="vf-tile-raster"
|
|
294
|
-
style="width:${
|
|
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
|
|
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 ?
|
|
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
|
-
|
|
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 {
|
|
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
|
|
75
|
-
* System 7
|
|
76
|
-
*
|
|
77
|
-
*
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import i from "../
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
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
|
|
22
|
-
constructor(...
|
|
23
|
-
super(...
|
|
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 -
|
|
30
|
-
y: E(t, n.height -
|
|
31
|
-
}), this.#u = new
|
|
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
|
|
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 ||
|
|
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 = (
|
|
66
|
-
if (this.#S(), !(this._editing ||
|
|
67
|
-
if ((
|
|
68
|
-
|
|
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 (
|
|
71
|
+
switch (t.key) {
|
|
72
72
|
case "Enter":
|
|
73
73
|
if (!this.editable) return;
|
|
74
|
-
|
|
74
|
+
t.preventDefault(), this.startEditing();
|
|
75
75
|
return;
|
|
76
76
|
case " ":
|
|
77
77
|
if (!this.selectable) return;
|
|
78
|
-
|
|
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
|
-
|
|
86
|
-
let
|
|
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 = [
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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 ||=
|
|
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
|
|
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
|
|
396
|
-
if (
|
|
397
|
-
this._draft =
|
|
398
|
-
attempted:
|
|
399
|
-
kept:
|
|
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
|
-
|
|
405
|
-
label:
|
|
406
|
-
previous:
|
|
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(
|
|
473
|
-
|
|
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(
|
|
481
|
-
|
|
482
|
-
attempted:
|
|
483
|
-
accepted:
|
|
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
|
-
|
|
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, "
|
|
503
|
+
})], D.prototype, "selected", void 0), a([x({
|
|
494
504
|
type: Boolean,
|
|
495
505
|
reflect: !0
|
|
496
|
-
})], D.prototype, "
|
|
506
|
+
})], D.prototype, "color", void 0), a([x({
|
|
497
507
|
type: Boolean,
|
|
498
508
|
reflect: !0
|
|
499
|
-
})], D.prototype, "open", void 0),
|
|
509
|
+
})], D.prototype, "open", void 0), a([x({
|
|
500
510
|
type: Boolean,
|
|
501
511
|
reflect: !0
|
|
502
|
-
})], D.prototype, "movable", void 0),
|
|
512
|
+
})], D.prototype, "movable", void 0), a([x({
|
|
503
513
|
type: Boolean,
|
|
504
514
|
reflect: !0
|
|
505
|
-
})], D.prototype, "editable", void 0),
|
|
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 };
|