vintage-frames 0.14.0 → 0.15.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/README.md +16 -0
  2. package/custom-elements.json +271 -27
  3. package/dist/components/vf-button.d.ts +5 -1
  4. package/dist/components/vf-button.js +1 -1
  5. package/dist/components/vf-container.d.ts +3 -1
  6. package/dist/components/vf-container.js +34 -16
  7. package/dist/components/vf-desktop.d.ts +114 -12
  8. package/dist/components/vf-desktop.js +119 -58
  9. package/dist/components/vf-dialog.d.ts +7 -1
  10. package/dist/components/vf-icon-field.d.ts +1 -1
  11. package/dist/components/vf-icon.js +68 -61
  12. package/dist/components/vf-menu-bar.d.ts +5 -0
  13. package/dist/components/vf-menu-bar.js +67 -43
  14. package/dist/components/vf-window.d.ts +13 -0
  15. package/dist/components/vf-window.js +10 -1
  16. package/dist/events.d.ts +3 -2
  17. package/dist/events.js +3 -3
  18. package/dist/index.d.ts +3 -1
  19. package/dist/index.js +44 -43
  20. package/dist/modal-dialog.d.ts +31 -4
  21. package/dist/modal-dialog.js +98 -82
  22. package/dist/pattern-fill.d.ts +11 -8
  23. package/dist/pattern-fill.js +2 -4
  24. package/dist/position.d.ts +25 -7
  25. package/dist/position.js +31 -23
  26. package/dist/shell/alert.d.ts +40 -0
  27. package/dist/shell/alert.js +41 -0
  28. package/dist/shell/catalog.d.ts +168 -0
  29. package/dist/shell/catalog.js +278 -0
  30. package/dist/shell/clock.d.ts +16 -0
  31. package/dist/shell/clock.js +36 -0
  32. package/dist/shell/filing.d.ts +39 -0
  33. package/dist/shell/filing.js +68 -0
  34. package/dist/shell/finder.d.ts +156 -0
  35. package/dist/shell/finder.js +598 -0
  36. package/dist/shell/geometry.d.ts +196 -0
  37. package/dist/shell/geometry.js +241 -0
  38. package/dist/shell/index.d.ts +27 -0
  39. package/dist/shell/index.js +10 -0
  40. package/dist/shell/shell.d.ts +164 -0
  41. package/dist/shell/shell.js +234 -0
  42. package/dist/shell/state.d.ts +88 -0
  43. package/dist/shell/state.js +103 -0
  44. package/dist/shell/storage.d.ts +14 -0
  45. package/dist/shell/storage.js +41 -0
  46. package/dist/shell/windows.d.ts +234 -0
  47. package/dist/shell/windows.js +387 -0
  48. package/dist/text-control.d.ts +6 -0
  49. package/dist/text-control.js +2 -2
  50. package/dist/window-chrome.d.ts +43 -0
  51. package/dist/window-chrome.js +13 -0
  52. package/docs/SPEC.md +17 -16
  53. package/editor/vscode.html-custom-data.json +11 -6
  54. package/editor/web-types.json +55 -14
  55. package/package.json +10 -2
package/dist/index.js CHANGED
@@ -31,46 +31,47 @@ import { VfDesktop as He } from "./components/vf-desktop.js";
31
31
  import { VfSized as Ue } from "./size.js";
32
32
  import { DragController as We } from "./drag.js";
33
33
  import { BLINK_FLIPS as Ge, BLINK_INTERVAL_MS as Ke, DRAG_SLOP_COARSE_PX as qe, DRAG_SLOP_PX as Je, PRESS_HOLD_MS as Ye, RENAME_DELAY_MS as Xe, TAP_PAIR_MS as Ze, TAP_PAIR_SLOP_PX as Qe, WALK_BEAT_MS as $e, WALK_STEP_MS as et, WALK_STEP_PX as tt, WINDOW_RECTS_VISIBLE as nt, WINDOW_RECT_RATIO as rt, WINDOW_RECT_STEPS as it, WINDOW_RECT_STEP_MS as at, dragSlop as ot, prefersReducedMotion as st, runOutlineTravel as ct, runSelectionBlink as lt, windowRectFraction as ut } from "./motion.js";
