vintage-frames 0.14.1 → 0.16.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.
Files changed (55) hide show
  1. package/custom-elements.json +770 -74
  2. package/dist/chrome.d.ts +10 -1
  3. package/dist/chrome.js +8 -3
  4. package/dist/components/vf-button.d.ts +5 -1
  5. package/dist/components/vf-button.js +1 -1
  6. package/dist/components/vf-desktop.d.ts +5 -2
  7. package/dist/components/vf-desktop.js +5 -5
  8. package/dist/components/vf-dialog.d.ts +13 -2
  9. package/dist/components/vf-dialog.js +27 -27
  10. package/dist/components/vf-menu-bar.js +9 -10
  11. package/dist/components/vf-menu-item.js +18 -13
  12. package/dist/components/vf-menu.d.ts +8 -3
  13. package/dist/components/vf-menu.js +85 -61
  14. package/dist/components/vf-number-field.d.ts +4 -0
  15. package/dist/components/vf-number-field.js +28 -25
  16. package/dist/components/vf-paragraph.d.ts +3 -1
  17. package/dist/components/vf-paragraph.js +7 -0
  18. package/dist/components/vf-scroll-area.d.ts +16 -1
  19. package/dist/components/vf-scroll-area.js +39 -29
  20. package/dist/components/vf-select.d.ts +5 -4
  21. package/dist/components/vf-select.js +26 -17
  22. package/dist/components/vf-text-field.d.ts +5 -5
  23. package/dist/components/vf-text-field.js +1 -1
  24. package/dist/components/vf-window.d.ts +22 -5
  25. package/dist/components/vf-window.js +113 -98
  26. package/dist/cursor.d.ts +8 -0
  27. package/dist/cursor.js +70 -73
  28. package/dist/events.d.ts +3 -2
  29. package/dist/events.js +3 -3
  30. package/dist/index.d.ts +2 -1
  31. package/dist/modal-dialog.d.ts +49 -4
  32. package/dist/modal-dialog.js +115 -87
  33. package/dist/position.js +25 -20
  34. package/dist/shell/alert.d.ts +17 -9
  35. package/dist/shell/alert.js +25 -28
  36. package/dist/shell/catalog.d.ts +1 -1
  37. package/dist/shell/catalog.js +32 -18
  38. package/dist/shell/finder.d.ts +46 -1
  39. package/dist/shell/finder.js +166 -126
  40. package/dist/shell/index.d.ts +2 -4
  41. package/dist/shell/index.js +5 -6
  42. package/dist/shell/pure.d.ts +10 -0
  43. package/dist/shell/pure.js +4 -0
  44. package/dist/shell/shell.d.ts +40 -13
  45. package/dist/shell/shell.js +87 -51
  46. package/dist/shell/windows.d.ts +69 -12
  47. package/dist/shell/windows.js +245 -144
  48. package/dist/text-control.d.ts +30 -1
  49. package/dist/text-control.js +27 -6
  50. package/dist/top-layer.d.ts +13 -0
  51. package/dist/top-layer.js +16 -0
  52. package/docs/SPEC.md +25 -24
  53. package/editor/vscode.html-custom-data.json +22 -12
  54. package/editor/web-types.json +58 -25
  55. package/package.json +5 -1
