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.
@@ -1,11 +1,11 @@
1
- import { vfElement as e } from "../define.js";
2
- import { ScaleController as t, sys as n, toSys as r } from "../scale.js";
3
- import i from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
4
- import { VfPositioned as a } from "../position.js";
5
- import { vfBase as o } from "../styles/recipes/host.js";
6
- import { vfFocusUnderline as s } from "../styles/recipes/focus.js";
7
- import { GridSnapController as c } from "../grid-snap.js";
8
- import { emit as l, emitNative as u } from "../events.js";
1
+ import { emit as e, emitNative as t } from "../events.js";
2
+ import { vfElement as n } from "../define.js";
3
+ import { ScaleController as r, sys as i, toSys as a } from "../scale.js";
4
+ import o from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
5
+ import { VfPositioned as s } from "../position.js";
6
+ import { vfBase as c } from "../styles/recipes/host.js";
7
+ import { vfFocusUnderline as l } from "../styles/recipes/focus.js";
8
+ import { GridSnapController as u } from "../grid-snap.js";
9
9
  import { SLIDER_THUMB as d, SLIDER_THUMB_FACE as f } from "../glyphs.js";
10
10
  import { VfFormControl as p } from "../form-control.js";
11
11
  import { FocusRuleController as m } from "../focus-modality.js";
@@ -21,9 +21,9 @@ function D(e, t) {
21
21
  };
22
22
  return r(1, 0, e - 2, 1), r(1, 3, e - 2, 1), r(0, 1, 1, 2), r(e - 1, 1, 1, 2), r(1, 1, Math.min(Math.max(t, 0), e - 1) - 1, 2), n.join("");
23
23
  }