34
- import { ScrollStateController as dt } from "./scroll-state.js";
35
- import { CARET_DOWN as ft, CARET_DOWN_SMALL as pt, CHECKBOX_X as mt, CHECKMARK as ht, RADIO_DOT as gt, RADIO_FACE as _t, RADIO_RING as vt, RADIO_RING_PRESSED as yt, SLIDER_THUMB as bt, SLIDER_THUMB_FACE as xt, STEPPER as St, STEPPER_DOWN_FILL as Ct, STEPPER_UP_FILL as wt, glyphSvg as Tt } from "./glyphs.js";
36
- import { ScrollRailController as Et, renderScrollRail as Dt } from "./scroll-rail.js";
37
- import { VfScrollArea as Ot } from "./components/vf-scroll-area.js";
38
- import { VfWindow as kt } from "./components/vf-window.js";
39
- import { VfModalDialog as At, modalDialogStyles as jt } from "./modal-dialog.js";
40
- import { VfDialog as Mt } from "./components/vf-dialog.js";
41
- import { VfSeparator as Nt } from "./components/vf-separator.js";
42
- import { VfFormControl as Pt } from "./form-control.js";
43
- import { VfButton as Ft } from "./components/vf-button.js";
44
- import { VfButtonGroup as It } from "./components/vf-button-group.js";
45
- import { VfSwatch as Lt } from "./components/vf-swatch.js";
46
- import { VfToggleControl as Rt } from "./toggle-control.js";
47
- import { VfCheckbox as zt } from "./components/vf-checkbox.js";
48
- import { VfRadio as Bt } from "./components/vf-radio.js";
49
- import { VfRadioGroup as Vt } from "./components/vf-radio-group.js";
50
- import { FocusRuleController as Ht, focusModality as Ut, trackFocusModality as Wt } from "./focus-modality.js";
51
- import { VfTextControlBase as Gt } from "./text-control.js";
52
- import { VfTextField as Kt } from "./components/vf-text-field.js";
53
- import { VfTextArea as qt } from "./components/vf-text-area.js";
54
- import { VfNumberField as Jt } from "./components/vf-number-field.js";
55
- import { VfOption as Yt } from "./components/vf-option.js";
56
- import { VfSelect as Xt } from "./components/vf-select.js";
57
- import { TrackWidthController as Zt } from "./track-width.js";
58
- import { VfProgressBar as Qt } from "./components/vf-progress-bar.js";
59
- import { VfSlider as $t } from "./components/vf-slider.js";
60
- import { VfLabel as en } from "./components/vf-label.js";
61
- import { VfParagraph as tn } from "./components/vf-paragraph.js";
62
- import { VfImg as nn } from "./components/vf-img.js";
63
- import { VfIcon as rn } from "./components/vf-icon.js";
64
- import { VfIconField as an } from "./components/vf-icon-field.js";
65
- import { VfMenuBar as on } from "./components/vf-menu-bar.js";
66
- import { VfMenu as sn } from "./components/vf-menu.js";
67
- import { VfMenuItem as cn } from "./components/vf-menu-item.js";
68
- import { VfList as ln } from "./components/vf-list.js";
69
- import { VfListItem as un } from "./components/vf-list-item.js";
70
- import { VfFieldset as dn } from "./components/vf-fieldset.js";
71
- import { VfGrid as fn } from "./components/vf-grid.js";
72
- import { VfStack as pn } from "./components/vf-stack.js";
73
- import { VfContainer as mn } from "./components/vf-container.js";
74
- import { CURSOR_ARROW as hn, CURSOR_CROSSHAIR as gn, CURSOR_I_BEAM as _n, CURSOR_WAIT as vn } from "./cursor-art.js";
75
- import { applyCursor as yn } from "./cursor.js";
76
- export { Ge as BLINK_FLIPS, Ke as BLINK_INTERVAL_MS, Ne as BUTTON_FACE, Pe as BUTTON_FRAME, ft as CARET_DOWN, pt as CARET_DOWN_SMALL, mt as CHECKBOX_X, ht as CHECKMARK, r as CLASSIC_DPI, i as CSS_REFERENCE_DPI, hn as CURSOR_ARROW, gn as CURSOR_CROSSHAIR, _n as CURSOR_I_BEAM, vn as CURSOR_WAIT, qe as DRAG_SLOP_COARSE_PX, Je as DRAG_SLOP_PX, Me as DocumentListenersController, We as DragController, Ht as FocusRuleController, Ae as GridSnapController, $ as PATTERNS, ee as PATTERN_NAMES, te as PATTERN_SIZE, D as PIXEL_GRID_METRICS, Ye as PRESS_HOLD_MS, Oe as PatternFillController, T as PlacementController, gt as RADIO_DOT, _t as RADIO_FACE, vt as RADIO_RING, yt as RADIO_RING_PRESSED, Xe as RENAME_DELAY_MS, G as REPEAT_TILE, Fe as RING_FRAME, Ie as RING_HOLE, Le as RING_INSET, ge as RULE_EDGES, K as RepeatTileController, Re as SCREEN_CORNER, bt as SLIDER_THUMB, xt as SLIDER_THUMB_FACE, St as STEPPER, Ct as STEPPER_DOWN_FILL, wt as STEPPER_UP_FILL, a as SYSTEM_PX_IN_CSS_PX, d as ScaleController, Et as ScrollRailController, dt as ScrollStateController, Ze as TAP_PAIR_MS, Qe as TAP_PAIR_SLOP_PX, R as TILE_LATTICE, Zt as TrackWidthController, k as VF_BODY_FAMILY, M as VF_DISPLAY_FAMILY, Ft as VfButton, It as VfButtonGroup, zt as VfCheckbox, mn as VfContainer, He as VfDesktop, Mt as VfDialog, dn as VfFieldset, Pt as VfFormControl, fn as VfGrid, rn as VfIcon, an as VfIconField, nn as VfImg, en as VfLabel, ln as VfList, un as VfListItem, sn as VfMenu, on as VfMenuBar, cn as VfMenuItem, At as VfModalDialog, Jt as VfNumberField, Yt as VfOption, tn as VfParagraph, E as VfPositioned, Qt as VfProgressBar, Bt as VfRadio, Vt as VfRadioGroup, Ot as VfScrollArea, Xt as VfSelect, Nt as VfSeparator, Ue as VfSized, $t as VfSlider, pn as VfStack, Lt as VfSwatch, qt as VfTextArea, Gt as VfTextControlBase, Kt as VfTextField, Rt as VfToggleControl, kt as VfWindow, $e as WALK_BEAT_MS, et as WALK_STEP_MS, tt as WALK_STEP_PX, nt as WINDOW_RECTS_VISIBLE, rt as WINDOW_RECT_RATIO, it as WINDOW_RECT_STEPS, at as WINDOW_RECT_STEP_MS, yn as applyCursor, f as applyScale, t as defineElement, q as devicePxAt, o as devicePxPerSystemPx, ot as dragSlop, p as effectiveScale, e as emit, Ut as focusModality, m as getScale, s as getZoom, Tt as glyphSvg, jt as modalDialogStyles, h as onScaleChange, c as onZoomChange, ne as parsePattern, _e as parseRule, re as patternHex, ie as patternMotif, J as patternOverride, ae as patternRects, st as prefersReducedMotion, A as registerBodyFace, N as registerDisplayFace, O as registerEmbeddedFont, Dt as renderScrollRail, Y as repeatTile, je as requestGridSnap, l as resetZoomBaseline, ve as ruleClasses, ct as runOutlineTravel, lt as runSelectionBlink, g as snapSys, _ as snapToDevicePx, v as snapToSystemPx, ze as steppedCornerClip, Be as steppedRectClip, Ve as steppedRingClip, y as sys, b as sysLength, x as sysLengths, S as systemPxQuantum, X as tileGrid, z as tileImage, B as tileRaster, V as tileRects, H as tileSpan, C as toSys, w as toSysExact, Wt as trackFocusModality, u as truePixelRatio, I as vfBase, j as vfBodyDecls, pe as vfChromeFrame, P as vfDisplay, F as vfDisplayDecls, oe as vfDots, n as vfElement, Ee as vfField, Se as vfFocus, Ce as vfFocusRing, we as vfFocusUnderline, ce as vfHardShadow, le as vfHardShadowDecls, me as vfModalFrame, he as vfPanel, ke as vfPatternFill, Z as vfRepeatTileSize, ye as vfRule, De as vfScrollRail, L as vfStaticText, se as vfStripes, ue as vfStrokeDecls, de as vfStrokeInset, fe as vfStrokeShadow, Q as vfTileGrid, U as vfTileMaskSize, W as vfTileSize, be as vfTitleBar, Te as vfToggle, xe as vfWindowWidgets, ut as windowRectFraction };
34
+ import { WINDOW_MIN_HEIGHT as dt, WINDOW_MIN_WIDTH as ft, windowChrome as pt } from "./window-chrome.js";
35
+ import { ScrollStateController as mt } from "./scroll-state.js";
36
+ import { CARET_DOWN as ht, CARET_DOWN_SMALL as gt, CHECKBOX_X as _t, CHECKMARK as vt, RADIO_DOT as yt, RADIO_FACE as bt, RADIO_RING as xt, RADIO_RING_PRESSED as St, SLIDER_THUMB as Ct, SLIDER_THUMB_FACE as wt, STEPPER as Tt, STEPPER_DOWN_FILL as Et, STEPPER_UP_FILL as Dt, glyphSvg as Ot } from "./glyphs.js";
37
+ import { ScrollRailController as kt, renderScrollRail as At } from "./scroll-rail.js";
38
+ import { VfScrollArea as jt } from "./components/vf-scroll-area.js";
39
+ import { VfWindow as Mt } from "./components/vf-window.js";
40
+ import { VfModalDialog as Nt, modalDialogStyles as Pt } from "./modal-dialog.js";
41
+ import { VfDialog as Ft } from "./components/vf-dialog.js";
42
+ import { VfSeparator as It } from "./components/vf-separator.js";
43
+ import { VfFormControl as Lt } from "./form-control.js";
44
+ import { VfButton as Rt } from "./components/vf-button.js";
45
+ import { VfButtonGroup as zt } from "./components/vf-button-group.js";
46
+ import { VfSwatch as Bt } from "./components/vf-swatch.js";
47
+ import { VfToggleControl as Vt } from "./toggle-control.js";
48
+ import { VfCheckbox as Ht } from "./components/vf-checkbox.js";
49
+ import { VfRadio as Ut } from "./components/vf-radio.js";
50
+ import { VfRadioGroup as Wt } from "./components/vf-radio-group.js";
51
+ import { FocusRuleController as Gt, focusModality as Kt, trackFocusModality as qt } from "./focus-modality.js";
52
+ import { VfTextControlBase as Jt } from "./text-control.js";
53
+ import { VfTextField as Yt } from "./components/vf-text-field.js";
54
+ import { VfTextArea as Xt } from "./components/vf-text-area.js";
55
+ import { VfNumberField as Zt } from "./components/vf-number-field.js";
56
+ import { VfOption as Qt } from "./components/vf-option.js";
57
+ import { VfSelect as $t } from "./components/vf-select.js";
58
+ import { TrackWidthController as en } from "./track-width.js";
59
+ import { VfProgressBar as tn } from "./components/vf-progress-bar.js";
60
+ import { VfSlider as nn } from "./components/vf-slider.js";
61
+ import { VfLabel as rn } from "./components/vf-label.js";
62
+ import { VfParagraph as an } from "./components/vf-paragraph.js";
63
+ import { VfImg as on } from "./components/vf-img.js";
64
+ import { VfIcon as sn } from "./components/vf-icon.js";
65
+ import { VfIconField as cn } from "./components/vf-icon-field.js";
66
+ import { VfMenuBar as ln } from "./components/vf-menu-bar.js";
67
+ import { VfMenu as un } from "./components/vf-menu.js";
68
+ import { VfMenuItem as dn } from "./components/vf-menu-item.js";
69
+ import { VfList as fn } from "./components/vf-list.js";
70
+ import { VfListItem as pn } from "./components/vf-list-item.js";
71
+ import { VfFieldset as mn } from "./components/vf-fieldset.js";
72
+ import { VfGrid as hn } from "./components/vf-grid.js";
73
+ import { VfStack as gn } from "./components/vf-stack.js";
74
+ import { VfContainer as _n } from "./components/vf-container.js";
75
+ import { CURSOR_ARROW as vn, CURSOR_CROSSHAIR as yn, CURSOR_I_BEAM as bn, CURSOR_WAIT as xn } from "./cursor-art.js";
76
+ import { applyCursor as Sn } from "./cursor.js";
77
+ export { Ge as BLINK_FLIPS, Ke as BLINK_INTERVAL_MS, Ne as BUTTON_FACE, Pe as BUTTON_FRAME, ht as CARET_DOWN, gt as CARET_DOWN_SMALL, _t as CHECKBOX_X, vt as CHECKMARK, r as CLASSIC_DPI, i as CSS_REFERENCE_DPI, vn as CURSOR_ARROW, yn as CURSOR_CROSSHAIR, bn as CURSOR_I_BEAM, xn as CURSOR_WAIT, qe as DRAG_SLOP_COARSE_PX, Je as DRAG_SLOP_PX, Me as DocumentListenersController, We as DragController, Gt as FocusRuleController, Ae as GridSnapController, $ as PATTERNS, ee as PATTERN_NAMES, te as PATTERN_SIZE, D as PIXEL_GRID_METRICS, Ye as PRESS_HOLD_MS, Oe as PatternFillController, T as PlacementController, yt as RADIO_DOT, bt as RADIO_FACE, xt as RADIO_RING, St as RADIO_RING_PRESSED, Xe as RENAME_DELAY_MS, G as REPEAT_TILE, Fe as RING_FRAME, Ie as RING_HOLE, Le as RING_INSET, ge as RULE_EDGES, K as RepeatTileController, Re as SCREEN_CORNER, Ct as SLIDER_THUMB, wt as SLIDER_THUMB_FACE, Tt as STEPPER, Et as STEPPER_DOWN_FILL, Dt as STEPPER_UP_FILL, a as SYSTEM_PX_IN_CSS_PX, d as ScaleController, kt as ScrollRailController, mt as ScrollStateController, Ze as TAP_PAIR_MS, Qe as TAP_PAIR_SLOP_PX, R as TILE_LATTICE, en as TrackWidthController, k as VF_BODY_FAMILY, M as VF_DISPLAY_FAMILY, Rt as VfButton, zt as VfButtonGroup, Ht as VfCheckbox, _n as VfContainer, He as VfDesktop, Ft as VfDialog, mn as VfFieldset, Lt as VfFormControl, hn as VfGrid, sn as VfIcon, cn as VfIconField, on as VfImg, rn as VfLabel, fn as VfList, pn as VfListItem, un as VfMenu, ln as VfMenuBar, dn as VfMenuItem, Nt as VfModalDialog, Zt as VfNumberField, Qt as VfOption, an as VfParagraph, E as VfPositioned, tn as VfProgressBar, Ut as VfRadio, Wt as VfRadioGroup, jt as VfScrollArea, $t as VfSelect, It as VfSeparator, Ue as VfSized, nn as VfSlider, gn as VfStack, Bt as VfSwatch, Xt as VfTextArea, Jt as VfTextControlBase, Yt as VfTextField, Vt as VfToggleControl, Mt as VfWindow, $e as WALK_BEAT_MS, et as WALK_STEP_MS, tt as WALK_STEP_PX, dt as WINDOW_MIN_HEIGHT, ft as WINDOW_MIN_WIDTH, nt as WINDOW_RECTS_VISIBLE, rt as WINDOW_RECT_RATIO, it as WINDOW_RECT_STEPS, at as WINDOW_RECT_STEP_MS, Sn as applyCursor, f as applyScale, t as defineElement, q as devicePxAt, o as devicePxPerSystemPx, ot as dragSlop, p as effectiveScale, e as emit, Kt as focusModality, m as getScale, s as getZoom, Ot as glyphSvg, Pt as modalDialogStyles, h as onScaleChange, c as onZoomChange, ne as parsePattern, _e as parseRule, re as patternHex, ie as patternMotif, J as patternOverride, ae as patternRects, st as prefersReducedMotion, A as registerBodyFace, N as registerDisplayFace, O as registerEmbeddedFont, At as renderScrollRail, Y as repeatTile, je as requestGridSnap, l as resetZoomBaseline, ve as ruleClasses, ct as runOutlineTravel, lt as runSelectionBlink, g as snapSys, _ as snapToDevicePx, v as snapToSystemPx, ze as steppedCornerClip, Be as steppedRectClip, Ve as steppedRingClip, y as sys, b as sysLength, x as sysLengths, S as systemPxQuantum, X as tileGrid, z as tileImage, B as tileRaster, V as tileRects, H as tileSpan, C as toSys, w as toSysExact, qt as trackFocusModality, u as truePixelRatio, I as vfBase, j as vfBodyDecls, pe as vfChromeFrame, P as vfDisplay, F as vfDisplayDecls, oe as vfDots, n as vfElement, Ee as vfField, Se as vfFocus, Ce as vfFocusRing, we as vfFocusUnderline, ce as vfHardShadow, le as vfHardShadowDecls, me as vfModalFrame, he as vfPanel, ke as vfPatternFill, Z as vfRepeatTileSize, ye as vfRule, De as vfScrollRail, L as vfStaticText, se as vfStripes, ue as vfStrokeDecls, de as vfStrokeInset, fe as vfStrokeShadow, Q as vfTileGrid, U as vfTileMaskSize, W as vfTileSize, be as vfTitleBar, Te as vfToggle, xe as vfWindowWidgets, pt as windowChrome, ut as windowRectFraction };
@@ -7,6 +7,16 @@ import { ScaleController } from './scale.js';
7
7
  * — a click outside the frame.