@@ -1,10 +1,10 @@
1
- import { emit as e } from "./events.js";
2
- import { ScaleController as t, onScaleChange as n, snapSys as r, sysLength as i, toSysExact as a } from "./scale.js";
3
- import o from "./_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
4
- import { DocumentListenersController as s } from "./document-listeners.js";
5
- import { LitElement as c, css as l } from "lit";
6
- import { property as u, query as d } from "lit/decorators.js";
7
- var f = 24, p = /* @__PURE__ */ new Set([
1
+ import { deferActivation as e, emit as t } from "./events.js";
2
+ import { ScaleController as n, onScaleChange as r, snapSys as i, sysLength as a, toSysExact as o } from "./scale.js";
3
+ import s from "./_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
4
+ import { DocumentListenersController as c } from "./document-listeners.js";
5
+ import { LitElement as l, css as u } from "lit";
6
+ import { property as d, query as f } from "lit/decorators.js";
7
+ var p = 24, m = /* @__PURE__ */ new Set([
8
8
  "text",
9
9
  "search",
10
10
  "url",
@@ -12,7 +12,7 @@ var f = 24, p = /* @__PURE__ */ new Set([
12
12
  "email",
13
13
  "password",
14
14
  "number"
15
- ]), m = (e) => e instanceof HTMLInputElement ? p.has(e.type) : !0, h = l`
15
+ ]), h = (e) => e instanceof HTMLInputElement ? m.has(e.type) : !0, g = "vf-text-field, vf-number-field, vf-text-area, textarea, input", _ = u`
16
16
  dialog {
17
17
  padding: 0;
18
18
  margin: auto;
@@ -51,110 +51,124 @@ var f = 24, p = /* @__PURE__ */ new Set([
51
51
  the fallback is the arrow it always showed. */
52
52
  cursor: var(--vf-cursor, default);
53
53
  }
54
- `, g = class extends c {
55
- constructor(...e) {
56
- super(...e), this.scale = new t(this), this.open = !1, this.lightDismiss = !1, this.#e = !1, this.#n = null, this.#r = null, this.#i = new s(this, () => [
54
+ `, v = class extends l {
55
+ get dialogSize() {
56
+ return {
57
+ width: a(this.width ?? 260),
58
+ height: this.height === void 0 ? null : a(this.height)
59
+ };
60
+ }
61
+ #e;
62
+ #t() {
63
+ if (this.#e || !this.open) return;
64
+ let e = [];
65
+ if (this.width === void 0 && e.push("width (falling back to 260 system px)"), this.height === void 0 && e.push("height (falling back to the content)"), e.length === 0) return;
66
+ this.#e = !0;
67
+ let t = this.getAttribute("heading") ?? this.getAttribute("label") ?? "";
68
+ console.warn(`${this.localName}${t ? ` ("${t}")` : ""}: no ${e.join(", no ")}. A modal owns its whole box — declare both in system px: <${this.localName} width="320" height="140">.`);
69
+ }
70
+ #n;
71
+ #r;
72
+ #i;
73
+ constructor() {
74
+ super(), this.scale = new n(this), this.open = !1, this.returnValue = "", this.lightDismiss = !1, this.#e = !1, this.#n = null, this.#r = null, this.#i = null, this.#a = (t) => {
75
+ let n = t.target;
76
+ if (!(n instanceof HTMLFormElement) || y(n) !== this) return;
77
+ let r = t.submitter;
78
+ if ((r?.hasAttribute("formmethod") ? r.getAttribute("formmethod") : n.getAttribute("method"))?.toLowerCase() !== "dialog") return;
79
+ let i = r instanceof HTMLButtonElement || r instanceof HTMLInputElement ? r.value : void 0;
80
+ e(this, t, () => this.close(i));
81
+ }, this.#o = null, this.#s = new c(this, () => [
57
82
  [
58
83
  this._dialog,
59
84
  "pointerdown",
60
- this.#s
85
+ this.#u
61
86
  ],
62
87
  [
63
88
  this._dialog,
64
89
  "pointerup",
65
- this.#c
90
+ this.#d
66
91
  ],
67
92
  [
68
93
  this._dialog,
69
94
  "pointercancel",
70
- this.#l
95
+ this.#f
71
96
  ],
72
97
  [
73
98
  this._dialog,
74
99
  "keydown",
75
- this.#o
100
+ this.#l
76
101
  ]
77
- ]), this.#o = (e) => {
102
+ ]), this.#l = (e) => {
78
103
  if (e.key !== "Enter" || e.defaultPrevented || e.isComposing || e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;
79
104
  let t = e.composedPath();
80
105
  if (t.some((e) => e instanceof HTMLAnchorElement && e.hasAttribute("href")) || t.some((e) => e instanceof HTMLTextAreaElement || e instanceof HTMLElement && e.isContentEditable) && e.code !== "NumpadEnter") return;
81
106
  let n = this.defaultButton;
82
107
  n && (e.preventDefault(), n.click());
83
- }, this.#s = (e) => {
84
- this.#r = e.target === this._dialog ? e.pointerId : null;
85
- }, this.#c = (e) => {
86
- let t = this.#r === e.pointerId;
87
- this.#r = null, !(!t || e.target !== this._dialog || !this.lightDismiss) && (this.#n = "outside", this.close());
88
- }, this.#l = () => {
89
- this.#r = null;
90
- }, this.#u = null, this.#g = () => this.settle();
91
- }
92
- get dialogSize() {
93
- return {
94
- width: i(this.width ?? 260),
95
- height: this.height === void 0 ? null : i(this.height)
96
- };
97
- }
98
- #e;
99
- #t() {
100
- if (this.#e || !this.open) return;
101
- let e = [];
102
- if (this.width === void 0 && e.push("width (falling back to 260 system px)"), this.height === void 0 && e.push("height (falling back to the content)"), e.length === 0) return;
103
- this.#e = !0;
104
- let t = this.getAttribute("heading") ?? this.getAttribute("label") ?? "";
105
- console.warn(`${this.localName}${t ? ` ("${t}")` : ""}: no ${e.join(", no ")}. A modal owns its whole box — declare both in system px: <${this.localName} width="320" height="140">.`);
106
- }
107
- #n;
108
- #r;
109
- #i;
108
+ }, this.#u = (e) => {
109
+ this.#o = e.target === this._dialog ? e.pointerId : null;
110
+ }, this.#d = (e) => {
111
+ let t = this.#o === e.pointerId;
112
+ this.#o = null, !(!t || e.target !== this._dialog || !this.lightDismiss) && (this.#n = "outside", this.close());
113
+ }, this.#f = () => {
114
+ this.#o = null;
115
+ }, this.#p = null, this.#y = () => this.settle(), this.addEventListener("submit", this.#a);
116
+ }
117
+ #a;
118
+ #o;
119
+ #s;
110
120
  get defaultButton() {
111
121
  let e = "vf-button[variant=\"default\"]";
112
122
  return [...this.querySelectorAll(e), ...this.renderRoot.querySelectorAll(e)].find((e) => !e.matches(":disabled")) ?? null;
113
123
  }
