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.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +262 -0
  3. package/custom-elements.json +19807 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js +9 -0
  5. package/dist/chrome.d.ts +73 -0
  6. package/dist/chrome.js +94 -0
  7. package/dist/components/vf-button-group.d.ts +50 -0
  8. package/dist/components/vf-button-group.js +68 -0
  9. package/dist/components/vf-button.d.ts +169 -0
  10. package/dist/components/vf-button.js +234 -0
  11. package/dist/components/vf-checkbox.d.ts +60 -0
  12. package/dist/components/vf-checkbox.js +135 -0
  13. package/dist/components/vf-container.d.ts +95 -0
  14. package/dist/components/vf-container.js +86 -0
  15. package/dist/components/vf-desktop.d.ts +243 -0
  16. package/dist/components/vf-desktop.js +310 -0
  17. package/dist/components/vf-dialog.d.ts +105 -0
  18. package/dist/components/vf-dialog.js +280 -0
  19. package/dist/components/vf-fieldset.d.ts +34 -0
  20. package/dist/components/vf-fieldset.js +76 -0
  21. package/dist/components/vf-grid.d.ts +124 -0
  22. package/dist/components/vf-grid.js +133 -0
  23. package/dist/components/vf-icon.d.ts +356 -0
  24. package/dist/components/vf-icon.js +507 -0
  25. package/dist/components/vf-img.d.ts +63 -0
  26. package/dist/components/vf-img.js +65 -0
  27. package/dist/components/vf-label.d.ts +117 -0
  28. package/dist/components/vf-label.js +151 -0
  29. package/dist/components/vf-list-item.d.ts +48 -0
  30. package/dist/components/vf-list-item.js +98 -0
  31. package/dist/components/vf-list.d.ts +77 -0
  32. package/dist/components/vf-list.js +256 -0
  33. package/dist/components/vf-menu-bar.d.ts +64 -0
  34. package/dist/components/vf-menu-bar.js +236 -0
  35. package/dist/components/vf-menu-item.d.ts +91 -0
  36. package/dist/components/vf-menu-item.js +252 -0
  37. package/dist/components/vf-menu.d.ts +95 -0
  38. package/dist/components/vf-menu.js +346 -0
  39. package/dist/components/vf-number-field.d.ts +60 -0
  40. package/dist/components/vf-number-field.js +248 -0
  41. package/dist/components/vf-option.d.ts +49 -0
  42. package/dist/components/vf-option.js +119 -0
  43. package/dist/components/vf-paragraph.d.ts +73 -0
  44. package/dist/components/vf-paragraph.js +66 -0
  45. package/dist/components/vf-progress-bar.d.ts +69 -0
  46. package/dist/components/vf-progress-bar.js +272 -0
  47. package/dist/components/vf-radio-group.d.ts +109 -0
  48. package/dist/components/vf-radio-group.js +105 -0
  49. package/dist/components/vf-radio.d.ts +59 -0
  50. package/dist/components/vf-radio.js +135 -0
  51. package/dist/components/vf-scroll-area.d.ts +75 -0
  52. package/dist/components/vf-scroll-area.js +124 -0
  53. package/dist/components/vf-select.d.ts +334 -0
  54. package/dist/components/vf-select.js +658 -0
  55. package/dist/components/vf-separator.d.ts +38 -0
  56. package/dist/components/vf-separator.js +55 -0
  57. package/dist/components/vf-slider.d.ts +80 -0
  58. package/dist/components/vf-slider.js +255 -0
  59. package/dist/components/vf-stack.d.ts +188 -0
  60. package/dist/components/vf-stack.js +168 -0
  61. package/dist/components/vf-swatch.d.ts +98 -0
  62. package/dist/components/vf-swatch.js +201 -0
  63. package/dist/components/vf-text-area.d.ts +77 -0
  64. package/dist/components/vf-text-area.js +121 -0
  65. package/dist/components/vf-text-field.d.ts +53 -0
  66. package/dist/components/vf-text-field.js +79 -0
  67. package/dist/components/vf-window.d.ts +157 -0
  68. package/dist/components/vf-window.js +377 -0
  69. package/dist/cursor-art.d.ts +37 -0
  70. package/dist/cursor-art.js +41 -0
  71. package/dist/cursor.d.ts +49 -0
  72. package/dist/cursor.js +171 -0
  73. package/dist/define.d.ts +45 -0
  74. package/dist/define.js +15 -0
  75. package/dist/document-listeners.d.ts +62 -0
  76. package/dist/document-listeners.js +29 -0
  77. package/dist/drag.d.ts +49 -0
  78. package/dist/drag.js +30 -0
  79. package/dist/events.d.ts +79 -0
  80. package/dist/events.js +25 -0
  81. package/dist/focus-modality.d.ts +94 -0
  82. package/dist/focus-modality.js +56 -0
  83. package/dist/form-control.d.ts +247 -0
  84. package/dist/form-control.js +127 -0
  85. package/dist/glyphs.d.ts +117 -0
  86. package/dist/glyphs.js +100 -0
  87. package/dist/grid-snap.d.ts +73 -0
  88. package/dist/grid-snap.js +135 -0
  89. package/dist/index.d.ts +145 -0
  90. package/dist/index.js +71 -0
  91. package/dist/menu-press.d.ts +60 -0
  92. package/dist/menu-press.js +97 -0
  93. package/dist/modal-dialog.d.ts +148 -0
  94. package/dist/modal-dialog.js +155 -0
  95. package/dist/motion.d.ts +72 -0
  96. package/dist/motion.js +22 -0
  97. package/dist/number.d.ts +24 -0
  98. package/dist/number.js +12 -0
  99. package/dist/open-art.d.ts +40 -0
  100. package/dist/open-art.js +35 -0
  101. package/dist/pixel-frame.d.ts +102 -0
  102. package/dist/pixel-frame.js +77 -0
  103. package/dist/popup-overflow.d.ts +157 -0
  104. package/dist/popup-overflow.js +45 -0
  105. package/dist/position.d.ts +187 -0
  106. package/dist/position.js +74 -0
  107. package/dist/scale.d.ts +259 -0
  108. package/dist/scale.js +133 -0
  109. package/dist/scroll-rail.d.ts +112 -0
  110. package/dist/scroll-rail.js +194 -0
  111. package/dist/scroll-state.d.ts +113 -0
  112. package/dist/scroll-state.js +55 -0
  113. package/dist/size.d.ts +47 -0
  114. package/dist/size.js +30 -0
  115. package/dist/styles/base.d.ts +38 -0
  116. package/dist/styles/body-font.d.ts +7 -0
  117. package/dist/styles/body-font.js +9 -0
  118. package/dist/styles/display-font.d.ts +7 -0
  119. package/dist/styles/display-font.js +9 -0
  120. package/dist/styles/recipes/body-face.d.ts +14 -0
  121. package/dist/styles/recipes/body-face.js +6 -0
  122. package/dist/styles/recipes/display-face.d.ts +23 -0
  123. package/dist/styles/recipes/display-face.js +10 -0
  124. package/dist/styles/recipes/field.d.ts +20 -0
  125. package/dist/styles/recipes/field.js +68 -0
  126. package/dist/styles/recipes/focus.d.ts +76 -0
  127. package/dist/styles/recipes/focus.js +39 -0
  128. package/dist/styles/recipes/host.d.ts +5 -0
  129. package/dist/styles/recipes/host.js +62 -0
  130. package/dist/styles/recipes/pattern.d.ts +80 -0
  131. package/dist/styles/recipes/pattern.js +82 -0
  132. package/dist/styles/recipes/scroll-rail.d.ts +69 -0
  133. package/dist/styles/recipes/scroll-rail.js +222 -0
  134. package/dist/styles/recipes/shadow.d.ts +13 -0
  135. package/dist/styles/recipes/shadow.js +5 -0
  136. package/dist/styles/recipes/static-text.d.ts +24 -0
  137. package/dist/styles/recipes/static-text.js +17 -0
  138. package/dist/styles/recipes/surface.d.ts +28 -0
  139. package/dist/styles/recipes/surface.js +27 -0
  140. package/dist/styles/recipes/tile.d.ts +122 -0
  141. package/dist/styles/recipes/tile.js +40 -0
  142. package/dist/styles/recipes/title-bar.d.ts +49 -0
  143. package/dist/styles/recipes/title-bar.js +134 -0
  144. package/dist/styles/recipes/toggle.d.ts +10 -0
  145. package/dist/styles/recipes/toggle.js +20 -0
  146. package/dist/styles/register-embedded-font.d.ts +64 -0
  147. package/dist/styles/register-embedded-font.js +30 -0
  148. package/dist/text-control.d.ts +131 -0
  149. package/dist/text-control.js +83 -0
  150. package/dist/tile-grid.d.ts +111 -0
  151. package/dist/tile-grid.js +53 -0
  152. package/dist/toggle-control.d.ts +60 -0
  153. package/dist/toggle-control.js +41 -0
  154. package/dist/track-width.d.ts +42 -0
  155. package/dist/track-width.js +30 -0
  156. package/dist/type-ahead.d.ts +35 -0
  157. package/dist/type-ahead.js +20 -0
  158. package/dist/zoom.d.ts +204 -0
  159. package/dist/zoom.js +105 -0
  160. package/docs/SPEC.md +2471 -0
  161. package/editor/vscode.html-custom-data.json +1320 -0
  162. package/editor/web-types.json +3237 -0
  163. package/package.json +118 -0