24
- var O = class extends a(p) {
24
+ var O = class extends s(p) {
25
25
  static {
26
- this.styles = [o, _`
26
+ this.styles = [c, _`
27
27
  :host {
28
28
  /* Padding just leaves room for the thumb's focus ring; the thumb itself
29
29
  stays within the rail (its travel is inset by half its width). */
@@ -102,7 +102,7 @@ var O = class extends a(p) {
102
102
  }
103
103
  .track.vf-focus-rule::after {
104
104
  --vf-focus-underline-offset: ${3}px;
105
- ${s}
105
+ ${l}
106
106
  }
107
107
  `];
108
108
  }
@@ -110,7 +110,7 @@ var O = class extends a(p) {
110
110
  #t;
111
111
  #n;
112
112
  constructor() {
113
- super(), this.value = 0, this.min = 0, this.max = 100, this.step = 1, this.name = "", this.label = "", this.trackSize = new g(this, () => this.track), this.scale = new t(this), this.gridSnap = new c(this), this.selfManagedTabIndex = !1, this.#e = new m(this), this.#t = 0, this.#n = !1, this.#f = (e) => {
113
+ super(), this.value = 0, this.min = 0, this.max = 100, this.step = 1, this.name = "", this.label = "", this.trackSize = new g(this, () => this.track), this.scale = new r(this), this.gridSnap = new u(this), this.selfManagedTabIndex = !1, this.#e = new m(this), this.#t = 0, this.#n = !1, this.#f = (e) => {
114
114
  if (!(this.isDisabled || e.button !== 0)) {
115
115
  e.preventDefault(), this.#e.suppress(), this.focus(), this.#n = !0, this.#t = this.value;
116
116
  try {
@@ -193,16 +193,16 @@ var O = class extends a(p) {
193
193
  #l(e) {
194
194
  e !== this.value && (this.value = e, this.#u("vf-input"));
195
195
  }
196
- #u(e) {
197
- l(this, e, { value: this.value }), u(this, e === "vf-input" ? "input" : "change");
196
+ #u(n) {
197
+ e(this, n, { value: this.value }), t(this, n === "vf-input" ? "input" : "change");
198
198
  }
199
199
  #d(e) {
200
200
  let t = this.track?.getBoundingClientRect();
201
201
  if (!t) return this.value;
202
- let r = t.width - n(x, this);
203
- if (r <= 0) return this.value;
204
- let i = Math.min(Math.max((e - t.left - n(w, this)) / r, 0), 1);
205
- return this.#o(this.min + i * this.#r);
202
+ let n = t.width - i(x, this);
203
+ if (n <= 0) return this.value;
204
+ let r = Math.min(Math.max((e - t.left - i(w, this)) / n, 0), 1);
205
+ return this.#o(this.min + r * this.#r);
206
206
  }
207
207
  #f;
208
208
  #p;
@@ -213,7 +213,7 @@ var O = class extends a(p) {
213
213
  (n || t) && this.syncFormValue(String(this.#s)), e.has("min") && (this.internals.ariaValueMin = String(this.min)), e.has("max") && (this.internals.ariaValueMax = String(this.max)), n && (this.internals.ariaValueNow = String(this.#s)), e.has("label") && (this.internals.ariaLabel = this.label || null), t && (this.internals.ariaDisabled = this.isDisabled ? "true" : "false", this.selfManagedTabIndex && (this.tabIndex = this.isDisabled ? -1 : 0));
214
214
  }
215
215
  render() {
216
- let e = r(this.trackSize.width, this), t = Math.round(this.#c * Math.max(0, e - x)), i = n(t, this), a = t + C;
216
+ let e = a(this.trackSize.width, this), t = Math.round(this.#c * Math.max(0, e - x)), n = i(t, this), r = t + C;
217
217
  return v`
218
218
  <div
219
219
  class="track vf-snap ${this.#e.marked ? "vf-focus-rule" : ""} ${this.isDisabled ? "disabled" : ""}"
@@ -227,15 +227,15 @@ var O = class extends a(p) {
227
227
  ${e >= 2 ? v`<svg
228
228
  class="rail"
229
229
  part="rail"
230
- width=${n(e, this)}
231
- height=${n(T, this)}
230
+ width=${i(e, this)}
231
+ height=${i(T, this)}
232
232
  viewBox="0 0 ${e} ${T}"
233
233
  shape-rendering="crispEdges"
234
234
  aria-hidden="true"
235
235
  >
236
- <path d=${D(e, a)}></path>
236
+ <path d=${D(e, r)}></path>
237
237
  </svg>` : null}
238
- <span class="thumb" part="thumb" style="left: ${i}px">
238
+ <span class="thumb" part="thumb" style="left: ${n}px">
239
239
  <svg
240
240
  class="thumb-glyph"
241
241
  viewBox="0 0 ${x} ${S}"
@@ -250,6 +250,6 @@ var O = class extends a(p) {
250
250
  `;
251
251
  }
252
252
  };
253
- i([y({ type: Number })], O.prototype, "value", void 0), i([y({ type: Number })], O.prototype, "min", void 0), i([y({ type: Number })], O.prototype, "max", void 0), i([y({ type: Number })], O.prototype, "step", void 0), i([y({ reflect: !0 })], O.prototype, "name", void 0), i([y()], O.prototype, "label", void 0), i([b(".track")], O.prototype, "track", void 0), O = i([e("vf-slider")], O);
253
+ o([y({ type: Number })], O.prototype, "value", void 0), o([y({ type: Number })], O.prototype, "min", void 0), o([y({ type: Number })], O.prototype, "max", void 0), o([y({ type: Number })], O.prototype, "step", void 0), o([y({ reflect: !0 })], O.prototype, "name", void 0), o([y()], O.prototype, "label", void 0), o([b(".track")], O.prototype, "track", void 0), O = o([n("vf-slider")], O);
254
254
  //#endregion
255
255
  export { O as VfSlider };
@@ -30,12 +30,18 @@ declare const VfWindow_base: (new (...args: any[]) => import("../size.js").VfSiz
30
30
  * says so once in the console.
31
31
  *
32
32
  * @slot - Default slot: window body content.
33
+ * @slot status - Optional status-bar content — the classic bottom readout
34
+ * strip ("40px x 40px"): a 1px rule over a 15px white band under the body,
35
+ * body-face text on its native line. Takes no space until populated; a
36
+ * `resizable` window's grow box sits flush in its right end.
33
37
  * @csspart frame - The outer chrome frame.
34
38
  * @csspart title-bar - The striped (or dithered) title bar.
35
39
  * @csspart title - The centered title patch (hidden on the utility bar).
36
40
  * @csspart close-box - The close widget (left).
37
41
  * @csspart zoom-box - The zoom widget (right).
38
42
  * @csspart body - The content area.
43
+ * @csspart status-bar - The bottom status strip (when the `status` slot is
44
+ * populated).
39
45
  * @csspart grow-box - The resize widget (bottom-right, when `resizable`).
40
46
  * @csspart viewport - The built-in scroll area's viewport (when `scrollbars`;
41
47
  * re-exported from vf-scroll-area).
@@ -43,6 +49,13 @@ declare const VfWindow_base: (new (...args: any[]) => import("../size.js").VfSiz
43
49
  * compatible with vf-dialog's `vf-close`). The window does NOT
44
50
  * remove itself; the consumer decides what closing means.
45
51
  * @fires vf-zoom - Zoom box clicked. Detail `{}`.
52
+ * @fires vf-resize - The grow box resized the window. Detail `{ width,
53
+ * height, commit }`, sizes in whole system px: one event per size the drag
54
+ * writes (`commit: false`), fired after the new box is applied so a handler
55
+ * that measures reads the resized layout, then a final `commit: true` as
56
+ * the gesture settles — only when it changed the size. Fired by the gesture
57
+ * alone: a programmatic `width`/`height` write fires nothing, the way a
58
+ * value set fires no `vf-change`.
46
59
  * @cssprop --vf-dots-pattern - the windoid bar's dot-grid dither — a 2×2 motif,
47
60
  * one black pixel at its origin, on a 30-system-px tile (`vfDots`; override
48
61
  * the whole tile like `--vf-desktop-pattern` — consumer art renders as a
@@ -51,6 +64,10 @@ declare const VfWindow_base: (new (...args: any[]) => import("../size.js").VfSiz
51
64
  * @cssprop [--vf-titlebar-height-utility=12px] - the slim
52
65
  * `vf-window[variant="utility"]` (windoid) bar — 11px interior + 1px bottom
53
66
  * rule, traced from `Windows/utility-window.png`
67
+ * @cssprop [--vf-status-bar-height=15px] - the status strip: 1px rule + 14px
68
+ * interior — the grow box's own height, so the two compose flush
69
+ * @cssprop [--vf-line-height=12px] - the body face's native line, which the
70
+ * status strip's text rides (whole-pixel centered in the 14px interior)
54
71
  */
55
72
  export declare class VfWindow extends VfWindow_base {
56
73
  #private;
@@ -90,6 +107,8 @@ export declare class VfWindow extends VfWindow_base {
90
107
  * vf-scroll-area) still works for windows that want an inset well instead.
91
108
  */
92
109
  scrollbars?: 'vertical' | 'horizontal' | 'both';
110
+ /** Whether the `status` slot has assigned content (drives the strip). */
111
+ private _hasStatus;
93
112
  /** Default-on display scaling (true 72dpi size); see src/scale.ts. */
94
113
  private readonly scale;
95
114
  /** Device-pixel grid snapping; see src/grid-snap.ts. */
@@ -134,9 +153,16 @@ export declare class VfWindow extends VfWindow_base {
134
153
  * are the same declaration and neither can be re-asserted over the other.
135
154
  * Controllers run before this hook, so the inline style the warning reads is
136
155
  * already written.
156
+ *
157
+ * The stream half of `vf-resize` also fires here, not from the pointermove
158
+ * that wrote the size: by this hook the controller has applied the box, so
159
+ * a handler that measures reads the resized layout — the contract that lets
160
+ * window content follow the grow box without a ResizeObserver.
137
161
  */
138
162
  protected updated(): void;
139
163
  disconnectedCallback(): void;
164
+ /** The `.empty` gate: the strip renders only while the slot is populated. */
165
+ private _onStatusSlotChange;
140
166
  private _onCloseClick;
141
167
  private _onZoomClick;
142
168
  private _onGrowPointerDown;
@@ -1,45 +1,45 @@
1
- import { vfElement as e } from "../define.js";
2
- import { ScaleController as t, snapSys as n, sysLength as r, toSysExact as i } from "../scale.js";
3
- import a from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
4
- import { PlacementController as o, VfPositioned as s, warnMovableContract as c } from "../position.js";
5
- import { vfBase as l } from "../styles/recipes/host.js";
6
- import { DOT_RECTS as u, DOT_SPAN as d, vfDots as f, vfStripes as p } from "../styles/recipes/pattern.js";
7
- import { vfChromeFrame as m } from "../styles/recipes/surface.js";
8
- import { vfTitleBar as h, vfWindowWidgets as g } from "../styles/recipes/title-bar.js";
9
- import { vfFocus as _ } from "../styles/recipes/focus.js";
10
- import { TileRasterCache as v, patternOverride as y, tileGrid as b, vfTileGrid as x } from "../tile-grid.js";
11
- import { GridSnapController as S } from "../grid-snap.js";
12
- import { VfSized as C } from "../size.js";
13
- import { DragController as w } from "../drag.js";
14
- import { TitleCenterController as T, chromeTitleBar as E, closeBox as D, widgetLabel as O, zoomBox as k } from "../chrome.js";
15
- import { emit as A } from "../events.js";
1
+ import { emit as e } from "../events.js";
2
+ import { vfElement as t } from "../define.js";
3
+ import { ScaleController as n, snapSys as r, sysLength as i, toSysExact as a } from "../scale.js";
4
+ import o from "../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
5
+ import { PlacementController as s, VfPositioned as c, warnMovableContract as l } from "../position.js";
6
+ import { vfBase as u } from "../styles/recipes/host.js";
7
+ import { DOT_RECTS as d, DOT_SPAN as f, vfDots as p, vfStripes as m } from "../styles/recipes/pattern.js";
8
+ import { vfChromeFrame as h } from "../styles/recipes/surface.js";
9
+ import { vfTitleBar as g, vfWindowWidgets as _ } from "../styles/recipes/title-bar.js";
10
+ import { vfFocus as v } from "../styles/recipes/focus.js";
11
+ import { TileRasterCache as y, patternOverride as b, tileGrid as x, vfTileGrid as S } from "../tile-grid.js";
12
+ import { GridSnapController as C } from "../grid-snap.js";
13
+ import { VfSized as w } from "../size.js";
14
+ import { DragController as T } from "../drag.js";
15
+ import { TitleCenterController as E, chromeTitleBar as D, closeBox as O, widgetLabel as k, zoomBox as A } from "../chrome.js";
16
16
  import "./vf-scroll-area.js";
17
17
  import { LitElement as j, css as M, html as N, nothing as P } from "lit";
18
- import { property as F } from "lit/decorators.js";
18
+ import { property as F, state as I } from "lit/decorators.js";
19
19
  //#region src/components/vf-window.ts
20
- var I = 80, L = 54, R = 24, z = 8, B = class extends C(s(j)) {
20
+ var L = 80, R = 54, z = 24, B = 8, V = class extends w(c(j)) {
21
21
  constructor(...e) {
22
- super(...e), this.heading = "", this.active = !0, this.closable = !0, this.zoomable = !1, this.movable = !1, this.resizable = !1, this.flush = !1, this.scale = new t(this), this.gridSnap = new S(this), this.titleCenter = new T(this), this._dotsPattern = "", this.#e = new v(), this.#t = (e, t, n) => {
23
- let r = i(this.offsetWidth, this);
22
+ super(...e), this.heading = "", this.active = !0, this.closable = !0, this.zoomable = !1, this.movable = !1, this.resizable = !1, this.flush = !1, this._hasStatus = !1, this.scale = new n(this), this.gridSnap = new C(this), this.titleCenter = new E(this), this._dotsPattern = "", this.#e = new y(), this.#t = (e, t, n) => {
23
+ let r = a(this.offsetWidth, this);
24
24
  return {
25
- x: Math.min(Math.max(e, R - r), n.width - R),
26
- y: Math.min(Math.max(t, 0), Math.max(0, n.height - R))
25
+ x: Math.min(Math.max(e, z - r), n.width - z),
26
+ y: Math.min(Math.max(t, 0), Math.max(0, n.height - z))
27
27
  };
28
- }, this._placement = new o(this, (e, t, n) => this.#t(e, t, n)), this._drag = new w(this, {
28
+ }, this._placement = new s(this, (e, t, n) => this.#t(e, t, n)), this._drag = new T(this, {
29
29
  onDragStart: (e) => !this.movable || e.button !== 0 || e.composedPath().some((e) => e instanceof HTMLElement && e.classList.contains("box")) ? null : (this.#i(), this._placement.seed()),
30
30
  onDrag: (e, t) => this._placement.moveTo(e, t)
31
31
  }), this._resizeState = null, this.#n = !1, this.#r = !1;
32
32
  }
33
33
  static {
34
34
  this.styles = [
35
- l,
36
- p,
37
- f,
38
- x,
39
- _,
35
+ u,
40
36
  m,
37
+ p,
38
+ S,
39
+ v,
41
40
  h,
42
41
  g,
42
+ _,
43
43
  M`
44
44
  :host {
45
45
  display: block;
@@ -206,6 +206,36 @@ var I = 80, L = 54, R = 24, z = 8, B = class extends C(s(j)) {
206
206
  margin: calc(var(--vf-scale, 1) * -1px);
207
207
  }
208
208
 
209
+ /* --- Status bar (slot="status") ---------------------------------- */
210
+ /* The classic bottom readout strip: a 1px rule over a white interior,
211
+ 15px in all — the grow box's own height, so a resizable window's
212
+ grow box sits flush in the strip's right end the way it sits in the
213
+ scroll rails' corner cell (its top and left borders take over the
214
+ rule there). Body-face text rides its native 12px line, whole-pixel
215
+ centered in the 14px interior. Under the scrollbars parameter, the
216
+ edge rails' bottom frame line lands exactly on the strip's rule (the
217
+ 1px overhang), so the two never double up. Takes no space until the
218
+ slot is populated. */
219
+ .status {
220
+ flex: none;
221
+ display: flex;
222
+ align-items: center;
223
+ height: calc(var(--vf-scale, 1) * var(--vf-status-bar-height, 15px));
224
+ border-top: calc(var(--vf-scale, 1) * 1px) solid var(--vf-black, #000000);
225
+ background: var(--vf-white, #ffffff);
226
+ padding-inline: calc(var(--vf-scale, 1) * 6px);
227
+ line-height: calc(var(--vf-scale, 1) * var(--vf-line-height, 12px));
228
+ white-space: nowrap;
229
+ overflow: hidden;
230
+ }
231
+ /* Clear the grow box: its 15px cell plus the strip's own 6px inset. */
232
+ :host([resizable]) .status {
233
+ padding-inline-end: calc(var(--vf-scale, 1) * 21px);
234
+ }
235
+ .status.empty {
236
+ display: none;
237
+ }
238
+
209
239
  /* --- Grow box --------------------------------------------------- */
210
240
  .grow {
211
241
  position: absolute;
@@ -251,30 +281,36 @@ var I = 80, L = 54, R = 24, z = 8, B = class extends C(s(j)) {
251
281
  }
252
282
  #e;
253
283
  willUpdate(e) {
254
- super.willUpdate(e), this.variant === "utility" && (this._dotsPattern = y(this, "--vf-dots-pattern"));
284
+ super.willUpdate(e), this.variant === "utility" && (this._dotsPattern = b(this, "--vf-dots-pattern"));
255
285
  }
256
286
  _dotsTexture() {
257
287
  if (this.width == null) return;
258
288
  let e = Math.max(1, this.width - 2);
259
- if (this._dotsPattern) return b({
260
- cols: Math.ceil(e / d),
289
+ if (this._dotsPattern) return x({
290
+ cols: Math.ceil(e / f),
261
291
  rows: 1,
262
- tile: d
292
+ tile: f
263
293
  });
264
- let t = Math.ceil((e + 2) / d) * d, n = z + 2;
294
+ let t = Math.ceil((e + 2) / f) * f, n = B + 2;
265
295
  return N`<div
266
296
  class="vf-tile-raster"
267
- style="width:${r(t)};height:${r(n)};background-image:${this.#e.for(2, 2, u, t, n)}"
297
+ style="width:${i(t)};height:${i(n)};background-image:${this.#e.for(2, 2, d, t, n)}"
268
298
  ></div>`;
269
299
  }
270
300
  #t;
271
301
  updated() {
272
302
  this.#a();
303
+ let t = this._resizeState;
304
+ t?.emitPending && (t.emitPending = !1, e(this, "vf-resize", {
305
+ width: this.width,
306
+ height: this.height,
307
+ commit: !1
308
+ }));
273
309
  }
274
310
  #n;
275
311
  #r;
276
312
  #i() {
277
- this.#r ||= c(this, `vf-window${this.heading ? ` ("${this.heading}")` : ""}`, "<vf-window movable top=\"30\" left=\"40\" width=\"240\" height=\"176\">");
313
+ this.#r ||= l(this, `vf-window${this.heading ? ` ("${this.heading}")` : ""}`, "<vf-window movable top=\"30\" left=\"40\" width=\"240\" height=\"176\">");
278
314
  }
279
315
  #a() {
280
316
  if (this.#n) return;
@@ -284,11 +320,15 @@ var I = 80, L = 54, R = 24, z = 8, B = class extends C(s(j)) {
284
320
  disconnectedCallback() {
285
321
  super.disconnectedCallback(), this._resizeState = null;
286
322
  }
323
+ _onStatusSlotChange(e) {
324
+ let t = e.target;
325
+ this._hasStatus = t.assignedElements().length > 0;
326
+ }
287
327
  _onCloseClick() {
288
- A(this, "vf-close", { reason: "close" });
328
+ e(this, "vf-close", { reason: "close" });
289
329
  }
290
330
  _onZoomClick() {
291
- A(this, "vf-zoom", {});
331
+ e(this, "vf-zoom", {});
292
332
  }
293
333
  _onGrowPointerDown(e) {
294
334
  if (!this.resizable || e.button !== 0) return;
@@ -297,22 +337,28 @@ var I = 80, L = 54, R = 24, z = 8, B = class extends C(s(j)) {
297
337
  pointerId: e.pointerId,
298
338
  startX: e.clientX,
299
339
  startY: e.clientY,
300
- baseWidth: i(t.width, this),
301
- baseHeight: i(t.height, this)
340
+ baseWidth: a(t.width, this),
341
+ baseHeight: a(t.height, this),
342
+ emitPending: !1,
343
+ resized: !1
302
344
  }, e.currentTarget.setPointerCapture(e.pointerId), e.preventDefault();
303
345
  }
304
346
  _onGrowPointerMove(e) {
305
347
  let t = this._resizeState;
306
348
  if (!t || e.pointerId !== t.pointerId) return;
307
- let r = Math.max(I, t.baseWidth + i(e.clientX - t.startX, this)), a = Math.max(L, t.baseHeight + i(e.clientY - t.startY, this));
308
- this.width = n(r, this), this.height = n(a, this);
349
+ let n = r(Math.max(L, t.baseWidth + a(e.clientX - t.startX, this)), this), i = r(Math.max(R, t.baseHeight + a(e.clientY - t.startY, this)), this);
350
+ (n !== this.width || i !== this.height) && (t.emitPending = !0, t.resized = !0), this.width = n, this.height = i;
309
351
  }
310
- _onGrowPointerEnd(e) {
311
- let t = this._resizeState;
312
- if (!t || e.pointerId !== t.pointerId) return;
352
+ _onGrowPointerEnd(t) {
353
+ let n = this._resizeState;
354
+ if (!n || t.pointerId !== n.pointerId) return;
313
355
  this._resizeState = null;
314
- let n = e.currentTarget;
315
- n.hasPointerCapture(e.pointerId) && n.releasePointerCapture(e.pointerId);
356
+ let r = t.currentTarget;
357
+ r.hasPointerCapture(t.pointerId) && r.releasePointerCapture(t.pointerId), n.resized && e(this, "vf-resize", {
358
+ width: this.width,
359
+ height: this.height,
360
+ commit: !0
361
+ });
316
362
  }
317
363
  render() {
318
364
  return N`
@@ -322,10 +368,10 @@ var I = 80, L = 54, R = 24, z = 8, B = class extends C(s(j)) {
322
368
  role="group"
323
369
  aria-labelledby=${this.heading ? "title" : P}
324
370
  >
325
- ${E(this._drag, N`
326
- ${this.closable ? D(O("Close", this.heading), this._onCloseClick) : P}
371
+ ${D(this._drag, N`
372
+ ${this.closable ? O(k("Close", this.heading), this._onCloseClick) : P}
327
373
  <span class="vf-title" part="title" id="title">${this.heading}</span>
328
- ${this.zoomable ? k(O("Zoom", this.heading), this._onZoomClick) : P}
374
+ ${this.zoomable ? A(k("Zoom", this.heading), this._onZoomClick) : P}
329
375
  `, this.variant === "utility" ? "vf-dots" : "vf-stripes", this.variant === "utility" ? this._dotsTexture() : void 0)}
330
376
  <div class="body" part="body">
331
377
  ${this.scrollbars ? N`
@@ -339,6 +385,9 @@ var I = 80, L = 54, R = 24, z = 8, B = class extends C(s(j)) {
339
385
  </vf-scroll-area>
340
386
  ` : N`<slot></slot>`}
341
387
  </div>
388
+ <div class="status ${this._hasStatus ? "" : "empty"}" part="status-bar">
389
+ <slot name="status" @slotchange=${this._onStatusSlotChange}></slot>
390
+ </div>
342
391
  ${this.resizable ? N`
343
392
  <div
344
393
  class="grow"
@@ -354,24 +403,24 @@ var I = 80, L = 54, R = 24, z = 8, B = class extends C(s(j)) {
354
403
  `;
355
404
  }
356
405
  };
357
- a([F({ reflect: !0 })], B.prototype, "variant", void 0), a([F()], B.prototype, "heading", void 0), a([F({
406
+ o([F({ reflect: !0 })], V.prototype, "variant", void 0), o([F()], V.prototype, "heading", void 0), o([F({
358
407
  type: Boolean,
359
408
  reflect: !0
360
- })], B.prototype, "active", void 0), a([F({
409
+ })], V.prototype, "active", void 0), o([F({
361
410
  type: Boolean,
362
411
  reflect: !0
363
- })], B.prototype, "closable", void 0), a([F({
412
+ })], V.prototype, "closable", void 0), o([F({
364
413
  type: Boolean,
365
414
  reflect: !0
366
- })], B.prototype, "zoomable", void 0), a([F({
415
+ })], V.prototype, "zoomable", void 0), o([F({
367
416
  type: Boolean,
368
417
  reflect: !0
369
- })], B.prototype, "movable", void 0), a([F({
418
+ })], V.prototype, "movable", void 0), o([F({
370
419
  type: Boolean,
371
420
  reflect: !0
372
- })], B.prototype, "resizable", void 0), a([F({
421
+ })], V.prototype, "resizable", void 0), o([F({
373
422
  type: Boolean,
374
423
  reflect: !0
375
- })], B.prototype, "flush", void 0), a([F({ reflect: !0 })], B.prototype, "scrollbars", void 0), B = a([e("vf-window")], B);
424
+ })], V.prototype, "flush", void 0), o([F({ reflect: !0 })], V.prototype, "scrollbars", void 0), o([I()], V.prototype, "_hasStatus", void 0), V = o([t("vf-window")], V);
376
425
  //#endregion
377
- export { B as VfWindow };
426
+ export { V as VfWindow };
package/dist/index.js CHANGED
@@ -1,31 +1,31 @@
1
- import { defineElement as e, vfElement as t } from "./define.js";
2
- import { CLASSIC_DPI as n, CSS_REFERENCE_DPI as r, SYSTEM_PX_IN_CSS_PX as i, devicePxPerSystemPx as a, getZoom as o, onZoomChange as s, resetZoomBaseline as c, truePixelRatio as l } from "./zoom.js";
3
- import { ScaleController as u, applyScale as d, effectiveScale as f, getScale as p, onScaleChange as m, snapSys as h, snapToDevicePx as g, snapToSystemPx as _, sys as v, sysLength as y, sysLengths as b, systemPxQuantum as x, toSys as S, toSysExact as C } from "./scale.js";
4
- import { PlacementController as w, VfPositioned as T } from "./position.js";
5
- import { PIXEL_GRID_METRICS as E, registerEmbeddedFont as D } from "./styles/register-embedded-font.js";
6
- import { VF_BODY_FAMILY as O, registerBodyFace as k } from "./styles/body-font.js";
7
- import { vfBodyDecls as A } from "./styles/recipes/body-face.js";
8
- import { VF_DISPLAY_FAMILY as j, registerDisplayFace as M } from "./styles/display-font.js";
9
- import { vfDisplay as N, vfDisplayDecls as P } from "./styles/recipes/display-face.js";
10
- import { vfBase as F } from "./styles/recipes/host.js";
11
- import { vfStaticText as I } from "./styles/recipes/static-text.js";
12
- import { TILE_LATTICE as L, tileImage as R, tileRaster as z, tileRects as B, tileSpan as V, vfTileMaskSize as H, vfTileSize as U } from "./styles/recipes/tile.js";
13
- import { vfDots as W, vfStripes as G } from "./styles/recipes/pattern.js";
14
- import { vfHardShadowDecls as K } from "./styles/recipes/shadow.js";
15
- import { vfChromeFrame as q, vfModalFrame as J, vfPanel as Y } from "./styles/recipes/surface.js";
16
- import { vfTitleBar as X, vfWindowWidgets as Z } from "./styles/recipes/title-bar.js";
17
- import { vfFocus as Q, vfFocusRing as $, vfFocusUnderline as ee } from "./styles/recipes/focus.js";
18
- import { vfToggle as te } from "./styles/recipes/toggle.js";
19
- import { vfField as ne } from "./styles/recipes/field.js";
20
- import { vfScrollRail as re } from "./styles/recipes/scroll-rail.js";
21
- import { TileRasterCache as ie, patternOverride as ae, tileGrid as oe, vfTileGrid as se } from "./tile-grid.js";
22
- import { GridSnapController as ce, requestGridSnap as le } from "./grid-snap.js";
23
- import { DocumentListenersController as ue } from "./document-listeners.js";
24
- import { BUTTON_FACE as de, BUTTON_FRAME as fe, RING_FRAME as pe, RING_HOLE as me, RING_INSET as he, SCREEN_CORNER as ge, steppedCornerClip as _e, steppedRectClip as ve, steppedRingClip as ye } from "./pixel-frame.js";
25
- import { VfDesktop as be } from "./components/vf-desktop.js";
26
- import { VfSized as xe } from "./size.js";
27
- import { DragController as Se } from "./drag.js";
28
- import { emit as Ce } from "./events.js";
1
+ import { emit as e } from "./events.js";
2
+ import { defineElement as t, vfElement as n } from "./define.js";
3
+ import { CLASSIC_DPI as r, CSS_REFERENCE_DPI as i, SYSTEM_PX_IN_CSS_PX as a, devicePxPerSystemPx as o, getZoom as s, onZoomChange as c, resetZoomBaseline as l, truePixelRatio as u } from "./zoom.js";
4
+ import { ScaleController as d, applyScale as f, effectiveScale as p, getScale as m, onScaleChange as h, snapSys as g, snapToDevicePx as _, snapToSystemPx as v, sys as y, sysLength as b, sysLengths as x, systemPxQuantum as S, toSys as C, toSysExact as w } from "./scale.js";
5
+ import { PlacementController as T, VfPositioned as E } from "./position.js";
6
+ import { PIXEL_GRID_METRICS as D, registerEmbeddedFont as O } from "./styles/register-embedded-font.js";
7
+ import { VF_BODY_FAMILY as k, registerBodyFace as A } from "./styles/body-font.js";
8
+ import { vfBodyDecls as j } from "./styles/recipes/body-face.js";
9
+ import { VF_DISPLAY_FAMILY as M, registerDisplayFace as N } from "./styles/display-font.js";
10
+ import { vfDisplay as P, vfDisplayDecls as F } from "./styles/recipes/display-face.js";
11
+ import { vfBase as I } from "./styles/recipes/host.js";
12
+ import { vfStaticText as L } from "./styles/recipes/static-text.js";
13
+ import { TILE_LATTICE as R, tileImage as z, tileRaster as B, tileRects as V, tileSpan as H, vfTileMaskSize as U, vfTileSize as W } from "./styles/recipes/tile.js";
14
+ import { vfDots as G, vfStripes as K } from "./styles/recipes/pattern.js";
15
+ import { vfHardShadowDecls as q } from "./styles/recipes/shadow.js";
16
+ import { vfChromeFrame as J, vfModalFrame as Y, vfPanel as X } from "./styles/recipes/surface.js";
17
+ import { vfTitleBar as Z, vfWindowWidgets as Q } from "./styles/recipes/title-bar.js";
18
+ import { vfFocus as $, vfFocusRing as ee, vfFocusUnderline as te } from "./styles/recipes/focus.js";
19
+ import { vfToggle as ne } from "./styles/recipes/toggle.js";
20
+ import { vfField as re } from "./styles/recipes/field.js";
21
+ import { vfScrollRail as ie } from "./styles/recipes/scroll-rail.js";
22
+ import { TileRasterCache as ae, patternOverride as oe, tileGrid as se, vfTileGrid as ce } from "./tile-grid.js";
23
+ import { GridSnapController as le, requestGridSnap as ue } from "./grid-snap.js";
24
+ import { DocumentListenersController as de } from "./document-listeners.js";
25
+ import { BUTTON_FACE as fe, BUTTON_FRAME as pe, RING_FRAME as me, RING_HOLE as he, RING_INSET as ge, SCREEN_CORNER as _e, steppedCornerClip as ve, steppedRectClip as ye, steppedRingClip as be } from "./pixel-frame.js";
26
+ import { VfDesktop as xe } from "./components/vf-desktop.js";
27
+ import { VfSized as Se } from "./size.js";
28
+ import { DragController as Ce } from "./drag.js";
29
29
  import { ScrollStateController as we } from "./scroll-state.js";
30
30
  import { BLINK_FLIPS as Te, BLINK_INTERVAL_MS as Ee, PRESS_HOLD_MS as De, RENAME_DELAY_MS as Oe, prefersReducedMotion as ke, runSelectionBlink as Ae } from "./motion.js";
31
31
  import { CARET_DOWN as je, CHECKBOX_X as Me, CHECKMARK as Ne, RADIO_DOT as Pe, RADIO_FACE as Fe, RADIO_RING as Ie, RADIO_RING_PRESSED as Le, SLIDER_THUMB as Re, SLIDER_THUMB_FACE as ze, STEPPER as Be, STEPPER_DOWN_FILL as Ve, STEPPER_UP_FILL as He, glyphSvg as Ue } from "./glyphs.js";
@@ -68,4 +68,4 @@ import { VfStack as kt } from "./components/vf-stack.js";
68
68
  import { VfContainer as At } from "./components/vf-container.js";
69
69
  import { CURSOR_ARROW as jt, CURSOR_CROSSHAIR as Mt, CURSOR_I_BEAM as Nt, CURSOR_WAIT as Pt } from "./cursor-art.js";
70
70
  import { applyCursor as Ft } from "./cursor.js";
71
- export { Te as BLINK_FLIPS, Ee as BLINK_INTERVAL_MS, de as BUTTON_FACE, fe as BUTTON_FRAME, je as CARET_DOWN, Me as CHECKBOX_X, Ne as CHECKMARK, n as CLASSIC_DPI, r as CSS_REFERENCE_DPI, jt as CURSOR_ARROW, Mt as CURSOR_CROSSHAIR, Nt as CURSOR_I_BEAM, Pt as CURSOR_WAIT, ue as DocumentListenersController, Se as DragController, ot as FocusRuleController, ce as GridSnapController, E as PIXEL_GRID_METRICS, De as PRESS_HOLD_MS, w as PlacementController, Pe as RADIO_DOT, Fe as RADIO_FACE, Ie as RADIO_RING, Le as RADIO_RING_PRESSED, Oe as RENAME_DELAY_MS, pe as RING_FRAME, me as RING_HOLE, he as RING_INSET, ge as SCREEN_CORNER, Re as SLIDER_THUMB, ze as SLIDER_THUMB_FACE, Be as STEPPER, Ve as STEPPER_DOWN_FILL, He as STEPPER_UP_FILL, i as SYSTEM_PX_IN_CSS_PX, u as ScaleController, We as ScrollRailController, we as ScrollStateController, L as TILE_LATTICE, ie as TileRasterCache, ht as TrackWidthController, O as VF_BODY_FAMILY, j as VF_DISPLAY_FAMILY, et as VfButton, Xe as VfButtonGroup, rt as VfCheckbox, At as VfContainer, be as VfDesktop, Ze as VfDialog, Dt as VfFieldset, $e as VfFormControl, Ot as VfGrid, xt as VfIcon, bt as VfImg, vt as VfLabel, Tt as VfList, Et as VfListItem, Ct as VfMenu, St as VfMenuBar, wt as VfMenuItem, Je as VfModalDialog, ft as VfNumberField, pt as VfOption, yt as VfParagraph, T as VfPositioned, gt as VfProgressBar, it as VfRadio, at as VfRadioGroup, Ke as VfScrollArea, mt as VfSelect, Qe as VfSeparator, xe as VfSized, _t as VfSlider, kt as VfStack, tt as VfSwatch, dt as VfTextArea, lt as VfTextControlBase, ut as VfTextField, nt as VfToggleControl, qe as VfWindow, Ft as applyCursor, d as applyScale, e as defineElement, a as devicePxPerSystemPx, f as effectiveScale, Ce as emit, st as focusModality, p as getScale, o as getZoom, Ue as glyphSvg, Ye as modalDialogStyles, m as onScaleChange, s as onZoomChange, ae as patternOverride, ke as prefersReducedMotion, k as registerBodyFace, M as registerDisplayFace, D as registerEmbeddedFont, Ge as renderScrollRail, le as requestGridSnap, c as resetZoomBaseline, Ae as runSelectionBlink, h as snapSys, g as snapToDevicePx, _ as snapToSystemPx, _e as steppedCornerClip, ve as steppedRectClip, ye as steppedRingClip, v as sys, y as sysLength, b as sysLengths, x as systemPxQuantum, oe as tileGrid, R as tileImage, z as tileRaster, B as tileRects, V as tileSpan, S as toSys, C as toSysExact, ct as trackFocusModality, l as truePixelRatio, F as vfBase, A as vfBodyDecls, q as vfChromeFrame, N as vfDisplay, P as vfDisplayDecls, W as vfDots, t as vfElement, ne as vfField, Q as vfFocus, $ as vfFocusRing, ee as vfFocusUnderline, K as vfHardShadowDecls, J as vfModalFrame, Y as vfPanel, re as vfScrollRail, I as vfStaticText, G as vfStripes, se as vfTileGrid, H as vfTileMaskSize, U as vfTileSize, X as vfTitleBar, te as vfToggle, Z as vfWindowWidgets };
71
+ export { Te as BLINK_FLIPS, Ee as BLINK_INTERVAL_MS, fe as BUTTON_FACE, pe as BUTTON_FRAME, je as CARET_DOWN, Me as CHECKBOX_X, Ne as CHECKMARK, r as CLASSIC_DPI, i as CSS_REFERENCE_DPI, jt as CURSOR_ARROW, Mt as CURSOR_CROSSHAIR, Nt as CURSOR_I_BEAM, Pt as CURSOR_WAIT, de as DocumentListenersController, Ce as DragController, ot as FocusRuleController, le as GridSnapController, D as PIXEL_GRID_METRICS, De as PRESS_HOLD_MS, T as PlacementController, Pe as RADIO_DOT, Fe as RADIO_FACE, Ie as RADIO_RING, Le as RADIO_RING_PRESSED, Oe as RENAME_DELAY_MS, me as RING_FRAME, he as RING_HOLE, ge as RING_INSET, _e as SCREEN_CORNER, Re as SLIDER_THUMB, ze as SLIDER_THUMB_FACE, Be as STEPPER, Ve as STEPPER_DOWN_FILL, He as STEPPER_UP_FILL, a as SYSTEM_PX_IN_CSS_PX, d as ScaleController, We as ScrollRailController, we as ScrollStateController, R as TILE_LATTICE, ae as TileRasterCache, ht as TrackWidthController, k as VF_BODY_FAMILY, M as VF_DISPLAY_FAMILY, et as VfButton, Xe as VfButtonGroup, rt as VfCheckbox, At as VfContainer, xe as VfDesktop, Ze as VfDialog, Dt as VfFieldset, $e as VfFormControl, Ot as VfGrid, xt as VfIcon, bt as VfImg, vt as VfLabel, Tt as VfList, Et as VfListItem, Ct as VfMenu, St as VfMenuBar, wt as VfMenuItem, Je as VfModalDialog, ft as VfNumberField, pt as VfOption, yt as VfParagraph, E as VfPositioned, gt as VfProgressBar, it as VfRadio, at as VfRadioGroup, Ke as VfScrollArea, mt as VfSelect, Qe as VfSeparator, Se as VfSized, _t as VfSlider, kt as VfStack, tt as VfSwatch, dt as VfTextArea, lt as VfTextControlBase, ut as VfTextField, nt as VfToggleControl, qe as VfWindow, Ft as applyCursor, f as applyScale, t as defineElement, o as devicePxPerSystemPx, p as effectiveScale, e as emit, st as focusModality, m as getScale, s as getZoom, Ue as glyphSvg, Ye as modalDialogStyles, h as onScaleChange, c as onZoomChange, oe as patternOverride, ke as prefersReducedMotion, A as registerBodyFace, N as registerDisplayFace, O as registerEmbeddedFont, Ge as renderScrollRail, ue as requestGridSnap, l as resetZoomBaseline, Ae as runSelectionBlink, g as snapSys, _ as snapToDevicePx, v as snapToSystemPx, ve as steppedCornerClip, ye as steppedRectClip, be as steppedRingClip, y as sys, b as sysLength, x as sysLengths, S as systemPxQuantum, se as tileGrid, z as tileImage, B as tileRaster, V as tileRects, H as tileSpan, C as toSys, w as toSysExact, ct as trackFocusModality, u as truePixelRatio, I as vfBase, j as vfBodyDecls, J as vfChromeFrame, P as vfDisplay, F as vfDisplayDecls, G as vfDots, n as vfElement, re as vfField, $ as vfFocus, ee as vfFocusRing, te as vfFocusUnderline, q as vfHardShadowDecls, Y as vfModalFrame, X as vfPanel, ie as vfScrollRail, L as vfStaticText, K as vfStripes, ce as vfTileGrid, U as vfTileMaskSize, W as vfTileSize, Z as vfTitleBar, ne as vfToggle, Q as vfWindowWidgets };
@@ -1,6 +1,6 @@
1
- import { ScaleController as e, onScaleChange as t, snapSys as n, sysLength as r, toSysExact as i } from "./scale.js";
2
- import a from "./_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
3
- import { emit as o } from "./events.js";
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
4
  import { LitElement as s, css as c } from "lit";
5
5
  import { property as l, query as u } from "lit/decorators.js";
6
6
  var d = 24, f = c`
@@ -43,13 +43,13 @@ var d = 24, f = c`
43
43
  cursor: var(--vf-cursor, default);
44
44
  }
45
45
  `, p = class extends s {
46
- constructor(...t) {
47
- super(...t), this.scale = new e(this), this.open = !1, this.#e = !1, this.#n = null, this.#r = null, this.#l = () => this.settle();
46
+ constructor(...e) {
47
+ super(...e), this.scale = new t(this), this.open = !1, this.#e = !1, this.#n = null, this.#r = null, this.#l = () => this.settle();
48
48
  }
49
49
  get dialogSize() {
50
50
  return {
51
- width: r(this.width ?? 260),
52
- height: this.height === void 0 ? null : r(this.height)
51
+ width: i(this.width ?? 260),
52
+ height: this.height === void 0 ? null : i(this.height)
53
53
  };
54
54
  }
55
55
  #e;
@@ -75,12 +75,12 @@ var d = 24, f = c`
75
75
  #i() {
76
76
  let e = document.documentElement;
77
77
  return {
78
- width: i(e.clientWidth || window.innerWidth, this),
79
- height: i(e.clientHeight || window.innerHeight, this)
78
+ width: a(e.clientWidth || window.innerWidth, this),
79
+ height: a(e.clientHeight || window.innerHeight, this)
80
80
  };
81
81
  }
82
82
  #a(e, t) {
83
- let n = this.#i(), r = i(this._dialog?.offsetWidth ?? 0, this);
83
+ let n = this.#i(), r = a(this._dialog?.offsetWidth ?? 0, this);
84
84
  return {
85
85
  x: Math.min(Math.max(e, d - r), n.width - d),
86
86
  y: Math.min(Math.max(t, 0), Math.max(0, n.height - d))
@@ -89,13 +89,13 @@ var d = 24, f = c`
89
89
  #o() {
90
90
  let e = this.#i(), t = this._dialog?.getBoundingClientRect();
91
91
  return {
92
- x: (e.width - i(t?.width ?? 0, this)) / 2,
93
- y: (e.height - i(t?.height ?? 0, this)) / 2
92
+ x: (e.width - a(t?.width ?? 0, this)) / 2,
93
+ y: (e.height - a(t?.height ?? 0, this)) / 2
94
94
  };
95
95
  }
96
96
  placeAt(e, t) {
97
- let r = this.#a(e, t);
98
- this.left = n(r.x, this), this.top = n(r.y, this);
97
+ let n = this.#a(e, t);
98
+ this.left = r(n.x, this), this.top = r(n.y, this);
99
99
  }
100
100
  settle() {
101
101
  let e = this._dialog;
@@ -103,8 +103,8 @@ var d = 24, f = c`
103
103
  let t = this.left != null || this.top != null ? {
104
104
  x: this.left ?? 0,
105
105
  y: this.top ?? 0
106
- } : this.#o(), i = this.#a(t.x, t.y);
107
- e.style.left = r(n(i.x, this)), e.style.top = r(n(i.y, this)), e.style.right = "auto", e.style.bottom = "auto", e.style.margin = "0";
106
+ } : this.#o(), n = this.#a(t.x, t.y);
107
+ 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";
108
108
  }
109
109
  #s() {
110
110
  let e = this._dialog?.style;
@@ -124,7 +124,7 @@ var d = 24, f = c`
124
124
  #u;
125
125
  #d;
126
126
  #f(e) {
127
- typeof ResizeObserver < "u" && !this.#u && (this.#u = new ResizeObserver(this.#l), this.#u.observe(e)), window.addEventListener("resize", this.#l), this.#d ??= t(this.#l);
127
+ typeof ResizeObserver < "u" && !this.#u && (this.#u = new ResizeObserver(this.#l), this.#u.observe(e)), window.addEventListener("resize", this.#l), this.#d ??= n(this.#l);
128
128
  }
129
129
  #p() {
130
130
  this.#u?.disconnect(), this.#u = void 0, window.removeEventListener("resize", this.#l), this.#d?.(), this.#d = void 0;
@@ -143,13 +143,13 @@ var d = 24, f = c`
143
143
  this.#n = "escape";
144
144
  }
145
145
  _onNativeClose() {
146
- let e = this.#n ?? "close";
147
- this.#n = null, this.#r = null, this.#p(), this.open = !1, this.#s(), o(this, "vf-close", { reason: e });
146
+ let t = this.#n ?? "close";
147
+ this.#n = null, this.#r = null, this.#p(), this.open = !1, this.#s(), e(this, "vf-close", { reason: t });
148
148
  }
149
149
  };
150
- a([l({
150
+ o([l({
151
151
  type: Boolean,
152
152
  reflect: !0
153
- })], p.prototype, "open", void 0), a([l({ type: Number })], p.prototype, "width", void 0), a([l({ type: Number })], p.prototype, "height", void 0), a([l({ type: Number })], p.prototype, "top", void 0), a([l({ type: Number })], p.prototype, "left", void 0), a([u("dialog")], p.prototype, "_dialog", void 0);
153
+ })], p.prototype, "open", void 0), o([l({ type: Number })], p.prototype, "width", void 0), o([l({ type: Number })], p.prototype, "height", void 0), o([l({ type: Number })], p.prototype, "top", void 0), o([l({ type: Number })], p.prototype, "left", void 0), o([u("dialog")], p.prototype, "_dialog", void 0);
154
154
  //#endregion
155
155
  export { p as VfModalDialog, f as modalDialogStyles };