114
124
  get initialFocusTarget() {
115
- return this.querySelector("[autofocus]") || ([...this.querySelectorAll("vf-text-field, vf-number-field, vf-text-area, textarea, input")].find((e) => m(e) && !e.matches(":disabled")) ?? this.defaultButton);
125
+ return this.querySelector("[autofocus]") || ([...this.querySelectorAll(g)].find((e) => h(e) && !e.matches(":disabled")) ?? this.defaultButton);
116
126
  }
117
- #a() {
118
- this.initialFocusTarget?.focus();
127
+ #c() {
128
+ let e = this.initialFocusTarget;
129
+ return e?.focus(), e;
119
130
  }
120
- #o;
121
- #s;
122
- #c;
123
131
  #l;
124
132
  #u;
133
+ #d;
134
+ #f;
135
+ #p;
125
136
  show() {
126
- this.open = !0, this.hasUpdated && this.#h();
137
+ this.open = !0, this.hasUpdated && this.#v();
138
+ }
139
+ close(e) {
140
+ this.open && e !== void 0 && (this.#r = e), this.open = !1, this.hasUpdated && this.#v();
127
141
  }
128
- close() {
129
- this.open = !1, this.hasUpdated && this.#h();
142
+ closeFromBox(e) {
143
+ this.open && (this.#i = e), this.close();
130
144
  }
131
145
  updated(e) {
132
- e.has("open") && this.#h(), (e.has("top") || e.has("left")) && this.settle(), this.#t();
146
+ e.has("open") && this.#v(), (e.has("top") || e.has("left")) && this.settle(), this.#t();
133
147
  }
134
- #d() {
148
+ #m() {
135
149
  let e = document.documentElement;
136
150
  return {
137
- width: a(e.clientWidth || window.innerWidth, this),
138
- height: a(e.clientHeight || window.innerHeight, this)
151
+ width: o(e.clientWidth || window.innerWidth, this),
152
+ height: o(e.clientHeight || window.innerHeight, this)
139
153
  };
140
154
  }
141
- #f(e, t) {
142
- let n = this.#d(), r = a(this._dialog?.offsetWidth ?? 0, this);
155
+ #h(e, t) {
156
+ let n = this.#m(), r = o(this._dialog?.offsetWidth ?? 0, this);
143
157
  return {
144
- x: Math.min(Math.max(e, f - r), n.width - f),
145
- y: Math.min(Math.max(t, 0), Math.max(0, n.height - f))
158
+ x: Math.min(Math.max(e, p - r), n.width - p),
159
+ y: Math.min(Math.max(t, 0), Math.max(0, n.height - p))
146
160
  };
147
161
  }
148
- #p() {
149
- let e = this.#d(), t = this._dialog?.getBoundingClientRect();
162
+ #g() {
163
+ let e = this.#m(), t = this._dialog?.getBoundingClientRect();
150
164
  return {
151
- x: (e.width - a(t?.width ?? 0, this)) / 2,
152
- y: (e.height - a(t?.height ?? 0, this)) / 2
165
+ x: (e.width - o(t?.width ?? 0, this)) / 2,
166
+ y: (e.height - o(t?.height ?? 0, this)) / 2
153
167
  };
154
168
  }