8
8
  */
9
9
  export type VfCloseReason = 'escape' | 'close' | 'outside';
10
+ /** The `vf-close` event's detail. */
11
+ export interface VfCloseDetail {
12
+ reason: VfCloseReason;
13
+ /**
14
+ * The value this close carried — the submitting button's `value`, or
15
+ * `close(value)`'s — or null when it carried none: Escape, a click
16
+ * outside, `close()` alone, or removal from the DOM.
17
+ */
18
+ returnValue: string | null;
19
+ }
10
20
  /**
11
21
  * The width an undeclared modal falls back to, in system px — a classic
12
22
  * dialog's own measure, wide enough for a line of chrome text and a button row.
@@ -49,12 +59,18 @@ export declare const modalDialogStyles: import("lit").CSSResult;
49
59
  * closed and re-centered, and focus returns to the element that was focused
50
60
  * when the modal opened.
51
61
  *
62
+ * A `<form method="dialog">` inside the modal closes it with the submitting
63
+ * button's `value` as {@link returnValue}, as a form inside a native
64
+ * `<dialog>` does. The platform's own rule looks for a `<dialog>` around the
65
+ * form, and this one is in the shadow root, so the modal listens for the
66
+ * submit itself.
67
+ *
52
68
  * Subclasses supply only the frame chrome: a `render()` returning
53
69
  * `<dialog @cancel=${this._onNativeCancel} @close=${this._onNativeClose}>` with
54
70
  * their role/ARIA and body, and {@link modalDialogStyles} in `static styles`.
55
71
  *
56
72
  * @fires vf-close - The modal closed. `detail: { reason: 'escape' | 'close' |
57
- * 'outside' }`.
73
+ * 'outside', returnValue: string | null }`.
58
74
  */
