vintage-frames 0.18.0 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/custom-elements.json +278 -51
- package/dist/build/app-file.d.ts +2 -2
- package/dist/build/app-file.js +1 -0
- package/dist/build/plugins.d.ts +2 -2
- package/dist/build/plugins.js +62 -59
- package/dist/components/vf-icon.d.ts +7 -0
- package/dist/components/vf-icon.js +101 -81
- package/dist/components/vf-menu-bar.d.ts +6 -4
- package/dist/components/vf-menu-bar.js +26 -56
- package/dist/components/vf-menu-item.d.ts +33 -5
- package/dist/components/vf-menu-item.js +128 -61
- package/dist/components/vf-menu.d.ts +35 -0
- package/dist/components/vf-menu.js +171 -111
- package/dist/glyphs.d.ts +6 -0
- package/dist/glyphs.js +18 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -14
- package/dist/menu-navigation.d.ts +34 -0
- package/dist/menu-navigation.js +53 -0
- package/dist/menu-press.d.ts +25 -7
- package/dist/menu-press.js +78 -44
- package/dist/motion.d.ts +10 -0
- package/dist/shell/app-file.d.ts +20 -4
- package/dist/shell/app-file.js +65 -53
- package/dist/shell/catalog.d.ts +79 -1
- package/dist/shell/catalog.js +206 -153
- package/dist/shell/finder.d.ts +28 -9
- package/dist/shell/finder.js +339 -267
- package/dist/shell/geometry.d.ts +7 -0
- package/dist/shell/geometry.js +19 -3
- package/dist/shell/index.d.ts +4 -4
- package/dist/shell/index.js +12 -12
- package/dist/shell/pure.d.ts +1 -1
- package/dist/shell/pure.js +6 -6
- package/dist/shell/shell.d.ts +14 -10
- package/dist/shell/shell.js +148 -116
- package/dist/shell/version.d.ts +1 -1
- package/dist/shell/version.js +1 -1
- package/dist/styles/body-italic-font.d.ts +2 -0
- package/dist/styles/body-italic-font.js +10 -0
- package/dist/styles/register-embedded-font.d.ts +5 -4
- package/dist/styles/register-embedded-font.js +11 -10
- package/docs/SPEC.md +11 -7
- package/editor/vscode.html-custom-data.json +15 -5
- package/editor/web-types.json +55 -9
- package/package.json +7 -3
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PIXEL_GRID_METRICS as e, registerEmbeddedFont as t } from "./register-embedded-font.js";
|
|
2
|
+
import { VF_BODY_FAMILY as n } from "./body-font.js";
|
|
3
|
+
//#region src/styles/body-italic-font.ts
|
|
4
|
+
var r = "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";
|
|
5
|
+
function i() {
|
|
6
|
+
t(n, r, e, "italic");
|
|
7
|
+
}
|
|
8
|
+
i();
|
|
9
|
+
//#endregion
|
|
10
|
+
export { i as registerBodyItalicFace };
|
|
@@ -53,12 +53,13 @@ export interface EmbeddedFontMetrics {
|
|
|
53
53
|
*/
|
|
54
54
|
export declare const PIXEL_GRID_METRICS: EmbeddedFontMetrics;
|
|
55
55
|
/**
|
|
56
|
-
* Register `family` from an inlined base64 WOFF2 exactly once per session
|
|
56
|
+
* Register `family` from an inlined base64 WOFF2 exactly once per session —
|
|
57
|
+
* its `style` face, `normal` unless the WOFF2 is the family's italic.
|
|
57
58
|
*
|
|
58
59
|
* Idempotent and environment-safe: it no-ops under SSR (no `document`), when
|
|
59
|
-
* the CSS Font Loading API is unavailable, or when the
|
|
60
|
-
* present (duplicate bundles / HMR). A failed decode releases the
|
|
60
|
+
* the CSS Font Loading API is unavailable, or when the face is already
|
|
61
|
+
* present (duplicate bundles / HMR). A failed decode releases the face so a
|
|
61
62
|
* later explicit call can retry, and on any failure components simply keep the
|
|
62
63
|
* fallback stack — so this can never break rendering.
|
|
63
64
|
*/
|
|
64
|
-
export declare function registerEmbeddedFont(family: string, woff2Base64: string, metrics?: EmbeddedFontMetrics): void;
|
|
65
|
+
export declare function registerEmbeddedFont(family: string, woff2Base64: string, metrics?: EmbeddedFontMetrics, style?: 'normal' | 'italic'): void;
|
|
@@ -4,26 +4,27 @@ var e = /* @__PURE__ */ new Set(), t = {
|
|
|
4
4
|
descentOverride: "25%",
|
|
5
5
|
lineGapOverride: "0%"
|
|
6
6
|
};
|
|
7
|
-
function n(t, n, r) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
function n(t, n, r, i = "normal") {
|
|
8
|
+
let a = `${t} ${i}`;
|
|
9
|
+
if (e.has(a) || typeof document > "u" || !("fonts" in document)) return;
|
|
10
|
+
for (let n of document.fonts) if (n.family === t && n.style === i) {
|
|
11
|
+
e.add(a);
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
13
|
-
e.add(
|
|
14
|
-
let
|
|
14
|
+
e.add(a);
|
|
15
|
+
let o = `url(data:font/woff2;base64,${n}) format('woff2')`;
|
|
15
16
|
try {
|
|
16
|
-
let n = new FontFace(t,
|
|
17
|
-
style:
|
|
17
|
+
let n = new FontFace(t, o, {
|
|
18
|
+
style: i,
|
|
18
19
|
weight: "100 900",
|
|
19
20
|
display: "swap",
|
|
20
21
|
...r
|
|
21
22
|
});
|
|
22
23
|
document.fonts.add(n), n.load().then(() => {}, () => {
|
|
23
|
-
document.fonts.delete(n), e.delete(
|
|
24
|
+
document.fonts.delete(n), e.delete(a);
|
|
24
25
|
});
|
|
25
26
|
} catch {
|
|
26
|
-
e.delete(
|
|
27
|
+
e.delete(a);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
//#endregion
|
package/docs/SPEC.md
CHANGED
|
@@ -365,7 +365,7 @@ The classic popup menu control ("Macintosh HD ▼").
|
|
|
365
365
|
#### `vf-menu-bar` (`VfMenuBar`, vf-menu-bar.ts)
|
|
366
366
|
- **Attributes/props:** `label: string` — accessible name for the menubar, mirrored as host `aria-label` (guarded: a consumer's own `aria-label`/`aria-labelledby` is left alone). `rounded: boolean` (reflected) — draws the System 7 screen-corner mask over the bar's top-left/top-right corners. `shortcuts: boolean` (reflected) — makes every slotted menu's item `shortcut`s live key equivalents, one declaration for the whole bar the way MenuKey() answered for every menu at once (see vf-menu-item for the claim contract). Off by default: key equivalents are page-global, and only *the* menu bar should own them.
|
|
367
367
|
- **Visual:** `display: block/flex`, height `var(--vf-menubar-height, 20px)` — 19 white system px over the 1px black rule, the Menus.png bar strip exactly — white bg, the rule `vfRule`'s `.vf-rule-bottom` on the bar (§4), children laid out horizontally from left. Adjacent titles are pulled 4px into each other (`margin-inline-start: -4px` on every slotted menu, absorbed by 13px of bar start padding — 9px of bar before the first plate plus the first title's 4px share): title ink sits 15px apart while each title's plate runs 10px left / 9px right of its own ink, so neighboring plates *overlap* by 4px. With `rounded`, two 5×5 system-px corner overlays paint the traced stair-step mask (per-row runs 5/3/2/1/1 — `SCREEN_CORNER` + `steppedCornerClip` in `pixel-frame.ts`) in `--vf-black` *over* the bar: on the classic screen the rounding was the ROM's black corner mask sitting on top of the menu bar, not a shape of the bar's own, so it is ink over any backdrop rather than a cutout.
|
|
368
|
-
- **Behavior:** container/controller for slotted `vf-menu` children. Pressing a menu label → opens it (label inverts while open). While any menu is open, hovering another label switches to it (classic behavior). Escape / outside click / item selection closes. `role="menubar"`, behind a first-connect ownership latch so a consumer's own role survives upgrade; the shadow `.bar` is `role="presentation"` and each slotted `vf-menu` host `role="none"`, so the `menubar → menuitem` ownership chain has no generics in it. While a menu is open
|
|
368
|
+
- **Behavior:** container/controller for slotted `vf-menu` children. Pressing a menu label → opens it (label inverts while open). While any menu is open, hovering another label switches to it (classic behavior). Escape / outside click / item selection closes. `role="menubar"`, behind a first-connect ownership latch so a consumer's own role survives upgrade; the shadow `.bar` is `role="presentation"` and each slotted `vf-menu` host `role="none"`, so the `menubar → menuitem` ownership chain has no generics in it. While a menu is open the keyboard is `src/menu-navigation.ts`'s, which a standalone `vf-menu` shares, acting on the deepest open menu holding focus (the APG menubar pattern): ArrowDown/Up walk its items, Home/End jump to its first/last enabled item, and printable keys run the shared Finder first-letter type-ahead over them (`src/type-ahead.ts`; Space stays the focused item's activation key, and the prefix resets on menu switch, a level change or close). ArrowRight on an item that opens a submenu opens it and focuses its first enabled item; on any other item it opens the next menu. ArrowLeft in a submenu closes it and refocuses its item; at the top level it opens the previous menu. Escape closes one level: a submenu back to its item, the menu back to its title. The bar also **owns the press-drag-release gesture** across its menus (`MenuPressController`, `src/menu-press.ts` — see `vf-menu`), since one press may travel over several of them: it binds the opening `pointerdown` and hands the controller its own open/close rules, so the gesture changes *when* a menu opens, never *how*.
|
|
369
369
|
- **Slots:** default (vf-menu elements); `end` — the bar's right end, where a clock goes: a flex row of its own pushed to the end with an auto start margin and held 9px in, mirroring the first title's inset, setting `--vf-label-line-height` to the bar's height so a `vf-label` there rides the titles' baseline. Empty, it is `display: none` and takes no part in the row, so a page that pushes its own item to the end keeps the whole of the slack. `npm run verify:archetypes` (END SLOT). **Parts:** `bar`.
|
|
370
370
|
|
|
371
371
|
#### `vf-menu` (`VfMenu`, vf-menu.ts)
|
|
@@ -374,18 +374,22 @@ The classic popup menu control ("Macintosh HD ▼").
|
|
|
374
374
|
- **Keyboard focus: no ring** — `vfFocusUnderline` (§4) at `--vf-focus-underline-offset: -2px`, a dashed rule one blank system px row under the `.title` box. That box is `line-height: 1`, i.e. the face's own em, whose bottom edge is the descent line — so the one offset clears a descender *and* a slotted 16px `vf-img` (the Apple menu), where the button's baseline-anchored rule is crossed by both. In `currentColor`, so it inverts with the title on an open menu's black cell.
|
|
375
375
|
- **Closed only** (`:host(:not([open]))`). A dropped menu inverts its whole cell, which already shows where focus is; the rule marks the state the inversion can't — focused but not yet open — and drawing both would put a second mark (in white, since it is `currentColor`) under the first. The class stays on through the open state, so the rule returns by itself when the menu closes and hands focus back.
|
|
376
376
|
- Gated on a `.vf-focus-rule` class from the page's input modality, not `:focus-visible` (§4): `MenuPressController` `preventDefault`s the opening `pointerdown` and calls `focusLabel()` itself. The menu also calls the controller's `suppress()` from its own host `pointerdown`, so a press on an already-focused title — which moves no focus, and so fires no `focusin` — still drops the mark, as does mousing into the dropped panel. `npm run verify:focus`.
|
|
377
|
-
- **Behavior:** delegates open-state coordination to parent `vf-menu-bar` when present (only one open at a time; standalone, `#requestToggle` doesn't emit the coordination event at all — see the events convention in §2). Keyboard on the label: Enter, Space and ArrowDown all open **and move focus to the first enabled item** (APG, menubar and menu-button patterns alike — opening without entering would park the keyboard on the title with the panel dropped). While open standalone the menu runs its
|
|
377
|
+
- **Behavior:** delegates open-state coordination to parent `vf-menu-bar` when present (only one open at a time; standalone, `#requestToggle` doesn't emit the coordination event at all — see the events convention in §2). Keyboard on the label: Enter, Space and ArrowDown all open **and move focus to the first enabled item** (APG, menubar and menu-button patterns alike — opening without entering would park the keyboard on the title with the panel dropped). While open standalone the menu runs the bar's keyboard itself (`src/menu-navigation.ts`, see `vf-menu-bar`) over its items and its submenus: ArrowDown/Up wrap, Home/End jump, printable keys run the shared first-letter type-ahead (`src/type-ahead.ts`), ArrowRight and ArrowLeft open and close submenus, Escape closes one level and at the top refocuses the label. Sets `--vf-separator-color: var(--vf-disabled, #c0c0c0)` on its panel so slotted `vf-separator`s render dimmed, each spending one full `--vf-menu-row-height` — the MDEF's divider-as-item — with the rule 8px in (12px under the ink band above, 10 over the one below, per InfiniteMac's System 7.5 Edit menu and the 32px cross-divider ink pitch in `Menus.png`). **Pointer:** the two styles `vf-select` supports, on the same terms and the same `PRESS_HOLD_MS` threshold (`src/motion.ts`) — the menus get theirs from `MenuPressController` (`src/menu-press.ts`), which a standalone menu hosts itself and a `vf-menu-bar` hosts for all of its menus. Opening is on **pointerdown**, and the press is then tracked to its release anywhere:
|
|
378
378
|
- *System 7 press-drag-release* — press the title, slide onto a command, release over it to run it. Sliding sideways onto another title switches menus mid-press. Releasing over a disabled row, a separator, the title, or off the menu closes with nothing chosen (the classic "release outside").
|
|
379
|
-
- *Modern click-to-open* — a quick in-place tap (under `PRESS_HOLD_MS`, 200ms) on a title leaves the menu dropped for a second, independent click; a *held* in-place press closes it, and a press on an already-dropped title closes it. Time is consulted only for an in-place release: any press that travels is a drag-pick however long it took. Hit-testing is by **coordinates**, not event target, so tracking survives touch's implicit pointer capture (every move is delivered to the pressed title)
|
|
379
|
+
- *Modern click-to-open* — a quick in-place tap (under `PRESS_HOLD_MS`, 200ms) on a title leaves the menu dropped for a second, independent click; a *held* in-place press closes it, and a press on an already-dropped title closes it. Time is consulted only for an in-place release: any press that travels is a drag-pick however long it took. Hit-testing is by **coordinates**, not event target, so tracking survives touch's implicit pointer capture (every move is delivered to the pressed title). The trailing `click` the browser synthesises after a press is swallowed by the label and by the row (the same guard `vf-select` uses), so a keyboard/assistive-tech click — which arrives with no preceding pointerdown — is the only click that still toggles or activates.
|
|
380
|
+
- *One pointer model for both.* While a menu is open the pointer is tracked with or without a button down; the button only changes what a release means. Each open menu highlights one row as `vf-menu-item[active]`: the row under the pointer, or, with the pointer elsewhere, the item whose submenu is open. `:hover` paints no row inside a menu, so none shows two. Hit-testing tries the open menus deepest first, since a submenu is painted over its parent.
|
|
381
|
+
- **Submenus.** A `vf-menu` in a `vf-menu-item`'s `submenu` slot is a submenu: no title, only its panel, beside its item. Its host is `role="none"`, its panel `role="menu"`, named by the item's `labelText` unless it has a `label`. The menu holding the item opens it through `expand(item, { focus })`, which closes the submenu already open in that menu and everything under it (`null` closes it); `expandedItem` reads it. The pointer resting on the item for `SUBMENU_OPEN_MS` (150ms) opens it, in either style; on another row of the same menu an open submenu closes after `SUBMENU_CLOSE_MS` (300ms), and never once the pointer reaches it, so a diagonal slide into it can cross the rows between (`src/motion.ts`, the interaction itself, so not reduced-motion gated). A release or a click on the item opens its submenu now and leaves every menu dropped, so the visitor carries on clicking; a finger taps it. A pick at any depth closes every menu through the usual close request, which a submenu passes up; a key equivalent's flash request passes up to the top title too. Closing a menu closes its open submenu. Menus nest to any depth.
|
|
382
|
+
- *Placement*, traced from an Infinite Mac capture of System 7.5's Apple menu at 3×: the submenu's top frame is the row above its item, so its first row is level with the item, and its left frame is 5px left of the parent's right frame, covering the parent's last 4px, frame and shadow, the item's highlight running up to it. The host is a box as wide as the row at the row's top (the item's `.submenu`), and the panel hangs from it by those offsets. It opens toward the side its parent opened toward, the right first, and flips (mirrored: its right frame 5px right of the parent's left frame) where that side has no room and the other has. It is raised by whole system px to fit above the screen's bottom, never past its top. The screen is the closest `vf-desktop`'s `.screen` below its menu bar, within the viewport, else the viewport. It stays inside its parent's panel, so it paints in the parent's stacking context and takes its grid correction.
|
|
380
383
|
- **Slots:** default (vf-menu-item / vf-separator), `label` (replaces the `label` text in the bar — e.g. the Apple menu's `vf-img` apple; the `label` attribute stays set as the accessible name, mirrored to the bar item's `aria-label`). **Parts:** `label`, `panel`.
|
|
381
384
|
- **An icon title.** When the `label` slot holds only art (`vf-img`, `img`, `svg`, `picture` or `canvas`), the title is drawn as an icon: the art goes in a 16×16 cell, 6 system px into its plate and 6 short of the plate's end (`padding-inline` 6/6 in place of the text title's 9/8), on the plate's top row: one row above where centering on the bar's line would put it. Art drawn from x 2, y 1 of its cell, as the apple is (its ink is 11 × 14 at x 2..12, y 1..14), then has 8 px of plate before its ink: as the first title, the cell lands at x 15, its ink at x 17..27 on rows 2..15, and the next title's plate at x 33, its ink at x 43. A text title, from `label` or text in the slot, keeps the text geometry. `npm run verify:archetypes` (ICON TITLE).
|
|
382
385
|
|
|
383
386
|
#### `vf-menu-item` (`VfMenuItem`, vf-menu-item.ts)
|
|
384
|
-
- **Attributes/props:** `disabled`, `checked` (shows ✓ in left gutter), `checkable` (declares a toggle up front — see Behavior), `shortcut: string` (e.g. `"⌘H"`, drawn in the left-aligned shortcut column; a **live key equivalent** under a `shortcuts` grant — see Behavior), `value?: string` (defaults to
|
|
385
|
-
- **
|
|
387
|
+
- **Attributes/props:** `disabled`, `checked` (shows ✓ in left gutter), `checkable` (declares a toggle up front — see Behavior), `shortcut: string` (e.g. `"⌘H"`, drawn in the left-aligned shortcut column; a **live key equivalent** under a `shortcuts` grant — see Behavior), `value?: string` (defaults to `labelText`), `active` (reflect; the highlight under the pointer, or on the item whose submenu is open, managed by the menu — mirrors `vf-option[active]`, not an authoring API), `expanded` (reflect; its submenu is open, managed by the menu, announced as `aria-expanded`). Read-only: `submenu` (the `vf-menu` in the `submenu` slot, or null) and `labelText` (the default slot's text, trimmed, without a submenu's rows: the default value, the menus' type-ahead and a submenu item's name read it).
|
|
388
|
+
- **Submenu items.** An item holding a `vf-menu` in its `submenu` slot draws ▶ (`CARET_RIGHT`, 6×11, `CARET_DOWN` on its side, traced from `Menus.png`'s submenu rows) where a shortcut would go: 8px in from the row's end, as a System 7.5 capture has it too, 2 rows down the 16px row (centered, the odd row below), with an 8px label↔▶ minimum. Its `shortcut` isn't drawn, announced or matched. It is never chosen: a click, Enter, Space or `activate()` opens its submenu and focuses the submenu's first enabled item. It is `menuitem` with `aria-haspopup="menu"` and `aria-expanded`, and its accessible name is its `labelText`, so an open submenu's rows never join it. Events from the submenu pass through it on their way up, and it leaves them alone: a click, press or keydown that came from inside its submenu is that row's.
|
|
389
|
+
- **Visual:** height `var(--vf-menu-row-height, 16px)` — `Menus.png` puts every menu row on a 16px pitch (3px above + the 9px glyph + 4px below), so a pulldown row matches a popup row exactly; the line box is locked to the same expression so an inherited line-height can never overflow the panel. `padding: 0 12px 0 var(--vf-select-gutter, 16px)` (left gutter for ✓, shared with `vf-select`/`vf-option` — `Menus.png` puts a pulldown's label ink at the same inset as a popup's; a shortcut row trades the 12 for 1px, the slot being the clearance there). The shortcut is left-aligned in a right-anchored `--vf-menu-shortcut-column` (23px) slot — every ⌘ at the same x, 23px from the right border, the widest letters running to within ~3px of it (`Menus.png`'s File pulldown) — with an 8px label↔shortcut min gap. `color: var(--vf-disabled)` when disabled. `[active]`, keyboard focus, and hover for a row outside a menu (not disabled): full-width inversion — each with its own `.blink-off` override at matching specificity, so a drag-picked row keeps its flag through the blink and the release reads as the highlight flashing off. Inside a menu the pointer's row is the menu's `[active]`, since the item whose submenu is open stays lit while the pointer is in the submenu. A disabled row dims its ✓ along with the label — a **documented deviation** from the §1 "dim the label, chrome glyphs stay black" rule, because authentic System 7 greyed the whole disabled row.
|
|
386
390
|
- **Behavior:** `role="menuitem"` — or `role="menuitemcheckbox"` with `aria-checked` when the item is *checkable*: either `checkable` is set, or the item has ever been `checked`. Set `checkable` on a toggle that starts **off**, which would otherwise announce as a plain command until its first flip (a boolean `checked` attribute can't express "checkable but off"). The role is re-derived on every connect, so re-parenting a checkable item keeps it; an author-supplied `role` is left alone. On activation — a click, Enter/Space, or the public `activate()` the menu's press gesture calls for the row a drag was released over (which the row's own `click` never sees, since a press that started on the title dispatches its click above both): classic **blink** (invert toggles 3 times over ~250ms via timer; skipped under `prefers-reduced-motion`, selecting at once), then dispatch `vf-menu-select` detail `{ value, item }` and signal ancestors to close the menu — the close signal is skipped when the ancestor menu is already closed (the key-equivalent path below), since the close paths return focus to the bar label and would yank it from wherever the user was typing. Disabling an item mid-blink cancels it and drops the pending `vf-menu-select`.
|
|
387
391
|
- **Key equivalents** (the MenuKey() half of `shortcut`): under an ancestor `vf-menu[shortcuts]` / `vf-menu-bar[shortcuts]` grant, a document-level keydown matching the shortcut activates the item from anywhere on the page, menu open or not — File → Save *shows* ⌘S and *answers* it, no page-side plumbing. Matching is exact on modifiers (⌘=Meta, ⌃=Control, ⌥=Alt, ⇧=Shift — the same mapping `aria-keyshortcuts` announces) with `event.key` compared case-insensitively, except that a declared ⌘ is met by Control too — Ctrl standing in for ⌘ off the Mac, vf-icon's own ⌘O reading — while a shortcut spelling ⌃ itself keeps meaning the Control key alone; the grant is checked per event, so toggling it needs no re-wiring. The claim contract: a `defaultPrevented` stroke is already someone's (a page handler that ran first keeps its key); a match claims with `preventDefault()` and no `stopPropagation`, so the first connected item wins a contested key and later page listeners still observe the claimed event; a **disabled** item claims nothing — the stroke falls through, so a grayed Undo leaves ⌘Z to the focused field's own native undo; auto-repeat strokes are claimed but activate once; a shortcut with no ⌘/⌃/⌥ and a single printable key renders and announces but never matches (a bare letter claimed globally would hijack typing — a named key like "F1" needs no modifier). The arrow glyphs ← ↑ → ↓ name the arrow keys: "⌘→" matches `ArrowRight` and announces as `Meta+ArrowRight`; a bare arrow counts as a single key and never matches, so it can't take the arrows from a list, a menu or a field. Activation is the normal path — blink, `vf-menu-select` — and a **closed** ancestor menu answers by flashing its bar title on the same cadence (MenuKey's acknowledgment; skipped with the blink under `prefers-reduced-motion`): the panel never opens and focus never moves. `npm run verify:menu-keys`.
|
|
388
|
-
- **Slots:** default (label). **Parts:** `item`, `check`, `label`, `shortcut`.
|
|
392
|
+
- **Slots:** default (label), `submenu` (a `vf-menu`). **Parts:** `item`, `check`, `label`, `shortcut`, `arrow`.
|
|
389
393
|
- **Events:** `vf-menu-select` — menu-specific by design. A plain `vf-select` would collide with the `<vf-select>` popup on any delegated ancestor listener, since both bubble and compose while `<vf-select>` itself commits with `vf-change`. Parallels the existing `vf-menu-*` coordination names.
|
|
390
394
|
|
|
391
395
|
#### `vf-list` (`VfList`, vf-list-item children) (vf-list.ts)
|
|
@@ -480,7 +484,7 @@ A raster image — the reference art's pixel icons — on the kit's grid, treati
|
|
|
480
484
|
|
|
481
485
|
#### `vf-icon` (`VfIcon`, vf-icon.ts)
|
|
482
486
|
The Finder icon — pixel art in a reserved cell with its name on a plate below, as one selectable, movable, renameable unit. `vf-img` puts a picture on the grid; this makes it the thing the Finder manipulates.
|
|
483
|
-
- **Attributes/props:** `label`: string (the name; empty draws no plate — that is the "no label" setting, rather than a second attribute that could disagree with it). `size`: `large` (default, 32×32) | `small` (16×16) — picks the slot that paints *and* the cell it paints in. `selectable`, `selected`, `movable`, `editable`: boolean. `color`: boolean — declares the art a **color icon**, so selection darkens instead of inverting (see Visual). `open`: boolean — the icon's window is on screen, and the art paints as the derived open ghost (below). `target`: boolean (reflected) — the destination highlight under a drag: the selected treatment of the *art* alone (`invert(1)`, or `brightness(0.5)` under `color`) with none of `selected`'s semantics — no `vf-select`, no outside listener, no `aria-selected`, the plate untouched; the page sets it on the folder a `vf-drag` reports the pointer over. `width`: number (system px, **even**; the cell/grid pitch, which a longer name overflows rather than being bound by). `maxlength`: number (31).
|
|
487
|
+
- **Attributes/props:** `label`: string (the name; empty draws no plate — that is the "no label" setting, rather than a second attribute that could disagree with it). `size`: `large` (default, 32×32) | `small` (16×16) — picks the slot that paints *and* the cell it paints in. `selectable`, `selected`, `movable`, `editable`: boolean. `color`: boolean — declares the art a **color icon**, so selection darkens instead of inverting (see Visual). `open`: boolean — the icon's window is on screen, and the art paints as the derived open ghost (below). `alias`: boolean (reflected) — the icon stands for another item: its name, plate and rename field alike, is set in the body face's italic (`registerBodyItalicFace`, built from the face's own glyphs, each row shifted right on the grid, never a synthesized oblique), and the plate widens to the slant's last pixel, read from the run's ink in a canvas set in the plate's font. `target`: boolean (reflected) — the destination highlight under a drag: the selected treatment of the *art* alone (`invert(1)`, or `brightness(0.5)` under `color`) with none of `selected`'s semantics — no `vf-select`, no outside listener, no `aria-selected`, the plate untouched; the page sets it on the folder a `vf-drag` reports the pointer over. `width`: number (system px, **even**; the cell/grid pitch, which a longer name overflows rather than being bound by). `maxlength`: number (31).
|
|
484
488
|
- **Visual:** `display: inline-block`. A column: the art cell (`--_cell` system px square, `overflow: hidden`, art centered), then, directly under it (`--vf-icon-gap`, 0 by default), the name plate — body face on a `--vf-icon-label-height` (12px) line box, the Finder's own plate height: the face's 16px em centers in it, 3px above the ascenders and descenders on the bottom edge, exactly as the Finder drew it — 1px horizontal padding, **opaque `--vf-white`** in its own right rather than `--vf-surface`: on the desktop dither the name reads because it sits on a plate, and `--vf-surface` is unset out there (`Example screen (1-bit).png`, the "Macintosh HD" icon). Selected: the plate takes the `--vf-highlight` pair and the art takes `filter: invert(1)` — a System 7 icon is ink and opaque white on a transparent surround, i.e. precisely an image plus its mask, so inverting flips the two and leaves the surround alone. That is the complete classic selected appearance for 1-bit art. Color art would invert into a photographic negative, which System 7 never showed: declare `color` and selection **darkens** instead — Icon Utilities' ttSelected transform, every color blended halfway toward black (`filter: brightness(0.5)`), whites going gray, the surround still untouched. The declaration is the consumer's, since the component cannot tell color art from a mask by looking at a slotted image; it covers whatever the cell shows (the open ghost included, so a color icon has one selected treatment open or closed), and the plate inverts either way — the selected name was inverted whatever the art.
|
|
485
489
|
- **The open ghost is derived, not shipped** (`open`; `open-art.ts`). The art redraws as the Finder's open-window ghost — outline held in solid black, interior re-filled with the scrollbar trough's 4×2 dot lattice (a dot at (0,0) and (2,1), 25%) on opaque white, surround untouched — derived from the slotted art itself, by compositing alone: a silhouette via `source-in`; a 1px 4-neighborhood erosion via four `destination-in` draws of the silhouette shifted one pixel each way (off-canvas composites as transparent, so the raster's own edge erodes too and an interior hole rings itself); the lattice via `createPattern` anchored at the art's top-left, where 32 and 16 being whole multiples of the tile keeps a field of icons in one phase; then the fill composed over the un-eroded silhouette, so the ring the erosion removed reads as the outline. Never `getImageData` — a canvas that drew a cross-origin image is tainted, which forbids *reading* pixels but not drawing or displaying them, so the ghost works for CORS-less sources too — and never `ctx.filter` (Safari's shaky corner; compositing operators are universal). Keeping the interior *opaque white* is what lets a selected open icon invert under the same `filter: invert(1)` with no second treatment. The slot stays in the tree while the ghost paints, hidden via a class gated on a successful derivation — art the pipeline cannot draw (nothing slotted, a failed load, an inline `<svg>`) keeps rendering as itself. The ghost re-derives on slotchange, the art's `load`/`error`, and `open`/`size` changes, keyed by `currentSrc` so a refresh that changed nothing is a string compare; the source's `alt` is carried onto the ghost (`role="img"` + `aria-label`) so a graphic that names its icon keeps doing so while its slot is hidden. The ghost displays on `vf-img`'s terms: natural raster size in system px, `image-rendering: pixelated`, one image pixel per system pixel.
|
|
486
490
|
- **Behavior:** clicking selects, Shift/⌘ toggles, and a press elsewhere clears — a `DocumentListenersController` capture-phase listener attached only while selectable *and* selected, which is what makes single-selection work with no container owning the set. For an icon alone, elsewhere is anywhere outside it. For an icon in a field, only a press on another icon or on a field (`vf-icon-field`, or a `role="listbox"` element of the page's own) clears it; a press on the menu bar, a menu, a dialog, a window's title bar or another window leaves the selection, so a menu command still has its icons to act on and a selection survives an application switch. Either way the press calls off a pending rename and a half-finished tap pair. Double-click fires `vf-open`, and its keyboard route is ⌘O / ⌘↓ (Ctrl off the Mac) — the System 7 Open shortcuts, added because a double-click is a pointer-only gesture (§1). **The instrument never changes what the icon means**, so a finger or a pen opens it too, on a *tap pair* the icon classifies from its own pointer events rather than from `dblclick`: two taps on the icon, the second pressed within `TAP_PAIR_MS` (500) of the first and no further than `TAP_PAIR_SLOP_PX` (24 CSS px) from it, `vf-open` firing on the second release. A platform reserves the double-tap for its zoom and may deliver no `dblclick` for one, and a movable icon's press is `preventDefault()`ed for the drag, which can suppress it as well; the pair depends on neither. A tap is a press released where it landed — one that became a drag, or that the platform cancelled, is not half of a pair — and a pair does not chain. The mouse keeps the platform's `dblclick`, which follows the user's own double-click setting; each press takes exactly one of the two routes, so a platform that also delivers a `dblclick` for a double-tap opens the icon once. The frame sets `touch-action: manipulation`, which takes the double-tap zoom off the icon and leaves panning and pinching to the page. Both are additions in the kit's idiom — System 7 had the mouse alone. Return is deliberately not one: the Finder's Return renamed, never opened, so it starts the edit on an editable icon and does nothing on a non-editable one. A double-click opens the icon **wherever it lands, the name included** — the handler is on the frame, and the name is as much the icon as the art is. `editable`: a press on the plate of an ALREADY-selected icon opens a rename field overlaying it (the press that does the selecting never does); the whole name starts selected, Return commits, Escape reverts, and the hidden plate keeps rendering the draft so the box widens as you type. **The two pointer gestures on a name are the same press**, and only the second one tells them apart, so the rename *waits*: the press arms a field that opens `RENAME_DELAY_MS` (800ms, `src/motion.ts`) later, and a press landing inside that window — wherever in the icon it falls — calls it off, leaving the double-click to open with no rename flashing up behind it. The window is long deliberately: no API reports what the browser counts as a double-click (it follows a user-movable platform setting), and reading a lone click as a pair costs only a wait, while reading a pair as a lone click renames when the user meant to open. A press that travels into a drag, a press outside, and any key call it off too — so a name drags like the art does, and Return opens the field at once, having no second half to wait for. `movable` — **not `draggable`**, which is a global HTML attribute and an `HTMLElement` accessor (the same trap as `align`, §5 Group G) — drags via `DragController` on the `vf-window` delegate shape (the frame is the handle and sets `touch-action: none` while movable, as the title bars do), plus arrow-key nudging (1 system px, 8 with Shift) because a pointer-only gesture is the kind of gap the kit closes (§1). Focus is the dashed rule below the plate, gated on `FocusRuleController` rather than `:focus-visible`: the host focuses itself so the press-drag can own the pointer.
|
|
@@ -538,6 +538,11 @@
|
|
|
538
538
|
"description": "The icon's window is on screen, so the art paints as the Finder's open\nghost — outline held, interior re-filled with the kit's loose dither —\nderived in the client from the slotted art itself (see the class doc).\nSet it when handling `vf-open`, clear it when the window goes away.\nSelection inverts the ghost exactly as it inverts the art.",
|
|
539
539
|
"values": []
|
|
540
540
|
},
|
|
541
|
+
{
|
|
542
|
+
"name": "alias",
|
|
543
|
+
"description": "The icon is an alias, an item standing for another: its name is set in\nitalics, the body face's own, and the plate widens to the slant's last\npixel.",
|
|
544
|
+
"values": []
|
|
545
|
+
},
|
|
541
546
|
{
|
|
542
547
|
"name": "movable",
|
|
543
548
|
"description": "Drag to move — `movable`, never `draggable`, which is a platform attribute\nand accessor (see the class doc). Arrow keys move a focused icon too, which\nmeans pairing this with selectable: focus is what that grants.",
|
|
@@ -761,7 +766,7 @@
|
|
|
761
766
|
},
|
|
762
767
|
{
|
|
763
768
|
"name": "vf-menu-bar",
|
|
764
|
-
"description": "`<vf-menu-bar>` — the System 7 menu bar: white strip, 1px black bottom\nrule, slotted `<vf-menu>` children laid out from the left. `rounded` adds\nthe classic screen-corner mask to the top corners.\n\nCoordinates its menus: pressing a label opens that menu (and inverts the\nlabel); while any menu is open, hovering another label switches to it;\nEscape, an outside click, or item selection closes.
|
|
769
|
+
"description": "`<vf-menu-bar>` — the System 7 menu bar: white strip, 1px black bottom\nrule, slotted `<vf-menu>` children laid out from the left. `rounded` adds\nthe classic screen-corner mask to the top corners.\n\nCoordinates its menus: pressing a label opens that menu (and inverts the\nlabel); while any menu is open, hovering another label switches to it;\nEscape, an outside click, or item selection closes. While a menu is open\nthe keyboard is src/menu-navigation.ts's: ArrowDown/ArrowUp move focus\nthrough the open menu's items, Home/End jump to its first/last, typed\nletters run the shared Finder first-letter type-ahead (src/type-ahead.ts),\nArrowRight opens an item's submenu and ArrowLeft closes it, and at the top\nlevel ArrowLeft/ArrowRight move between menus.\n\nThe bar also owns the **press-drag-release** gesture (see src/menu-press.ts)\n— press a title, slide onto a command, release over it — because one press\nmay travel across several of its menus. `vf-select` drives its popup by the\nsame mechanic.\n---\n\n\n### **Slots:**\n - _default_ - `vf-menu` elements.\n- **end** - The bar's right end: a clock, say. Held 9px in from the end, and a `vf-label` there rides the bar's line, so its baseline is the menu titles'.\n\n### **CSS Properties:**\n - **--vf-menubar-height** - `vf-menu-bar` _(default: 20px)_\n\n### **CSS Parts:**\n - **bar** - The horizontal layout container.",
|
|
765
770
|
"attributes": [
|
|
766
771
|
{
|
|
767
772
|
"name": "label",
|
|
@@ -803,7 +808,7 @@
|
|
|
803
808
|
},
|
|
804
809
|
{
|
|
805
810
|
"name": "vf-menu-item",
|
|
806
|
-
"description": "`<vf-menu-item>` — a single command inside a `<vf-menu>` panel.\n\nRenders the classic System 7 menu row: optional ✓ check in the\n`--vf-select-gutter` left column (16px, shared with vf-select/vf-option),\nlabel, and the keyboard shortcut left-aligned in a right-anchored column,\nso every ⌘ lands at the same x. On activation the item performs the classic\n3-blink inversion (~250ms), then dispatches `vf-menu-select` and asks its\nancestors to close the menu.\n\nTakes `top`/`left` like every other element (VfPositioned), for the\nconsumer who wants a row somewhere other than a pulldown. Inside its parent\n`<vf-menu>` the panel is as wide as its widest row and stacks them in flow,\nso stating an origin takes that row out of both: it no longer contributes to\nthe panel's width and the rows below close the gap. The placement doing what\nit says — but not how a pulldown is laid out.\n---\n\n\n### **Events:**\n - **vf-menu-select** - After the blink completes. `detail: { value, item }`. Named for the menu rather than plain `vf-select`, which would collide with the `<vf-select>` popup on any delegated ancestor listener (that component commits with `vf-change`).\n\n### **Slots:**\n - _default_ - The item label.\n\n### **CSS Properties:**\n - **--vf-menu-row-height** - `vf-menu-item` row pitch (`Menus.png`; kept separate from `--vf-popup-height` so re-theming the popup pill doesn't move pulldown rows) _(default: 16px)_\n- **--vf-menu-shortcut-column** - `vf-menu-item` shortcut slot, right-anchored with the text left-aligned in it so every ⌘ lands at the same x (`Menus.png`) — the MDEF reserve, ⌘'s 11px advance + the face's widest letter (M/W, 12px); widen it to line up longer shortcuts (\"⌘⇧S\") _(default: 23px)_\n- **--vf-select-gutter** - checkmark column: `vf-select` left inset / `vf-option` + `vf-menu-item` ✓ column (shared so the value doesn't shift on open) _(default: 16px)_\n\n### **CSS Parts:**\n - **item** - The row container.\n- **check** - The ✓ checkmark glyph (rendered when `checked`).\n- **label** - The label wrapper around the default slot.\n- **shortcut** - The shortcut text, left-aligned in the shared column.",
|
|
811
|
+
"description": "`<vf-menu-item>` — a single command inside a `<vf-menu>` panel.\n\nRenders the classic System 7 menu row: optional ✓ check in the\n`--vf-select-gutter` left column (16px, shared with vf-select/vf-option),\nlabel, and the keyboard shortcut left-aligned in a right-anchored column,\nso every ⌘ lands at the same x. On activation the item performs the classic\n3-blink inversion (~250ms), then dispatches `vf-menu-select` and asks its\nancestors to close the menu.\n\nA `<vf-menu>` in the `submenu` slot makes the item open a submenu: it ends\nin ▶ where a shortcut would go, and choosing it opens the submenu beside\nit rather than firing `vf-menu-select`. The item stays highlighted while\nits submenu is open.\n\nTakes `top`/`left` like every other element (VfPositioned), for the\nconsumer who wants a row somewhere other than a pulldown. Inside its parent\n`<vf-menu>` the panel is as wide as its widest row and stacks them in flow,\nso stating an origin takes that row out of both: it no longer contributes to\nthe panel's width and the rows below close the gap. The placement doing what\nit says — but not how a pulldown is laid out.\n---\n\n\n### **Events:**\n - **vf-menu-select** - After the blink completes. `detail: { value, item }`. Named for the menu rather than plain `vf-select`, which would collide with the `<vf-select>` popup on any delegated ancestor listener (that component commits with `vf-change`).\n\n### **Slots:**\n - _default_ - The item label.\n- **submenu** - A `vf-menu`, the submenu the item opens.\n\n### **CSS Properties:**\n - **--vf-menu-row-height** - `vf-menu-item` row pitch (`Menus.png`; kept separate from `--vf-popup-height` so re-theming the popup pill doesn't move pulldown rows) _(default: 16px)_\n- **--vf-menu-shortcut-column** - `vf-menu-item` shortcut slot, right-anchored with the text left-aligned in it so every ⌘ lands at the same x (`Menus.png`) — the MDEF reserve, ⌘'s 11px advance + the face's widest letter (M/W, 12px); widen it to line up longer shortcuts (\"⌘⇧S\") _(default: 23px)_\n- **--vf-select-gutter** - checkmark column: `vf-select` left inset / `vf-option` + `vf-menu-item` ✓ column (shared so the value doesn't shift on open) _(default: 16px)_\n\n### **CSS Parts:**\n - **item** - The row container.\n- **check** - The ✓ checkmark glyph (rendered when `checked`).\n- **label** - The label wrapper around the default slot.\n- **shortcut** - The shortcut text, left-aligned in the shared column.\n- **arrow** - The ▶ of an item that opens a submenu.",
|
|
807
812
|
"attributes": [
|
|
808
813
|
{
|
|
809
814
|
"name": "disabled",
|
|
@@ -817,7 +822,12 @@
|
|
|
817
822
|
},
|
|
818
823
|
{
|
|
819
824
|
"name": "active",
|
|
820
|
-
"description": "Transient highlight — the full-row inversion
|
|
825
|
+
"description": "Transient highlight — the full-row inversion on the row under the pointer\nwhile its menu is open, button down or not (`:hover` can't: under touch\nthe pointer is captured by the title the press started on), or on the\nitem whose submenu is open while the pointer is elsewhere. Managed by the\nmenu, mirroring `vf-option[active]`; not part of the authoring API.",
|
|
826
|
+
"values": []
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
"name": "expanded",
|
|
830
|
+
"description": "Whether this item's submenu is open. Reflected, and announced as\n`aria-expanded`. Managed by the menu (VfMenu.expand), like\nactive; not part of the authoring API.",
|
|
821
831
|
"values": []
|
|
822
832
|
},
|
|
823
833
|
{
|
|
@@ -832,7 +842,7 @@
|
|
|
832
842
|
},
|
|
833
843
|
{
|
|
834
844
|
"name": "value",
|
|
835
|
-
"description": "Value reported in the `vf-menu-select` event detail. Defaults to the item's\
|
|
845
|
+
"description": "Value reported in the `vf-menu-select` event detail. Defaults to the item's\nlabelText when unset.",
|
|
836
846
|
"values": []
|
|
837
847
|
},
|
|
838
848
|
{
|
|
@@ -860,7 +870,7 @@
|
|
|
860
870
|
},
|
|
861
871
|
{
|
|
862
872
|
"name": "vf-menu",
|
|
863
|
-
"description": "`<vf-menu>` — a pull-down menu: a bar label plus a dropped panel of\n`<vf-menu-item>` / `<vf-separator>` children.\n\nInside a `<vf-menu-bar>` the bar coordinates open state (only one menu open,\nhover-switching, outside-click/Escape dismissal) and owns the pointer\ngesture, which may travel between its menus. Used standalone, the menu\ntoggles itself on label click and manages its own dismissal, its own press\ngesture and item keyboard navigation (ArrowUp/ArrowDown, Home/End, and the\nshared first-letter type-ahead — src/type-ahead.ts) while open.\n\nPointer — the two styles `vf-select` supports, on the same terms (see\nsrc/menu-press.ts): the System 7 press-drag-release (press the title, slide\nonto a command, release over it) and a modern quick tap that leaves the menu\ndropped for a second click.\n\nTakes `top`/`left` like every other element (VfPositioned) — the\nnatural fit being a standalone menu, which is a free-standing menu button and\nplaces like any other control. The panel is anchored to the host's own box\n(`top: 100%`), so it follows a placed menu down without any further work.\nInside a `<vf-menu-bar>`, the bar lays its titles out in flow — placing one\nlifts it off the bar and the titles beside it close the gap. Slotted straight\ninto a `<vf-desktop>`, a free-standing menu sits on the desktop's menu tier\nabove every window, palettes included, as a bar does.\n---\n\n\n### **Slots:**\n - _default_ - Menu contents: `vf-menu-item` and `vf-separator` elements.\n- **label** - Replaces the `label` text in the bar — e.g. a `vf-img` apple icon for the Apple menu. An icon (`vf-img`, `img`, `svg`, `picture` or `canvas`) is drawn in a 16×16 cell and placed for one: 6 system px into its plate, 6 short of the plate's end, on the plate's top row. Text keeps the text title's place. Keep the `label` attribute set too: it stays the menu's accessible name (the bar item's `aria-label` and the panel's) when the visible title is an image.\n\n### **CSS Properties:**\n - **--vf-menubar-height** - `vf-menu-bar` _(default: 20px)_\n- **--vf-menu-row-height** - `vf-menu-item` row pitch; the panel also spends one of these on every slotted `vf-separator`, the full row the MDEF gave a divider (rule 8px into it — see the panel CSS) _(default: 16px)_\n\n### **CSS Parts:**\n - **label** - The menu title in the bar (inverts while open; flashes when a closed menu's item is activated by its key equivalent).\n- **panel** - The dropped `.vf-panel` containing the items.",
|
|
873
|
+
"description": "`<vf-menu>` — a pull-down menu: a bar label plus a dropped panel of\n`<vf-menu-item>` / `<vf-separator>` children.\n\nInside a `<vf-menu-bar>` the bar coordinates open state (only one menu open,\nhover-switching, outside-click/Escape dismissal) and owns the pointer\ngesture, which may travel between its menus. Used standalone, the menu\ntoggles itself on label click and manages its own dismissal, its own press\ngesture and item keyboard navigation (ArrowUp/ArrowDown, Home/End, and the\nshared first-letter type-ahead — src/type-ahead.ts) while open.\n\nPointer — the two styles `vf-select` supports, on the same terms (see\nsrc/menu-press.ts): the System 7 press-drag-release (press the title, slide\nonto a command, release over it) and a modern quick tap that leaves the menu\ndropped for a second click.\n\nA `vf-menu` in a `vf-menu-item`'s `submenu` slot is a **submenu**: no title,\nonly its panel, opened beside its item by the menu holding the item\n(expand). The pointer resting on the item opens it in either style,\nand so do a click or tap on the item, →, Enter and Space. It overlaps its\nparent as System 7.5's did: its first row level with its item, its frame\n5px inside the parent's right edge, covering the parent's frame and\nshadow. It opens on the side its parent opened toward, the right first,\nflips where that side has no room, and moves up to fit the screen. Menus\nnest to any depth.\n\nTakes `top`/`left` like every other element (VfPositioned) — the\nnatural fit being a standalone menu, which is a free-standing menu button and\nplaces like any other control. The panel is anchored to the host's own box\n(`top: 100%`), so it follows a placed menu down without any further work.\nInside a `<vf-menu-bar>`, the bar lays its titles out in flow — placing one\nlifts it off the bar and the titles beside it close the gap. Slotted straight\ninto a `<vf-desktop>`, a free-standing menu sits on the desktop's menu tier\nabove every window, palettes included, as a bar does.\n---\n\n\n### **Slots:**\n - _default_ - Menu contents: `vf-menu-item` and `vf-separator` elements.\n- **label** - Replaces the `label` text in the bar — e.g. a `vf-img` apple icon for the Apple menu. An icon (`vf-img`, `img`, `svg`, `picture` or `canvas`) is drawn in a 16×16 cell and placed for one: 6 system px into its plate, 6 short of the plate's end, on the plate's top row. Text keeps the text title's place. Keep the `label` attribute set too: it stays the menu's accessible name (the bar item's `aria-label` and the panel's) when the visible title is an image.\n\n### **CSS Properties:**\n - **--vf-menubar-height** - `vf-menu-bar` _(default: 20px)_\n- **--vf-menu-row-height** - `vf-menu-item` row pitch; the panel also spends one of these on every slotted `vf-separator`, the full row the MDEF gave a divider (rule 8px into it — see the panel CSS) _(default: 16px)_\n\n### **CSS Parts:**\n - **label** - The menu title in the bar (inverts while open; flashes when a closed menu's item is activated by its key equivalent).\n- **panel** - The dropped `.vf-panel` containing the items.",
|
|
864
874
|
"attributes": [
|
|
865
875
|
{
|
|
866
876
|
"name": "label",
|
package/editor/web-types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json",
|
|
3
3
|
"name": "vintage-frames",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.19.1",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"contributions": {
|
|
7
7
|
"html": {
|
|
@@ -1191,6 +1191,11 @@
|
|
|
1191
1191
|
"description": "The icon's window is on screen, so the art paints as the Finder's open\nghost — outline held, interior re-filled with the kit's loose dither —\nderived in the client from the slotted art itself (see the class doc).\nSet it when handling `vf-open`, clear it when the window goes away.\nSelection inverts the ghost exactly as it inverts the art.",
|
|
1192
1192
|
"value": { "type": "boolean", "default": "false" }
|
|
1193
1193
|
},
|
|
1194
|
+
{
|
|
1195
|
+
"name": "alias",
|
|
1196
|
+
"description": "The icon is an alias, an item standing for another: its name is set in\nitalics, the body face's own, and the plate widens to the slant's last\npixel.",
|
|
1197
|
+
"value": { "type": "boolean", "default": "false" }
|
|
1198
|
+
},
|
|
1194
1199
|
{
|
|
1195
1200
|
"name": "movable",
|
|
1196
1201
|
"description": "Drag to move — `movable`, never `draggable`, which is a platform attribute\nand accessor (see the class doc). Arrow keys move a focused icon too, which\nmeans pairing this with selectable: focus is what that grants.",
|
|
@@ -1317,6 +1322,11 @@
|
|
|
1317
1322
|
"description": "The icon's window is on screen, so the art paints as the Finder's open\nghost — outline held, interior re-filled with the kit's loose dither —\nderived in the client from the slotted art itself (see the class doc).\nSet it when handling `vf-open`, clear it when the window goes away.\nSelection inverts the ghost exactly as it inverts the art.",
|
|
1318
1323
|
"type": "boolean"
|
|
1319
1324
|
},
|
|
1325
|
+
{
|
|
1326
|
+
"name": "alias",
|
|
1327
|
+
"description": "The icon is an alias, an item standing for another: its name is set in\nitalics, the body face's own, and the plate widens to the slant's last\npixel.",
|
|
1328
|
+
"type": "boolean"
|
|
1329
|
+
},
|
|
1320
1330
|
{
|
|
1321
1331
|
"name": "movable",
|
|
1322
1332
|
"description": "Drag to move — `movable`, never `draggable`, which is a platform attribute\nand accessor (see the class doc). Arrow keys move a focused icon too, which\nmeans pairing this with selectable: focus is what that grants.",
|
|
@@ -1789,7 +1799,7 @@
|
|
|
1789
1799
|
},
|
|
1790
1800
|
{
|
|
1791
1801
|
"name": "vf-menu-bar",
|
|
1792
|
-
"description": "`<vf-menu-bar>` — the System 7 menu bar: white strip, 1px black bottom\nrule, slotted `<vf-menu>` children laid out from the left. `rounded` adds\nthe classic screen-corner mask to the top corners.\n\nCoordinates its menus: pressing a label opens that menu (and inverts the\nlabel); while any menu is open, hovering another label switches to it;\nEscape, an outside click, or item selection closes.
|
|
1802
|
+
"description": "`<vf-menu-bar>` — the System 7 menu bar: white strip, 1px black bottom\nrule, slotted `<vf-menu>` children laid out from the left. `rounded` adds\nthe classic screen-corner mask to the top corners.\n\nCoordinates its menus: pressing a label opens that menu (and inverts the\nlabel); while any menu is open, hovering another label switches to it;\nEscape, an outside click, or item selection closes. While a menu is open\nthe keyboard is src/menu-navigation.ts's: ArrowDown/ArrowUp move focus\nthrough the open menu's items, Home/End jump to its first/last, typed\nletters run the shared Finder first-letter type-ahead (src/type-ahead.ts),\nArrowRight opens an item's submenu and ArrowLeft closes it, and at the top\nlevel ArrowLeft/ArrowRight move between menus.\n\nThe bar also owns the **press-drag-release** gesture (see src/menu-press.ts)\n— press a title, slide onto a command, release over it — because one press\nmay travel across several of its menus. `vf-select` drives its popup by the\nsame mechanic.\n---\n\n\n### **Slots:**\n - _default_ - `vf-menu` elements.\n- **end** - The bar's right end: a clock, say. Held 9px in from the end, and a `vf-label` there rides the bar's line, so its baseline is the menu titles'.\n\n### **CSS Properties:**\n - **--vf-menubar-height** - `vf-menu-bar` _(default: 20px)_\n\n### **CSS Parts:**\n - **bar** - The horizontal layout container.",
|
|
1793
1803
|
"doc-url": "",
|
|
1794
1804
|
"attributes": [
|
|
1795
1805
|
{
|
|
@@ -1879,7 +1889,7 @@
|
|
|
1879
1889
|
},
|
|
1880
1890
|
{
|
|
1881
1891
|
"name": "vf-menu-item",
|
|
1882
|
-
"description": "`<vf-menu-item>` — a single command inside a `<vf-menu>` panel.\n\nRenders the classic System 7 menu row: optional ✓ check in the\n`--vf-select-gutter` left column (16px, shared with vf-select/vf-option),\nlabel, and the keyboard shortcut left-aligned in a right-anchored column,\nso every ⌘ lands at the same x. On activation the item performs the classic\n3-blink inversion (~250ms), then dispatches `vf-menu-select` and asks its\nancestors to close the menu.\n\nTakes `top`/`left` like every other element (VfPositioned), for the\nconsumer who wants a row somewhere other than a pulldown. Inside its parent\n`<vf-menu>` the panel is as wide as its widest row and stacks them in flow,\nso stating an origin takes that row out of both: it no longer contributes to\nthe panel's width and the rows below close the gap. The placement doing what\nit says — but not how a pulldown is laid out.\n---\n\n\n### **Events:**\n - **vf-menu-select** - After the blink completes. `detail: { value, item }`. Named for the menu rather than plain `vf-select`, which would collide with the `<vf-select>` popup on any delegated ancestor listener (that component commits with `vf-change`).\n\n### **Slots:**\n - _default_ - The item label.\n\n### **CSS Properties:**\n - **--vf-menu-row-height** - `vf-menu-item` row pitch (`Menus.png`; kept separate from `--vf-popup-height` so re-theming the popup pill doesn't move pulldown rows) _(default: 16px)_\n- **--vf-menu-shortcut-column** - `vf-menu-item` shortcut slot, right-anchored with the text left-aligned in it so every ⌘ lands at the same x (`Menus.png`) — the MDEF reserve, ⌘'s 11px advance + the face's widest letter (M/W, 12px); widen it to line up longer shortcuts (\"⌘⇧S\") _(default: 23px)_\n- **--vf-select-gutter** - checkmark column: `vf-select` left inset / `vf-option` + `vf-menu-item` ✓ column (shared so the value doesn't shift on open) _(default: 16px)_\n\n### **CSS Parts:**\n - **item** - The row container.\n- **check** - The ✓ checkmark glyph (rendered when `checked`).\n- **label** - The label wrapper around the default slot.\n- **shortcut** - The shortcut text, left-aligned in the shared column.",
|
|
1892
|
+
"description": "`<vf-menu-item>` — a single command inside a `<vf-menu>` panel.\n\nRenders the classic System 7 menu row: optional ✓ check in the\n`--vf-select-gutter` left column (16px, shared with vf-select/vf-option),\nlabel, and the keyboard shortcut left-aligned in a right-anchored column,\nso every ⌘ lands at the same x. On activation the item performs the classic\n3-blink inversion (~250ms), then dispatches `vf-menu-select` and asks its\nancestors to close the menu.\n\nA `<vf-menu>` in the `submenu` slot makes the item open a submenu: it ends\nin ▶ where a shortcut would go, and choosing it opens the submenu beside\nit rather than firing `vf-menu-select`. The item stays highlighted while\nits submenu is open.\n\nTakes `top`/`left` like every other element (VfPositioned), for the\nconsumer who wants a row somewhere other than a pulldown. Inside its parent\n`<vf-menu>` the panel is as wide as its widest row and stacks them in flow,\nso stating an origin takes that row out of both: it no longer contributes to\nthe panel's width and the rows below close the gap. The placement doing what\nit says — but not how a pulldown is laid out.\n---\n\n\n### **Events:**\n - **vf-menu-select** - After the blink completes. `detail: { value, item }`. Named for the menu rather than plain `vf-select`, which would collide with the `<vf-select>` popup on any delegated ancestor listener (that component commits with `vf-change`).\n\n### **Slots:**\n - _default_ - The item label.\n- **submenu** - A `vf-menu`, the submenu the item opens.\n\n### **CSS Properties:**\n - **--vf-menu-row-height** - `vf-menu-item` row pitch (`Menus.png`; kept separate from `--vf-popup-height` so re-theming the popup pill doesn't move pulldown rows) _(default: 16px)_\n- **--vf-menu-shortcut-column** - `vf-menu-item` shortcut slot, right-anchored with the text left-aligned in it so every ⌘ lands at the same x (`Menus.png`) — the MDEF reserve, ⌘'s 11px advance + the face's widest letter (M/W, 12px); widen it to line up longer shortcuts (\"⌘⇧S\") _(default: 23px)_\n- **--vf-select-gutter** - checkmark column: `vf-select` left inset / `vf-option` + `vf-menu-item` ✓ column (shared so the value doesn't shift on open) _(default: 16px)_\n\n### **CSS Parts:**\n - **item** - The row container.\n- **check** - The ✓ checkmark glyph (rendered when `checked`).\n- **label** - The label wrapper around the default slot.\n- **shortcut** - The shortcut text, left-aligned in the shared column.\n- **arrow** - The ▶ of an item that opens a submenu.",
|
|
1883
1893
|
"doc-url": "",
|
|
1884
1894
|
"attributes": [
|
|
1885
1895
|
{
|
|
@@ -1894,7 +1904,12 @@
|
|
|
1894
1904
|
},
|
|
1895
1905
|
{
|
|
1896
1906
|
"name": "active",
|
|
1897
|
-
"description": "Transient highlight — the full-row inversion
|
|
1907
|
+
"description": "Transient highlight — the full-row inversion on the row under the pointer\nwhile its menu is open, button down or not (`:hover` can't: under touch\nthe pointer is captured by the title the press started on), or on the\nitem whose submenu is open while the pointer is elsewhere. Managed by the\nmenu, mirroring `vf-option[active]`; not part of the authoring API.",
|
|
1908
|
+
"value": { "type": "boolean", "default": "false" }
|
|
1909
|
+
},
|
|
1910
|
+
{
|
|
1911
|
+
"name": "expanded",
|
|
1912
|
+
"description": "Whether this item's submenu is open. Reflected, and announced as\n`aria-expanded`. Managed by the menu (VfMenu.expand), like\nactive; not part of the authoring API.",
|
|
1898
1913
|
"value": { "type": "boolean", "default": "false" }
|
|
1899
1914
|
},
|
|
1900
1915
|
{
|
|
@@ -1909,7 +1924,7 @@
|
|
|
1909
1924
|
},
|
|
1910
1925
|
{
|
|
1911
1926
|
"name": "value",
|
|
1912
|
-
"description": "Value reported in the `vf-menu-select` event detail. Defaults to the item's\
|
|
1927
|
+
"description": "Value reported in the `vf-menu-select` event detail. Defaults to the item's\nlabelText when unset.",
|
|
1913
1928
|
"value": { "type": "string | undefined" }
|
|
1914
1929
|
},
|
|
1915
1930
|
{
|
|
@@ -1933,7 +1948,13 @@
|
|
|
1933
1948
|
"value": { "type": "PlacementOrigin | null | undefined" }
|
|
1934
1949
|
}
|
|
1935
1950
|
],
|
|
1936
|
-
"slots": [
|
|
1951
|
+
"slots": [
|
|
1952
|
+
{ "name": "", "description": "The item label." },
|
|
1953
|
+
{
|
|
1954
|
+
"name": "submenu",
|
|
1955
|
+
"description": "A `vf-menu`, the submenu the item opens."
|
|
1956
|
+
}
|
|
1957
|
+
],
|
|
1937
1958
|
"events": [
|
|
1938
1959
|
{
|
|
1939
1960
|
"name": "vf-menu-select",
|
|
@@ -1954,7 +1975,12 @@
|
|
|
1954
1975
|
},
|
|
1955
1976
|
{
|
|
1956
1977
|
"name": "active",
|
|
1957
|
-
"description": "Transient highlight — the full-row inversion
|
|
1978
|
+
"description": "Transient highlight — the full-row inversion on the row under the pointer\nwhile its menu is open, button down or not (`:hover` can't: under touch\nthe pointer is captured by the title the press started on), or on the\nitem whose submenu is open while the pointer is elsewhere. Managed by the\nmenu, mirroring `vf-option[active]`; not part of the authoring API.",
|
|
1979
|
+
"type": "boolean"
|
|
1980
|
+
},
|
|
1981
|
+
{
|
|
1982
|
+
"name": "expanded",
|
|
1983
|
+
"description": "Whether this item's submenu is open. Reflected, and announced as\n`aria-expanded`. Managed by the menu (VfMenu.expand), like\nactive; not part of the authoring API.",
|
|
1958
1984
|
"type": "boolean"
|
|
1959
1985
|
},
|
|
1960
1986
|
{
|
|
@@ -1969,9 +1995,19 @@
|
|
|
1969
1995
|
},
|
|
1970
1996
|
{
|
|
1971
1997
|
"name": "value",
|
|
1972
|
-
"description": "Value reported in the `vf-menu-select` event detail. Defaults to the item's\
|
|
1998
|
+
"description": "Value reported in the `vf-menu-select` event detail. Defaults to the item's\nlabelText when unset.",
|
|
1973
1999
|
"type": "string | undefined"
|
|
1974
2000
|
},
|
|
2001
|
+
{
|
|
2002
|
+
"name": "submenu",
|
|
2003
|
+
"description": "The submenu this item opens: the `vf-menu` in its `submenu` slot, or null.",
|
|
2004
|
+
"type": "VfMenu | null"
|
|
2005
|
+
},
|
|
2006
|
+
{
|
|
2007
|
+
"name": "labelText",
|
|
2008
|
+
"description": "The item's label as text: what its default slot holds, trimmed, without\nthe rows of a submenu. The default value and the menus'\ntype-ahead read it, and it names an item that opens a submenu.",
|
|
2009
|
+
"type": "string"
|
|
2010
|
+
},
|
|
1975
2011
|
{
|
|
1976
2012
|
"name": "top",
|
|
1977
2013
|
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
@@ -2003,7 +2039,7 @@
|
|
|
2003
2039
|
},
|
|
2004
2040
|
{
|
|
2005
2041
|
"name": "vf-menu",
|
|
2006
|
-
"description": "`<vf-menu>` — a pull-down menu: a bar label plus a dropped panel of\n`<vf-menu-item>` / `<vf-separator>` children.\n\nInside a `<vf-menu-bar>` the bar coordinates open state (only one menu open,\nhover-switching, outside-click/Escape dismissal) and owns the pointer\ngesture, which may travel between its menus. Used standalone, the menu\ntoggles itself on label click and manages its own dismissal, its own press\ngesture and item keyboard navigation (ArrowUp/ArrowDown, Home/End, and the\nshared first-letter type-ahead — src/type-ahead.ts) while open.\n\nPointer — the two styles `vf-select` supports, on the same terms (see\nsrc/menu-press.ts): the System 7 press-drag-release (press the title, slide\nonto a command, release over it) and a modern quick tap that leaves the menu\ndropped for a second click.\n\nTakes `top`/`left` like every other element (VfPositioned) — the\nnatural fit being a standalone menu, which is a free-standing menu button and\nplaces like any other control. The panel is anchored to the host's own box\n(`top: 100%`), so it follows a placed menu down without any further work.\nInside a `<vf-menu-bar>`, the bar lays its titles out in flow — placing one\nlifts it off the bar and the titles beside it close the gap. Slotted straight\ninto a `<vf-desktop>`, a free-standing menu sits on the desktop's menu tier\nabove every window, palettes included, as a bar does.\n---\n\n\n### **Slots:**\n - _default_ - Menu contents: `vf-menu-item` and `vf-separator` elements.\n- **label** - Replaces the `label` text in the bar — e.g. a `vf-img` apple icon for the Apple menu. An icon (`vf-img`, `img`, `svg`, `picture` or `canvas`) is drawn in a 16×16 cell and placed for one: 6 system px into its plate, 6 short of the plate's end, on the plate's top row. Text keeps the text title's place. Keep the `label` attribute set too: it stays the menu's accessible name (the bar item's `aria-label` and the panel's) when the visible title is an image.\n\n### **CSS Properties:**\n - **--vf-menubar-height** - `vf-menu-bar` _(default: 20px)_\n- **--vf-menu-row-height** - `vf-menu-item` row pitch; the panel also spends one of these on every slotted `vf-separator`, the full row the MDEF gave a divider (rule 8px into it — see the panel CSS) _(default: 16px)_\n\n### **CSS Parts:**\n - **label** - The menu title in the bar (inverts while open; flashes when a closed menu's item is activated by its key equivalent).\n- **panel** - The dropped `.vf-panel` containing the items.",
|
|
2042
|
+
"description": "`<vf-menu>` — a pull-down menu: a bar label plus a dropped panel of\n`<vf-menu-item>` / `<vf-separator>` children.\n\nInside a `<vf-menu-bar>` the bar coordinates open state (only one menu open,\nhover-switching, outside-click/Escape dismissal) and owns the pointer\ngesture, which may travel between its menus. Used standalone, the menu\ntoggles itself on label click and manages its own dismissal, its own press\ngesture and item keyboard navigation (ArrowUp/ArrowDown, Home/End, and the\nshared first-letter type-ahead — src/type-ahead.ts) while open.\n\nPointer — the two styles `vf-select` supports, on the same terms (see\nsrc/menu-press.ts): the System 7 press-drag-release (press the title, slide\nonto a command, release over it) and a modern quick tap that leaves the menu\ndropped for a second click.\n\nA `vf-menu` in a `vf-menu-item`'s `submenu` slot is a **submenu**: no title,\nonly its panel, opened beside its item by the menu holding the item\n(expand). The pointer resting on the item opens it in either style,\nand so do a click or tap on the item, →, Enter and Space. It overlaps its\nparent as System 7.5's did: its first row level with its item, its frame\n5px inside the parent's right edge, covering the parent's frame and\nshadow. It opens on the side its parent opened toward, the right first,\nflips where that side has no room, and moves up to fit the screen. Menus\nnest to any depth.\n\nTakes `top`/`left` like every other element (VfPositioned) — the\nnatural fit being a standalone menu, which is a free-standing menu button and\nplaces like any other control. The panel is anchored to the host's own box\n(`top: 100%`), so it follows a placed menu down without any further work.\nInside a `<vf-menu-bar>`, the bar lays its titles out in flow — placing one\nlifts it off the bar and the titles beside it close the gap. Slotted straight\ninto a `<vf-desktop>`, a free-standing menu sits on the desktop's menu tier\nabove every window, palettes included, as a bar does.\n---\n\n\n### **Slots:**\n - _default_ - Menu contents: `vf-menu-item` and `vf-separator` elements.\n- **label** - Replaces the `label` text in the bar — e.g. a `vf-img` apple icon for the Apple menu. An icon (`vf-img`, `img`, `svg`, `picture` or `canvas`) is drawn in a 16×16 cell and placed for one: 6 system px into its plate, 6 short of the plate's end, on the plate's top row. Text keeps the text title's place. Keep the `label` attribute set too: it stays the menu's accessible name (the bar item's `aria-label` and the panel's) when the visible title is an image.\n\n### **CSS Properties:**\n - **--vf-menubar-height** - `vf-menu-bar` _(default: 20px)_\n- **--vf-menu-row-height** - `vf-menu-item` row pitch; the panel also spends one of these on every slotted `vf-separator`, the full row the MDEF gave a divider (rule 8px into it — see the panel CSS) _(default: 16px)_\n\n### **CSS Parts:**\n - **label** - The menu title in the bar (inverts while open; flashes when a closed menu's item is activated by its key equivalent).\n- **panel** - The dropped `.vf-panel` containing the items.",
|
|
2007
2043
|
"doc-url": "",
|
|
2008
2044
|
"attributes": [
|
|
2009
2045
|
{
|
|
@@ -2090,6 +2126,16 @@
|
|
|
2090
2126
|
"description": "Viewport rect of the bar title, or `null` before the first render. The\npress gesture hit-tests by coordinates rather than by event target (see\nsrc/menu-press.ts), so it wants the box, not the element.",
|
|
2091
2127
|
"type": "DOMRect | null"
|
|
2092
2128
|
},
|
|
2129
|
+
{
|
|
2130
|
+
"name": "panelRect",
|
|
2131
|
+
"description": "Viewport rect of the dropped panel, or `null` while closed. The press\ngesture hit-tests the open menus by their panels, deepest first.",
|
|
2132
|
+
"type": "DOMRect | null"
|
|
2133
|
+
},
|
|
2134
|
+
{
|
|
2135
|
+
"name": "expandedItem",
|
|
2136
|
+
"description": "The item in this menu whose submenu is open, or `null`.",
|
|
2137
|
+
"type": "VfMenuItem | null"
|
|
2138
|
+
},
|
|
2093
2139
|
{
|
|
2094
2140
|
"name": "top",
|
|
2095
2141
|
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vintage-frames",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Lit web components that emulate the look and feel of classic Mac OS System 7",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
"**/display-font.ts",
|
|
21
21
|
"**/body-font.js",
|
|
22
22
|
"**/body-font.ts",
|
|
23
|
+
"**/body-italic-font.js",
|
|
24
|
+
"**/body-italic-font.ts",
|
|
23
25
|
"**/*.css"
|
|
24
26
|
],
|
|
25
27
|
"main": "./dist/index.js",
|
|
@@ -74,8 +76,10 @@
|
|
|
74
76
|
"build:pages": "vite build --config vite.pages.config.ts",
|
|
75
77
|
"preview:pages": "vite preview --config vite.pages.config.ts",
|
|
76
78
|
"prepack": "npm run build && npm run verify:manifest",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
+
"preversion": "npm run check:app-api",
|
|
80
|
+
"version": "npm run analyze && node scripts/write-version.mjs && git add custom-elements.json editor app-api.json src/shell/version.ts",
|
|
81
|
+
"analyze": "cem analyze && node scripts/app-api.mjs",
|
|
82
|
+
"check:app-api": "npm run analyze && node scripts/check-app-api.mjs",
|
|
79
83
|
"verify:manifest": "node scripts/verify-manifest.mjs",
|
|
80
84
|
"typecheck": "tsc --noEmit",
|
|
81
85
|
"preview": "vite preview",
|