155
169
  placeAt(e, t) {
156
- let n = this.#f(e, t);
157
- this.left = r(n.x, this), this.top = r(n.y, this);
170
+ let n = this.#h(e, t);
171
+ this.left = i(n.x, this), this.top = i(n.y, this);
158
172
  }
159
173
  settle() {
160
174
  let e = this._dialog;
@@ -162,10 +176,10 @@ var f = 24, p = /* @__PURE__ */ new Set([
162
176
  let t = this.left != null || this.top != null ? {
163
177
  x: this.left ?? 0,
164
178
  y: this.top ?? 0
165
- } : this.#p(), n = this.#f(t.x, t.y);
166
- e.style.left = i(r(n.x, this)), e.style.top = i(r(n.y, this)), e.style.right = "auto", e.style.bottom = "auto", e.style.margin = "0";
179
+ } : this.#g(), n = this.#h(t.x, t.y);
180
+ e.style.left = a(i(n.x, this)), e.style.top = a(i(n.y, this)), e.style.right = "auto", e.style.bottom = "auto", e.style.margin = "0";
167
181
  }
168
- #m() {
182
+ #_() {
169
183
  let e = this._dialog?.style;
170
184
  if (e) for (let t of [
171
185
  "left",
@@ -175,44 +189,58 @@ var f = 24, p = /* @__PURE__ */ new Set([
175
189
  "margin"
176
190
  ]) e.removeProperty(t);
177
191
  }
178
- #h() {
192
+ #v() {
179
193
  let e = this._dialog;
180
- e && (this.open && !e.open ? (this.#u = document.activeElement, e.showModal(), this.#a(), this.settle(), this.#y(e), this.#i.attach()) : !this.open && e.open && e.close());
194
+ if (e) {
195
+ if (this.open && !e.open) {
196
+ this.#p = document.activeElement, this.returnValue = "", e.showModal();
197
+ let n = this.#c();
198
+ this.settle(), this.#S(e), this.#s.attach(), t(this, "vf-show", { focus: n });
199
+ } else !this.open && e.open && e.close();
200
+ }
181
201
  }
182
- #g;
183
- #_;
184
- #v;
185
- #y(e) {
186
- typeof ResizeObserver < "u" && !this.#_ && (this.#_ = new ResizeObserver(this.#g), this.#_.observe(e)), window.addEventListener("resize", this.#g), this.#v ??= n(this.#g);
202
+ #y;
203
+ #b;
204
+ #x;
205
+ #S(e) {
206
+ typeof ResizeObserver < "u" && !this.#b && (this.#b = new ResizeObserver(this.#y), this.#b.observe(e)), window.addEventListener("resize", this.#y), this.#x ??= r(this.#y);
187
207
  }
188
- #b() {
189
- this.#_?.disconnect(), this.#_ = void 0, window.removeEventListener("resize", this.#g), this.#v?.(), this.#v = void 0;
208
+ #C() {
209
+ this.#b?.disconnect(), this.#b = void 0, window.removeEventListener("resize", this.#y), this.#x?.(), this.#x = void 0;
190
210
  }
191
211
  disconnectedCallback() {
192
- super.disconnectedCallback(), this.#b();
212
+ super.disconnectedCallback(), this.#C();
193
213
  let e = this._dialog;
194
214
  if (e?.open) {
195
215
  e.close();
196
- let t = this.#u, n = document.activeElement;
216
+ let t = this.#p, n = document.activeElement;
197
217
  t instanceof HTMLElement && t.isConnected && (n === null || n === document.body) && t.focus();
198
218
  }
199
- this.#u = null;
219
+ this.#p = null;
200
220
  }
201
221
  _onNativeCancel() {
202
222
  this.#n = "escape";
203
223
  }
204
224
  _onNativeClose() {
205
- let t = this.#n ?? "close";
206
- this.#n = null, this.#u = null, this.#r = null, this.#i.detach(), this.#b(), this.open = !1, this.#m(), e(this, "vf-close", { reason: t });
225
+ let e = this.#n ?? "close", n = this.#r, r = this.#i;
226
+ this.#n = null, this.#r = null, this.#i = null, n !== null && (this.returnValue = n), this.#p = null, this.#o = null, this.#s.detach(), this.#C(), this.open = !1, this.#_(), t(this, "vf-close", {
227
+ reason: e,
228
+ returnValue: n,
229
+ ...r
230
+ });
207
231
  }