59
75
  export declare class VfModalDialog extends LitElement {
60
76
  #private;
@@ -62,6 +78,13 @@ export declare class VfModalDialog extends LitElement {
62
78
  protected readonly scale: ScaleController;
63
79
  /** Whether the modal is open. Kept in sync with the native `<dialog>`. */
64
80
  open: boolean;
81
+ /**
82
+ * The modal's answer, as on `<dialog>`: set by `close(value)` and by a
83
+ * submit from a `<form method="dialog">` inside it (the submitting
84
+ * button's `value`). Cleared on each open, so a dialog asked again doesn't
85
+ * start with its last answer.
86
+ */
87
+ returnValue: string;
65
88
  /**
66
89
  * Modal width in whole system px — the art's own unit, so the box holds its
67
90
  * proportion to the chrome inside it at every display density.
@@ -130,6 +153,7 @@ export declare class VfModalDialog extends LitElement {
130
153
  * drag from squeezing the box.
131
154
  */
132
155
  protected get dialogSize(): Record<string, string | null>;
156
+ constructor();
133
157
  /**
134
158
  * The dialog's default button — the one wearing the bold ring
135
159
  * (`vf-button[variant="default"]`) — or null with none, or none enabled.
@@ -159,8 +183,11 @@ export declare class VfModalDialog extends LitElement {
159
183
  protected get initialFocusTarget(): HTMLElement | null;
160
184
  /** Open the modal (native `showModal()`), pinned onto the device grid. */
161
185
  show(): void;
162
- /** Close the modal. Fires `vf-close` with `{ reason: 'close' }`. */
163
- close(): void;
186
+ /**
187
+ * Close the modal, with `returnValue` as its answer when one is given.
188
+ * Fires `vf-close` with `{ reason: 'close', returnValue }`.
189
+ */
190
+ close(returnValue?: string): void;
164
191
  protected updated(changed: PropertyValues<this>): void;
165
192
  /**
166
193
  * State the origin, in system px — clamped on screen and snapped onto the
@@ -197,7 +224,7 @@ export declare class VfModalDialog extends LitElement {
197
224
  * the written origin so the next open re-derives it from the box it will
198
225
  * actually have (a stated `top`/`left` is the author's or the user's and
199
226
  * survives, and is re-applied by that open), syncs `open`, and fires
200
- * `vf-close` with the reason.
227
+ * `vf-close` with the reason and the value the close carried.
201
228
  */
202
229
  protected _onNativeClose(): void;
203
230
  }
@@ -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 = u`
16
16
  dialog {
17
17
  padding: 0;
18
18
  margin: auto;
@@ -51,110 +51,119 @@ 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
+ `, _ = 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
+ constructor() {
73
+ 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 = (t) => {
74
+ let n = t.target;
75
+ if (!(n instanceof HTMLFormElement) || v(n) !== this) return;
76
+ let r = t.submitter;
77
+ if ((r?.hasAttribute("formmethod") ? r.getAttribute("formmethod") : n.getAttribute("method"))?.toLowerCase() !== "dialog") return;
78
+ let i = r instanceof HTMLButtonElement || r instanceof HTMLInputElement ? r.value : void 0;
79
+ e(this, t, () => this.close(i));
80
+ }, this.#a = null, this.#o = new c(this, () => [
57
81
  [
58
82
  this._dialog,
59
83
  "pointerdown",
60
- this.#s
84
+ this.#l
61
85
  ],
62
86
  [
63
87
  this._dialog,
64
88
  "pointerup",
65
- this.#c
89
+ this.#u
66
90
  ],
67
91
  [
68
92
  this._dialog,
69
93
  "pointercancel",
70
- this.#l
94
+ this.#d
71
95
  ],
72
96
  [
73
97
  this._dialog,
74
98
  "keydown",
75
- this.#o
99
+ this.#c
76
100
  ]
77
- ]), this.#o = (e) => {
101
+ ]), this.#c = (e) => {
78
102
  if (e.key !== "Enter" || e.defaultPrevented || e.isComposing || e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;
79
103
  let t = e.composedPath();
80
104
  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
105
  let n = this.defaultButton;
82
106
  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">.`);
107
+ }, this.#l = (e) => {
108
+ this.#a = e.target === this._dialog ? e.pointerId : null;
109
+ }, this.#u = (e) => {
110
+ let t = this.#a === e.pointerId;
111
+ this.#a = null, !(!t || e.target !== this._dialog || !this.lightDismiss) && (this.#n = "outside", this.close());
112
+ }, this.#d = () => {
113
+ this.#a = null;
114
+ }, this.#f = null, this.#v = () => this.settle(), this.addEventListener("submit", this.#i);
106
115
  }
