vintage-frames 0.18.0 → 0.19.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.
Files changed (47) hide show
  1. package/README.md +1 -1
  2. package/custom-elements.json +278 -51
  3. package/dist/build/app-file.d.ts +2 -2
  4. package/dist/build/app-file.js +1 -0
  5. package/dist/build/plugins.d.ts +2 -2
  6. package/dist/build/plugins.js +62 -59
  7. package/dist/components/vf-icon.d.ts +7 -0
  8. package/dist/components/vf-icon.js +101 -81
  9. package/dist/components/vf-menu-bar.d.ts +6 -4
  10. package/dist/components/vf-menu-bar.js +26 -56
  11. package/dist/components/vf-menu-item.d.ts +33 -5
  12. package/dist/components/vf-menu-item.js +128 -61
  13. package/dist/components/vf-menu.d.ts +35 -0
  14. package/dist/components/vf-menu.js +171 -111
  15. package/dist/glyphs.d.ts +6 -0
  16. package/dist/glyphs.js +18 -14
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.js +15 -14
  19. package/dist/menu-navigation.d.ts +34 -0
  20. package/dist/menu-navigation.js +53 -0
  21. package/dist/menu-press.d.ts +25 -7
  22. package/dist/menu-press.js +78 -44
  23. package/dist/motion.d.ts +10 -0
  24. package/dist/shell/app-file.d.ts +20 -4
  25. package/dist/shell/app-file.js +65 -53
  26. package/dist/shell/catalog.d.ts +79 -1
  27. package/dist/shell/catalog.js +206 -153
  28. package/dist/shell/finder.d.ts +28 -9
  29. package/dist/shell/finder.js +339 -267
  30. package/dist/shell/geometry.d.ts +7 -0
  31. package/dist/shell/geometry.js +19 -3
  32. package/dist/shell/index.d.ts +4 -4
  33. package/dist/shell/index.js +12 -12
  34. package/dist/shell/pure.d.ts +1 -1
  35. package/dist/shell/pure.js +6 -6
  36. package/dist/shell/shell.d.ts +14 -10
  37. package/dist/shell/shell.js +148 -116
  38. package/dist/shell/version.d.ts +1 -1
  39. package/dist/shell/version.js +1 -1
  40. package/dist/styles/body-italic-font.d.ts +2 -0
  41. package/dist/styles/body-italic-font.js +10 -0
  42. package/dist/styles/register-embedded-font.d.ts +5 -4
  43. package/dist/styles/register-embedded-font.js +11 -10
  44. package/docs/SPEC.md +11 -7
  45. package/editor/vscode.html-custom-data.json +15 -5
  46. package/editor/web-types.json +55 -9
  47. package/package.json +7 -3
@@ -1,41 +1,41 @@
1
- import { inspectAppFile as e, isVersion as t, satisfies as n } from "../shell/app-file.js";
2
- import { VERSION as r } from "../shell/version.js";
3
- import { packApp as i } from "./app-file.js";
4
- import { mkdir as a, readFile as o, writeFile as s } from "node:fs/promises";
5
- import { join as c, relative as l, resolve as u } from "node:path";
1
+ import { VERSION as e } from "../shell/version.js";
2
+ import { appRuns as t, inspectAppFile as n, isVersion as r, satisfies as i } from "../shell/app-file.js";
3
+ import { packApp as a } from "./app-file.js";
4
+ import { mkdir as o, readFile as s, writeFile as c } from "node:fs/promises";
5
+ import { join as l, relative as u, resolve as d } from "node:path";
6
6
  //#region src/build/plugins.ts