208
232
  };
209
- o([u({
233
+ s([d({
210
234
  type: Boolean,
211
235
  reflect: !0
212
- })], g.prototype, "open", void 0), o([u({ type: Number })], g.prototype, "width", void 0), o([u({ type: Number })], g.prototype, "height", void 0), o([u({ type: Number })], g.prototype, "top", void 0), o([u({ type: Number })], g.prototype, "left", void 0), o([u({
236
+ })], v.prototype, "open", void 0), s([d({ type: Number })], v.prototype, "width", void 0), s([d({ type: Number })], v.prototype, "height", void 0), s([d({ type: Number })], v.prototype, "top", void 0), s([d({ type: Number })], v.prototype, "left", void 0), s([d({
213
237
  type: Boolean,
214
238
  reflect: !0,
215
239
  attribute: "light-dismiss"
216
- })], g.prototype, "lightDismiss", void 0), o([d("dialog")], g.prototype, "_dialog", void 0);
240
+ })], v.prototype, "lightDismiss", void 0), s([f("dialog")], v.prototype, "_dialog", void 0);
241
+ function y(e) {
242
+ for (let t = e.parentElement; t; t = t.parentElement) if (t instanceof v) return t;
243
+ return null;
244
+ }
217
245
  //#endregion
218
- export { g as VfModalDialog, h as modalDialogStyles };
246
+ export { v as VfModalDialog, _ as modalDialogStyles };
package/dist/position.js CHANGED
@@ -70,25 +70,25 @@ var h = class {
70
70
  return u(e.width, e.height, this.#s, t(this.#e));
71
71
  }
72
72
  hostConnected() {
73
- this.#a && (this.#r || this.#l) && this.#y();
73
+ this.#a && (this.#r || this.#l) && this.#b();
74
74
  }
75
75
  hostDisconnected() {
76
- this.#b();
76
+ this.#x();
77
77
  }
78
78
  hostUpdated() {
79
79
  let e = this.#e.top ?? null, t = this.#e.left ?? null, n = this.#e.fixed === !0, r = this.#e.origin ?? null, i = this.#e.style;
80
80
  if (r !== this.#o && (this.#o = r, this.#s = this.#p(r)), e === null && t === null && !n) {
81
81
  if (!this.#a) return;
82
- this.#r && this.#v(), this.#b(), this.#a = !1, this.#r = !1, this.#l = !1, this.#u = 0, this.#d = 0, i.removeProperty("position"), i.removeProperty("top"), i.removeProperty("left"), i.removeProperty("right"), i.removeProperty("bottom"), i.removeProperty("margin"), this.#g(null, null);
82
+ this.#r && this.#y(), this.#x(), this.#a = !1, this.#r = !1, this.#l = !1, this.#u = 0, this.#d = 0, i.removeProperty("position"), i.removeProperty("top"), i.removeProperty("left"), i.removeProperty("right"), i.removeProperty("bottom"), i.removeProperty("margin"), this.#_(null, null);
83
83
  return;
84
84
  }
85
85
  if (this.#a && e === this.#t && t === this.#n && n === this.#r && r === this.#i) return;
86
86
  let a = this.#a && this.#r, o = this.#s !== c;
87
87
  if (this.#a = !0, this.#t = e, this.#n = t, this.#r = n, this.#i = r, this.#l = o, i.position = n ? "sticky" : "absolute", o) {
88
88
  let e = this.#e.getBoundingClientRect();
89
- (e.width > 0 || e.height > 0) && this.#h(e.width, e.height);
89
+ (e.width > 0 || e.height > 0) && this.#g(e.width, e.height);
90
90
  } else this.#u = 0, this.#d = 0;
91
- this.#m(), i.right = "auto", i.bottom = "auto", n ? a || this.#_() : (a && this.#v(), i.margin = "0"), n || o ? this.#y() : this.#b(), this.#g(t ?? 0, e ?? 0);
91
+ this.#m(), i.right = "auto", i.bottom = "auto", n ? a || this.#v() : (a && this.#y(), i.margin = "0", this.#h()), n || o ? this.#b() : this.#x(), this.#_(t ?? 0, e ?? 0);
92
92
  }
93
93
  #p(e) {
94
94
  if (e == null) return c;
@@ -97,49 +97,54 @@ var h = class {
97
97
  }
98
98
  #m() {
99
99
  let e = this.#e.style;
100
- e.top = r((this.#t ?? 0) - this.#d), e.left = r((this.#n ?? 0) - this.#u);
100
+ e.top = r((this.#t ?? 0) - this.#d), e.left = r((this.#n ?? 0) - this.#u), this.#h();
101
101
  }
102
- #h(e, n) {
102
+ #h() {
103
+ !this.#l || this.#r || (this.#e.style.marginRight = r(-((this.#n ?? 0) - this.#u)));
104
+ }
105
+ #g(e, n) {
103
106
  let r = u(e, n, this.#s, t(this.#e));
104
107
  return r.x === this.#u && r.y === this.#d ? !1 : (this.#u = r.x, this.#d = r.y, !0);
105
108
  }
106
- #g(t, n) {
109
+ #_(t, n) {
107
110
  e(this.#e, "vf-placement-change", {
108
111
  left: t,
109
112
  top: n
110
113
  }, { composed: !1 });
111
114
  }
112
- #_() {
115
+ #v() {
113
116
  let e = this.#e.style;
114
- e.maxWidth = "fit-content", e.zIndex = "1", this.#x = !1;
117
+ e.maxWidth = "fit-content", e.zIndex = "1", this.#S = !1;
115
118
  let t = this.#e.getBoundingClientRect();
116
- (t.width > 0 || t.height > 0) && this.#S(t.width, t.height);
119
+ (t.width > 0 || t.height > 0) && this.#C(t.width, t.height);
117
120
  }
118
- #v() {
119
- this.#x = !1;
121
+ #y() {
122
+ this.#S = !1;
120
123
  let e = this.#e.style;
121
124
  e.removeProperty("display"), e.removeProperty("max-width"), e.removeProperty("z-index");
122
125
  }
123
- #y() {
126
+ #b() {
124
127
  this.#f ??= new ResizeObserver((e) => {
125
128
  let t = e[e.length - 1]?.borderBoxSize?.[0], n = t ? {
126
129
  width: t.inlineSize,
127
130
  height: t.blockSize
128
131
  } : this.#e.getBoundingClientRect();
129
- this.#r && this.#S(n.width, n.height), this.#l && this.#h(n.width, n.height) && (this.#m(), this.#g(this.#n ?? 0, this.#t ?? 0));
132
+ this.#r && this.#C(n.width, n.height);
133
+ let r = n.width > 0 || n.height > 0;
134
+ this.#l && r && this.#g(n.width, n.height) && (this.#m(), this.#_(this.#n ?? 0, this.#t ?? 0));
130
135
  }), this.#f.observe(this.#e);