107
- #n;
108
- #r;
109
116
  #i;
117
+ #a;
118
+ #o;
110
119
  get defaultButton() {
111
120
  let e = "vf-button[variant=\"default\"]";
112
121
  return [...this.querySelectorAll(e), ...this.renderRoot.querySelectorAll(e)].find((e) => !e.matches(":disabled")) ?? null;
113
122
  }
114
123
  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);
124
+ return this.querySelector("[autofocus]") || ([...this.querySelectorAll("vf-text-field, vf-number-field, vf-text-area, textarea, input")].find((e) => h(e) && !e.matches(":disabled")) ?? this.defaultButton);
116
125
  }
117
- #a() {
126
+ #s() {
118
127
  this.initialFocusTarget?.focus();
119
128
  }
120
- #o;
121
- #s;
122
129
  #c;
123
130
  #l;
124
131
  #u;
132
+ #d;
133
+ #f;
125
134
  show() {
126
- this.open = !0, this.hasUpdated && this.#h();
135
+ this.open = !0, this.hasUpdated && this.#_();
127
136
  }
128
- close() {
129
- this.open = !1, this.hasUpdated && this.#h();
137
+ close(e) {
138
+ this.open && e !== void 0 && (this.#r = e), this.open = !1, this.hasUpdated && this.#_();
130
139
  }
131
140
  updated(e) {
132
- e.has("open") && this.#h(), (e.has("top") || e.has("left")) && this.settle(), this.#t();
141
+ e.has("open") && this.#_(), (e.has("top") || e.has("left")) && this.settle(), this.#t();
133
142
  }
134
- #d() {
143
+ #p() {
135
144
  let e = document.documentElement;
136
145
  return {
137
- width: a(e.clientWidth || window.innerWidth, this),
138
- height: a(e.clientHeight || window.innerHeight, this)
146
+ width: o(e.clientWidth || window.innerWidth, this),
147
+ height: o(e.clientHeight || window.innerHeight, this)
139
148
  };
140
149
  }
141
- #f(e, t) {
142
- let n = this.#d(), r = a(this._dialog?.offsetWidth ?? 0, this);
150
+ #m(e, t) {
151
+ let n = this.#p(), r = o(this._dialog?.offsetWidth ?? 0, this);
143
152
  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))