@@ -0,0 +1,356 @@
1
+ import { LitElement } from 'lit';
2
+ /** Which member of the icon family paints — the two System 7 resource sizes. */
3
+ export type VfIconSize = 'large' | 'small';
4
+ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfPositionedInterface) & typeof LitElement;
5
+ /**
6
+ * `<vf-icon>` — a Finder icon: pixel art in a reserved cell with its name on a
7
+ * plate below, selectable, movable and renameable in place.
8
+ *
9
+ * It is the one composite in the kit whose parts already existed separately —
10
+ * `vf-img` draws the art, `vf-list-item` inverts on selection, `vf-window`
11
+ * drags — and the reason to have it anyway is that the *icon* is the unit the
12
+ * Finder actually manipulates. A picture and a caption that select together,
13
+ * move together and rename together is a control, not a layout.
14
+ *
15
+ * ### The art arrives by slot
16
+ *
17
+ * Two slots, one per resource size — `large` is the 32×32 `ICN#` and `small`
18
+ * the 16×16 `ics#` — each holding a `vf-img` around the consumer's own `<img>`:
19
+ *
20
+ * ```html
21
+ * <vf-icon label="Macintosh HD" selectable movable editable>
22
+ * <vf-img slot="large"><img src="hd-32.png" alt=""></vf-img>
23
+ * <vf-img slot="small"><img src="hd-16.png" alt=""></vf-img>
24
+ * </vf-icon>
25
+ * ```
26
+ *
27
+ * Slots rather than `src` properties, for the reason `vf-img` exists at all:
28
+ * the kit ships no raster files and never builds an `<img>` on a consumer's
29
+ * behalf, so the graphic stays a real element in the light DOM with its own
30
+ * `alt`, `srcset`, loading behavior and asset URLs. A `src` string can express
31
+ * none of that, and it could not hold an inline `<svg>` or a `<canvas>` either.
32
+ * `vf-list-item`'s `icon` slot makes the same trade.
33
+ *
34
+ * The cost is that both files fetch even though one paints — pay it with two
35
+ * data URIs, or slot only the size that view uses.
36
+ *
37
+ * ### The cell is reserved, the art is registered in it
38
+ *
39
+ * `size` picks which slot paints *and* the cell it paints in: 32×32 or 16×16,
40
+ * held whether or not there is art for it. A folder is 32×20 of ink and a
41
+ * document 25×32, and a row of them keeps one baseline only because the cell —
42
+ * not the ink — is the unit, which is what an icon resource always was.
43
+ *
44
+ * ### Everything centered lands on a whole pixel, by parity
45
+ *
46
+ * The frame centers two things over one axis — the art cell and the name — and
47
+ * a centered child sits at `(box − child) / 2`. That is a whole number exactly
48
+ * when the box and the child have the **same parity**. Half a system pixel is
49
+ * what fringes 1-bit art: the glyph stems smear across two device columns and
50
+ * go gray, while the plate behind them stays sharp, because backgrounds are
51
+ * pixel-snapped by the compositor and glyphs are not. A crisp plate under a
52
+ * grey name is the signature of exactly this.
53
+ *
54
+ * So the component makes the parities agree instead of correcting afterwards.
55
+ * The cell is 32 or 16, and {@link #measurePlate} sizes the name plate to a
56
+ * whole **even** number of system px — measured from the text, rounded up. Both
57
+ * children are then even, and so is every offset, at every display density and
58
+ * whether or not a `width` is declared. Nothing is snapped, nothing leans on
59
+ * the rasterizer, and `verify:icon` asserts both the geometry and that a field
60
+ * of names renders without a single gray pixel — with the kit's normal
61
+ * antialiasing left on, since a run on whole pixels gives it nothing to smooth.
62
+ *
63
+ * Your side of it is one rule: **a declared `width` must be even**, since the
64
+ * component cannot round a number you chose. Supply art at the cell size too —
65
+ * which "one image pixel is one system pixel" already implies — because art
66
+ * differing from its cell by an odd number centers the same way.
67
+ *
68
+ * ### Selection inverts, because the art is a 1-bit mask
69
+ *
70
+ * A System 7 icon is black ink and opaque white on a transparent surround —
71
+ * precisely an image plus its mask — so inverting it flips ink and fill and
72
+ * leaves the surround alone, which is the whole of the classic selected
73
+ * appearance. `filter: invert(1)` reproduces it exactly for 1-bit art. Color
74
+ * art inverts too, into a photographic negative rather than the darkening
75
+ * System 7 gave it; that is the case to revisit if the kit ever grows a
76
+ * selected-state treatment of its own. The label plate inverts to the
77
+ * `--vf-highlight` pair, sharing one selection color with `vf-list-item`.
78
+ *
79
+ * ### Open is derived, not shipped
80
+ *
81
+ * With `open`, the art redraws as the Finder's open ghost: the outline held
82
+ * in solid black, the interior re-filled with the kit's loose 25% dither (the
83
+ * scrollbar trough's lattice), the transparent surround untouched. There is
84
+ * no second raster and no second fetch — the same alpha channel that makes
85
+ * selection an inversion makes the ghost derivable, and `src/open-art.ts`
86
+ * derives it from the slotted art by canvas compositing alone. No pixels are
87
+ * ever read back, so a cross-origin image that taints its canvas still works:
88
+ * taint forbids reading, not drawing or displaying.
89
+ *
90
+ * The ghost keeps the shape selection expects — ink and opaque white on a
91
+ * transparent surround — so a selected open icon inverts exactly as a closed
92
+ * one does, with no second treatment. The slot stays in the tree while the
93
+ * ghost paints, hidden (it is where the art loads, and re-loads, from), and
94
+ * art the pipeline cannot draw — nothing slotted yet, a failed load, an
95
+ * inline `<svg>` — keeps rendering as itself rather than vanishing behind a
96
+ * state it cannot show.
97
+ *
98
+ * ### `movable`, not `draggable`
99
+ *
100
+ * `draggable` is a global HTML attribute *and* an `HTMLElement` accessor, so
101
+ * declaring it would both shadow a platform member and hand the element to the
102
+ * browser's own drag-and-drop machinery. This is the `align` trap from
103
+ * `vf-stack` in a second costume — `align`, `hidden`, `dir`, `draggable` and
104
+ * `title` all carry behavior a custom element never asked for. The kit already
105
+ * spells this parameter `movable` on `vf-window`, so the icon does too, and it
106
+ * moves the same way: `DragController` tracks the gesture and
107
+ * `PlacementController` writes the result into `left`/`top` in whole system px,
108
+ * the art's own unit — the same pair markup places an icon with, so a moved
109
+ * icon is still where it was dropped after a zoom.
110
+ *
111
+ * Dragging is a pointer gesture with no keyboard equivalent, which is the kind
112
+ * of gap the kit closes rather than inherits (SPEC §1): a focused movable icon
113
+ * also moves under the arrow keys, one system px at a time and eight with
114
+ * Shift. Focus is what `selectable` grants, so the keyboard half of `movable`
115
+ * and `editable` presupposes it — see the role section below.
116
+ *
117
+ * Opening gets the same treatment. The double-click is the pointer gesture,
118
+ * and its keyboard route is ⌘O / ⌘↓ — the System 7 Open shortcuts, with Ctrl
119
+ * standing in for ⌘ off the Mac. Return is deliberately not one of them: the
120
+ * Finder's Return renamed, never opened, so on an editable icon it starts the
121
+ * edit and on a non-editable one it does nothing at all.
122
+ *
123
+ * ### The name and the art are one target, and the second click decides
124
+ *
125
+ * A double-click opens the icon *wherever it lands* — the name is as much the
126
+ * icon as the picture is, and the Finder never made you aim at the 32 pixels of
127
+ * art. But the name is also where a single click renames, so the two gestures
128
+ * begin with the same press and only the second one tells them apart.
129
+ *
130
+ * So the rename waits for it. A press on the plate of an already-selected icon
131
+ * arms the field rather than opening it, and the next press inside
132
+ * {@link RENAME_DELAY_MS} calls it off — leaving the double-click to open, with
133
+ * no rename box flashing up behind it. Nothing needs to *undo* an edit that
134
+ * began: the press that starts one and the press that opens are the same
135
+ * press, so the only thing that can be got right is not committing early.
136
+ *
137
+ * The window is generous in the one direction that is cheap. Reading a lone
138
+ * click as a pair costs a wait before the box appears; reading a pair as a lone
139
+ * click renames when the user asked to open. The same reasoning covers a press
140
+ * that turns into a drag, a press elsewhere, and any key — each calls the
141
+ * pending rename off, because none of them is the click it is waiting for.
142
+ *
143
+ * ### An icon alone is a picture; an icon in a field is an option
144
+ *
145
+ * `role="option"` is only meaningful inside a `listbox` that owns it. Written
146
+ * unconditionally it is not merely untidy — the browser *drops* it, and
147
+ * `aria-selected` with it, so a `selectable` icon announced as a bare generic
148
+ * and its selection state reached assistive tech nowhere at all.
149
+ *
150
+ * So the role follows the container. Owned, the icon is an `option` that names
151
+ * itself from its plate and publishes `aria-selected`. Unowned, it degrades to
152
+ * `role="img"` with a name — the same vocabulary the derived open ghost uses,
153
+ * and true of what it is. Deliberately not `button`: that would promise Enter
154
+ * and Space activate, and here Return *renames* while the open route is ⌘O / ⌘↓.
155
+ *
156
+ * Declaring the owner is one attribute on whatever already holds the field, and
157
+ * it is what buys the selection state back:
158
+ *
159
+ * ```html
160
+ * <div role="listbox" aria-label="Desktop" aria-multiselectable="true">
161
+ * <vf-icon label="Macintosh HD" selectable movable editable>…</vf-icon>
162
+ * <vf-icon label="Trash" selectable movable editable>…</vf-icon>
163
+ * </div>
164
+ * ```
165
+ *
166
+ * A `vf-desktop` cannot be that container itself: it also holds windows and a
167
+ * menu bar, and a non-`option` child of a listbox is invalid the same way the
168
+ * orphaned option was. The plain wrapper above is layout-neutral — placed icons
169
+ * anchor to the nearest *positioned* ancestor, which is still the desktop's
170
+ * raster. One divergence from the APG listbox is deliberate: its options share
171
+ * a single roving tab stop, while these stay one stop each, the way a Finder
172
+ * icon is reached on its own.
173
+ *
174
+ * **`selectable` is what makes an icon focusable**, and `movable`/`editable`
175
+ * presuppose it. That is the Finder's own model — you cannot move or rename
176
+ * what you have not selected — and the pointer path already assumed it: the
177
+ * rename opens on a press on the plate of an *already-selected* icon. A
178
+ * `movable`-only icon is a picture you can drag, not a widget.
179
+ *
180
+ * ### The label is a property, because it is editable
181
+ *
182
+ * The caption is `label` rather than slotted content: renaming means the
183
+ * component owns the string and hands it back on `vf-change`, and it cannot own
184
+ * text that lives in the consumer's DOM. An empty `label` draws no plate at
185
+ * all — that *is* the "no label" parameter, in preference to a second attribute
186
+ * that could disagree with it. `editable` then lets a click on the plate of an
187
+ * already-selected icon open the rename box a moment later, as the Finder's
188
+ * does (see above), with Return committing, Escape reverting, and the plate
189
+ * widening as you type.
190
+ *
191
+ * ### A name is never abbreviated, and never folded
192
+ *
193
+ * There is no ellipsis, no clipping and no wrapping: one line, always. System 7
194
+ * solved the long-name problem at the *other* end — HFS capped a filename at 31
195
+ * characters — so the Finder could afford to always draw the name in full, and
196
+ * did. A name wider than its cell simply overflows it, centered, the way a name
197
+ * wider than a 32-pixel icon always did.
198
+ *
199
+ * Staying on one line is also what keeps the name on the grid: a single run has
200
+ * a single measured width, so the even-plate rule above is one number rather
201
+ * than one per line, each with its own parity. `width` is therefore the cell —
202
+ * the grid pitch — not a bound on the name.
203
+ *
204
+ * `maxlength` (31) bounds the rename field rather than the `label` property:
205
+ * the name belongs to the consumer's model, and truncating one handed to us
206
+ * would lose data.
207
+ *
208
+ * The box hugs its text while you type it, not only once you are done, which is
209
+ * what keeps the name from moving when the edit commits: the plate is the same
210
+ * width either side of it, so the glyphs stay exactly where they were.
211
+ *
212
+ * A file also has to be called *something*, so a rename committed empty — or
213
+ * as nothing but spaces — is refused rather than applied, and the previous name
214
+ * comes back, which is what System 7 did. An empty `label` is still a perfectly
215
+ * good state to *start* in, though: a freshly made icon has no name until it is
216
+ * given one. Such an icon draws no plate but stays selectable, focusable and
217
+ * renameable — Return opens a field, and an edit with nothing in it yet is the
218
+ * one time the box stops hugging and reserves a cell's width, since a field you
219
+ * cannot see is one you cannot type into.
220
+ *
221
+ * @slot large - The 32×32 art, normally a `vf-img` around an `<img>`.
222
+ * @slot small - The 16×16 art, shown under `size="small"`.
223
+ * @csspart frame - The icon and its label plate, stacked.
224
+ * @csspart icon - The reserved art cell.
225
+ * @csspart label - The name block; its lines are centered under the art.
226
+ * @csspart plate - The inked run behind the name, which each wrapped line gets
227
+ * its own of (inverts when selected).
228
+ * @csspart input - The rename field, while editing.
229
+ * @cssprop --vf-icon-gap - Space between the art cell and the name plate
230
+ * @cssprop --vf-icon-label-height - The name plate's line box
231
+ * @fires vf-select - Selection changed by user interaction. `detail: { selected: boolean }`.
232
+ * @fires vf-change - The name was committed. `detail: { label: string, previous: string }`.
233
+ * @fires vf-open - The icon was opened — double-clicked anywhere on it, its
234
+ * name included, or ⌘O / ⌘↓ from the keyboard (Ctrl off the Mac), the
235
+ * System 7 shortcuts. Return renames instead, as the Finder's did.
236
+ * `detail: {}`.
237
+ * @fires vf-name-too-long - A rename was typed or pasted past `maxlength`, and
238
+ * the field refused the excess. `detail: { attempted, accepted, limit }` —
239
+ * enough to raise the alert System 7 raised rather than drop the characters
240
+ * silently. Not fired for a `label` set from your own code, which is never
241
+ * truncated in the first place.
242
+ * @fires vf-name-rejected - A rename was committed with no name in it, so the
243
+ * edit was dropped and the old name put back.
244
+ * `detail: { attempted, kept, reason: 'empty' }`. A `vf-change` is *not*
245
+ * fired alongside it — nothing changed.
246
+ */
247
+ export declare class VfIcon extends VfIcon_base {
248
+ #private;
249
+ static styles: import("lit").CSSResult[];
250
+ /** The icon's name. Empty draws no plate — that is the "no label" setting. */
251
+ label: string;
252
+ /**
253
+ * Which member of the icon family paints, and the cell it is registered in:
254
+ * `large` (32×32) or `small` (16×16).
255
+ */
256
+ size: VfIconSize;
257
+ /**
258
+ * Clicking selects. Set `selected` yourself to drive selection some other way.
259
+ *
260
+ * This is also the flag that makes an icon focusable and gives it a role, so
261
+ * the keyboard halves of {@link movable} and {@link editable} presuppose it —
262
+ * as the Finder did. A container carrying `role="listbox"` turns the role from
263
+ * `img` into a real `option`; see the class doc.
264
+ */
265
+ selectable: boolean;
266
+ /** Whether the icon is selected: the art inverts and the plate goes black. */
267
+ selected: boolean;
268
+ /**
269
+ * The icon's window is on screen, so the art paints as the Finder's open
270
+ * ghost — outline held, interior re-filled with the kit's loose dither —
271
+ * derived in the client from the slotted art itself (see the class doc).
272
+ * Set it when handling `vf-open`, clear it when the window goes away.
273
+ * Selection inverts the ghost exactly as it inverts the art.
274
+ */
275
+ open: boolean;
276
+ /**
277
+ * Drag to move — `movable`, never `draggable`, which is a platform attribute
278
+ * and accessor (see the class doc). Arrow keys move a focused icon too, which
279
+ * means pairing this with {@link selectable}: focus is what that grants.
280
+ */
281
+ movable: boolean;
282
+ /**
283
+ * The name can be renamed in place: click a selected plate, or press Return.
284
+ * Pair with {@link selectable} — both routes start from a selected icon.
285
+ *
286
+ * The pointer route opens the field once the double-click window has passed
287
+ * ({@link RENAME_DELAY_MS}), so double-clicking the *name* opens the icon the
288
+ * way double-clicking its art does. Return opens it at once — a keypress has
289
+ * no second half to wait for.
290
+ */
291
+ editable: boolean;
292
+ /**
293
+ * The cell width in whole system px — the grid pitch, and it must be
294
+ * **even**: the component rounds its own plate to keep every centered offset
295
+ * whole, but it cannot round a number you chose (see the class doc).
296
+ *
297
+ * It is not a bound on the name. Left off, the box is as wide as the wider of
298
+ * the art cell and the name; set, a longer name overflows it, centered.
299
+ * Declaring one is what keeps a field of icons on a single pitch, and what
300
+ * keeps a text-sized box off a fractional origin (contract rule 3).
301
+ */
302
+ width?: number;
303
+ /**
304
+ * The most characters the rename field will accept — 31, the HFS filename
305
+ * limit every System 7 name was cut to, which is also why the Finder could
306
+ * afford to always draw the whole name. Going past it fires
307
+ * `vf-name-too-long` with what was tried, so a host can say so rather than
308
+ * let characters vanish.
309
+ *
310
+ * It bounds *typing* only: a `label` set from your own data is displayed as
311
+ * given and fires nothing, since the name belongs to your model and silently
312
+ * truncating it would lose data.
313
+ */
314
+ maxlength: number;
315
+ /** Default-on display scaling (true 72dpi size); see src/scale.ts. */
316
+ private readonly scale;
317
+ /** Device-pixel grid snapping (opt in with applyGridSnap()); see src/grid-snap.ts. */
318
+ private readonly gridSnap;
319
+ /** Whether to wear the dashed focus rule; see src/focus-modality.ts. */
320
+ private readonly focusRule;
321
+ /** True while the rename field is open. */
322
+ private _editing;
323
+ /** The name as typed. The hidden plate renders it, so the box tracks it. */
324
+ private _draft;
325
+ /** The derived open ghost, or null while there is nothing to derive from. */
326
+ private _ghost;
327
+ connectedCallback(): void;
328
+ disconnectedCallback(): void;
329
+ protected updated(changed: Map<PropertyKey, unknown>): void;
330
+ firstUpdated(): void;
331
+ /**
332
+ * Open the rename field. The whole name starts selected, as the Finder's did
333
+ * — the common rename is a replacement, not an edit.
334
+ */
335
+ startEditing(): void;
336
+ /**
337
+ * Keep the typed name and close the field — unless there is no name left, in
338
+ * which case the edit is refused and the old one comes back.
339
+ *
340
+ * A file has to be called something: System 7 would not let you commit an
341
+ * empty name, and this does the same, treating a run of nothing but spaces
342
+ * as empty too (the plate would read as blank either way). The refusal is
343
+ * reported as `vf-name-rejected` for the same reason `vf-name-too-long` is —
344
+ * so a host can say why instead of leaving the name to silently snap back.
345
+ */
346
+ commitEditing(): void;
347
+ /** Put the previous name back and close the field. */
348
+ cancelEditing(): void;
349
+ protected render(): import("lit-html").TemplateResult<1>;
350
+ }
351
+ declare global {
352
+ interface HTMLElementTagNameMap {
353
+ 'vf-icon': VfIcon;
354
+ }
355
+ }
356
+ export {};