131
136
  }
132
- #b() {
137
+ #x() {
133
138
  this.#f?.disconnect(), this.#f = null;
134
139
  }
135
- #x = !1;
136
- #S(e, t) {
140
+ #S = !1;
141
+ #C(e, t) {
137
142
  let n = this.#e.style;
138
- if (!this.#x) {
143
+ if (!this.#S) {
139
144
  let e = getComputedStyle(this.#e).display;
140
145
  if (e) {
141
146
  let t = d[e];
142
- t && (n.display = t), this.#x = !0;
147
+ t && (n.display = t), this.#S = !0;
143
148
  }
144
149
  }
145
150
  n.margin = `0 ${-e}px ${-t}px 0`;
@@ -1,16 +1,19 @@
1
1
  /**
2
- * The shell's alert: a plain-framed `vf-dialog` with the site's caution art,
2
+ * The Finder's alert: a plain-framed `vf-dialog` with the site's caution art,
3
3
  * a message and a row of buttons, sized to the message — composed from kit
4
- * elements, as every alert in the kit is.
4
+ * elements, as every alert in the kit is. Its buttons submit a
5
+ * `<form method="dialog">`, so it answers with the pressed button's `value`
6
+ * like any dialog an application holds.
5
7
  *
6
8
  * The layout follows the plain frame's body, its width and height less 10:
7
9
  * the art and the message 16 in from the body's top-left, the buttons'
8
10
  * bottom-right corner 16 in from the body's.
9
11
  */
12
+ import type { VfDialog } from '../index.js';
10
13
  /** One button of an alert. */
11
14
  export interface AlertButton {
12
15
  label: string;
13
- /** What the alert resolves to when it is pressed. */
16
+ /** What the alert answers when it is pressed. */
14
17
  value: string;
15
18
  /** The default button, which Return presses. */
16
19
  default?: boolean;
@@ -20,13 +23,18 @@ export interface AlertOptions {
20
23
  buttons?: AlertButton[];
21
24
  /** The dialog's width, system px. Default 400. */
22
25
  width?: number;
23
- /** The 32×32 art beside the message; default the shell's caution art. */
26
+ /** The 32×32 art beside the message, or null for none. */
24
27
  art?: string | null;
25
28
  /** The dialog's accessible name. Default "Alert". */
26
29
  label?: string;
27
30
  }
28
- /**
29
- * Show an alert inside `host` (the desktop), and resolve the value of the
30
- * button pressed — or null when it closed any other way, Escape say.
31
- */
32
- export declare function showAlert(host: Element, message: string, options?: AlertOptions): Promise<string | null>;
31
+ /** An alert, made but not yet shown. */
32
+ export interface ComposedAlert {
33
+ dialog: VfDialog;
34
+ /** Resolves once its parts have rendered, so `show()` opens it at once. Call it once the dialog is in the page. */
35
+ rendered(): Promise<unknown>;
36
+ /** Size the box to the message. Call it right after `show()`: a closed dialog lays out nothing. */
37
+ fit(): void;
38
+ }
39
+ /** Make an alert for `message`. */
40
+ export declare function composeAlert(message: string, options?: AlertOptions): ComposedAlert;
@@ -2,43 +2,40 @@ import { effectiveScale as e } from "../scale.js";
2
2
  import "../index.js";
3
3
  //#region src/shell/alert.ts
4
4
  var t = 10, n = 16, r = 32, i = 28;
5
- async function a(a, o, s = {}) {
6
- let { buttons: c = [{
5
+ function a(a, o = {}) {
6
+ let { buttons: s = [{
7
7
  label: "OK",
8
8
  value: "ok",
9
9
  default: !0
10
- }], width: l = 400, art: u = null, label: d = "Alert" } = s, f = document.createElement("vf-dialog");
11
- f.frame = "plain", f.label = d, f.width = l, f.height = 120;
12
- let p = u ? 64 : n;
13
- if (u) {
10
+ }], width: c = 400, art: l = null, label: u = "Alert" } = o, d = document.createElement("vf-dialog");
11
+ d.frame = "plain", d.label = u, d.width = c, d.height = 120;
12
+ let f = document.createElement("form");
13
+ f.method = "dialog", f.noValidate = !0;
14
+ let p = l ? 64 : n;
15
+ if (l) {
14
16
  let e = document.createElement("vf-img");
15
17
  e.width = r, e.height = r, e.left = n, e.top = n;
16
18
  let t = document.createElement("img");
17
- t.src = u, t.alt = "", e.append(t), f.append(e);
19
+ t.src = l, t.alt = "", e.append(t), f.append(e);
18
20
  }
19
21
  let m = document.createElement("vf-paragraph");
20
- m.face = "display", m.width = l - t - p - n, m.left = p, m.top = n, m.textContent = o, f.append(m);
22
+ m.face = "display", m.width = c - t - p - n, m.left = p, m.top = n, m.textContent = a, f.append(m);
21
23
  let h = document.createElement("vf-button-group");
22
- h.origin = "bottom right";
23
- let g = c.map((e) => {
24
+ return h.origin = "bottom right", h.append(...s.map((e) => {
24
25
  let t = document.createElement("vf-button");
25
- return t.textContent = e.label, t.dataset.value = e.value, e.default && (t.variant = "default"), t;
26
- });
27
- h.append(...g), f.append(h), a.append(f), await Promise.all([
28
- f.updateComplete,
29
- m.updateComplete,
30
- h.updateComplete
31
- ]);
32
- let _ = Math.ceil(m.getBoundingClientRect().height / e(m)), v = Math.max(u ? 48 : 0, n + _) + n + i + n;
33
- return f.height = v + t, h.left = l - t - n, h.top = v - n, new Promise((e) => {
34
- let t = null;
35
- for (let e of g) e.addEventListener("click", () => {
36
- t = e.dataset.value ?? null, f.close();
37
- });
38
- f.addEventListener("vf-close", () => {
39
- f.remove(), e(t);
40
- }, { once: !0 }), f.show();
41
- });
26
+ return t.textContent = e.label, t.type = "submit", t.value = e.value, e.default && (t.variant = "default"), t;
27
+ })), f.append(h), d.append(f), {
28
+ dialog: d,
29
+ rendered: () => Promise.all([
30
+ d.updateComplete,
31
+ m.updateComplete,
32
+ h.updateComplete
33
+ ]),
34
+ fit() {
35
+ let r = Math.ceil(m.getBoundingClientRect().height / e(m)), a = Math.max(l ? 48 : 0, n + r) + n + i + n;
36
+ d.height = a + t, h.left = c - t - n, h.top = a - n;
37
+ }
38
+ };
42
39
  }
43
40
  //#endregion
44
- export { a as showAlert };
41
+ export { a as composeAlert };
@@ -158,7 +158,7 @@ export interface Catalog {
158
158
  clear(): Promise<void>;
159
159
  import(archive: CatalogArchive, options?: {
160
160
  mode?: 'merge' | 'replace';
161
- }): Promise<number>;
161
+ }): Promise<Map<string, Item>>;
162
162
  dispose(): Promise<void>;
163
163
  }
164
164
  export declare function createCatalog(options: CatalogOptions): Catalog;
@@ -119,7 +119,13 @@ function x(n) {
119
119
  ...t,
120
120
  name: ""
121
121
  };
122
- }, I = {
122
+ };
123
+ async function I() {
124
+ M.clear();
125
+ for (let e of await A().list()) e.id !== i && (await A().remove(e.id), C.delete(e.id));
126
+ C = /* @__PURE__ */ new Map();
127
+ }
128
+ let L = {
123
129
  get: () => E,
124
130
  subscribe(e) {
125
131
  return D.add(e), () => {
@@ -143,7 +149,7 @@ function x(n) {
143
149
  k();
144
150
  },
145
151
  async seed(e) {
146
- return !r || !w || T ? !1 : (await e(I), await r.put({
152
+ return !r || !w || T ? !1 : (await e(L), await r.put({
147
153
  id: i,
148
154
  name: "",
149
155
  kind: i,
@@ -240,30 +246,38 @@ function x(n) {
240
246
  return { items: [...C.values()] };
241
247
  },
242
248
  async clear() {
243
- if (r) {
244
- for (let e of await r.list()) e.id !== i && await r.remove(e.id);
245
- C = /* @__PURE__ */ new Map(), M.clear(), k();
249
+ if (r) try {
250
+ await I();
251
+ } finally {
252
+ k();
246
253
  }
247
254
  },
248
255
  async import(e, { mode: t = "merge" } = {}) {
249
- let n = e.items.filter((e) => e.id !== i && !o(e.id));
250
- if (!n.length || !r) return 0;
251
- let a = t === "replace", s = /* @__PURE__ */ new Map();
252
- for (let e of n) s.set(e.id, a ? e.id : x());
253
- let c = (e) => e == null || o(e) ? e : s.get(e) ?? null;
254
- a && await I.clear();
255
- for (let e of n) await j({
256
- ...e,
257
- id: s.get(e.id),
258
- parent: c(e.parent)
259
- });
260
- return k(), n.length;
256
+ let n = /* @__PURE__ */ new Map(), a = e.items.filter((e) => e.id !== i && !o(e.id));
257
+ if (!a.length || !r) return n;
258
+ let s = t === "replace", c = /* @__PURE__ */ new Map();
259
+ for (let e of a) c.set(e.id, s ? e.id : x());
260
+ let l = (e) => e == null || o(e) ? e : c.get(e) ?? null;
261
+ try {
262
+ s && await I();
263
+ for (let e of a) {
264
+ let t = {
265
+ ...e,
266
+ id: c.get(e.id),
267
+ parent: l(e.parent)
268
+ };
269
+ await j(t), n.set(e.id, t);
270
+ }
271
+ } finally {
272
+ k();
273
+ }
274
+ return n;
261
275
  },
262
276
  async dispose() {
263
277
  await P(), D.clear();
264
278
  }
265
279
  };
266
- return I;
280
+ return L;
267
281
  }
268
282
  function S(e = []) {
269
283
  let t = new Map(e.map((e) => [e.id, e]));