153
+ x: Math.min(Math.max(e, p - r), n.width - p),
154
+ y: Math.min(Math.max(t, 0), Math.max(0, n.height - p))
146
155
  };
147
156
  }
148
- #p() {
149
- let e = this.#d(), t = this._dialog?.getBoundingClientRect();
157
+ #h() {
158
+ let e = this.#p(), t = this._dialog?.getBoundingClientRect();
150
159
  return {
151
- x: (e.width - a(t?.width ?? 0, this)) / 2,
152
- y: (e.height - a(t?.height ?? 0, this)) / 2
160
+ x: (e.width - o(t?.width ?? 0, this)) / 2,
161
+ y: (e.height - o(t?.height ?? 0, this)) / 2
153
162
  };
154
163
  }
155
164
  placeAt(e, t) {
156
- let n = this.#f(e, t);
157
- this.left = r(n.x, this), this.top = r(n.y, this);
165
+ let n = this.#m(e, t);
166
+ this.left = i(n.x, this), this.top = i(n.y, this);
158
167
  }
159
168
  settle() {
160
169
  let e = this._dialog;
@@ -162,10 +171,10 @@ var f = 24, p = /* @__PURE__ */ new Set([
162
171
  let t = this.left != null || this.top != null ? {
163
172
  x: this.left ?? 0,
164
173
  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";
174
+ } : this.#h(), n = this.#m(t.x, t.y);
175
+ 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
176
  }
168
- #m() {
177
+ #g() {
169
178
  let e = this._dialog?.style;
170
179
  if (e) for (let t of [
171
180
  "left",
@@ -175,44 +184,51 @@ var f = 24, p = /* @__PURE__ */ new Set([
175
184
  "margin"
176
185
  ]) e.removeProperty(t);
177
186
  }
178
- #h() {
187
+ #_() {
179
188
  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());
189
+ e && (this.open && !e.open ? (this.#f = document.activeElement, this.returnValue = "", e.showModal(), this.#s(), this.settle(), this.#x(e), this.#o.attach()) : !this.open && e.open && e.close());
181
190
  }
182
- #g;
183
- #_;
184
191
  #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);
192
+ #y;
193
+ #b;
194
+ #x(e) {
195
+ typeof ResizeObserver < "u" && !this.#y && (this.#y = new ResizeObserver(this.#v), this.#y.observe(e)), window.addEventListener("resize", this.#v), this.#b ??= r(this.#v);
187
196
  }
188
- #b() {
189
- this.#_?.disconnect(), this.#_ = void 0, window.removeEventListener("resize", this.#g), this.#v?.(), this.#v = void 0;
197
+ #S() {
198
+ this.#y?.disconnect(), this.#y = void 0, window.removeEventListener("resize", this.#v), this.#b?.(), this.#b = void 0;
190
199
  }
191
200
  disconnectedCallback() {
192
- super.disconnectedCallback(), this.#b();
201
+ super.disconnectedCallback(), this.#S();
193
202
  let e = this._dialog;
194
203
  if (e?.open) {
195
204
  e.close();
196
- let t = this.#u, n = document.activeElement;
205
+ let t = this.#f, n = document.activeElement;
197
206
  t instanceof HTMLElement && t.isConnected && (n === null || n === document.body) && t.focus();
198
207
  }
199
- this.#u = null;
208
+ this.#f = null;
200
209
  }
201
210
  _onNativeCancel() {
202
211
  this.#n = "escape";
203
212
  }
204
213
  _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 });
