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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Adam Portilla
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Vintage Frames
|
|
2
|
+
|
|
3
|
+
Lit web components that rebuild the Mac OS System 7 interface — racing-stripe
|
|
4
|
+
title bars, 1px black borders, hard offset shadows, bitmap type. 31 elements,
|
|
5
|
+
no stylesheet to load.
|
|
6
|
+
|
|
7
|
+
- **[Showcase](https://aportilla.github.io/vintage-frames/)** — a full faux
|
|
8
|
+
desktop: menu bar, movable windows, dialogs, icons, every control, drawn
|
|
9
|
+
cursor
|
|
10
|
+
- **[Component reference](https://aportilla.github.io/vintage-frames/examples.html)**
|
|
11
|
+
— every element, its API, and a live specimen of each state
|
|
12
|
+
- **[Integration example](https://aportilla.github.io/vintage-frames/blog.html)**
|
|
13
|
+
— an ordinary blog page (system-font copy, normal flow, no global CSS) using
|
|
14
|
+
the controls in its header, sidebar and forms
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npm install vintage-frames
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import 'vintage-frames' // registers every <vf-*> element
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Every visual constant is a `--vf-*` custom property with an inlined fallback,
|
|
25
|
+
the two bitmap faces register themselves on `document.fonts`, and each
|
|
26
|
+
component scales itself — so a component on a blank page renders correctly with
|
|
27
|
+
no global CSS at all.
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<vf-desktop width="512" height="342">
|
|
31
|
+
<vf-menu-bar>
|
|
32
|
+
<vf-menu label="File">
|
|
33
|
+
<vf-menu-item shortcut="⌘N">New Window</vf-menu-item>
|
|
34
|
+
<vf-separator></vf-separator>
|
|
35
|
+
<vf-menu-item shortcut="⌘Q">Quit</vf-menu-item>
|
|
36
|
+
</vf-menu>
|
|
37
|
+
</vf-menu-bar>
|
|
38
|
+
|
|
39
|
+
<vf-window heading="My Installer" movable width="360" height="220"
|
|
40
|
+
top="40" left="76">
|
|
41
|
+
<vf-stack fill-width gap="12">
|
|
42
|
+
<vf-paragraph>Welcome!</vf-paragraph>
|
|
43
|
+
<vf-fieldset fill-width legend="Install Location">
|
|
44
|
+
<vf-select value="hd">
|
|
45
|
+
<vf-option value="hd">Macintosh HD</vf-option>
|
|
46
|
+
</vf-select>
|
|
47
|
+
</vf-fieldset>
|
|
48
|
+
<vf-stack fill-width place="end">
|
|
49
|
+
<vf-button-group>
|
|
50
|
+
<vf-button>Quit</vf-button>
|
|
51
|
+
<vf-button variant="default">Install</vf-button>
|
|
52
|
+
</vf-button-group>
|
|
53
|
+
</vf-stack>
|
|
54
|
+
</vf-stack>
|
|
55
|
+
</vf-window>
|
|
56
|
+
</vf-desktop>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Components
|
|
60
|
+
|
|
61
|
+
| Element | What it is |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `vf-desktop` | Gray dithered desktop raster. Declare `width`/`height` in system px, or derive them with `fitWithin(w, h)`. Stacks slotted windows, manages active state, floats `variant="utility"` windows on their own tier. `bezel` adds the CRT surround with rounded top screen corners |
|
|
64
|
+
| `vf-window` | Window shell: striped title bar, `closable`/`zoomable` boxes, `movable`, `resizable`, edge scroll rails (`scrollbars`), slim windoid chrome (`variant="utility"`). Declare `width`/`height` in system px |
|
|
65
|
+
| `vf-dialog` | Modal shell over a native `<dialog>`. Striped movable bar by default; `frame="plain"` is the double-rule modal frame. Declare `width`/`height`; unset `top`/`left` means centered |
|
|
66
|
+
| `vf-separator` | 1px rule, `vertical` or horizontal. Renders as the dimmed dotted rule inside a menu |
|
|
67
|
+
| `vf-button` | Push button with pixel-stepped corners. `variant="default"` draws the double ring. Form-associated: `type="submit"`/`"reset"`, `name`/`value` |
|
|
68
|
+
| `vf-button-group` | Row (or `vertical` column) of buttons sized to the widest, faces aligned so a `variant="default"` button lines up with its neighbors. `natural` keeps each button's own width |
|
|
69
|
+
| `vf-swatch` | Color-swatch button — a white-inset color well sized in system px, showing a transparency checker with no `color`. `shadow` opts into the hard drop shadow |
|
|
70
|
+
| `vf-checkbox` | Checkbox with the classic ✕ mark |
|
|
71
|
+
| `vf-radio`, `vf-radio-group` | Radio buttons; the group is the form-associated surface and owns `value` |
|
|
72
|
+
| `vf-text-field`, `vf-text-area` | Bordered text inputs. `vf-text-area` reserves a permanent scroll rail |
|
|
73
|
+
| `vf-number-field` | Numeric field with the "little arrows" stepper; `min`/`max`/`step` |
|
|
74
|
+
| `vf-select`, `vf-option` | Popup menu. Press-drag-release or click-to-open. A list taller than the screen is clipped, not scrolled, with a scroll arrow in the edge row |
|
|
75
|
+
| `vf-progress-bar` | Determinate fill or `indeterminate` barber stripes |
|
|
76
|
+
| `vf-slider` | Horizontal 1-bit slider: solid fill up to a shield-shaped handle |
|
|
77
|
+
| `vf-menu-bar`, `vf-menu`, `vf-menu-item` | Pull-down menus with ⌘ shortcuts, selection blink, press-drag-release. `rounded` masks the bar's top corners |
|
|
78
|
+
| `vf-list`, `vf-list-item` | List box: inverted selection, permanent scroll rail, first-letter type-ahead, `multiple`. Each row takes a leading graphic in its `icon` slot |
|
|
79
|
+
| `vf-scroll-area` | Container with System 7 scrollbars. Reserves the rail per `axis` — arrows always drawn, trough and thumb filling in on overflow |
|
|
80
|
+
| `vf-fieldset` | Group box with the legend punching through the border |
|
|
81
|
+
| `vf-grid` | Lattice of equal cells with 1px rules. `columns`/`rows`/`cell-width`/`cell-height`; `rules` picks the pen, `frameless` drops the perimeter, `collapse` lands a cell's border on the rule |
|
|
82
|
+
| `vf-stack` | Flexbox whose `gap`, `pad`, `width` and `height` are declared in system px. Content-governed; `fill-width`/`fill-height` on a child asks for more |
|
|
83
|
+
| `vf-container` | A plain box with a declared `width`/`height` and no paint of its own. The positioned ancestor for children placed with `top`/`left`; takes `top`/`left` itself and keeps its box (and everything placed in it) on the device-pixel grid |
|
|
84
|
+
| `vf-label` | Static caption in the chrome face. `for` focuses and names a control; `width` sets a whole-pixel caption column |
|
|
85
|
+
| `vf-paragraph` | Copy in the body face on a whole-pixel line box; `width`/`height` set the box the text wraps to |
|
|
86
|
+
| `vf-img` | Pixel art on the grid — sizes a slotted `<img>` to one system px per image px, magnified nearest-neighbor |
|
|
87
|
+
| `vf-icon` | Finder icon: art in a 32×32 or 16×16 cell with a name plate below. `selectable`, `open`, `movable`, `editable` |
|
|
88
|
+
|
|
89
|
+
The [component reference](https://aportilla.github.io/vintage-frames/examples.html)
|
|
90
|
+
shows each of these live, with its full API.
|
|
91
|
+
|
|
92
|
+
## Taking only what you use
|
|
93
|
+
|
|
94
|
+
The root import registers all 31 elements. Import by name to ship less — same
|
|
95
|
+
elements, same self-registration, one module each:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import 'vintage-frames/vf-button.js'
|
|
99
|
+
import 'vintage-frames/vf-checkbox.js'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Those subpaths and the root are the whole export surface; a deeper path fails
|
|
103
|
+
at resolve time rather than as a 404 in production. Bundled and minified with
|
|
104
|
+
`lit` external:
|
|
105
|
+
|
|
106
|
+
| Imported | min | gzip |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| `vf-separator.js` — sets no chrome type, so it carries no display face | 18.8 KB | 10.3 KB |
|
|
109
|
+
| `vf-button.js` | 40.3 KB | 20.0 KB |
|
|
110
|
+
| …plus `vf-checkbox.js` | 46.0 KB | 21.6 KB |
|
|
111
|
+
| the root import — all 31 elements | 299 KB | 91.0 KB |
|
|
112
|
+
|
|
113
|
+
The first component carries the shared code; each one after it adds a couple
|
|
114
|
+
of KB, so importing by name pays off up to roughly a third of the kit. Keep it
|
|
115
|
+
one copy of one package — the scaling, grid snapping, focus modality and font
|
|
116
|
+
registration are module-scoped singletons. If a second copy loads anyway,
|
|
117
|
+
elements register through `defineElement()`, which keeps the first
|
|
118
|
+
registration and warns rather than throwing.
|
|
119
|
+
|
|
120
|
+
## Sizing
|
|
121
|
+
|
|
122
|
+
Every component is authored in *system pixels* — the 1-bit art grid, where a
|
|
123
|
+
border is 1 and a push button 20 tall. On a Macintosh that pixel was 1/72 inch.
|
|
124
|
+
Each component reads the display density and renders one system pixel as the
|
|
125
|
+
whole number of device pixels nearest that size, so the art always lands on
|
|
126
|
+
the device-pixel grid. On by default, no setup, nested components never
|
|
127
|
+
double-scale, and page zoom is tracked and handled the same way.
|
|
128
|
+
|
|
129
|
+
So the CSS size follows the display: the same push button is 20px tall on a 1×
|
|
130
|
+
monitor and 30px on a 2× one, while the page's own 17px copy is 17px on both.
|
|
131
|
+
That suits a full-screen faux desktop; next to ordinary page text you may want
|
|
132
|
+
a fixed size. Pin it with the inherited `--vf-scale` custom property, declared
|
|
133
|
+
in a stylesheet the page loads *before* the components upgrade:
|
|
134
|
+
|
|
135
|
+
```css
|
|
136
|
+
:root { --vf-scale: 1; } /* fixed authored size: a 20px button, 16px label */
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
A hand-picked factor must keep `--vf-scale × devicePixelRatio` a whole number
|
|
140
|
+
— `1`, `2`, `3` everywhere; `1.5` only on displays it multiplies out on — or
|
|
141
|
+
the 1-bit art rasterizes gray. Two helpers put the rest of the page on the
|
|
142
|
+
same grid:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { applyScale, applyGridSnap } from 'vintage-frames'
|
|
146
|
+
|
|
147
|
+
applyScale() // your own markup adopts the kit's scale via --vf-scale
|
|
148
|
+
applyGridSnap() // every component cancels a fractional offset your layout hands it
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
[docs/SIZING.md](https://github.com/aportilla/vintage-frames/blob/main/docs/SIZING.md)
|
|
152
|
+
covers the density ladder, zoom, and the three rules that keep a page on the
|
|
153
|
+
device-pixel grid.
|
|
154
|
+
|
|
155
|
+
## Layout
|
|
156
|
+
|
|
157
|
+
Two stylesheet-free ways to lay out a window's insides. `vf-stack` is a
|
|
158
|
+
flexbox whose `gap`, `pad`, `width` and `height` are declared in whole system
|
|
159
|
+
px — content-governed, with `fill-width`/`fill-height` on a child asking for
|
|
160
|
+
more. Or place each child by coordinate: nearly every component takes `top`
|
|
161
|
+
and `left` in whole system px, absolutely positioned within the nearest kit
|
|
162
|
+
container (a window's content region, a dialog, a stack, a `vf-container`).
|
|
163
|
+
Gestures write through the same properties — a title-bar drag, an icon nudge
|
|
164
|
+
and the grow box all state whole system px, so read positions off `win.left`,
|
|
165
|
+
not `style.left`.
|
|
166
|
+
|
|
167
|
+
## Window archetypes
|
|
168
|
+
|
|
169
|
+
The 1992 *Macintosh Human Interface Guidelines* names five standard windows.
|
|
170
|
+
The kit ships two parameterized shells; each archetype is a one-line recipe:
|
|
171
|
+
|
|
172
|
+
| Archetype | Recipe |
|
|
173
|
+
| --- | --- |
|
|
174
|
+
| Document window | `<vf-window closable zoomable movable resizable scrollbars="both">` |
|
|
175
|
+
| Movable modal dialog box | `<vf-dialog heading="…">` |
|
|
176
|
+
| Modal dialog box | `<vf-dialog frame="plain">` |
|
|
177
|
+
| Modeless dialog box | `<vf-window closable movable>` |
|
|
178
|
+
| Utility (floating) window | `<vf-window variant="utility" movable>` |
|
|
179
|
+
|
|
180
|
+
There is no alert component — an alert is the plain modal frame plus your own
|
|
181
|
+
icon art in a `vf-img`.
|
|
182
|
+
|
|
183
|
+
## Fonts
|
|
184
|
+
|
|
185
|
+
Two bitmap faces ship inside the components and register themselves on
|
|
186
|
+
`document.fonts`, so they render inside every shadow root with no global CSS:
|
|
187
|
+
**VF Display**, the chrome face, and **VF Body**, the body face. Both are the
|
|
188
|
+
kit's own artwork — re-drawn strikes in the style of Chicago 12pt and Geneva
|
|
189
|
+
9pt, the classic Macintosh faces designed by Susan Kare for Apple — extended
|
|
190
|
+
in the same idiom (`€`, arrows, `⌘ ⇧ ⌥ ⌃`, fractions, accents) so modern copy
|
|
191
|
+
doesn't fall back mid-sentence. Set your own text in them with `vf-label` and
|
|
192
|
+
`vf-paragraph`, whose line boxes sit on whole system pixels; every strike
|
|
193
|
+
renders at its native size.
|
|
194
|
+
|
|
195
|
+
## The cursor
|
|
196
|
+
|
|
197
|
+
The chrome sets the classic cursors with ordinary CSS. A faux desktop can also
|
|
198
|
+
draw the pointer itself:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
import { applyCursor } from 'vintage-frames'
|
|
202
|
+
|
|
203
|
+
applyCursor() // → returns a cleanup function that restores the native pointer
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
That replaces the native pointer with the embedded System 7 set — arrow,
|
|
207
|
+
I-beam, crosshair and wristwatch as pixel art locked to the system-pixel
|
|
208
|
+
lattice, the I-beam and crosshair drawn with the classic XOR pen. Each kind
|
|
209
|
+
accepts custom art.
|
|
210
|
+
|
|
211
|
+
## Accessibility
|
|
212
|
+
|
|
213
|
+
Keyboard focus is drawn in the 1-bit vocabulary — a dashed underline on the
|
|
214
|
+
pixel grid, keyboard-only. Forced-colors mode (Windows High Contrast)
|
|
215
|
+
re-declares the palette in system colors and keeps drawing the kit's artwork.
|
|
216
|
+
The platform's form vocabulary works, including into shadow roots: `<label
|
|
217
|
+
for>`, `aria-label`/`aria-labelledby`/`aria-describedby`, and `required` with
|
|
218
|
+
real constraint validation — `form.reportValidity()` blocks, `:invalid`
|
|
219
|
+
matches on the host, and `vf-button` submits like a native button.
|
|
220
|
+
|
|
221
|
+
## Editor support
|
|
222
|
+
|
|
223
|
+
The package ships a [custom elements manifest](https://github.com/webcomponents/custom-elements-manifest)
|
|
224
|
+
and the two editor formats derived from it. Point your editor at the matching
|
|
225
|
+
format and `<vf-` completes, with each attribute's doc comment on hover:
|
|
226
|
+
|
|
227
|
+
```jsonc
|
|
228
|
+
// VS Code — .vscode/settings.json
|
|
229
|
+
{ "html.customData": ["./node_modules/vintage-frames/editor/vscode.html-custom-data.json"] }
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
JetBrains IDEs read the `web-types` field in `package.json` on their own.
|
|
233
|
+
|
|
234
|
+
## Matching the kit
|
|
235
|
+
|
|
236
|
+
The toolkit the components are built from is exported from the package root —
|
|
237
|
+
the 1-bit CSS recipes (`vfPanel`, `vfTitleBar`, `vfFocusUnderline`, …), the
|
|
238
|
+
glyph sprites, the stepped-corner clip traces, the scale/zoom/snap machinery
|
|
239
|
+
and the form-control base classes — so a custom control can match the kit
|
|
240
|
+
pixel-for-pixel. [docs/TOOLKIT.md](https://github.com/aportilla/vintage-frames/blob/main/docs/TOOLKIT.md)
|
|
241
|
+
documents every export.
|
|
242
|
+
|
|
243
|
+
## Documentation
|
|
244
|
+
|
|
245
|
+
| Doc | What it covers |
|
|
246
|
+
| --- | --- |
|
|
247
|
+
| [docs/SPEC.md](https://github.com/aportilla/vintage-frames/blob/main/docs/SPEC.md) | The design spec — every token, slot, part and event. Ships in the package |
|
|
248
|
+
| [docs/DESIGN-TOKENS.md](https://github.com/aportilla/vintage-frames/blob/main/docs/DESIGN-TOKENS.md) | Every `--vf-*` theming token, its default and what reads it |
|
|
249
|
+
| [docs/SIZING.md](https://github.com/aportilla/vintage-frames/blob/main/docs/SIZING.md) | True-size rendering: the density ladder, zoom, the device-pixel grid rules, grid snapping, the tile grid |
|
|
250
|
+
| [docs/LAYOUT.md](https://github.com/aportilla/vintage-frames/blob/main/docs/LAYOUT.md) | `vf-stack`, coordinate placement, the window archetypes in full |
|
|
251
|
+
| [docs/FONTS.md](https://github.com/aportilla/vintage-frames/blob/main/docs/FONTS.md) | The bitmap faces: metrics, theming, design lineage |
|
|
252
|
+
| [docs/ICONS.md](https://github.com/aportilla/vintage-frames/blob/main/docs/ICONS.md) | `vf-img` and `vf-icon` in full |
|
|
253
|
+
| [docs/CURSOR.md](https://github.com/aportilla/vintage-frames/blob/main/docs/CURSOR.md) | The drawn cursor set and custom cursor art |
|
|
254
|
+
| [docs/ACCESSIBILITY.md](https://github.com/aportilla/vintage-frames/blob/main/docs/ACCESSIBILITY.md) | Focus, forced colors, and the form contract in full |
|
|
255
|
+
| [docs/TOOLKIT.md](https://github.com/aportilla/vintage-frames/blob/main/docs/TOOLKIT.md) | Every root export — recipes, controllers, base classes |
|
|
256
|
+
| [docs/DEVELOPING.md](https://github.com/aportilla/vintage-frames/blob/main/docs/DEVELOPING.md) | Working on the kit: demo pages, the verify suite, the generated editor data |
|
|
257
|
+
|
|
258
|
+
## License
|
|
259
|
+
|
|
260
|
+
[MIT](https://github.com/aportilla/vintage-frames/blob/main/LICENSE) © Adam
|
|
261
|
+
Portilla. The embedded faces are the kit's own re-drawn strikes; the designs
|
|
262
|
+
they re-draw — Chicago and Geneva — were created by Susan Kare for Apple.
|