vintage-frames 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +262 -0
- package/custom-elements.json +19807 -0
- package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js +9 -0
- package/dist/chrome.d.ts +73 -0
- package/dist/chrome.js +94 -0
- package/dist/components/vf-button-group.d.ts +50 -0
- package/dist/components/vf-button-group.js +68 -0
- package/dist/components/vf-button.d.ts +169 -0
- package/dist/components/vf-button.js +234 -0
- package/dist/components/vf-checkbox.d.ts +60 -0
- package/dist/components/vf-checkbox.js +135 -0
- package/dist/components/vf-container.d.ts +95 -0
- package/dist/components/vf-container.js +86 -0
- package/dist/components/vf-desktop.d.ts +243 -0
- package/dist/components/vf-desktop.js +310 -0
- package/dist/components/vf-dialog.d.ts +105 -0
- package/dist/components/vf-dialog.js +280 -0
- package/dist/components/vf-fieldset.d.ts +34 -0
- package/dist/components/vf-fieldset.js +76 -0
- package/dist/components/vf-grid.d.ts +124 -0
- package/dist/components/vf-grid.js +133 -0
- package/dist/components/vf-icon.d.ts +356 -0
- package/dist/components/vf-icon.js +507 -0
- package/dist/components/vf-img.d.ts +63 -0
- package/dist/components/vf-img.js +65 -0
- package/dist/components/vf-label.d.ts +117 -0
- package/dist/components/vf-label.js +151 -0
- package/dist/components/vf-list-item.d.ts +48 -0
- package/dist/components/vf-list-item.js +98 -0
- package/dist/components/vf-list.d.ts +77 -0
- package/dist/components/vf-list.js +256 -0
- package/dist/components/vf-menu-bar.d.ts +64 -0
- package/dist/components/vf-menu-bar.js +236 -0
- package/dist/components/vf-menu-item.d.ts +91 -0
- package/dist/components/vf-menu-item.js +252 -0
- package/dist/components/vf-menu.d.ts +95 -0
- package/dist/components/vf-menu.js +346 -0
- package/dist/components/vf-number-field.d.ts +60 -0
- package/dist/components/vf-number-field.js +248 -0
- package/dist/components/vf-option.d.ts +49 -0
- package/dist/components/vf-option.js +119 -0
- package/dist/components/vf-paragraph.d.ts +73 -0
- package/dist/components/vf-paragraph.js +66 -0
- package/dist/components/vf-progress-bar.d.ts +69 -0
- package/dist/components/vf-progress-bar.js +272 -0
- package/dist/components/vf-radio-group.d.ts +109 -0
- package/dist/components/vf-radio-group.js +105 -0
- package/dist/components/vf-radio.d.ts +59 -0
- package/dist/components/vf-radio.js +135 -0
- package/dist/components/vf-scroll-area.d.ts +75 -0
- package/dist/components/vf-scroll-area.js +124 -0
- package/dist/components/vf-select.d.ts +334 -0
- package/dist/components/vf-select.js +658 -0
- package/dist/components/vf-separator.d.ts +38 -0
- package/dist/components/vf-separator.js +55 -0
- package/dist/components/vf-slider.d.ts +80 -0
- package/dist/components/vf-slider.js +255 -0
- package/dist/components/vf-stack.d.ts +188 -0
- package/dist/components/vf-stack.js +168 -0
- package/dist/components/vf-swatch.d.ts +98 -0
- package/dist/components/vf-swatch.js +201 -0
- package/dist/components/vf-text-area.d.ts +77 -0
- package/dist/components/vf-text-area.js +121 -0
- package/dist/components/vf-text-field.d.ts +53 -0
- package/dist/components/vf-text-field.js +79 -0
- package/dist/components/vf-window.d.ts +157 -0
- package/dist/components/vf-window.js +377 -0
- package/dist/cursor-art.d.ts +37 -0
- package/dist/cursor-art.js +41 -0
- package/dist/cursor.d.ts +49 -0
- package/dist/cursor.js +171 -0
- package/dist/define.d.ts +45 -0
- package/dist/define.js +15 -0
- package/dist/document-listeners.d.ts +62 -0
- package/dist/document-listeners.js +29 -0
- package/dist/drag.d.ts +49 -0
- package/dist/drag.js +30 -0
- package/dist/events.d.ts +79 -0
- package/dist/events.js +25 -0
- package/dist/focus-modality.d.ts +94 -0
- package/dist/focus-modality.js +56 -0
- package/dist/form-control.d.ts +247 -0
- package/dist/form-control.js +127 -0
- package/dist/glyphs.d.ts +117 -0
- package/dist/glyphs.js +100 -0
- package/dist/grid-snap.d.ts +73 -0
- package/dist/grid-snap.js +135 -0
- package/dist/index.d.ts +145 -0
- package/dist/index.js +71 -0
- package/dist/menu-press.d.ts +60 -0
- package/dist/menu-press.js +97 -0
- package/dist/modal-dialog.d.ts +148 -0
- package/dist/modal-dialog.js +155 -0
- package/dist/motion.d.ts +72 -0
- package/dist/motion.js +22 -0
- package/dist/number.d.ts +24 -0
- package/dist/number.js +12 -0
- package/dist/open-art.d.ts +40 -0
- package/dist/open-art.js +35 -0
- package/dist/pixel-frame.d.ts +102 -0
- package/dist/pixel-frame.js +77 -0
- package/dist/popup-overflow.d.ts +157 -0
- package/dist/popup-overflow.js +45 -0
- package/dist/position.d.ts +187 -0
- package/dist/position.js +74 -0
- package/dist/scale.d.ts +259 -0
- package/dist/scale.js +133 -0
- package/dist/scroll-rail.d.ts +112 -0
- package/dist/scroll-rail.js +194 -0
- package/dist/scroll-state.d.ts +113 -0
- package/dist/scroll-state.js +55 -0
- package/dist/size.d.ts +47 -0
- package/dist/size.js +30 -0
- package/dist/styles/base.d.ts +38 -0
- package/dist/styles/body-font.d.ts +7 -0
- package/dist/styles/body-font.js +9 -0
- package/dist/styles/display-font.d.ts +7 -0
- package/dist/styles/display-font.js +9 -0
- package/dist/styles/recipes/body-face.d.ts +14 -0
- package/dist/styles/recipes/body-face.js +6 -0
- package/dist/styles/recipes/display-face.d.ts +23 -0
- package/dist/styles/recipes/display-face.js +10 -0
- package/dist/styles/recipes/field.d.ts +20 -0
- package/dist/styles/recipes/field.js +68 -0
- package/dist/styles/recipes/focus.d.ts +76 -0
- package/dist/styles/recipes/focus.js +39 -0
- package/dist/styles/recipes/host.d.ts +5 -0
- package/dist/styles/recipes/host.js +62 -0
- package/dist/styles/recipes/pattern.d.ts +80 -0
- package/dist/styles/recipes/pattern.js +82 -0
- package/dist/styles/recipes/scroll-rail.d.ts +69 -0
- package/dist/styles/recipes/scroll-rail.js +222 -0
- package/dist/styles/recipes/shadow.d.ts +13 -0
- package/dist/styles/recipes/shadow.js +5 -0
- package/dist/styles/recipes/static-text.d.ts +24 -0
- package/dist/styles/recipes/static-text.js +17 -0
- package/dist/styles/recipes/surface.d.ts +28 -0
- package/dist/styles/recipes/surface.js +27 -0
- package/dist/styles/recipes/tile.d.ts +122 -0
- package/dist/styles/recipes/tile.js +40 -0
- package/dist/styles/recipes/title-bar.d.ts +49 -0
- package/dist/styles/recipes/title-bar.js +134 -0
- package/dist/styles/recipes/toggle.d.ts +10 -0
- package/dist/styles/recipes/toggle.js +20 -0
- package/dist/styles/register-embedded-font.d.ts +64 -0
- package/dist/styles/register-embedded-font.js +30 -0
- package/dist/text-control.d.ts +131 -0
- package/dist/text-control.js +83 -0
- package/dist/tile-grid.d.ts +111 -0
- package/dist/tile-grid.js +53 -0
- package/dist/toggle-control.d.ts +60 -0
- package/dist/toggle-control.js +41 -0
- package/dist/track-width.d.ts +42 -0
- package/dist/track-width.js +30 -0
- package/dist/type-ahead.d.ts +35 -0
- package/dist/type-ahead.js +20 -0
- package/dist/zoom.d.ts +204 -0
- package/dist/zoom.js +105 -0
- package/docs/SPEC.md +2471 -0
- package/editor/vscode.html-custom-data.json +1320 -0
- package/editor/web-types.json +3237 -0
- package/package.json +118 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { LitElement, type PropertyValues } from 'lit';
|
|
2
|
+
declare const VfDesktop_base: (new (...args: any[]) => import("../position.js").VfPositionedInterface) & typeof LitElement;
|
|
3
|
+
/**
|
|
4
|
+
* `<vf-desktop>` — the full-bleed classic desktop container.
|
|
5
|
+
*
|
|
6
|
+
* Renders the 50%-dither gray desktop pattern and manages the stacking order
|
|
7
|
+
* and `active` state of slotted `vf-window` children: a `pointerdown` or
|
|
8
|
+
* `focusin` (keyboard focus) anywhere inside a window brings it to the front
|
|
9
|
+
* and makes it the single active window. The windows' light-DOM order is kept
|
|
10
|
+
* in step with the stacking order (bottom-most first, at pointer-gesture
|
|
11
|
+
* ends), so tabbing walks the stack the way the eye does and Shift+Tab is
|
|
12
|
+
* its exact mirror.
|
|
13
|
+
*
|
|
14
|
+
* Utility windows (`vf-window[variant="utility"]`) stack in a floating tier
|
|
15
|
+
* above every document-tier window, restack only among themselves, and stand
|
|
16
|
+
* outside the single-active invariant entirely — clicking a palette neither
|
|
17
|
+
* deactivates the active document window nor greys the palette, exactly as
|
|
18
|
+
* System 7's floating windoids behaved while their application was frontmost.
|
|
19
|
+
*
|
|
20
|
+
* The desktop is a raster with an explicit size, always: **`width` and
|
|
21
|
+
* `height`**, in system px, the way a WIND resource declared a window's —
|
|
22
|
+
* the host box renders at the declared screen plus `2 × bezel` per axis, a
|
|
23
|
+
* whole number of system pixels by construction (default 512×342, the
|
|
24
|
+
* compact Mac's screen). Pure CSS sizing is not supported; the page sets
|
|
25
|
+
* the numbers — directly, or via {@link VfDesktop.fitWithin} on
|
|
26
|
+
* `resize`/`onScaleChange` for a viewport-filling desktop — and positions
|
|
27
|
+
* the sized box with its own stylesheet, keeping any sub-system-pixel
|
|
28
|
+
* slack on its side. `bezel` (system px) draws the black screen surround —
|
|
29
|
+
* the CRT's unlit margin — around the screen, rounding its top corners
|
|
30
|
+
* with the classic corner mask.
|
|
31
|
+
*
|
|
32
|
+
* Custom properties:
|
|
33
|
+
* - `--vf-desktop-pattern` — the dither's tile art (default a 1-bit 50%
|
|
34
|
+
* checker, opaque black-on-white on a 30-system-px tile). Overriding it
|
|
35
|
+
* renders the token as a placed tile grid at that same 30-px geometry
|
|
36
|
+
* (src/tile-grid.ts); a token swapped at runtime without touching the
|
|
37
|
+
* component wants a `requestUpdate()`.
|
|
38
|
+
* - `--vf-desktop` — base color painted *under* the pattern layer (default
|
|
39
|
+
* `#808080`). The default tile is opaque, so this only becomes visible when
|
|
40
|
+
* `--vf-desktop-pattern` is overridden with a tile that has transparent
|
|
41
|
+
* cells (or with `none`).
|
|
42
|
+
*
|
|
43
|
+
* @slot - Default slot: menu bar, windows, anything.
|
|
44
|
+
* @csspart desktop - The dithered screen surface — the whole-system-px
|
|
45
|
+
* raster (inset by `bezel` when one is set).
|
|
46
|
+
* @cssprop [--vf-desktop=#808080] - base color under the desktop dither —
|
|
47
|
+
* occluded by the default (opaque) tile, so it only shows through a custom
|
|
48
|
+
* `--vf-desktop-pattern`
|
|
49
|
+
* @cssprop --vf-desktop-pattern - the desktop dither's art — a 50% checker
|
|
50
|
+
* drawn as opaque black-on-white rects, on a 30-system-px tile. Override the
|
|
51
|
+
* whole tile; consumer art renders as a placed tile grid at that same
|
|
52
|
+
* geometry (raster art magnifies nearest-neighbor, the `vf-img` idiom)
|
|
53
|
+
*/
|
|
54
|
+
export declare class VfDesktop extends VfDesktop_base {
|
|
55
|
+
#private;
|
|
56
|
+
static styles: import("lit").CSSResult[];
|
|
57
|
+
/**
|
|
58
|
+
* Screen width in system px — the raster's own size, the way a WIND
|
|
59
|
+
* resource declared a window's. The host box renders at exactly
|
|
60
|
+
* `width + 2 × bezel` system px, always whole; a desktop is never sized
|
|
61
|
+
* by page CSS — the page sets these numbers (directly or via
|
|
62
|
+
* {@link fitWithin}) and positions the explicitly sized box with its own
|
|
63
|
+
* stylesheet, keeping whatever sub-system-pixel slack its layout has on
|
|
64
|
+
* its side of the fence. Defaults to the compact Mac's 512.
|
|
65
|
+
*/
|
|
66
|
+
width: number;
|
|
67
|
+
/** Screen height in system px; see {@link width}. Defaults to 342. */
|
|
68
|
+
height: number;
|
|
69
|
+
/**
|
|
70
|
+
* Width of the black screen bezel, in system px (`0` = none), added onto
|
|
71
|
+
* the declared screen on every side — a `width="502" bezel="5"` desktop
|
|
72
|
+
* renders a 512-system-px host box. The compact Mac's CRT showed an
|
|
73
|
+
* unlit black margin between the desktop's raster and the case; `bezel`
|
|
74
|
+
* draws it around the screen and puts the classic screen-corner mask on
|
|
75
|
+
* the screen's two *top* corners — only the top pair was rounded in the
|
|
76
|
+
* framebuffer. Flow, window coordinates and the drag clip all belong to
|
|
77
|
+
* the screen, so windows crop at its edge. Inside a bezeled desktop a
|
|
78
|
+
* menu bar needs no `rounded` of its own — the desktop's mask lands on
|
|
79
|
+
* the same pixels.
|
|
80
|
+
*/
|
|
81
|
+
bezel: number;
|
|
82
|
+
/**
|
|
83
|
+
* Size the screen to the largest whole-system-px raster whose host box —
|
|
84
|
+
* bezel included — fits a CSS-px bound, and return what was set. The
|
|
85
|
+
* page's half of the sizing contract: it owns the viewport, so it
|
|
86
|
+
* measures the box and hands it here on `resize` and `onScaleChange`
|
|
87
|
+
* (zoom and density moves change how many CSS px a system px costs),
|
|
88
|
+
* and the sub-system-pixel remainder stays on the page, behind the
|
|
89
|
+
* bezel. The epsilon forgives float error in the division so an
|
|
90
|
+
* exact-fit bound never drops a whole system pixel.
|
|
91
|
+
*/
|
|
92
|
+
fitWithin(maxWidth: number, maxHeight: number): {
|
|
93
|
+
width: number;
|
|
94
|
+
height: number;
|
|
95
|
+
};
|
|
96
|
+
/** Slotted `vf-window` children (direct children only). */
|
|
97
|
+
private _windows;
|
|
98
|
+
/** Default-on display scaling (true 72dpi size); see src/scale.ts. */
|
|
99
|
+
private readonly scale;
|
|
100
|
+
/** Device-pixel grid snapping (opt in with applyGridSnap()); see src/grid-snap.ts. */
|
|
101
|
+
private readonly gridSnap;
|
|
102
|
+
/**
|
|
103
|
+
* The consumer's `--vf-desktop-pattern` override, or `''` for the kit
|
|
104
|
+
* dither — which of the two exact-fill paths render() takes (see
|
|
105
|
+
* src/tile-grid.ts). Re-read every update; a token swapped at runtime
|
|
106
|
+
* without touching the component wants a `requestUpdate()`.
|
|
107
|
+
*/
|
|
108
|
+
private _pattern;
|
|
109
|
+
/** Monotonic z-index counter for window stacking. */
|
|
110
|
+
private _zCounter;
|
|
111
|
+
/** Whether a one-shot post-upgrade re-normalization is already pending. */
|
|
112
|
+
private _awaitingUpgrade;
|
|
113
|
+
/** Whether a pointer gesture that began on the desktop is still in flight. */
|
|
114
|
+
private _pointerGesture;
|
|
115
|
+
/** Whether {@link _syncDomOrder} is putting focus back after a node move. */
|
|
116
|
+
private _restoringFocus;
|
|
117
|
+
/**
|
|
118
|
+
* Ends the pointer-gesture window that defers DOM reordering. Capture-phase
|
|
119
|
+
* on the document so a component's `stopPropagation` can't strand the flag,
|
|
120
|
+
* and detached on host disconnect by the controller.
|
|
121
|
+
*/
|
|
122
|
+
private readonly _gestureEnd;
|
|
123
|
+
connectedCallback(): void;
|
|
124
|
+
disconnectedCallback(): void;
|
|
125
|
+
/** Whether a slotted window belongs to the floating (utility) tier. The
|
|
126
|
+
* attribute is the source of truth here so a not-yet-upgraded element
|
|
127
|
+
* still lands in the right tier (variant reflects, so an upgraded
|
|
128
|
+
* property-set window agrees). */
|
|
129
|
+
private _isUtility;
|
|
130
|
+
/**
|
|
131
|
+
* Bring a slotted window to the front of its tier. A document-tier window
|
|
132
|
+
* also becomes the single active window (clearing `active` on the other
|
|
133
|
+
* document windows); a utility window restacks within the floating tier
|
|
134
|
+
* and leaves every `active` state alone.
|
|
135
|
+
*
|
|
136
|
+
* The light-DOM order of the slotted windows follows ({@link _syncDomOrder}):
|
|
137
|
+
* visual stacking and sequential focus order come from independent channels
|
|
138
|
+
* (z-index vs DOM position), and letting them drift apart is how a desktop
|
|
139
|
+
* tabs front-to-back one way and back-to-front the other, with widgets
|
|
140
|
+
* reachable only travelling backwards. Deferred to the end of any in-flight
|
|
141
|
+
* pointer gesture — moving a node clears the pointer capture a title-bar
|
|
142
|
+
* drag or grow-box resize holds on it, and a background window must stay
|
|
143
|
+
* draggable in the same gesture that raises it.
|
|
144
|
+
*/
|
|
145
|
+
bringToFront(win: HTMLElement): void;
|
|
146
|
+
/** The z/active half of a raise, shared by every path. */
|
|
147
|
+
private _restack;
|
|
148
|
+
/** Sync the DOM order now, or at gesture end if a pointer is down. */
|
|
149
|
+
private _requestDomSync;
|
|
150
|
+
/**
|
|
151
|
+
* Raise the window an event originated in, skipping the restack/activation
|
|
152
|
+
* churn when it is already on top of its own tier (and, for a document
|
|
153
|
+
* window, already active): otherwise every click inside the front window
|
|
154
|
+
* would bump _zCounter and re-run the whole-fleet activation loop for
|
|
155
|
+
* nothing.
|
|
156
|
+
*
|
|
157
|
+
* Restacks z/active only — deliberately no DOM sync. A focus-driven raise
|
|
158
|
+
* MUST NOT move nodes: moving the window focus just entered re-orders the
|
|
159
|
+
* sequence mid-traversal, and a Shift+Tab that raises each window it
|
|
160
|
+
* enters (pushing it forward in the DOM, back the way the traversal came)
|
|
161
|
+
* would revisit it forever. The pointer path syncs at gesture end instead,
|
|
162
|
+
* which is also the next safe point after any keyboard-session staleness.
|
|
163
|
+
*/
|
|
164
|
+
private _raise;
|
|
165
|
+
/**
|
|
166
|
+
* Delegated pointerdown: raise the window the event originated in. Any
|
|
167
|
+
* press opens the gesture window that defers DOM reordering (see
|
|
168
|
+
* {@link bringToFront}) — a raise can be requested mid-gesture by this
|
|
169
|
+
* press or by code the press runs.
|
|
170
|
+
*/
|
|
171
|
+
private _onPointerDown;
|
|
172
|
+
/**
|
|
173
|
+
* The press ended (or was cancelled) — sync the DOM order. Unconditional
|
|
174
|
+
* rather than only-if-raised: the sync no-ops when order already agrees,
|
|
175
|
+
* and running it at every gesture end is what heals the staleness a
|
|
176
|
+
* keyboard-only stretch leaves behind (focus-driven raises change z but
|
|
177
|
+
* never move nodes — see {@link _raise}).
|
|
178
|
+
*/
|
|
179
|
+
private _onGestureEnd;
|
|
180
|
+
/**
|
|
181
|
+
* Delegated focusin: raise the window keyboard focus entered, so tabbing
|
|
182
|
+
* into a background window brings it to front (and reveals its close/zoom
|
|
183
|
+
* widgets) just like a pointerdown would. Ignored while `_syncDomOrder` is
|
|
184
|
+
* putting focus back after a node move — the restore re-fires focusin on
|
|
185
|
+
* an element that may sit in a *background* window, and raising that
|
|
186
|
+
* window would undo the raise that triggered the sync.
|
|
187
|
+
*/
|
|
188
|
+
private _onFocusIn;
|
|
189
|
+
/** The slotted window the event originated in, if any. */
|
|
190
|
+
private _windowFromEvent;
|
|
191
|
+
/** Wire up newly slotted windows: seed z-indices, normalize `active`. */
|
|
192
|
+
private _onSlotChange;
|
|
193
|
+
/**
|
|
194
|
+
* Re-assert the single-active-window state after slotted `<vf-window>`
|
|
195
|
+
* elements upgrade. One-shot: the flag collapses repeat slotchanges into a
|
|
196
|
+
* single wait, and once the definition is registered `_onSlotChange` stops
|
|
197
|
+
* calling this at all. If a consumer never imports vf-window the promise
|
|
198
|
+
* simply never settles — those elements render nothing either way.
|
|
199
|
+
*/
|
|
200
|
+
private _normalizeAfterUpgrade;
|
|
201
|
+
/** Set `active` on `win` only, clearing it on every other *document-tier*
|
|
202
|
+
* window. Utility windows stand outside the invariant: a palette keeps
|
|
203
|
+
* whatever `active` state it has (true by default, so its dither and
|
|
204
|
+
* widgets stay drawn while document windows trade the highlight). */
|
|
205
|
+
private _setActive;
|
|
206
|
+
/**
|
|
207
|
+
* Set a window's `active` state. Prefers the property (the source of truth
|
|
208
|
+
* on an upgraded `vf-window`, whose reflection then wins over any pending
|
|
209
|
+
* initial-value reflection); falls back to the attribute for not-yet
|
|
210
|
+
* upgraded elements.
|
|
211
|
+
*/
|
|
212
|
+
private _setWindowActive;
|
|
213
|
+
/** The window with the highest z-index, or null when there are none. */
|
|
214
|
+
private _topmost;
|
|
215
|
+
/** The innermost focused element, through open shadow roots. */
|
|
216
|
+
private _deepActiveElement;
|
|
217
|
+
/**
|
|
218
|
+
* Re-order the slotted windows in the light DOM to match their z-order
|
|
219
|
+
* (bottom-most first), so sequential focus navigation walks the stack the
|
|
220
|
+
* way the eye does — and Shift+Tab is its exact mirror. The utility band
|
|
221
|
+
* sorts the floating tier after every document window by construction.
|
|
222
|
+
*
|
|
223
|
+
* Minimal-move: windows already in relative order are never touched (the
|
|
224
|
+
* common case — after one raise, one window moves). Non-window siblings
|
|
225
|
+
* (a menu bar, page content) keep their positions; only a window that must
|
|
226
|
+
* cross the stack moves past them. Moving a node containing the focused
|
|
227
|
+
* element drops focus to `<body>`, so it is restored afterwards — behind
|
|
228
|
+
* `_restoringFocus`, because the restore re-fires focusin (see
|
|
229
|
+
* {@link _onFocusIn}) on an element that may sit in a background window.
|
|
230
|
+
* Only runs between pointer gestures or programmatically, never from a
|
|
231
|
+
* focus-driven raise (see {@link _raise} for why).
|
|
232
|
+
*/
|
|
233
|
+
private _syncDomOrder;
|
|
234
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
235
|
+
protected updated(changed: Map<PropertyKey, unknown>): void;
|
|
236
|
+
protected render(): unknown;
|
|
237
|
+
}
|
|
238
|
+
declare global {
|
|
239
|
+
interface HTMLElementTagNameMap {
|
|
240
|
+
'vf-desktop': VfDesktop;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
export {};
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { vfElement as e } from "../define.js";
|
|
2
|
+
import { ScaleController as t, effectiveScale as n, sysLength 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 { tileImage as s, tileRaster as c, tileRects as l, tileSpan as u, vfTileSize as d } from "../styles/recipes/tile.js";
|
|
7
|
+
import { TileRasterCache as f, patternOverride as p, tileGrid as m, vfTileGrid as h } from "../tile-grid.js";
|
|
8
|
+
import { GridSnapController as g } from "../grid-snap.js";
|
|
9
|
+
import { DocumentListenersController as _ } from "../document-listeners.js";
|
|
10
|
+
import { SCREEN_CORNER as v, steppedCornerClip as y } from "../pixel-frame.js";
|
|
11
|
+
import { LitElement as b, css as x, html as S, unsafeCSS as C } from "lit";
|
|
12
|
+
import { property as w, queryAssignedElements as T } from "lit/decorators.js";
|
|
13
|
+
//#region src/components/vf-desktop.ts
|
|
14
|
+
var E = 1e6, D = 512, O = 342, k = 2, A = [
|
|
15
|
+
[
|
|
16
|
+
0,
|
|
17
|
+
0,
|
|
18
|
+
2,
|
|
19
|
+
2,
|
|
20
|
+
"#ffffff"
|
|
21
|
+
],
|
|
22
|
+
[
|
|
23
|
+
0,
|
|
24
|
+
0,
|
|
25
|
+
1,
|
|
26
|
+
1,
|
|
27
|
+
"#000000"
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
1,
|
|
31
|
+
1,
|
|
32
|
+
1,
|
|
33
|
+
1,
|
|
34
|
+
"#000000"
|
|
35
|
+
]
|
|
36
|
+
], j = s(k, k, l(A)), M = c(k, k, A), N = u(k), P = class extends a(b) {
|
|
37
|
+
constructor(...e) {
|
|
38
|
+
super(...e), this.width = D, this.height = O, this.bezel = 0, this.scale = new t(this), this.gridSnap = new g(this), this._pattern = "", this.#e = new f(), this._zCounter = 0, this._awaitingUpgrade = !1, this._pointerGesture = !1, this._restoringFocus = !1, this._gestureEnd = new _(this, () => [[
|
|
39
|
+
document,
|
|
40
|
+
"pointerup",
|
|
41
|
+
this._onGestureEnd,
|
|
42
|
+
!0
|
|
43
|
+
], [
|
|
44
|
+
document,
|
|
45
|
+
"pointercancel",
|
|
46
|
+
this._onGestureEnd,
|
|
47
|
+
!0
|
|
48
|
+
]]), this._onPointerDown = (e) => {
|
|
49
|
+
this._pointerGesture || (this._pointerGesture = !0, this._gestureEnd.attach());
|
|
50
|
+
let t = this._windowFromEvent(e);
|
|
51
|
+
t && this._raise(t);
|
|
52
|
+
}, this._onGestureEnd = () => {
|
|
53
|
+
this._gestureEnd.detach(), this._pointerGesture = !1, this._syncDomOrder();
|
|
54
|
+
}, this._onFocusIn = (e) => {
|
|
55
|
+
if (this._restoringFocus) return;
|
|
56
|
+
let t = this._windowFromEvent(e);
|
|
57
|
+
t && this._raise(t);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
static {
|
|
61
|
+
this.styles = [
|
|
62
|
+
o,
|
|
63
|
+
h,
|
|
64
|
+
x`
|
|
65
|
+
:host {
|
|
66
|
+
display: block;
|
|
67
|
+
position: relative;
|
|
68
|
+
}
|
|
69
|
+
.desktop {
|
|
70
|
+
position: relative;
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
}
|
|
74
|
+
/* The bezel surface: the unlit black margin a compact Mac's CRT showed
|
|
75
|
+
between the raster and the case. Painted only when bezeled, so an
|
|
76
|
+
unbezeled desktop's paint is exactly the screen's. */
|
|
77
|
+
.desktop.bezeled {
|
|
78
|
+
background: var(--vf-black, #000);
|
|
79
|
+
}
|
|
80
|
+
.screen {
|
|
81
|
+
position: absolute;
|
|
82
|
+
top: 0;
|
|
83
|
+
left: 0;
|
|
84
|
+
width: 100%;
|
|
85
|
+
height: 100%;
|
|
86
|
+
/* Clip here rather than on the host so dragged windows crop at the
|
|
87
|
+
raster's corrected edge, not the host's possibly-fractional one. */
|
|
88
|
+
overflow: hidden;
|
|
89
|
+
/* An isolated stacking context, so the tile grid's z-index: -1 below
|
|
90
|
+
resolves HERE — above this element's own underlay background, under
|
|
91
|
+
every slotted child. Without it the negative z-index would resolve
|
|
92
|
+
against some ancestor stacking context and paint the tiles beneath
|
|
93
|
+
this background. */
|
|
94
|
+
isolation: isolate;
|
|
95
|
+
background-color: var(--vf-desktop, #808080);
|
|
96
|
+
/* Classic 50% checker dither as a crisp 1-bit SVG tile — a 2×2 motif
|
|
97
|
+
painting an opaque white base with two black pixels on the diagonal.
|
|
98
|
+
Black-on-white is the authentic System 7 dither, so the tile is
|
|
99
|
+
deliberately opaque and covers the background-color above (see the
|
|
100
|
+
--vf-desktop note in the class doc). Scaled with --vf-scale so each
|
|
101
|
+
system pixel lands on whole device pixels; unlike a conic-gradient
|
|
102
|
+
(whose hard stops the browser feathers into a blur), the SVG rects are
|
|
103
|
+
pixel-exact.
|
|
104
|
+
|
|
105
|
+
This CSS-repeated layer is the UNDERLAY: what actually shows is the
|
|
106
|
+
whole-surface raster (or, under a consumer pattern token, the
|
|
107
|
+
placed tile grid) rendered over it — see src/tile-grid.ts — which
|
|
108
|
+
is what keeps the dither 1-bit at the zoom-minted scales a
|
|
109
|
+
repeating fill cannot hold. The declaration stays as
|
|
110
|
+
belt-and-braces paint beneath the (opaque) kit fill. Override the
|
|
111
|
+
whole tile via --vf-desktop-pattern — the tile grid renders the
|
|
112
|
+
same token at the same documented geometry. */
|
|
113
|
+
background-image: var(--vf-desktop-pattern, ${C(j)});
|
|
114
|
+
${d(k)}
|
|
115
|
+
/* Forced colors: the checker is opaque literal white-and-black (a
|
|
116
|
+
preserved url() tile), which ignores a dark theme entirely. A
|
|
117
|
+
backdrop is decoration, and high-contrast mode is a request for
|
|
118
|
+
less of that — so the desktop goes flat Canvas (the forced
|
|
119
|
+
background-color) rather than re-dithering in the user's pair.
|
|
120
|
+
Deliberate; the windoid dot bar, which carries meaning, IS
|
|
121
|
+
re-inked (see vfDots). */
|
|
122
|
+
@media (forced-colors: active) {
|
|
123
|
+
background-image: none;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/* With a consumer pattern token in play the exact fill is the placed
|
|
127
|
+
tile grid, and the CSS-repeated underlay must not paint: a
|
|
128
|
+
translucent consumer tile would show the underlay's *drifting* copy
|
|
129
|
+
of the same art through itself. The base color stays — that is the
|
|
130
|
+
layer translucent art composites over, as documented. */
|
|
131
|
+
.screen.patterned {
|
|
132
|
+
background-image: none;
|
|
133
|
+
}
|
|
134
|
+
/* The dither's exact fill — the whole-surface raster (kit art) or the
|
|
135
|
+
placed tile grid (consumer art) — kept under every slotted child
|
|
136
|
+
(menu bar, windows) by the negative z-index the .screen isolation
|
|
137
|
+
scopes. The grid's tiles resolve the pattern token stated once here
|
|
138
|
+
rather than per tile. */
|
|
139
|
+
.screen > .vf-tile-grid,
|
|
140
|
+
.screen > .vf-tile-raster {
|
|
141
|
+
z-index: -1;
|
|
142
|
+
/* Forced colors: hidden with the underlay's tile, same posture — the
|
|
143
|
+
desktop goes flat Canvas (a backdrop is decoration). */
|
|
144
|
+
@media (forced-colors: active) {
|
|
145
|
+
display: none;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
.screen > .vf-tile-grid {
|
|
149
|
+
position: absolute;
|
|
150
|
+
inset: 0;
|
|
151
|
+
--_vf-tile-image: var(--vf-desktop-pattern, ${C(M)});
|
|
152
|
+
}
|
|
153
|
+
/* Bezeled, the screen is inset by exactly one bezel width. The host
|
|
154
|
+
is always the declared screen + 2×bezel (written in updated()), so
|
|
155
|
+
this subtraction is exact and the raster is whole by construction —
|
|
156
|
+
a page's sub-system-pixel slack never enters the component. */
|
|
157
|
+
.bezeled .screen {
|
|
158
|
+
top: var(--vf-desktop-bezel, 0px);
|
|
159
|
+
left: var(--vf-desktop-bezel, 0px);
|
|
160
|
+
width: calc(100% - 2 * var(--vf-desktop-bezel, 0px));
|
|
161
|
+
height: calc(100% - 2 * var(--vf-desktop-bezel, 0px));
|
|
162
|
+
}
|
|
163
|
+
/* Slotted windows need a positioning context so z-index applies.
|
|
164
|
+
(An inline position: absolute set by a movable window wins.) */
|
|
165
|
+
::slotted(vf-window) {
|
|
166
|
+
position: relative;
|
|
167
|
+
}
|
|
168
|
+
/* With a bezel, the screen's top corners wear the SCREEN_CORNER mask,
|
|
169
|
+
rounding into the surrounding black — the top pair only, because the
|
|
170
|
+
classic framebuffer masked only those; the raster's bottom corners
|
|
171
|
+
ran square. Children of .screen, so they anchor to the raster's own
|
|
172
|
+
corners (over a slotted menu bar's, which sit in the same place). The
|
|
173
|
+
hardware mask was in front of every pixel — a window dragged into a
|
|
174
|
+
corner slides under it — hence the maximal z-index. */
|
|
175
|
+
.corner {
|
|
176
|
+
position: absolute;
|
|
177
|
+
top: 0;
|
|
178
|
+
width: calc(var(--vf-scale, 1) * ${v[0]}px);
|
|
179
|
+
height: calc(var(--vf-scale, 1) * ${v.length}px);
|
|
180
|
+
background: var(--vf-black, #000);
|
|
181
|
+
pointer-events: none;
|
|
182
|
+
z-index: 2147483647;
|
|
183
|
+
}
|
|
184
|
+
.corner.tl {
|
|
185
|
+
left: 0;
|
|
186
|
+
clip-path: ${C(y(v, "left"))};
|
|
187
|
+
}
|
|
188
|
+
.corner.tr {
|
|
189
|
+
right: 0;
|
|
190
|
+
clip-path: ${C(y(v, "right"))};
|
|
191
|
+
}
|
|
192
|
+
`
|
|
193
|
+
];
|
|
194
|
+
}
|
|
195
|
+
fitWithin(e, t) {
|
|
196
|
+
let r = n(this), i = (e) => Math.max(0, Math.floor(e / r + 1e-6) - 2 * this.bezel);
|
|
197
|
+
return this.width = i(e), this.height = i(t), {
|
|
198
|
+
width: this.width,
|
|
199
|
+
height: this.height
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
#e;
|
|
203
|
+
connectedCallback() {
|
|
204
|
+
super.connectedCallback(), this.addEventListener("pointerdown", this._onPointerDown), this.addEventListener("focusin", this._onFocusIn);
|
|
205
|
+
}
|
|
206
|
+
disconnectedCallback() {
|
|
207
|
+
this.removeEventListener("pointerdown", this._onPointerDown), this.removeEventListener("focusin", this._onFocusIn), this._pointerGesture = !1, super.disconnectedCallback();
|
|
208
|
+
}
|
|
209
|
+
_isUtility(e) {
|
|
210
|
+
return e.getAttribute("variant") === "utility";
|
|
211
|
+
}
|
|
212
|
+
bringToFront(e) {
|
|
213
|
+
this._restack(e), this._requestDomSync();
|
|
214
|
+
}
|
|
215
|
+
_restack(e) {
|
|
216
|
+
let t = this._isUtility(e);
|
|
217
|
+
e.style.zIndex = String(++this._zCounter + (t ? E : 0)), t || this._setActive(e);
|
|
218
|
+
}
|
|
219
|
+
_requestDomSync() {
|
|
220
|
+
this._pointerGesture || this._syncDomOrder();
|
|
221
|
+
}
|
|
222
|
+
_raise(e) {
|
|
223
|
+
let t = this._isUtility(e), n = this._windows.filter((e) => this._isUtility(e) === t);
|
|
224
|
+
this._topmost(n) === e && (t || e.hasAttribute("active")) || this._restack(e);
|
|
225
|
+
}
|
|
226
|
+
_windowFromEvent(e) {
|
|
227
|
+
let t = this._windows;
|
|
228
|
+
return e.composedPath().find((e) => e instanceof HTMLElement && t.includes(e));
|
|
229
|
+
}
|
|
230
|
+
_onSlotChange() {
|
|
231
|
+
let e = this._windows, t = null;
|
|
232
|
+
for (let n of e) if (!n.style.zIndex) {
|
|
233
|
+
let e = this._isUtility(n);
|
|
234
|
+
n.style.zIndex = String(++this._zCounter + (e ? E : 0)), e || (t = n);
|
|
235
|
+
}
|
|
236
|
+
let n = t ?? this._topmost(e.filter((e) => !this._isUtility(e)));
|
|
237
|
+
n && this._setActive(n), customElements.get("vf-window") || this._normalizeAfterUpgrade();
|
|
238
|
+
}
|
|
239
|
+
_normalizeAfterUpgrade() {
|
|
240
|
+
this._awaitingUpgrade || (this._awaitingUpgrade = !0, customElements.whenDefined("vf-window").then(() => {
|
|
241
|
+
if (this._awaitingUpgrade = !1, !this.isConnected) return;
|
|
242
|
+
let e = this._topmost(this._windows.filter((e) => !this._isUtility(e)));
|
|
243
|
+
e && this._setActive(e);
|
|
244
|
+
}));
|
|
245
|
+
}
|
|
246
|
+
_setActive(e) {
|
|
247
|
+
for (let t of this._windows) this._isUtility(t) || this._setWindowActive(t, t === e);
|
|
248
|
+
}
|
|
249
|
+
_setWindowActive(e, t) {
|
|
250
|
+
if ("active" in e) {
|
|
251
|
+
let n = e;
|
|
252
|
+
n.active !== t && (n.active = t);
|
|
253
|
+
} else e.hasAttribute("active") !== t && e.toggleAttribute("active", t);
|
|
254
|
+
}
|
|
255
|
+
_topmost(e) {
|
|
256
|
+
let t = null, n = -Infinity;
|
|
257
|
+
for (let r of e) {
|
|
258
|
+
let e = Number(r.style.zIndex) || 0;
|
|
259
|
+
e >= n && (n = e, t = r);
|
|
260
|
+
}
|
|
261
|
+
return t;
|
|
262
|
+
}
|
|
263
|
+
_deepActiveElement() {
|
|
264
|
+
let e = document.activeElement;
|
|
265
|
+
for (; e?.shadowRoot?.activeElement;) e = e.shadowRoot.activeElement;
|
|
266
|
+
return e;
|
|
267
|
+
}
|
|
268
|
+
_syncDomOrder() {
|
|
269
|
+
if (!this.isConnected) return;
|
|
270
|
+
let e = this._windows;
|
|
271
|
+
if (e.length < 2) return;
|
|
272
|
+
let t = [...e].sort((e, t) => (Number(e.style.zIndex) || 0) - (Number(t.style.zIndex) || 0)), n = this._deepActiveElement(), r = !1, i = null;
|
|
273
|
+
for (let e of t) i && i.compareDocumentPosition(e) & Node.DOCUMENT_POSITION_PRECEDING && (this.insertBefore(e, i.nextSibling), r = !0), i = e;
|
|
274
|
+
r && n instanceof HTMLElement && n.isConnected && this._deepActiveElement() !== n && (this._restoringFocus = !0, n.focus({ preventScroll: !0 }), this._restoringFocus = !1);
|
|
275
|
+
}
|
|
276
|
+
willUpdate(e) {
|
|
277
|
+
super.willUpdate(e), this._pattern = p(this, "--vf-desktop-pattern");
|
|
278
|
+
}
|
|
279
|
+
updated(e) {
|
|
280
|
+
if (e.has("bezel") && (this.bezel > 0 ? this.style.setProperty("--vf-desktop-bezel", r(this.bezel)) : this.style.removeProperty("--vf-desktop-bezel")), e.has("width") || e.has("height") || e.has("bezel")) {
|
|
281
|
+
let e = this.width ?? D, t = this.height ?? O;
|
|
282
|
+
this.style.width = r(e + 2 * this.bezel), this.style.height = r(t + 2 * this.bezel);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
render() {
|
|
286
|
+
let e = this.width ?? D, t = this.height ?? O, n = Math.ceil(e / N), i = Math.ceil(t / N), a = this._pattern ? S`<div class="vf-tile-grid">
|
|
287
|
+
${m({
|
|
288
|
+
cols: n,
|
|
289
|
+
rows: i,
|
|
290
|
+
tile: N
|
|
291
|
+
})}
|
|
292
|
+
</div>` : S`<div
|
|
293
|
+
class="vf-tile-raster"
|
|
294
|
+
style="width:${r(n * N)};height:${r(i * N)};background-image:${this.#e.for(k, k, A, n * N, i * N)}"
|
|
295
|
+
></div>`;
|
|
296
|
+
return S`
|
|
297
|
+
<div class=${this.bezel > 0 ? "desktop vf-snap bezeled" : "desktop vf-snap"}>
|
|
298
|
+
<div class="screen${this._pattern ? " patterned" : ""}" part="desktop">
|
|
299
|
+
${a}
|
|
300
|
+
<slot @slotchange=${this._onSlotChange}></slot>
|
|
301
|
+
${this.bezel > 0 ? S`<div class="corner tl"></div>
|
|
302
|
+
<div class="corner tr"></div>` : null}
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
`;
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
i([w({ type: Number })], P.prototype, "width", void 0), i([w({ type: Number })], P.prototype, "height", void 0), i([w({ type: Number })], P.prototype, "bezel", void 0), i([T({ selector: "vf-window" })], P.prototype, "_windows", void 0), P = i([e("vf-desktop")], P);
|
|
309
|
+
//#endregion
|
|
310
|
+
export { P as VfDesktop };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { VfModalDialog } from '../modal-dialog.js';
|
|
2
|
+
import './vf-button-group.js';
|
|
3
|
+
/**
|
|
4
|
+
* `<vf-dialog>` — the System 7 modal dialog shell.
|
|
5
|
+
*
|
|
6
|
+
* Two chromes, one modal lifecycle (native `<dialog>` for top-layer rendering
|
|
7
|
+
* and focus trapping, with a fully transparent backdrop — no dimming):
|
|
8
|
+
*
|
|
9
|
+
* - **Default:** a striped title bar with a centered title over a white body —
|
|
10
|
+
* the movable-modal look. Drag the title bar to move it. `closable` adds the
|
|
11
|
+
* standard close box (left of the bar) — the HIG's own figures disagree on
|
|
12
|
+
* whether a movable modal carries one (Figure 5-1 says yes, Figure 6-1 and
|
|
13
|
+
* the Chapter 6 text say no), so the component enables either reading rather
|
|
14
|
+
* than enforcing one.
|
|
15
|
+
* - **`frame="plain"`:** the classic dBoxProc modal-dialog frame — 1px outer
|
|
16
|
+
* border, 2px gap, 2px inner band, no shadow, no title bar — and immovable,
|
|
17
|
+
* like the original. A `heading` renders as a centered display-face heading
|
|
18
|
+
* at the top of the body (the reference art's "Dialog title"); `closable` is
|
|
19
|
+
* ignored, there being no bar to carry the widget.
|
|
20
|
+
*
|
|
21
|
+
* Open it with `show()` (or set the `open` attribute/property); close with
|
|
22
|
+
* `close()`. Escape closes it and fires `vf-close` with
|
|
23
|
+
* `{ reason: 'escape' }`; the close box and programmatic closing fire
|
|
24
|
+
* `{ reason: 'close' }`.
|
|
25
|
+
*
|
|
26
|
+
* @slot - Default slot: dialog body content.
|
|
27
|
+
* @slot buttons - Optional action buttons. Rendered as a bottom-right
|
|
28
|
+
* `vf-button-group` (equal-width, faces aligned); the footer only takes
|
|
29
|
+
* space when the slot is populated.
|
|
30
|
+
* @csspart frame - The outer chrome frame (striped-bar or plain).
|
|
31
|
+
* @csspart title-bar - The striped title bar (default chrome only).
|
|
32
|
+
* @csspart title - The centered title patch (or the plain-frame heading).
|
|
33
|
+
* @csspart close-box - The close widget (`closable`, default chrome only).
|
|
34
|
+
* @csspart body - The white content area.
|
|
35
|
+
* @csspart content - The scrolling region inside the body (heading + slotted
|
|
36
|
+
* content, not the footer). Inert while the content fits; over-stuffed, it
|
|
37
|
+
* scrolls under a System 7 rail and becomes a keyboard stop.
|
|
38
|
+
* @csspart footer - The action row wrapping the buttons.
|
|
39
|
+
* @csspart buttons - The button group inside the footer.
|
|
40
|
+
* @fires vf-close - Dialog closed. Detail `{ reason: 'escape' | 'close' }`.
|
|
41
|
+
* @cssprop --vf-dots-pattern - the windoid bar's dot-grid dither — a 2×2 tile,
|
|
42
|
+
* one black pixel at the origin (`vfDots`; override the whole pattern like
|
|
43
|
+
* `--vf-desktop-pattern`)
|
|
44
|
+
* @cssprop --vf-titlebar-height - window/dialog title bars
|
|
45
|
+
* @cssprop --vf-scrollbar-thumb - scrollbar thumb/elevator (white)
|
|
46
|
+
* @cssprop --vf-scrollbar-track - the scroll trough's base color under the
|
|
47
|
+
* dot-dither (white)
|
|
48
|
+
*/
|
|
49
|
+
export declare class VfDialog extends VfModalDialog {
|
|
50
|
+
static styles: import("lit").CSSResult[];
|
|
51
|
+
/**
|
|
52
|
+
* Title-bar drag-to-move (shared with `vf-window` via {@link DragController}).
|
|
53
|
+
* The gesture states the modal's `top`/`left` in system px — viewport
|
|
54
|
+
* coordinates, since `showModal()` puts the box in the top layer — so a
|
|
55
|
+
* dragged dialog is placed exactly the way an authored one is, and holds its
|
|
56
|
+
* spot through a zoom rather than being re-centered by it. Inert with
|
|
57
|
+
* `frame="plain"` — no bar is rendered, so no pointer ever reaches the
|
|
58
|
+
* controller (dBoxProc dialogs don't move).
|
|
59
|
+
*/
|
|
60
|
+
private readonly _drag;
|
|
61
|
+
/** Holds the centered title patch on the placement lattice (src/chrome.ts). */
|
|
62
|
+
private readonly _titleCenter;
|
|
63
|
+
/** Title text: the bar's centered patch, or the plain frame's heading. */
|
|
64
|
+
heading: string;
|
|
65
|
+
/**
|
|
66
|
+
* Accessible name for the dialog (`aria-label`), for a dialog with no
|
|
67
|
+
* `heading` — an untitled title bar has no text to be named by. Ignored when
|
|
68
|
+
* empty and a `heading` is set (the title patch names the dialog then);
|
|
69
|
+
* defaults to `'Dialog'` when neither is given.
|
|
70
|
+
*/
|
|
71
|
+
label: string;
|
|
72
|
+
/**
|
|
73
|
+
* Show the close box (left side of the title bar). Off by default — the
|
|
74
|
+
* bare movable-modal bar. Ignored with `frame="plain"` (no bar). Clicking
|
|
75
|
+
* it closes the dialog and fires `vf-close` with `{ reason: 'close' }`.
|
|
76
|
+
*/
|
|
77
|
+
closable: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Frame chrome. Omit for the striped title bar (movable modal); `'plain'`
|
|
80
|
+
* for the immovable dBoxProc double frame with no bar (modal dialog box).
|
|
81
|
+
*/
|
|
82
|
+
frame?: 'plain';
|
|
83
|
+
/** Whether the `buttons` slot has assigned content (drives the footer). */
|
|
84
|
+
private _hasButtons;
|
|
85
|
+
private _content;
|
|
86
|
+
/** Whether the body content overflows its box (drives the content stop). */
|
|
87
|
+
private _scrollable;
|
|
88
|
+
/**
|
|
89
|
+
* Activates the System 7 rail — and the content region's keyboard stop —
|
|
90
|
+
* once the body content overflows the declared (or viewport-capped) box.
|
|
91
|
+
*/
|
|
92
|
+
private readonly _scrollState;
|
|
93
|
+
/** Syncs the drawn rail to the content region and drives its interactions. */
|
|
94
|
+
private readonly _rail;
|
|
95
|
+
/** Content changed under the fixed box — re-measure the overflow. */
|
|
96
|
+
private _onBodySlotChange;
|
|
97
|
+
private _onCloseClick;
|
|
98
|
+
protected render(): unknown;
|
|
99
|
+
private _onButtonsSlotChange;
|
|
100
|
+
}
|
|
101
|
+
declare global {
|
|
102
|
+
interface HTMLElementTagNameMap {
|
|
103
|
+
'vf-dialog': VfDialog;
|
|
104
|
+
}
|
|
105
|
+
}
|