7
- var d = [
7
+ var f = [
8
8
  "vintage-frames",
9
9
  "vintage-frames/shell",
10
10
  "vintage-frames/shell/pure"
11
- ], f = "app-code";
12
- function p(e) {
11
+ ], p = "app-code";
12
+ function m(e) {
13
13
  let t = e.match(/(?<=[\\/]node_modules[\\/])(?:@[^\\/]+[\\/])?[^\\/]+/g)?.at(-1)?.replace("\\", "/");
14
14
  return t === "vintage-frames" ? "a copy of vintage-frames" : t && /^(?:lit|lit-html|lit-element|@lit\/.+|@lit-labs\/.+)$/.test(t) ? `Lit (${t})` : null;
15
15
  }
16
- async function m(e) {
17
- let n = JSON.parse(await o(c(e, "package.json"), "utf8")), i = n.devDependencies?.["vintage-frames"] ?? n.dependencies?.["vintage-frames"];
16
+ async function h(t) {
17
+ let n = JSON.parse(await s(l(t, "package.json"), "utf8")), i = n.devDependencies?.["vintage-frames"] ?? n.dependencies?.["vintage-frames"];
18
18
  if (typeof i != "string") throw Error("package.json has no vintage-frames dev dependency");
19
- if (!i.startsWith("^") || !t(i.slice(1))) throw Error(`package.json's vintage-frames range is "${i}", and an app file requires a caret range: ^${r}`);
19
+ if (!i.startsWith("^") || !r(i.slice(1))) throw Error(`package.json's vintage-frames range is "${i}", and an app file requires a caret range: ^${e}`);
20
20
  return i;
21
21
  }
22
- function h(e) {
23
- let { app: l, entry: f, icon: h, artwork: g, copyTo: _ } = e;
22
+ function g(t) {
23
+ let { app: n, entry: u, icon: p, artwork: g, copyTo: _ } = t;
24
24
  for (let e of [
25
25
  "id",
26
26
  "name",
27
27
  "version",
28
28
  "author"
29
- ]) if (typeof l?.[e] != "string" || !l[e]) throw Error(`vintage-frames appFile(): app.${e} is missing`);
30
- if (!t(l.version)) throw Error(`vintage-frames appFile(): app.version, ${l.version}, is not a version`);
31
- if (!f || !h) throw Error(`vintage-frames appFile(): ${f ? "icon" : "entry"} is missing`);
32
- let v = `${l.name.replace(/[\\/:*?"<>|]/g, "-")}.png`, y = "", b = null;
29
+ ]) if (typeof n?.[e] != "string" || !n[e]) throw Error(`vintage-frames appFile(): app.${e} is missing`);
30
+ if (!r(n.version)) throw Error(`vintage-frames appFile(): app.version, ${n.version}, is not a version`);
31
+ if (!u || !p) throw Error(`vintage-frames appFile(): ${u ? "icon" : "entry"} is missing`);
32
+ let v = `${n.name.replace(/[\\/:*?"<>|]/g, "-")}.png`, y = "", b = null;
33
33
  return {
34
34
  name: "vintage-frames:app-file",
35
35
  apply: "build",
36
36
  config: () => ({ build: {
37
37
  lib: {
38
- entry: f,
38
+ entry: u,
39
39
  formats: ["es"],
40
40
  fileName: "app"
41
41
  },
@@ -50,44 +50,44 @@ function h(e) {
50
50
  },
51
51
  buildStart() {
52
52
  for (let e of [
53
- h,
53
+ p,
54
54
  g,
55
55
  "package.json"
56
- ]) e && this.addWatchFile(u(y, e));
56
+ ]) e && this.addWatchFile(d(y, e));
57
57
  },
58
58
  generateBundle: {
59
59
  order: "post",
60
- async handler(e, t) {
61
- let a = Object.values(t), s = a.filter((e) => e.type === "chunk"), c = a.filter((e) => e.type === "asset").map((e) => e.fileName);
62
- c.length && this.error(`${l.name} emits ${c.join(", ")} beside its code, and an app file holds one module: no CSS import, no source map file, its art inlined.`);
63
- let [f] = s;
64
- (!f || s.length > 1) && this.error(`${l.name} builds to ${s.length} modules, and an app file holds one.`);
65
- for (let e of Object.keys(f.modules)) {
66
- let t = p(e);
67
- t && this.error(`${l.name} bundles ${t}. It composes the page's kit and brings none of its own.`);
60
+ async handler(t, r) {
61
+ let o = Object.values(r), c = o.filter((e) => e.type === "chunk"), l = o.filter((e) => e.type === "asset").map((e) => e.fileName);
62
+ l.length && this.error(`${n.name} emits ${l.join(", ")} beside its code, and an app file holds one module: no CSS import, no source map file, its art inlined.`);
63
+ let [u] = c;
64
+ (!u || c.length > 1) && this.error(`${n.name} builds to ${c.length} modules, and an app file holds one.`);
65
+ for (let e of Object.keys(u.modules)) {
66
+ let t = m(e);
67
+ t && this.error(`${n.name} bundles ${t}. It composes the page's kit and brings none of its own.`);
68
68
  }
69
- let _ = [...f.imports, ...f.dynamicImports].filter((e) => !d.includes(e));
70
- _.length && this.error(`${l.name} imports ${_.join(", ")}. An application imports ${d.join(", ")} and its own files.`);
69
+ let _ = [...u.imports, ...u.dynamicImports].filter((e) => !f.includes(e));
70
+ _.length && this.error(`${n.name} imports ${_.join(", ")}. An application imports ${f.join(", ")} and its own files.`);
71
71
  try {
72
- let e = await m(y);
73
- if (!n("0.18.0", e)) throw Error(`package.json requires vintage-frames ${e}, and the build is on ${r}: move the range`);
74
- b = await i({
72
+ let t = await h(y);
73
+ if (!i("0.19.1", t)) throw Error(`package.json requires vintage-frames ${t}, and the build is on ${e}: move the range`);
74
+ b = await a({
75
75
  manifest: {
76
- id: l.id,
77
- name: l.name,
78
- version: l.version,
79
- requires: e,
80
- author: l.author,
81
- description: l.description
76
+ id: n.id,
77
+ name: n.name,
78
+ version: n.version,
79
+ requires: t,
80
+ author: n.author,
81
+ description: n.description
82
82
  },
83
- icon: new Uint8Array(await o(u(y, h))),
84
- code: f.code,
85
- artwork: g ? new Uint8Array(await o(u(y, g))) : void 0
83
+ icon: new Uint8Array(await s(d(y, p))),
84
+ code: u.code,
85
+ artwork: g ? new Uint8Array(await s(d(y, g))) : void 0
86
86
  });
87
87
  } catch (e) {
88
- this.error(`${l.name}: ${e.message}`);
88
+ this.error(`${n.name}: ${e.message}`);
89
89
  }
90
- delete t[f.fileName], this.emitFile({
90
+ delete r[u.fileName], this.emitFile({
91
91
  type: "asset",
92
92
  fileName: v,
93
93
  source: b
@@ -96,31 +96,34 @@ function h(e) {
96
96
  },
97
97
  async writeBundle() {
98
98
  if (!_ || !b) return;
99
- let e = u(y, _);
100
- await a(e, { recursive: !0 }), await s(c(e, v), b);
99
+ let e = d(y, _);
100
+ await o(e, { recursive: !0 }), await c(l(e, v), b);
101
101
  }
102
102
  };
103
103
  }
104
- function g() {
105
- let t = "";
104
+ function _(t) {
105
+ return t.api === void 0 ? `requires vintage-frames ${t.requires}, and this site has ${e}` : `is built for app API ${t.api}, and this site's kit runs app API 2`;
106
+ }
107
+ function v() {
108
+ let r = "";
106
109
  return {
107
110
  name: "vintage-frames:app-files",
108
111
  enforce: "pre",
109
112
  configResolved(e) {
110
- t = e.root;
113
+ r = e.root;
111
114
  },
112
115
  async load(i) {
113
116
  let a = i.indexOf("?");
114
117
  if (a < 0) return null;
115
- let s = i.slice(0, a), c = new URLSearchParams(i.slice(a + 1));
116
- if (!s.endsWith(".png") || !(c.has("app") || c.has(f))) return null;
117
- this.addWatchFile(s);
118
- let u = l(t, s), d = await e(new Uint8Array(await o(s)));
119
- typeof d == "string" && this.error(`${u} is not an app file: ${d}.`);
120
- let { manifest: p, code: m } = d;
121
- return c.has(f) ? m : (n("0.18.0", p.requires) || this.error(`${u}: ${p.name} ${p.version} requires vintage-frames ${p.requires}, and this site has ${r}. Build ${p.name} on ${r} and copy its app file in.`), [
122
- `import factory from ${JSON.stringify(`${s}?${f}`)}`,
123
- `export const manifest = ${JSON.stringify(p)}`,
118
+ let o = i.slice(0, a), c = new URLSearchParams(i.slice(a + 1));
119
+ if (!o.endsWith(".png") || !(c.has("app") || c.has(p))) return null;
120
+ this.addWatchFile(o);
121
+ let l = u(r, o), d = await n(new Uint8Array(await s(o)));
122
+ typeof d == "string" && this.error(`${l} is not an app file: ${d}.`);
123
+ let { manifest: f, code: m } = d;
124
+ return c.has(p) ? m : (t(f) || this.error(`${l}: ${f.name} ${f.version} ${_(f)}. Build ${f.name} on ${e} and copy its app file in.`), [
125
+ `import factory from ${JSON.stringify(`${o}?${p}`)}`,
126
+ `export const manifest = ${JSON.stringify(f)}`,
124
127
  "export default (...args) => ({ ...factory(...args), icon: manifest.icon })",
125
128
  ""
126
129
  ].join("\n"));
@@ -128,4 +131,4 @@ function g() {
128
131
  };
129
132
  }
130
133
  //#endregion
131
- export { h as appFile, g as appFiles };
134
+ export { g as appFile, v as appFiles };
@@ -1,4 +1,5 @@
1
1
  import { LitElement } from 'lit';
2
+ import '../styles/body-italic-font.js';
2
3
  /** Which member of the icon family paints — the two System 7 resource sizes. */
3
4
  export type VfIconSize = 'large' | 'small';
4
5
  /**
@@ -523,6 +524,12 @@ export declare class VfIcon extends VfIcon_base {
523
524
  * Selection inverts the ghost exactly as it inverts the art.
524
525
  */
525
526
  open: boolean;
527
+ /**
528
+ * The icon is an alias, an item standing for another: its name is set in
529
+ * italics, the body face's own, and the plate widens to the slant's last
530
+ * pixel.
531
+ */
532
+ alias: boolean;
526
533
  /**
527
534
  * Drag to move — `movable`, never `draggable`, which is a platform attribute
528
535
  * and accessor (see the class doc). Arrow keys move a focused icon too, which
@@ -13,28 +13,29 @@ import { DragController as g } from "../drag.js";
13
13
  import { dragSlop as _, prefersReducedMotion as v, runOutlineTravel as y } from "../motion.js";
14
14
  import { deriveDragOutline as b, deriveOpenArt as x, dotOutline as S, penPhase as C, xorPenCanvas as w } from "../open-art.js";
15
15
  import { FocusRuleController as T } from "../focus-modality.js";
16
+ import "../styles/body-italic-font.js";
16
17
  import { LitElement as E, css as D, html as O, nothing as k } from "lit";
17
18
  import { property as A, state as j } from "lit/decorators.js";
18
19
  //#region src/components/vf-icon.ts
19
20
  var M, N = {
20
21
  large: 32,
21
22
  small: 16
22
- }, P = 1, F = 8, I = (e, t, n) => n <= t ? Math.max(e, t) : Math.min(Math.max(e, t), n), L = "vf-icon-field, [role=\"listbox\"]", R = (e) => e instanceof Element && e.matches(L), z = class extends c(E) {
23
+ }, P, F = 1, I = 8, L = (e, t, n) => n <= t ? Math.max(e, t) : Math.min(Math.max(e, t), n), R = "vf-icon-field, [role=\"listbox\"]", z = (e) => e instanceof Element && e.matches(R), B = class extends c(E) {
23
24
  static {
24
25
  M = this;
25
26
  }
26
27
  constructor(...t) {
27
- super(...t), this.label = "", this.size = "large", this.selectable = !1, this.selected = !1, this.target = !1, this.color = !1, this.open = !1, this.movable = !1, this.editable = !1, this.maxlength = 31, this.scale = new n(this), this.gridSnap = new m(this), this.focusRule = new T(this), this._editing = !1, this._draft = "", this.#e = 0, this._ghost = null, this.#t = null, this.#n = this.attachInternals(), this.#a = !1, this.#o = "", this.#s = "", this.#c = 0, this.#l = -Infinity, this.#u = !1, this.#d = null, this.#f = null, this.#p = new h(this, () => [[
28
+ super(...t), this.label = "", this.size = "large", this.selectable = !1, this.selected = !1, this.target = !1, this.color = !1, this.open = !1, this.alias = !1, this.movable = !1, this.editable = !1, this.maxlength = 31, this.scale = new n(this), this.gridSnap = new m(this), this.focusRule = new T(this), this._editing = !1, this._draft = "", this.#e = 0, this._ghost = null, this.#t = null, this.#n = this.attachInternals(), this.#a = !1, this.#o = "", this.#s = "", this.#c = 0, this.#l = -Infinity, this.#u = !1, this.#d = null, this.#f = null, this.#p = new h(this, () => [[
28
29
  document,
29
30
  "pointerdown",
30
- this.#ne,
31
+ this.#re,
31
32
  !0
32
33
  ]]), this.#m = (e, t, n) => this.#h() ? {
33
34
  x: Math.max(e, 0),
34
35
  y: Math.max(t, n.top)
35
36
  } : {
36
- x: I(e, 0, n.width - a(this.offsetWidth, this)),
37
- y: I(t, n.top, n.height - a(this.offsetHeight, this))
37
+ x: L(e, 0, n.width - a(this.offsetWidth, this)),
38
+ y: L(t, n.top, n.height - a(this.offsetHeight, this))
38
39
  }, this.#g = new s(this, (e, t, n) => this.#m(e, t, n)), this.#_ = null, this.#v = new g(this, {
39
40
  onDragStart: (e) => {
40
41
  if (!this.movable || e.button !== 0 || this._editing) return null;
@@ -85,20 +86,20 @@ var M, N = {
85
86
  this.#x?.finish();
86
87
  }, this.#w = (e) => {
87
88
  e.key !== "Escape" || !this.#x || (e.preventDefault(), e.stopPropagation(), this.#x.finish());
88
- }, this.#I = !1, this.#B = () => {
89
- this.#H(), this.#q();
90
- }, this.#V = () => {
91
- this.#U();
92
- }, this.#K = () => {
89
+ }, this.#I = !1, this.#V = () => {
90
+ this.#U(), this.#J();
91
+ }, this.#H = () => {
92
+ this.#W();
93
+ }, this.#q = () => {
93
94
  queueMicrotask(() => {
94
95
  if (!this._editing) return;
95
96
  let e = this.renderRoot.querySelector("input");
96
97
  e && this.renderRoot.activeElement === e || this.commitEditing();
97
98
  });
98
- }, this.#Q = (e) => {
99
+ }, this.#$ = (e) => {
99
100
  if (e.button !== 0 || this._editing) return;
100
101
  let t = e.composedPath().some((e) => e instanceof HTMLElement && e.classList.contains("label")), n = this.selected, r = e.timeStamp - this.#l < 800;
101
- this.#l = e.timeStamp, this.#G();
102
+ this.#l = e.timeStamp, this.#K();
102
103
  let i = this.#f;
103
104
  this.#f = null, this.#u = e.pointerType !== "mouse", this.#d = this.#u && e.isPrimary ? {
104
105
  pointerId: e.pointerId,
@@ -108,44 +109,44 @@ var M, N = {
108
109
  second: i !== null && e.timeStamp - i.time <= 500 && Math.hypot(e.clientX - i.x, e.clientY - i.y) <= 24
109
110
  } : null;
110
111
  let a = !e.shiftKey && !e.metaKey;
111
- this.selectable && (a ? this.#Z(!0) : this.#Z(!this.selected)), this.#a = a && n && this.#i !== null, this.editable && t && n && !r && !e.shiftKey && !e.metaKey && this.#W(), this.#Y && (this.focus({ preventScroll: !0 }), this.focusRule.suppress()), this.#v.onPointerDown(e);
112
- }, this.#$ = () => {
112
+ this.selectable && (a ? this.#Q(!0) : this.#Q(!this.selected)), this.#a = a && n && this.#i !== null, this.editable && t && n && !r && !e.shiftKey && !e.metaKey && this.#G(), this.#X && (this.focus({ preventScroll: !0 }), this.focusRule.suppress()), this.#v.onPointerDown(e);
113
+ }, this.#ee = () => {
113
114
  this._editing || this.#u || e(this, "vf-open", {});
114
- }, this.#ee = (t) => {
115
+ }, this.#te = (t) => {
115
116
  let n = this.#_?.proposal != null;
116
117
  this.#v.onPointerUp(t);
117
- let r = this.#te(t, n);
118
+ let r = this.#ne(t, n);
118
119
  if (this.#a) {
119
120
  this.#a = !1;
120
121
  let e = t.type === "pointercancel" ? null : this.#i;
121
122
  for (let t of e?.querySelectorAll("vf-icon") ?? []) t !== this && t.selected && t.setSelected(!1);
122
123
  }
123
124
  r && e(this, "vf-open", {});
124
- }, this.#ne = (e) => {
125
+ }, this.#re = (e) => {
125
126
  let t = e.composedPath();
126
- if (t.includes(this) || (this.#G(), this.#f = null, e.shiftKey || e.metaKey)) return;
127
+ if (t.includes(this) || (this.#K(), this.#f = null, e.shiftKey || e.metaKey)) return;
127
128
  let n = this.#i;
128
129
  if (n !== null) {
129
130
  let e = t.find((e) => e instanceof M);
130
- if (!e && !t.some(R) || e?.selected && e.#i === n) return;
131
+ if (!e && !t.some(z) || e?.selected && e.#i === n) return;
131
132
  }
132
- this.#Z(!1);
133
- }, this.#re = (e) => {
133
+ this.#Q(!1);
134
+ }, this.#ie = (e) => {
134
135
  let t = e.target, n = e.data ?? e.dataTransfer?.getData("text") ?? "";
135
136
  if (n === "") return;
136
137
  let r = t.selectionStart ?? t.value.length, i = t.selectionEnd ?? r, a = t.value.slice(0, r) + n + t.value.slice(i);
137
- a.length > this.maxlength && this.#ae(a);
138
- }, this.#ie = (e) => {
138
+ a.length > this.maxlength && this.#oe(a);
139
+ }, this.#ae = (e) => {
139
140
  let t = e.target;
140
141
  if (t.value.length > this.maxlength) {
141
142
  let e = t.value, n = Math.min(t.selectionStart ?? this.maxlength, this.maxlength);
142
- t.value = e.slice(0, this.maxlength), t.setSelectionRange(n, n), this.#ae(e);
143
+ t.value = e.slice(0, this.maxlength), t.setSelectionRange(n, n), this.#oe(e);
143
144
  }
144
145
  this._draft = t.value;
145
- }, this.#oe = (e) => {
146
+ }, this.#se = (e) => {
146
147
  e.key === "Enter" ? (e.preventDefault(), this.commitEditing(), this.focus()) : e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), this.cancelEditing(), this.focus());
147
- }, this.#se = (t) => {
148
- if (this.#G(), !(this._editing || t.defaultPrevented)) {
148
+ }, this.#ce = (t) => {
149
+ if (this.#K(), !(this._editing || t.defaultPrevented)) {
149
150
  if ((t.metaKey || t.ctrlKey) && !t.altKey && (t.key.toLowerCase() === "o" || t.key === "ArrowDown")) {
150
151
  t.preventDefault(), e(this, "vf-open", {});
151
152
  return;
@@ -157,7 +158,7 @@ var M, N = {
157
158
  return;
158
159
  case " ":
159
160
  if (!this.selectable) return;
160
- t.preventDefault(), this.focusRule.reveal(), this.#Z(!this.selected);
161
+ t.preventDefault(), this.focusRule.reveal(), this.#Q(!this.selected);
161
162
  return;
162
163
  case "ArrowLeft":
163
164
  case "ArrowRight":
@@ -165,7 +166,7 @@ var M, N = {
165
166
  case "ArrowDown": {
166
167
  if (!this.movable) return;
167
168
  t.preventDefault(), this.focusRule.reveal();
168
- let e = t.shiftKey ? F : P, n = t.key === "ArrowLeft" ? -e : t.key === "ArrowRight" ? e : 0, r = t.key === "ArrowUp" ? -e : t.key === "ArrowDown" ? e : 0;
169
+ let e = t.shiftKey ? I : F, n = t.key === "ArrowLeft" ? -e : t.key === "ArrowRight" ? e : 0, r = t.key === "ArrowUp" ? -e : t.key === "ArrowDown" ? e : 0;
169
170
  this.#L();
170
171
  let i = this.#g.seed();
171
172
  this.#g.moveTo(i.x + n, i.y + r);
@@ -302,6 +303,14 @@ var M, N = {
302
303
  padding: 0 calc(var(--vf-scale, 1) * 1px);
303
304
  text-align: left;
304
305
  }
306
+ /* An alias's name, plate and rename field alike: the body face's own
307
+ italic, slanted on the pixel grid. Never a synthesized oblique, which
308
+ would smear it; until the italic loads the name stands upright. */
309
+ :host([alias]) .label,
310
+ :host([alias]) .rename {
311
+ font-style: italic;
312
+ font-synthesis: none;
313
+ }
305
314
  :host([selected]) .name {
306
315
  /* Forced colors: exempt the inverted plate from the mode's text
307
316
  backplate, which would land a Canvas slab on the highlight bar —
@@ -411,7 +420,7 @@ var M, N = {
411
420
  return this.#i !== null;
412
421
  }
413
422
  get #i() {
414
- return this.closest(L);
423
+ return this.closest(R);
415
424
  }
416
425
  #a;
417
426
  #o;
@@ -489,7 +498,7 @@ var M, N = {
489
498
  clientY: r.clientY
490
499
  }, !i.proposal) {
491
500
  if (Math.hypot(r.clientX - i.press.clientX, r.clientY - i.press.clientY) < i.slop || t === i.origin.x && n === i.origin.y) return;
492
- this.#G(), this.#a = !1, i.proposal = {
501
+ this.#K(), this.#a = !1, i.proposal = {
493
502
  left: i.origin.x,
494
503
  top: i.origin.y
495
504
  }, this.#y.attach();
@@ -607,19 +616,19 @@ var M, N = {
607
616
  };
608
617
  }
609
618
  connectedCallback() {
610
- super.connectedCallback(), this.#X(), this.#q(), this.selectable && this.selected && this.#p.attach(), this.addEventListener("keydown", this.#se);
619
+ super.connectedCallback(), this.#Z(), this.#J(), this.selectable && this.selected && this.#p.attach(), this.addEventListener("keydown", this.#ce);
611
620
  }
612
621
  disconnectedCallback() {
613
- super.disconnectedCallback(), this.removeEventListener("keydown", this.#se), this.#G(), this.#_?.outline?.canvas.remove();
622
+ super.disconnectedCallback(), this.removeEventListener("keydown", this.#ce), this.#K(), this.#_?.outline?.canvas.remove();
614
623
  for (let e of this.#_?.followers ?? []) e.end();
615
624
  this.#_ = null, this.#x?.finish();
616
625
  }
617
626
  updated(e) {
618
- if (e.has("selectable") && this.#X(), (e.has("selectable") || e.has("selected") || e.has("label")) && this.#q(), (e.has("selected") || e.has("selectable")) && (this.selectable && this.selected ? this.#p.attach() : this.#p.detach()), e.has("_editing") && this._editing) {
627
+ if (e.has("selectable") && this.#Z(), (e.has("selectable") || e.has("selected") || e.has("label")) && this.#J(), (e.has("selected") || e.has("selectable")) && (this.selectable && this.selected ? this.#p.attach() : this.#p.detach()), e.has("_editing") && this._editing) {
619
628
  let e = this.renderRoot.querySelector("input");
620
629
  e?.focus(), e?.select();
621
630
  }
622
- (e.has("label") || e.has("_draft") || e.has("_editing")) && this.#R(), (e.has("open") || e.has("size")) && this.#H();
631
+ (e.has("label") || e.has("_draft") || e.has("_editing") || e.has("alias")) && this.#R(), (e.has("open") || e.has("size")) && this.#U();
623
632
  }
624
633
  #I;
625
634
  #L() {
@@ -639,15 +648,23 @@ var M, N = {
639
648
  let n = document.createRange();
640
649
  n.selectNodeContents(e), t = n.getBoundingClientRect().width, n.detach();
641
650
  }
642
- let n = t / r(this) + 2, i = Math.max(2, Math.ceil(n / 2) * 2);
643
- this.#e = this._editing && t === 0 ? Math.max(i, N[this.size]) : i, e.style.width = this.#z;
644
- }
645
- get #z() {
651
+ let n = t / r(this) + 2 + (this.alias ? this.#z(e) : 0), i = Math.max(2, Math.ceil(n / 2) * 2);
652
+ this.#e = this._editing && t === 0 ? Math.max(i, N[this.size]) : i, e.style.width = this.#B;
653
+ }
654
+ #z(e) {
655
+ let t = e.textContent ?? "";
656
+ if (P ??= document.createElement("canvas").getContext("2d"), !t || !P) return 0;
657
+ let { fontStyle: n, fontWeight: i, fontSize: a, fontFamily: o } = getComputedStyle(e);
658
+ P.font = `${n} ${i} ${a} ${o}`;
659
+ let s = P.measureText(t);
660
+ return Math.max(0, Math.ceil((s.actualBoundingBoxRight - s.width) / r(this)));
661
+ }
662
+ get #B() {
646
663
  return this.#e ? `calc(var(--vf-scale, 1) * ${this.#e}px)` : "";
647
664
  }
648
- #B;
649
665
  #V;
650
- #H() {
666
+ #H;
667
+ #U() {
651
668
  let e = this.renderRoot?.querySelector(`slot[name='${this.size}']`), t = null;
652
669
  for (let n of e?.assignedElements({ flatten: !0 }) ?? []) {
653
670
  let e = n instanceof HTMLImageElement || n instanceof HTMLCanvasElement ? n : n.querySelector("img, canvas");
@@ -656,9 +673,9 @@ var M, N = {
656
673
  break;
657
674
  }
658
675
  }
659
- t !== this.#t && (this.#t?.removeEventListener("load", this.#V), this.#t?.removeEventListener("error", this.#V), this.#t = t, t?.addEventListener("load", this.#V), t?.addEventListener("error", this.#V)), this.#U();
676
+ t !== this.#t && (this.#t?.removeEventListener("load", this.#H), this.#t?.removeEventListener("error", this.#H), this.#t = t, t?.addEventListener("load", this.#H), t?.addEventListener("error", this.#H)), this.#W();
660
677
  }
661
- #U() {
678
+ #W() {
662
679
  let e = this.#t, t = e instanceof HTMLImageElement ? e.complete && e.naturalWidth > 0 : e != null && e.width > 0;
663
680
  if (!this.open || e == null || !t) {
664
681
  this._ghost = null, this.#o = "";
@@ -674,16 +691,16 @@ var M, N = {
674
691
  }
675
692
  this._ghost = r, this.#o = r ? n : "";
676
693
  }
677
- #W() {
678
- this.#G(), this.#c = window.setTimeout(() => {
694
+ #G() {
695
+ this.#K(), this.#c = window.setTimeout(() => {
679
696
  this.#c = 0, this.startEditing();
680
697
  }, 800);
681
698
  }
682
- #G() {
699
+ #K() {
683
700
  this.#c &&= (clearTimeout(this.#c), 0);
684
701
  }
685
702
  startEditing() {
686
- this.#G(), !(!this.editable || this._editing) && (this.#s = this.label, this._draft = this.label, this._editing = !0);
703
+ this.#K(), !(!this.editable || this._editing) && (this.#s = this.label, this._draft = this.label, this._editing = !0);
687
704
  }
688
705
  commitEditing() {
689
706
  if (!this._editing) return;
@@ -702,7 +719,7 @@ var M, N = {
702
719
  previous: t
703
720
  }));
704
721
  }
705
- #K;
722
+ #q;
706
723
  cancelEditing() {
707
724
  this._editing && (this._editing = !1, this._draft = this.#s);
708
725
  }
@@ -712,15 +729,15 @@ var M, N = {
712
729
  class="frame vf-snap"
713
730
  part="frame"
714
731
  style=${o}
715
- @pointerdown=${this.#Q}
732
+ @pointerdown=${this.#$}
716
733
  @pointermove=${this.#v.onPointerMove}
717
- @pointerup=${this.#ee}
718
- @pointercancel=${this.#ee}
719
- @lostpointercapture=${this.#ee}
720
- @dblclick=${this.#$}
734
+ @pointerup=${this.#te}
735
+ @pointercancel=${this.#te}
736
+ @lostpointercapture=${this.#te}
737
+ @dblclick=${this.#ee}
721
738
  >
722
739
  <div class=${a} part="icon">
723
- ${this.size === "small" ? O`<slot name="small" @slotchange=${this.#B}></slot>` : O`<slot name="large" @slotchange=${this.#B}></slot>`}${this._ghost ?? k}
740
+ ${this.size === "small" ? O`<slot name="small" @slotchange=${this.#V}></slot>` : O`<slot name="large" @slotchange=${this.#V}></slot>`}${this._ghost ?? k}
724
741
  </div>
725
742
  ${r ? O`<div class=${i}>
726
743
  <!-- No whitespace around the span: it is the measured run, and a
@@ -728,7 +745,7 @@ var M, N = {
728
745
  <div class="label" part="label"><span
729
746
  class="name"
730
747
  part="plate"
731
- style=${this.#e ? `width: ${this.#z}` : ""}
748
+ style=${this.#e ? `width: ${this.#B}` : ""}
732
749
  >${t}</span
733
750
  ></div>
734
751
  ${e ? O`<div class="rename-box">
@@ -738,16 +755,16 @@ var M, N = {
738
755
  type="text"
739
756
  maxlength=${this.maxlength}
740
757
  .value=${this._draft}
741
- @beforeinput=${this.#re}
742
- @input=${this.#ie}
743
- @keydown=${this.#oe}
744
- @blur=${this.#K}
758
+ @beforeinput=${this.#ie}
759
+ @input=${this.#ae}
760
+ @keydown=${this.#se}
761
+ @blur=${this.#q}
745
762
  />
746
763
  </div>` : k}
747
764
  </div>` : k}
748
765
  </div>`;
749
766
  }
750
- #q() {
767
+ #J() {
751
768
  if (!this.selectable) {
752
769
  this.#n.role = null, this.#n.ariaSelected = null, this.#n.ariaLabel = null;
753
770
  return;
@@ -756,22 +773,22 @@ var M, N = {
756
773
  this.#n.role = "option", this.#n.ariaSelected = this.selected ? "true" : "false", this.#n.ariaLabel = null;
757
774
  return;
758
775
  }
759
- this.#n.role = "img", this.#n.ariaSelected = null, this.#n.ariaLabel = this.label || this.#J || null;
776
+ this.#n.role = "img", this.#n.ariaSelected = null, this.#n.ariaLabel = this.label || this.#Y || null;
760
777
  }
761
- get #J() {
778
+ get #Y() {
762
779
  return this.#t instanceof HTMLImageElement ? this.#t.alt : "";
763
780
  }
764
- get #Y() {
781
+ get #X() {
765
782
  return this.selectable;
766
783
  }
767
- #X() {
768
- this.hasAttribute("tabindex") || (this.#Y ? this.tabIndex = 0 : this.removeAttribute("tabindex"));
784
+ #Z() {
785
+ this.hasAttribute("tabindex") || (this.#X ? this.tabIndex = 0 : this.removeAttribute("tabindex"));
769
786
  }
770
- #Z(t) {
787
+ #Q(t) {
771
788
  t !== this.selected && (this.selected = t, e(this, "vf-select", { selected: t }));
772
789
  }
773
790
  setSelected(e) {
774
- this.#Z(e);
791
+ this.#Q(e);
775
792
  }
776
793
  touches(e) {
777
794
  let t = this.renderRoot;
@@ -801,10 +818,10 @@ var M, N = {
801
818
  }), this.#x = t, this.#S.attach();
802
819
  })) : (this.#g.moveTo(r.x, r.y), !1);
803
820
  }
804
- #Q;
805
821
  #$;
806
822
  #ee;
807
- #te(e, t) {
823
+ #te;
824
+ #ne(e, t) {
808
825
  let n = this.#d;
809
826
  return !n || n.pointerId !== e.pointerId || (this.#d = null, !(e.type !== "pointercancel" && !t && !this._editing && Math.hypot(e.clientX - n.x, e.clientY - n.y) < _(e))) ? !1 : n.second ? !0 : (this.#f = {
810
827
  time: n.time,
@@ -812,40 +829,43 @@ var M, N = {
812
829
  y: n.y
813
830
  }, !1);
814
831
  }
815
- #ne;
816
832
  #re;
817
833
  #ie;
818
- #ae(t) {
834
+ #ae;
835
+ #oe(t) {
819
836
  e(this, "vf-name-too-long", {
820
837
  attempted: t,
821
838
  accepted: t.slice(0, this.maxlength),
822
839
  limit: this.maxlength
823
840
  });
824
841
  }
825
- #oe;
826
842
  #se;
843
+ #ce;
827
844
  };
828
- o([A()], z.prototype, "label", void 0), o([A({ reflect: !0 })], z.prototype, "size", void 0), o([A({
845
+ o([A()], B.prototype, "label", void 0), o([A({ reflect: !0 })], B.prototype, "size", void 0), o([A({
846
+ type: Boolean,
847
+ reflect: !0
848
+ })], B.prototype, "selectable", void 0), o([A({
829
849
  type: Boolean,
830
850
  reflect: !0
831
- })], z.prototype, "selectable", void 0), o([A({
851
+ })], B.prototype, "selected", void 0), o([A({
832
852
  type: Boolean,
833
853
  reflect: !0
834
- })], z.prototype, "selected", void 0), o([A({
854
+ })], B.prototype, "target", void 0), o([A({
835
855
  type: Boolean,
836
856
  reflect: !0
837
- })], z.prototype, "target", void 0), o([A({
857
+ })], B.prototype, "color", void 0), o([A({
838
858
  type: Boolean,
839
859
  reflect: !0
840
- })], z.prototype, "color", void 0), o([A({
860
+ })], B.prototype, "open", void 0), o([A({
841
861
  type: Boolean,
842
862
  reflect: !0
843
- })], z.prototype, "open", void 0), o([A({
863
+ })], B.prototype, "alias", void 0), o([A({
844
864
  type: Boolean,
845
865
  reflect: !0
846
- })], z.prototype, "movable", void 0), o([A({
866
+ })], B.prototype, "movable", void 0), o([A({
847
867
  type: Boolean,
848
868
  reflect: !0
849
- })], z.prototype, "editable", void 0), o([A({ type: Number })], z.prototype, "width", void 0), o([A({ type: Number })], z.prototype, "maxlength", void 0), o([j()], z.prototype, "_editing", void 0), o([j()], z.prototype, "_draft", void 0), o([j()], z.prototype, "_ghost", void 0), z = M = o([t("vf-icon")], z);
869
+ })], B.prototype, "editable", void 0), o([A({ type: Number })], B.prototype, "width", void 0), o([A({ type: Number })], B.prototype, "maxlength", void 0), o([j()], B.prototype, "_editing", void 0), o([j()], B.prototype, "_draft", void 0), o([j()], B.prototype, "_ghost", void 0), B = M = o([t("vf-icon")], B);
850
870
  //#endregion
851
- export { z as VfIcon };
871
+ export { B as VfIcon };
@@ -7,10 +7,12 @@ declare const VfMenuBar_base: (new (...args: any[]) => import("../position.js").
7
7
  *
8
8
  * Coordinates its menus: pressing a label opens that menu (and inverts the
9
9
  * label); while any menu is open, hovering another label switches to it;
10
- * Escape, an outside click, or item selection closes. ArrowLeft/ArrowRight
11
- * move between menus while one is open; ArrowDown/ArrowUp move focus through
12
- * the open menu's items, Home/End jump to its first/last, and typed letters
13
- * run the shared Finder first-letter type-ahead (src/type-ahead.ts).
10
+ * Escape, an outside click, or item selection closes. While a menu is open
11
+ * the keyboard is src/menu-navigation.ts's: ArrowDown/ArrowUp move focus
12
+ * through the open menu's items, Home/End jump to its first/last, typed
13
+ * letters run the shared Finder first-letter type-ahead (src/type-ahead.ts),
14
+ * ArrowRight opens an item's submenu and ArrowLeft closes it, and at the top
15
+ * level ArrowLeft/ArrowRight move between menus.
14
16
  *
15
17
  * The bar also owns the **press-drag-release** gesture (see src/menu-press.ts)
16
18
  * — press a title, slide onto a command, release over it — because one press