214
+ let e = this.#n ?? "close", n = this.#r;
215
+ this.#n = null, this.#r = null, n !== null && (this.returnValue = n), this.#f = null, this.#a = null, this.#o.detach(), this.#S(), this.open = !1, this.#g(), t(this, "vf-close", {
216
+ reason: e,
217
+ returnValue: n
218
+ });
207
219
  }
208
220
  };
209
- o([u({
221
+ s([d({
210
222
  type: Boolean,
211
223
  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({
224
+ })], _.prototype, "open", void 0), s([d({ type: Number })], _.prototype, "width", void 0), s([d({ type: Number })], _.prototype, "height", void 0), s([d({ type: Number })], _.prototype, "top", void 0), s([d({ type: Number })], _.prototype, "left", void 0), s([d({
213
225
  type: Boolean,
214
226
  reflect: !0,
215
227
  attribute: "light-dismiss"
216
- })], g.prototype, "lightDismiss", void 0), o([d("dialog")], g.prototype, "_dialog", void 0);
228
+ })], _.prototype, "lightDismiss", void 0), s([f("dialog")], _.prototype, "_dialog", void 0);
229
+ function v(e) {
230
+ for (let t = e.parentElement; t; t = t.parentElement) if (t instanceof _) return t;
231
+ return null;
232
+ }
217
233
  //#endregion
218
- export { g as VfModalDialog, h as modalDialogStyles };
234
+ export { _ as VfModalDialog, g as modalDialogStyles };
@@ -47,14 +47,17 @@ export declare class PatternFillController extends RepeatTileController {
47
47
  * a pattern is resolved (the component's template knows).
48
48
  *
49
49
  * Painting: the tile the controller wrote, repeated from the padding box's
50
- * corner at {@link vfRepeatTileSize}, nearest-neighbor. The paper and the
51
- * pixelation ride the `vf-patterned` state so an unpatterned box paints
52
- * exactly nothing and inherits nothing new. `image-rendering` inherits, so
53
- * the slot hands `auto` back to slotted content: a consumer's own `<img>`
54
- * renders as it would anywhere else, and a kit element that wants
55
- * nearest-neighbor (`vf-img`, a `vf-icon`) says so itself. A page that set
56
- * `pixelated` on an ancestor gets `auto` inside a patterned box — its own
57
- * declaration on the child still wins, as everywhere.
50
+ * corner at {@link vfRepeatTileSize}, nearest-neighbor. All of it rides the
51
+ * `vf-patterned` state, the image included, so an unpatterned box paints
52
+ * exactly nothing. The tile's custom property inherits like any other: a
53
+ * box that read it unpatterned would paint the tile of the nearest
54
+ * patterned box around it — a desktop's dither inside a window.
55
+ * `image-rendering` inherits too, so the slot hands `auto` back to slotted
56
+ * content: a consumer's own `<img>` renders as it would anywhere else, and a
57
+ * kit element that wants nearest-neighbor (`vf-img`, a `vf-icon`) says so
58
+ * itself. A page that set `pixelated` on an ancestor gets `auto` inside a
59
+ * patterned box — its own declaration on the child still wins, as
60
+ * everywhere.
58
61
  *
59
62
  * Forced colors: the image goes, the paper is the remapped Canvas — the
60
63
  * desktop's posture, a backdrop being decoration.
@@ -17,12 +17,10 @@ var i = /* @__PURE__ */ new WeakMap(), a = (e) => {
17
17
  });
18
18
  }
19
19
  }, s = r`
20
- .vf-pattern-fill {
20
+ .vf-pattern-fill.vf-patterned {
21
21
  background-image: var(--_vf-pattern-image, none);
22
22
  ${t}
23
23
  background-repeat: repeat;
24
- }
25
- .vf-pattern-fill.vf-patterned {
26
24
  background-color: var(--vf-white, #fff);
27
25
  image-rendering: pixelated;
28
26
  }
@@ -30,7 +28,7 @@ var i = /* @__PURE__ */ new WeakMap(), a = (e) => {
30
28
  image-rendering: auto;
31
29
  }
32
30
  @media (forced-colors: active) {
33
- .vf-pattern-fill {
31
+ .vf-pattern-fill.vf-patterned {
34
32
  background-image: none;
35
33
  }
36
34
  }
@@ -97,14 +97,17 @@ type PositionedHost = HTMLElement & {
97
97
  * re-asserts a coordinate and costs nothing.
98
98
  *
99
99
  * **Every write it makes is announced** as `vf-placement-change` (bubbles,
100
- * `composed: false`, detail `{ left, top }` — nulls on a return to flow). It
101
- * is an internal coordination event on the terms of the menu handshakes:
102
- * parent and child share one light tree, and a kit protocol must not leak out
103
- * of a consumer's shadow boundary. `vf-scroll-area` listens for it and
100
+ * `composed: false`, detail `{ left, top }` — nulls on a return to flow), so
101
+ * a page hears every move the one way: a title-bar drag's steps and its
102
+ * release (an outline drag's single write), an arrow nudge, a drop, a walk's
103
+ * landing, an `origin` re-measure, and its own property writes. Non-composed,
104
+ * because parent and child share one light tree and the event has no reason
105
+ * to leave a consumer's shadow root. It is dispatched from the host's update,
106
+ * with the new pair already on its style: a handler that writes the pair
107
+ * again takes effect on the next update. `vf-scroll-area` listens for it and
104
108
  * re-measures, because a placed child moved through `top`/`left` changes the
105
109
  * scroll range with no box changing anywhere a ResizeObserver can see — the
106
- * plane's box is never grown by an absolutely positioned child. One funnel
107
- * covers a drop, an arrow nudge and a page's own `icon.left = …` alike.
110
+ * plane's box is never grown by an absolutely positioned child.
108
111
  *
109
112
  * **`origin`** names which point of the host's own box the pair places —
110
113
  * nine keywords, vertical then horizontal (`top center`, `bottom right`,
@@ -169,11 +172,26 @@ export declare function placementIn(anchor: Element, clientX: number, clientY: n
169
172
  left: number;
170
173
  top: number;
171
174
  };
172
- /** The box a gesture is clamped into, in system px — see {@link PlacementClamp}. */
175
+ /**
176
+ * The box a gesture is clamped into, in system px — see {@link PlacementClamp}.
177
+ * `width` and `height` are the positioning parent's box; `top` is the least
178
+ * `top` a placement may take there: 0, or on a desktop's screen the bottom of
179
+ * its menu bar (`vf-desktop.workArea`).
180
+ */
173
181
  export type PlacementBounds = {
174
182
  width: number;
175
183
  height: number;
184
+ top: number;
176
185
  };
186
+ /**
187
+ * The detail of `vf-placement-bounds-request`: the handshake a moved host
188
+ * makes when its gesture measures the box it is clamped into. A
189
+ * `vf-desktop` on its light-DOM path fills `bounds` for a host placed on its
190
+ * screen. Internal to the kit's placement.
191
+ */
192
+ export interface PlacementBoundsRequest {
193
+ bounds: PlacementBounds | null;
194
+ }
177
195
  /**
178
196
  * A moved host's own containment rule, in system px, against the box measured
179
197
  * once at the start of the gesture.