vintage-frames 0.2.0 → 0.3.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/custom-elements.json +214 -6
- package/dist/components/vf-checkbox.d.ts +5 -0
- package/dist/components/vf-checkbox.js +18 -10
- package/dist/components/vf-icon.d.ts +19 -4
- package/dist/components/vf-icon.js +11 -1
- package/dist/components/vf-menu-bar.d.ts +8 -0
- package/dist/components/vf-menu-bar.js +5 -2
- package/dist/components/vf-menu-item.d.ts +12 -6
- package/dist/components/vf-menu-item.js +32 -14
- package/dist/components/vf-menu.d.ts +14 -1
- package/dist/components/vf-menu.js +68 -48
- package/dist/components/vf-radio.d.ts +5 -0
- package/dist/components/vf-radio.js +16 -11
- package/dist/components/vf-window.d.ts +26 -0
- package/dist/components/vf-window.js +67 -18
- package/dist/styles/recipes/toggle.js +8 -0
- package/docs/SPEC.md +13 -10
- package/editor/vscode.html-custom-data.json +21 -6
- package/editor/web-types.json +53 -11
- package/package.json +3 -1
package/custom-elements.json
CHANGED
|
@@ -1144,7 +1144,7 @@
|
|
|
1144
1144
|
],
|
|
1145
1145
|
"slots": [
|
|
1146
1146
|
{
|
|
1147
|
-
"description": "The label, rendered to the right of the box with a 6px gap.",
|
|
1147
|
+
"description": "The label, rendered to the right of the box with a 6px gap. Left empty, the label and its gap collapse: the control is the bare 13×13 box.",
|
|
1148
1148
|
"name": ""
|
|
1149
1149
|
}
|
|
1150
1150
|
],
|
|
@@ -1185,6 +1185,16 @@
|
|
|
1185
1185
|
"description": "Value submitted with the form while checked.",
|
|
1186
1186
|
"attribute": "value"
|
|
1187
1187
|
},
|
|
1188
|
+
{
|
|
1189
|
+
"kind": "field",
|
|
1190
|
+
"name": "_hasLabel",
|
|
1191
|
+
"type": {
|
|
1192
|
+
"text": "boolean"
|
|
1193
|
+
},
|
|
1194
|
+
"privacy": "private",
|
|
1195
|
+
"default": "false",
|
|
1196
|
+
"description": "Whether the slot holds non-whitespace content; gates the label row."
|
|
1197
|
+
},
|
|
1188
1198
|
{
|
|
1189
1199
|
"kind": "field",
|
|
1190
1200
|
"name": "valueMissing",
|
|
@@ -1241,6 +1251,24 @@
|
|
|
1241
1251
|
"module": "src/toggle-control.ts"
|
|
1242
1252
|
}
|
|
1243
1253
|
},
|
|
1254
|
+
{
|
|
1255
|
+
"kind": "method",
|
|
1256
|
+
"name": "#onLabelSlotChange",
|
|
1257
|
+
"privacy": "private",
|
|
1258
|
+
"return": {
|
|
1259
|
+
"type": {
|
|
1260
|
+
"text": "void"
|
|
1261
|
+
}
|
|
1262
|
+
},
|
|
1263
|
+
"parameters": [
|
|
1264
|
+
{
|
|
1265
|
+
"name": "event",
|
|
1266
|
+
"type": {
|
|
1267
|
+
"text": "Event"
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
]
|
|
1271
|
+
},
|
|
1244
1272
|
{
|
|
1245
1273
|
"kind": "method",
|
|
1246
1274
|
"name": "formResetCallback",
|
|
@@ -3853,7 +3881,7 @@
|
|
|
3853
3881
|
"declarations": [
|
|
3854
3882
|
{
|
|
3855
3883
|
"kind": "class",
|
|
3856
|
-
"description": "`<vf-icon>` — a Finder icon: pixel art in a reserved cell with its name on a\nplate below, selectable, movable and renameable in place.\n\nIt is the one composite in the kit whose parts already existed separately —\n`vf-img` draws the art, `vf-list-item` inverts on selection, `vf-window`\ndrags — and the reason to have it anyway is that the *icon* is the unit the\nFinder actually manipulates. A picture and a caption that select together,\nmove together and rename together is a control, not a layout.\n\n### The art arrives by slot\n\nTwo slots, one per resource size — `large` is the 32×32 `ICN#` and `small`\nthe 16×16 `ics#` — each holding a `vf-img` around the consumer's own `<img>`:\n\n```html\n<vf-icon label=\"Macintosh HD\" selectable movable editable>\n <vf-img slot=\"large\"><img src=\"hd-32.png\" alt=\"\"></vf-img>\n <vf-img slot=\"small\"><img src=\"hd-16.png\" alt=\"\"></vf-img>\n</vf-icon>\n```\n\nSlots rather than `src` properties, for the reason `vf-img` exists at all:\nthe kit ships no raster files and never builds an `<img>` on a consumer's\nbehalf, so the graphic stays a real element in the light DOM with its own\n`alt`, `srcset`, loading behavior and asset URLs. A `src` string can express\nnone of that, and it could not hold an inline `<svg>` or a `<canvas>` either.\n`vf-list-item`'s `icon` slot makes the same trade.\n\nThe cost is that both files fetch even though one paints — pay it with two\ndata URIs, or slot only the size that view uses.\n\n### The cell is reserved, the art is registered in it\n\n`size` picks which slot paints *and* the cell it paints in: 32×32 or 16×16,\nheld whether or not there is art for it. A folder is 32×20 of ink and a\ndocument 25×32, and a row of them keeps one baseline only because the cell —\nnot the ink — is the unit, which is what an icon resource always was.\n\n### Everything centered lands on a whole pixel, by parity\n\nThe frame centers two things over one axis — the art cell and the name — and\na centered child sits at `(box − child) / 2`. That is a whole number exactly\nwhen the box and the child have the **same parity**. Half a system pixel is\nwhat fringes 1-bit art: the glyph stems smear across two device columns and\ngo gray, while the plate behind them stays sharp, because backgrounds are\npixel-snapped by the compositor and glyphs are not. A crisp plate under a\ngrey name is the signature of exactly this.\n\nSo the component makes the parities agree instead of correcting afterwards.\nThe cell is 32 or 16, and #measurePlate sizes the name plate to a\nwhole **even** number of system px — measured from the text, rounded up. Both\nchildren are then even, and so is every offset, at every display density and\nwhether or not a `width` is declared. Nothing is snapped, nothing leans on\nthe rasterizer, and `verify:icon` asserts both the geometry and that a field\nof names renders without a single gray pixel — with the kit's normal\nantialiasing left on, since a run on whole pixels gives it nothing to smooth.\n\nYour side of it is one rule: **a declared `width` must be even**, since the\ncomponent cannot round a number you chose. Supply art at the cell size too —\nwhich \"one image pixel is one system pixel\" already implies — because art\ndiffering from its cell by an odd number centers the same way.\n\n### Selection inverts, because the art is a 1-bit mask\n\nA System 7 icon is black ink and opaque white on a transparent surround —\nprecisely an image plus its mask — so inverting it flips ink and fill and\nleaves the surround alone, which is the whole of the classic selected\nappearance. `filter: invert(1)` reproduces it exactly for 1-bit art. Color\nart inverts too, into a photographic negative rather than the darkening\nSystem 7 gave it; that is the case to revisit if the kit ever grows a\nselected-state treatment of its own. The label plate inverts to the\n`--vf-highlight` pair, sharing one selection color with `vf-list-item`.\n\n### Open is derived, not shipped\n\nWith `open`, the art redraws as the Finder's open ghost: the outline held\nin solid black, the interior re-filled with the kit's loose 25% dither (the\nscrollbar trough's lattice), the transparent surround untouched. There is\nno second raster and no second fetch — the same alpha channel that makes\nselection an inversion makes the ghost derivable, and `src/open-art.ts`\nderives it from the slotted art by canvas compositing alone. No pixels are\never read back, so a cross-origin image that taints its canvas still works:\ntaint forbids reading, not drawing or displaying.\n\nThe ghost keeps the shape selection expects — ink and opaque white on a\ntransparent surround — so a selected open icon inverts exactly as a closed\none does, with no second treatment. The slot stays in the tree while the\nghost paints, hidden (it is where the art loads, and re-loads, from), and\nart the pipeline cannot draw — nothing slotted yet, a failed load, an\ninline `<svg>` — keeps rendering as itself rather than vanishing behind a\nstate it cannot show.\n\n### `movable`, not `draggable`\n\n`draggable` is a global HTML attribute *and* an `HTMLElement` accessor, so\ndeclaring it would both shadow a platform member and hand the element to the\nbrowser's own drag-and-drop machinery. This is the `align` trap from\n`vf-stack` in a second costume — `align`, `hidden`, `dir`, `draggable` and\n`title` all carry behavior a custom element never asked for. The kit already\nspells this parameter `movable` on `vf-window`, so the icon does too, and it\nmoves the same way: `DragController` tracks the gesture and\n`PlacementController` writes the result into `left`/`top` in whole system px,\nthe art's own unit — the same pair markup places an icon with, so a moved\nicon is still where it was dropped after a zoom.\n\nDragging is a pointer gesture with no keyboard equivalent, which is the kind\nof gap the kit closes rather than inherits (SPEC §1): a focused movable icon\nalso moves under the arrow keys, one system px at a time and eight with\nShift. Focus is what `selectable` grants, so the keyboard half of `movable`\nand `editable` presupposes it — see the role section below.\n\nOpening gets the same treatment. The double-click is the pointer gesture,\nand its keyboard route is ⌘O / ⌘↓ — the System 7 Open shortcuts, with Ctrl\nstanding in for ⌘ off the Mac. Return is deliberately not one of them: the\nFinder's Return renamed, never opened, so on an editable icon it starts the\nedit and on a non-editable one it does nothing at all.\n\n### The name and the art are one target, and the second click decides\n\nA double-click opens the icon *wherever it lands* — the name is as much the\nicon as the picture is, and the Finder never made you aim at the 32 pixels of\nart. But the name is also where a single click renames, so the two gestures\nbegin with the same press and only the second one tells them apart.\n\nSo the rename waits for it. A press on the plate of an already-selected icon\narms the field rather than opening it, and the next press inside\nRENAME_DELAY_MS calls it off — leaving the double-click to open, with\nno rename box flashing up behind it. Nothing needs to *undo* an edit that\nbegan: the press that starts one and the press that opens are the same\npress, so the only thing that can be got right is not committing early.\n\nThe window is generous in the one direction that is cheap. Reading a lone\nclick as a pair costs a wait before the box appears; reading a pair as a lone\nclick renames when the user asked to open. The same reasoning covers a press\nthat turns into a drag, a press elsewhere, and any key — each calls the\npending rename off, because none of them is the click it is waiting for.\n\n### An icon alone is a picture; an icon in a field is an option\n\n`role=\"option\"` is only meaningful inside a `listbox` that owns it. Written\nunconditionally it is not merely untidy — the browser *drops* it, and\n`aria-selected` with it, so a `selectable` icon announced as a bare generic\nand its selection state reached assistive tech nowhere at all.\n\nSo the role follows the container. Owned, the icon is an `option` that names\nitself from its plate and publishes `aria-selected`. Unowned, it degrades to\n`role=\"img\"` with a name — the same vocabulary the derived open ghost uses,\nand true of what it is. Deliberately not `button`: that would promise Enter\nand Space activate, and here Return *renames* while the open route is ⌘O / ⌘↓.\n\nDeclaring the owner is one attribute on whatever already holds the field, and\nit is what buys the selection state back:\n\n```html\n<div role=\"listbox\" aria-label=\"Desktop\" aria-multiselectable=\"true\">\n <vf-icon label=\"Macintosh HD\" selectable movable editable>…</vf-icon>\n <vf-icon label=\"Trash\" selectable movable editable>…</vf-icon>\n</div>\n```\n\nA `vf-desktop` cannot be that container itself: it also holds windows and a\nmenu bar, and a non-`option` child of a listbox is invalid the same way the\norphaned option was. The plain wrapper above is layout-neutral — placed icons\nanchor to the nearest *positioned* ancestor, which is still the desktop's\nraster. One divergence from the APG listbox is deliberate: its options share\na single roving tab stop, while these stay one stop each, the way a Finder\nicon is reached on its own.\n\n**`selectable` is what makes an icon focusable**, and `movable`/`editable`\npresuppose it. That is the Finder's own model — you cannot move or rename\nwhat you have not selected — and the pointer path already assumed it: the\nrename opens on a press on the plate of an *already-selected* icon. A\n`movable`-only icon is a picture you can drag, not a widget.\n\n### The label is a property, because it is editable\n\nThe caption is `label` rather than slotted content: renaming means the\ncomponent owns the string and hands it back on `vf-change`, and it cannot own\ntext that lives in the consumer's DOM. An empty `label` draws no plate at\nall — that *is* the \"no label\" parameter, in preference to a second attribute\nthat could disagree with it. `editable` then lets a click on the plate of an\nalready-selected icon open the rename box a moment later, as the Finder's\ndoes (see above), with Return committing, Escape reverting, and the plate\nwidening as you type.\n\n### A name is never abbreviated, and never folded\n\nThere is no ellipsis, no clipping and no wrapping: one line, always. System 7\nsolved the long-name problem at the *other* end — HFS capped a filename at 31\ncharacters — so the Finder could afford to always draw the name in full, and\ndid. A name wider than its cell simply overflows it, centered, the way a name\nwider than a 32-pixel icon always did.\n\nStaying on one line is also what keeps the name on the grid: a single run has\na single measured width, so the even-plate rule above is one number rather\nthan one per line, each with its own parity. `width` is therefore the cell —\nthe grid pitch — not a bound on the name.\n\n`maxlength` (31) bounds the rename field rather than the `label` property:\nthe name belongs to the consumer's model, and truncating one handed to us\nwould lose data.\n\nThe box hugs its text while you type it, not only once you are done, which is\nwhat keeps the name from moving when the edit commits: the plate is the same\nwidth either side of it, so the glyphs stay exactly where they were.\n\nA file also has to be called *something*, so a rename committed empty — or\nas nothing but spaces — is refused rather than applied, and the previous name\ncomes back, which is what System 7 did. An empty `label` is still a perfectly\ngood state to *start* in, though: a freshly made icon has no name until it is\ngiven one. Such an icon draws no plate but stays selectable, focusable and\nrenameable — Return opens a field, and an edit with nothing in it yet is the\none time the box stops hugging and reserves a cell's width, since a field you\ncannot see is one you cannot type into.",
|
|
3884
|
+
"description": "`<vf-icon>` — a Finder icon: pixel art in a reserved cell with its name on a\nplate below, selectable, movable and renameable in place.\n\nIt is the one composite in the kit whose parts already existed separately —\n`vf-img` draws the art, `vf-list-item` inverts on selection, `vf-window`\ndrags — and the reason to have it anyway is that the *icon* is the unit the\nFinder actually manipulates. A picture and a caption that select together,\nmove together and rename together is a control, not a layout.\n\n### The art arrives by slot\n\nTwo slots, one per resource size — `large` is the 32×32 `ICN#` and `small`\nthe 16×16 `ics#` — each holding a `vf-img` around the consumer's own `<img>`:\n\n```html\n<vf-icon label=\"Macintosh HD\" selectable movable editable>\n <vf-img slot=\"large\"><img src=\"hd-32.png\" alt=\"\"></vf-img>\n <vf-img slot=\"small\"><img src=\"hd-16.png\" alt=\"\"></vf-img>\n</vf-icon>\n```\n\nSlots rather than `src` properties, for the reason `vf-img` exists at all:\nthe kit ships no raster files and never builds an `<img>` on a consumer's\nbehalf, so the graphic stays a real element in the light DOM with its own\n`alt`, `srcset`, loading behavior and asset URLs. A `src` string can express\nnone of that, and it could not hold an inline `<svg>` or a `<canvas>` either.\n`vf-list-item`'s `icon` slot makes the same trade.\n\nThe cost is that both files fetch even though one paints — pay it with two\ndata URIs, or slot only the size that view uses.\n\n### The cell is reserved, the art is registered in it\n\n`size` picks which slot paints *and* the cell it paints in: 32×32 or 16×16,\nheld whether or not there is art for it. A folder is 32×20 of ink and a\ndocument 25×32, and a row of them keeps one baseline only because the cell —\nnot the ink — is the unit, which is what an icon resource always was.\n\n### Everything centered lands on a whole pixel, by parity\n\nThe frame centers two things over one axis — the art cell and the name — and\na centered child sits at `(box − child) / 2`. That is a whole number exactly\nwhen the box and the child have the **same parity**. Half a system pixel is\nwhat fringes 1-bit art: the glyph stems smear across two device columns and\ngo gray, while the plate behind them stays sharp, because backgrounds are\npixel-snapped by the compositor and glyphs are not. A crisp plate under a\ngrey name is the signature of exactly this.\n\nSo the component makes the parities agree instead of correcting afterwards.\nThe cell is 32 or 16, and #measurePlate sizes the name plate to a\nwhole **even** number of system px — measured from the text, rounded up. Both\nchildren are then even, and so is every offset, at every display density and\nwhether or not a `width` is declared. Nothing is snapped, nothing leans on\nthe rasterizer, and `verify:icon` asserts both the geometry and that a field\nof names renders without a single gray pixel — with the kit's normal\nantialiasing left on, since a run on whole pixels gives it nothing to smooth.\n\nYour side of it is one rule: **a declared `width` must be even**, since the\ncomponent cannot round a number you chose. Supply art at the cell size too —\nwhich \"one image pixel is one system pixel\" already implies — because art\ndiffering from its cell by an odd number centers the same way.\n\n### Selection inverts, because the art is a 1-bit mask\n\nA System 7 icon is black ink and opaque white on a transparent surround —\nprecisely an image plus its mask — so inverting it flips ink and fill and\nleaves the surround alone, which is the whole of the classic selected\nappearance. `filter: invert(1)` reproduces it exactly for 1-bit art. Color\nart would invert into a photographic negative, which was never what\nSystem 7 showed: declare `color` and selection **darkens** the art\ninstead — Icon Utilities' ttSelected transform, every color blended\nhalfway toward black (`brightness(0.5)`), whites going gray, the\ntransparent surround still untouched. The declaration is the consumer's\nbecause the component cannot tell color art from a mask by looking at a\nslotted image. It covers whatever the cell shows, the derived open ghost\nincluded, so a color icon has one selected treatment open or closed. The\nlabel plate inverts to the `--vf-highlight` pair either way, sharing one\nselection color with `vf-list-item` — the selected name was inverted\nwhatever the art.\n\n### Open is derived, not shipped\n\nWith `open`, the art redraws as the Finder's open ghost: the outline held\nin solid black, the interior re-filled with the kit's loose 25% dither (the\nscrollbar trough's lattice), the transparent surround untouched. There is\nno second raster and no second fetch — the same alpha channel that makes\nselection an inversion makes the ghost derivable, and `src/open-art.ts`\nderives it from the slotted art by canvas compositing alone. No pixels are\never read back, so a cross-origin image that taints its canvas still works:\ntaint forbids reading, not drawing or displaying.\n\nThe ghost keeps the shape selection expects — ink and opaque white on a\ntransparent surround — so a selected open icon inverts exactly as a closed\none does, with no second treatment. The slot stays in the tree while the\nghost paints, hidden (it is where the art loads, and re-loads, from), and\nart the pipeline cannot draw — nothing slotted yet, a failed load, an\ninline `<svg>` — keeps rendering as itself rather than vanishing behind a\nstate it cannot show.\n\n### `movable`, not `draggable`\n\n`draggable` is a global HTML attribute *and* an `HTMLElement` accessor, so\ndeclaring it would both shadow a platform member and hand the element to the\nbrowser's own drag-and-drop machinery. This is the `align` trap from\n`vf-stack` in a second costume — `align`, `hidden`, `dir`, `draggable` and\n`title` all carry behavior a custom element never asked for. The kit already\nspells this parameter `movable` on `vf-window`, so the icon does too, and it\nmoves the same way: `DragController` tracks the gesture and\n`PlacementController` writes the result into `left`/`top` in whole system px,\nthe art's own unit — the same pair markup places an icon with, so a moved\nicon is still where it was dropped after a zoom.\n\nDragging is a pointer gesture with no keyboard equivalent, which is the kind\nof gap the kit closes rather than inherits (SPEC §1): a focused movable icon\nalso moves under the arrow keys, one system px at a time and eight with\nShift. Focus is what `selectable` grants, so the keyboard half of `movable`\nand `editable` presupposes it — see the role section below.\n\nOpening gets the same treatment. The double-click is the pointer gesture,\nand its keyboard route is ⌘O / ⌘↓ — the System 7 Open shortcuts, with Ctrl\nstanding in for ⌘ off the Mac. Return is deliberately not one of them: the\nFinder's Return renamed, never opened, so on an editable icon it starts the\nedit and on a non-editable one it does nothing at all.\n\n### The name and the art are one target, and the second click decides\n\nA double-click opens the icon *wherever it lands* — the name is as much the\nicon as the picture is, and the Finder never made you aim at the 32 pixels of\nart. But the name is also where a single click renames, so the two gestures\nbegin with the same press and only the second one tells them apart.\n\nSo the rename waits for it. A press on the plate of an already-selected icon\narms the field rather than opening it, and the next press inside\nRENAME_DELAY_MS calls it off — leaving the double-click to open, with\nno rename box flashing up behind it. Nothing needs to *undo* an edit that\nbegan: the press that starts one and the press that opens are the same\npress, so the only thing that can be got right is not committing early.\n\nThe window is generous in the one direction that is cheap. Reading a lone\nclick as a pair costs a wait before the box appears; reading a pair as a lone\nclick renames when the user asked to open. The same reasoning covers a press\nthat turns into a drag, a press elsewhere, and any key — each calls the\npending rename off, because none of them is the click it is waiting for.\n\n### An icon alone is a picture; an icon in a field is an option\n\n`role=\"option\"` is only meaningful inside a `listbox` that owns it. Written\nunconditionally it is not merely untidy — the browser *drops* it, and\n`aria-selected` with it, so a `selectable` icon announced as a bare generic\nand its selection state reached assistive tech nowhere at all.\n\nSo the role follows the container. Owned, the icon is an `option` that names\nitself from its plate and publishes `aria-selected`. Unowned, it degrades to\n`role=\"img\"` with a name — the same vocabulary the derived open ghost uses,\nand true of what it is. Deliberately not `button`: that would promise Enter\nand Space activate, and here Return *renames* while the open route is ⌘O / ⌘↓.\n\nDeclaring the owner is one attribute on whatever already holds the field, and\nit is what buys the selection state back:\n\n```html\n<div role=\"listbox\" aria-label=\"Desktop\" aria-multiselectable=\"true\">\n <vf-icon label=\"Macintosh HD\" selectable movable editable>…</vf-icon>\n <vf-icon label=\"Trash\" selectable movable editable>…</vf-icon>\n</div>\n```\n\nA `vf-desktop` cannot be that container itself: it also holds windows and a\nmenu bar, and a non-`option` child of a listbox is invalid the same way the\norphaned option was. The plain wrapper above is layout-neutral — placed icons\nanchor to the nearest *positioned* ancestor, which is still the desktop's\nraster. One divergence from the APG listbox is deliberate: its options share\na single roving tab stop, while these stay one stop each, the way a Finder\nicon is reached on its own.\n\n**`selectable` is what makes an icon focusable**, and `movable`/`editable`\npresuppose it. That is the Finder's own model — you cannot move or rename\nwhat you have not selected — and the pointer path already assumed it: the\nrename opens on a press on the plate of an *already-selected* icon. A\n`movable`-only icon is a picture you can drag, not a widget.\n\n### The label is a property, because it is editable\n\nThe caption is `label` rather than slotted content: renaming means the\ncomponent owns the string and hands it back on `vf-change`, and it cannot own\ntext that lives in the consumer's DOM. An empty `label` draws no plate at\nall — that *is* the \"no label\" parameter, in preference to a second attribute\nthat could disagree with it. `editable` then lets a click on the plate of an\nalready-selected icon open the rename box a moment later, as the Finder's\ndoes (see above), with Return committing, Escape reverting, and the plate\nwidening as you type.\n\n### A name is never abbreviated, and never folded\n\nThere is no ellipsis, no clipping and no wrapping: one line, always. System 7\nsolved the long-name problem at the *other* end — HFS capped a filename at 31\ncharacters — so the Finder could afford to always draw the name in full, and\ndid. A name wider than its cell simply overflows it, centered, the way a name\nwider than a 32-pixel icon always did.\n\nStaying on one line is also what keeps the name on the grid: a single run has\na single measured width, so the even-plate rule above is one number rather\nthan one per line, each with its own parity. `width` is therefore the cell —\nthe grid pitch — not a bound on the name.\n\n`maxlength` (31) bounds the rename field rather than the `label` property:\nthe name belongs to the consumer's model, and truncating one handed to us\nwould lose data.\n\nThe box hugs its text while you type it, not only once you are done, which is\nwhat keeps the name from moving when the edit commits: the plate is the same\nwidth either side of it, so the glyphs stay exactly where they were.\n\nA file also has to be called *something*, so a rename committed empty — or\nas nothing but spaces — is refused rather than applied, and the previous name\ncomes back, which is what System 7 did. An empty `label` is still a perfectly\ngood state to *start* in, though: a freshly made icon has no name until it is\ngiven one. Such an icon draws no plate but stays selectable, focusable and\nrenameable — Return opens a field, and an edit with nothing in it yet is the\none time the box stops hugging and reserves a cell's width, since a field you\ncannot see is one you cannot type into.",
|
|
3857
3885
|
"name": "VfIcon",
|
|
3858
3886
|
"cssProperties": [
|
|
3859
3887
|
{
|
|
@@ -3941,6 +3969,17 @@
|
|
|
3941
3969
|
"attribute": "selected",
|
|
3942
3970
|
"reflects": true
|
|
3943
3971
|
},
|
|
3972
|
+
{
|
|
3973
|
+
"kind": "field",
|
|
3974
|
+
"name": "color",
|
|
3975
|
+
"type": {
|
|
3976
|
+
"text": "boolean"
|
|
3977
|
+
},
|
|
3978
|
+
"default": "false",
|
|
3979
|
+
"description": "Declares the slotted art a **color icon**, so selection darkens it — the\nttSelected transform, every color blended halfway toward black — instead\nof inverting it into a photographic negative (see the class doc). Yours\nto declare because the component cannot tell color art from a 1-bit mask\nby looking at a slotted image. The label plate inverts either way.",
|
|
3980
|
+
"attribute": "color",
|
|
3981
|
+
"reflects": true
|
|
3982
|
+
},
|
|
3944
3983
|
{
|
|
3945
3984
|
"kind": "field",
|
|
3946
3985
|
"name": "open",
|
|
@@ -4489,6 +4528,15 @@
|
|
|
4489
4528
|
"description": "Whether the icon is selected: the art inverts and the plate goes black.",
|
|
4490
4529
|
"fieldName": "selected"
|
|
4491
4530
|
},
|
|
4531
|
+
{
|
|
4532
|
+
"name": "color",
|
|
4533
|
+
"type": {
|
|
4534
|
+
"text": "boolean"
|
|
4535
|
+
},
|
|
4536
|
+
"default": "false",
|
|
4537
|
+
"description": "Declares the slotted art a **color icon**, so selection darkens it — the\nttSelected transform, every color blended halfway toward black — instead\nof inverting it into a photographic negative (see the class doc). Yours\nto declare because the component cannot tell color art from a 1-bit mask\nby looking at a slotted image. The label plate inverts either way.",
|
|
4538
|
+
"fieldName": "color"
|
|
4539
|
+
},
|
|
4492
4540
|
{
|
|
4493
4541
|
"name": "open",
|
|
4494
4542
|
"type": {
|
|
@@ -5923,6 +5971,17 @@
|
|
|
5923
5971
|
"attribute": "rounded",
|
|
5924
5972
|
"reflects": true
|
|
5925
5973
|
},
|
|
5974
|
+
{
|
|
5975
|
+
"kind": "field",
|
|
5976
|
+
"name": "shortcuts",
|
|
5977
|
+
"type": {
|
|
5978
|
+
"text": "boolean"
|
|
5979
|
+
},
|
|
5980
|
+
"default": "false",
|
|
5981
|
+
"description": "Makes every slotted menu's item `shortcut`s live key equivalents — one\ndeclaration for the whole bar, the way MenuKey() answered for every menu\nat once. See `vf-menu.shortcuts` (the per-menu grant) and\n`vf-menu-item.shortcut` for the claim contract. Off by default: key\nequivalents are page-global, and only *the* menu bar should own them.",
|
|
5982
|
+
"attribute": "shortcuts",
|
|
5983
|
+
"reflects": true
|
|
5984
|
+
},
|
|
5926
5985
|
{
|
|
5927
5986
|
"kind": "field",
|
|
5928
5987
|
"name": "_menus",
|
|
@@ -6190,6 +6249,15 @@
|
|
|
6190
6249
|
"description": "Rounds the bar's top corners the way System 7's were: not a curve of the\nbar itself but the black stair-step mask the compact Mac's ROM painted\nover the CRT's rounded corners, which the menu bar wore by sitting flush\nwith the screen top. Drawn as the traced 5-px staircase in `--vf-black`\nink over the bar's own corners — over any backdrop, as the hardware\nmask was.",
|
|
6191
6250
|
"fieldName": "rounded"
|
|
6192
6251
|
},
|
|
6252
|
+
{
|
|
6253
|
+
"name": "shortcuts",
|
|
6254
|
+
"type": {
|
|
6255
|
+
"text": "boolean"
|
|
6256
|
+
},
|
|
6257
|
+
"default": "false",
|
|
6258
|
+
"description": "Makes every slotted menu's item `shortcut`s live key equivalents — one\ndeclaration for the whole bar, the way MenuKey() answered for every menu\nat once. See `vf-menu.shortcuts` (the per-menu grant) and\n`vf-menu-item.shortcut` for the claim contract. Off by default: key\nequivalents are page-global, and only *the* menu bar should own them.",
|
|
6259
|
+
"fieldName": "shortcuts"
|
|
6260
|
+
},
|
|
6193
6261
|
{
|
|
6194
6262
|
"name": "top",
|
|
6195
6263
|
"type": {
|
|
@@ -6356,7 +6424,7 @@
|
|
|
6356
6424
|
"text": "string"
|
|
6357
6425
|
},
|
|
6358
6426
|
"default": "''",
|
|
6359
|
-
"description": "Keyboard shortcut
|
|
6427
|
+
"description": "Keyboard shortcut, e.g. `\"⌘H\"`, drawn left-aligned in the panel's\nshared shortcut column. The span is `aria-hidden` so the glyphs never\nconcatenate into the item's accessible name (\"Print… place of interest\nsign P\") — the host mirrors it as `aria-keyshortcuts` (\"Meta+H\") instead,\nso AT announces it *as* a shortcut. A consumer's own `aria-keyshortcuts`\nwins.\n\nInside a `vf-menu`/`vf-menu-bar` that declares `shortcuts`, this is a\nLIVE key equivalent, not a legend: a matching keydown anywhere on the\npage activates the item — menu open or not — claiming the stroke with\n`preventDefault()` (see the document keydown handler below for the full\ncontract).",
|
|
6360
6428
|
"attribute": "shortcut"
|
|
6361
6429
|
},
|
|
6362
6430
|
{
|
|
@@ -6501,6 +6569,12 @@
|
|
|
6501
6569
|
}
|
|
6502
6570
|
]
|
|
6503
6571
|
},
|
|
6572
|
+
{
|
|
6573
|
+
"kind": "field",
|
|
6574
|
+
"name": "#onDocKeydown",
|
|
6575
|
+
"privacy": "private",
|
|
6576
|
+
"description": "The MenuKey() half of shortcut: a document-level ear that answers\nthe item's key equivalent from anywhere on the page, menu open or not —\nso File → Save shows ⌘S *and* answers it, with no page-side plumbing.\n\nLive only under a grant: an ancestor `vf-menu` or `vf-menu-bar` declaring\n`shortcuts`. Key equivalents are page-global — the one thing in the kit\nthat is — and a page may hold several menus (a component reference, a\ndialog mock-up) of which only one is *the* menu bar; the grant says which,\nthe way `applyCursor()` is the page's own call. Checked per event, so\ntoggling the grant needs no re-wiring.\n\nContract, in claim order:\n- A `defaultPrevented` stroke is already someone's — a page handler that\n ran first keeps its key. A match claims with `preventDefault()` (no\n `stopPropagation`), so with several items contesting one key the first\n connected wins and later page listeners still observe the claimed event.\n- A disabled item claims nothing: the stroke falls through untouched, so\n a grayed Undo leaves ⌘Z to the focused field's own native undo.\n- Auto-repeat strokes are claimed but activate only once per press.\n- Activation is the normal path — blink, `vf-menu-select` — plus an\n internal flash request so a *closed* ancestor menu answers by flashing\n its bar title, exactly MenuKey's acknowledgment; the panel never opens\n and focus never moves. An open menu shows the item blink and closes."
|
|
6577
|
+
},
|
|
6504
6578
|
{
|
|
6505
6579
|
"kind": "method",
|
|
6506
6580
|
"name": "activate",
|
|
@@ -6608,7 +6682,7 @@
|
|
|
6608
6682
|
"text": "string"
|
|
6609
6683
|
},
|
|
6610
6684
|
"default": "''",
|
|
6611
|
-
"description": "Keyboard shortcut
|
|
6685
|
+
"description": "Keyboard shortcut, e.g. `\"⌘H\"`, drawn left-aligned in the panel's\nshared shortcut column. The span is `aria-hidden` so the glyphs never\nconcatenate into the item's accessible name (\"Print… place of interest\nsign P\") — the host mirrors it as `aria-keyshortcuts` (\"Meta+H\") instead,\nso AT announces it *as* a shortcut. A consumer's own `aria-keyshortcuts`\nwins.\n\nInside a `vf-menu`/`vf-menu-bar` that declares `shortcuts`, this is a\nLIVE key equivalent, not a legend: a matching keydown anywhere on the\npage activates the item — menu open or not — claiming the stroke with\n`preventDefault()` (see the document keydown handler below for the full\ncontract).",
|
|
6612
6686
|
"fieldName": "shortcut"
|
|
6613
6687
|
},
|
|
6614
6688
|
{
|
|
@@ -6699,7 +6773,7 @@
|
|
|
6699
6773
|
],
|
|
6700
6774
|
"cssParts": [
|
|
6701
6775
|
{
|
|
6702
|
-
"description": "The menu title in the bar (inverts while open).",
|
|
6776
|
+
"description": "The menu title in the bar (inverts while open; flashes when a closed menu's item is activated by its key equivalent).",
|
|
6703
6777
|
"name": "label"
|
|
6704
6778
|
},
|
|
6705
6779
|
{
|
|
@@ -6762,6 +6836,17 @@
|
|
|
6762
6836
|
"attribute": "open",
|
|
6763
6837
|
"reflects": true
|
|
6764
6838
|
},
|
|
6839
|
+
{
|
|
6840
|
+
"kind": "field",
|
|
6841
|
+
"name": "shortcuts",
|
|
6842
|
+
"type": {
|
|
6843
|
+
"text": "boolean"
|
|
6844
|
+
},
|
|
6845
|
+
"default": "false",
|
|
6846
|
+
"description": "Makes the items' `shortcut`s live key equivalents: a matching keydown\nanywhere on the page activates the item — menu open or not — and a\nclosed menu answers by flashing its bar title, MenuKey's acknowledgment.\nOff by default because key equivalents are page-global and a page may\nhold several menus of which only one is *the* menu bar; on a bar, declare\nit there once for every menu in it. The full claim contract lives on\n`vf-menu-item.shortcut`.",
|
|
6847
|
+
"attribute": "shortcuts",
|
|
6848
|
+
"reflects": true
|
|
6849
|
+
},
|
|
6765
6850
|
{
|
|
6766
6851
|
"kind": "field",
|
|
6767
6852
|
"name": "barTabIndex",
|
|
@@ -6862,6 +6947,41 @@
|
|
|
6862
6947
|
"name": "#onCloseRequest",
|
|
6863
6948
|
"privacy": "private"
|
|
6864
6949
|
},
|
|
6950
|
+
{
|
|
6951
|
+
"kind": "field",
|
|
6952
|
+
"name": "_flashOn",
|
|
6953
|
+
"type": {
|
|
6954
|
+
"text": "boolean"
|
|
6955
|
+
},
|
|
6956
|
+
"privacy": "private",
|
|
6957
|
+
"default": "false",
|
|
6958
|
+
"description": "`true` while the key-equivalent flash paints the title inverted."
|
|
6959
|
+
},
|
|
6960
|
+
{
|
|
6961
|
+
"kind": "field",
|
|
6962
|
+
"name": "#flashHandle",
|
|
6963
|
+
"privacy": "private",
|
|
6964
|
+
"type": {
|
|
6965
|
+
"text": "BlinkHandle | undefined"
|
|
6966
|
+
}
|
|
6967
|
+
},
|
|
6968
|
+
{
|
|
6969
|
+
"kind": "field",
|
|
6970
|
+
"name": "#onFlashRequest",
|
|
6971
|
+
"privacy": "private",
|
|
6972
|
+
"description": "A key equivalent activated one of this menu's items through the closed\npanel: flash the bar title on the item blink's own cadence, so the\nacknowledgment lands where the user can see it — the item's own blink\nruns unseen inside the hidden panel. An open menu skips it: the dropped\npanel already shows the blink, and the title is inverted the whole time."
|
|
6973
|
+
},
|
|
6974
|
+
{
|
|
6975
|
+
"kind": "method",
|
|
6976
|
+
"name": "#cancelFlash",
|
|
6977
|
+
"privacy": "private",
|
|
6978
|
+
"return": {
|
|
6979
|
+
"type": {
|
|
6980
|
+
"text": "void"
|
|
6981
|
+
}
|
|
6982
|
+
},
|
|
6983
|
+
"description": "Stops an in-flight title flash — opening or teardown takes over."
|
|
6984
|
+
},
|
|
6865
6985
|
{
|
|
6866
6986
|
"kind": "field",
|
|
6867
6987
|
"name": "#onDocPointerDown",
|
|
@@ -7077,6 +7197,15 @@
|
|
|
7077
7197
|
"description": "Whether the panel is dropped. Reflected. Managed by the parent\n`vf-menu-bar` when present, otherwise by the menu itself.",
|
|
7078
7198
|
"fieldName": "open"
|
|
7079
7199
|
},
|
|
7200
|
+
{
|
|
7201
|
+
"name": "shortcuts",
|
|
7202
|
+
"type": {
|
|
7203
|
+
"text": "boolean"
|
|
7204
|
+
},
|
|
7205
|
+
"default": "false",
|
|
7206
|
+
"description": "Makes the items' `shortcut`s live key equivalents: a matching keydown\nanywhere on the page activates the item — menu open or not — and a\nclosed menu answers by flashing its bar title, MenuKey's acknowledgment.\nOff by default because key equivalents are page-global and a page may\nhold several menus of which only one is *the* menu bar; on a bar, declare\nit there once for every menu in it. The full claim contract lives on\n`vf-menu-item.shortcut`.",
|
|
7207
|
+
"fieldName": "shortcuts"
|
|
7208
|
+
},
|
|
7080
7209
|
{
|
|
7081
7210
|
"name": "top",
|
|
7082
7211
|
"type": {
|
|
@@ -9966,7 +10095,7 @@
|
|
|
9966
10095
|
],
|
|
9967
10096
|
"slots": [
|
|
9968
10097
|
{
|
|
9969
|
-
"description": "The label, rendered to the right of the circle with a 6px gap.",
|
|
10098
|
+
"description": "The label, rendered to the right of the circle with a 6px gap. Left empty, the label and its gap collapse: the control is the bare 13×13 circle.",
|
|
9970
10099
|
"name": ""
|
|
9971
10100
|
}
|
|
9972
10101
|
],
|
|
@@ -10016,6 +10145,16 @@
|
|
|
10016
10145
|
"default": "false",
|
|
10017
10146
|
"description": "True while the containing `vf-radio-group` is disabled. Managed by the\ngroup — not intended to be set by consumers."
|
|
10018
10147
|
},
|
|
10148
|
+
{
|
|
10149
|
+
"kind": "field",
|
|
10150
|
+
"name": "_hasLabel",
|
|
10151
|
+
"type": {
|
|
10152
|
+
"text": "boolean"
|
|
10153
|
+
},
|
|
10154
|
+
"privacy": "private",
|
|
10155
|
+
"default": "false",
|
|
10156
|
+
"description": "Whether the slot holds non-whitespace content; gates the label row."
|
|
10157
|
+
},
|
|
10019
10158
|
{
|
|
10020
10159
|
"kind": "field",
|
|
10021
10160
|
"name": "internals",
|
|
@@ -10067,6 +10206,24 @@
|
|
|
10067
10206
|
"module": "src/toggle-control.ts"
|
|
10068
10207
|
}
|
|
10069
10208
|
},
|
|
10209
|
+
{
|
|
10210
|
+
"kind": "method",
|
|
10211
|
+
"name": "#onLabelSlotChange",
|
|
10212
|
+
"privacy": "private",
|
|
10213
|
+
"return": {
|
|
10214
|
+
"type": {
|
|
10215
|
+
"text": "void"
|
|
10216
|
+
}
|
|
10217
|
+
},
|
|
10218
|
+
"parameters": [
|
|
10219
|
+
{
|
|
10220
|
+
"name": "event",
|
|
10221
|
+
"type": {
|
|
10222
|
+
"text": "Event"
|
|
10223
|
+
}
|
|
10224
|
+
}
|
|
10225
|
+
]
|
|
10226
|
+
},
|
|
10070
10227
|
{
|
|
10071
10228
|
"kind": "method",
|
|
10072
10229
|
"name": "activate",
|
|
@@ -16677,6 +16834,16 @@
|
|
|
16677
16834
|
"description": "the slim `vf-window[variant=\"utility\"]` (windoid) bar — 11px interior + 1px bottom rule, traced from `Windows/utility-window.png`",
|
|
16678
16835
|
"name": "--vf-titlebar-height-utility",
|
|
16679
16836
|
"default": "12px"
|
|
16837
|
+
},
|
|
16838
|
+
{
|
|
16839
|
+
"description": "the status strip: 1px rule + 14px interior — the grow box's own height, so the two compose flush",
|
|
16840
|
+
"name": "--vf-status-bar-height",
|
|
16841
|
+
"default": "15px"
|
|
16842
|
+
},
|
|
16843
|
+
{
|
|
16844
|
+
"description": "the body face's native line, which the status strip's text rides (whole-pixel centered in the 14px interior)",
|
|
16845
|
+
"name": "--vf-line-height",
|
|
16846
|
+
"default": "12px"
|
|
16680
16847
|
}
|
|
16681
16848
|
],
|
|
16682
16849
|
"cssParts": [
|
|
@@ -16704,6 +16871,10 @@
|
|
|
16704
16871
|
"description": "The content area.",
|
|
16705
16872
|
"name": "body"
|
|
16706
16873
|
},
|
|
16874
|
+
{
|
|
16875
|
+
"description": "The bottom status strip (when the `status` slot is populated).",
|
|
16876
|
+
"name": "status-bar"
|
|
16877
|
+
},
|
|
16707
16878
|
{
|
|
16708
16879
|
"description": "The resize widget (bottom-right, when `resizable`).",
|
|
16709
16880
|
"name": "grow-box"
|
|
@@ -16717,6 +16888,10 @@
|
|
|
16717
16888
|
{
|
|
16718
16889
|
"description": "Default slot: window body content.",
|
|
16719
16890
|
"name": ""
|
|
16891
|
+
},
|
|
16892
|
+
{
|
|
16893
|
+
"description": "Optional status-bar content — the classic bottom readout strip (\"40px x 40px\"): a 1px rule over a 15px white band under the body, body-face text on its native line. Takes no space until populated; a `resizable` window's grow box sits flush in its right end.",
|
|
16894
|
+
"name": "status"
|
|
16720
16895
|
}
|
|
16721
16896
|
],
|
|
16722
16897
|
"members": [
|
|
@@ -16816,6 +16991,16 @@
|
|
|
16816
16991
|
"attribute": "scrollbars",
|
|
16817
16992
|
"reflects": true
|
|
16818
16993
|
},
|
|
16994
|
+
{
|
|
16995
|
+
"kind": "field",
|
|
16996
|
+
"name": "_hasStatus",
|
|
16997
|
+
"type": {
|
|
16998
|
+
"text": "boolean"
|
|
16999
|
+
},
|
|
17000
|
+
"privacy": "private",
|
|
17001
|
+
"default": "false",
|
|
17002
|
+
"description": "Whether the `status` slot has assigned content (drives the strip)."
|
|
17003
|
+
},
|
|
16819
17004
|
{
|
|
16820
17005
|
"kind": "field",
|
|
16821
17006
|
"name": "scale",
|
|
@@ -16942,6 +17127,25 @@
|
|
|
16942
17127
|
},
|
|
16943
17128
|
"description": "Both dimensions are required: a window is a fixed box in both axes, and\neach one left out falls back to a different wrong thing.\n\nAn inline `width`/`height` is the other honest way to declare it — the grow\nbox writes exactly that — so it counts. A stylesheet rule we cannot tell\napart from normal block layout, so it still warns."
|
|
16944
17129
|
},
|
|
17130
|
+
{
|
|
17131
|
+
"kind": "method",
|
|
17132
|
+
"name": "_onStatusSlotChange",
|
|
17133
|
+
"privacy": "private",
|
|
17134
|
+
"return": {
|
|
17135
|
+
"type": {
|
|
17136
|
+
"text": "void"
|
|
17137
|
+
}
|
|
17138
|
+
},
|
|
17139
|
+
"parameters": [
|
|
17140
|
+
{
|
|
17141
|
+
"name": "event",
|
|
17142
|
+
"type": {
|
|
17143
|
+
"text": "Event"
|
|
17144
|
+
}
|
|
17145
|
+
}
|
|
17146
|
+
],
|
|
17147
|
+
"description": "The `.empty` gate: the strip renders only while the slot is populated."
|
|
17148
|
+
},
|
|
16945
17149
|
{
|
|
16946
17150
|
"kind": "method",
|
|
16947
17151
|
"name": "_onCloseClick",
|
|
@@ -17078,6 +17282,10 @@
|
|
|
17078
17282
|
{
|
|
17079
17283
|
"description": "Zoom box clicked. Detail `{}`.",
|
|
17080
17284
|
"name": "vf-zoom"
|
|
17285
|
+
},
|
|
17286
|
+
{
|
|
17287
|
+
"description": "The grow box resized the window. Detail `{ width, height, commit }`, sizes in whole system px: one event per size the drag writes (`commit: false`), fired after the new box is applied so a handler that measures reads the resized layout, then a final `commit: true` as the gesture settles — only when it changed the size. Fired by the gesture alone: a programmatic `width`/`height` write fires nothing, the way a value set fires no `vf-change`.",
|
|
17288
|
+
"name": "vf-resize"
|
|
17081
17289
|
}
|
|
17082
17290
|
],
|
|
17083
17291
|
"attributes": [
|
|
@@ -12,6 +12,8 @@ declare const VfCheckbox_base: (new (...args: any[]) => import("../position.js")
|
|
|
12
12
|
* click and Space.
|
|
13
13
|
*
|
|
14
14
|
* @slot - The label, rendered to the right of the box with a 6px gap.
|
|
15
|
+
* Left empty, the label and its gap collapse: the control is the bare
|
|
16
|
+
* 13×13 box.
|
|
15
17
|
* @csspart box - The 13×13 checkbox square.
|
|
16
18
|
* @csspart label - The label wrapper around the slot.
|
|
17
19
|
* @fires vf-change - When toggled by user interaction. `detail: { checked: boolean }`.
|
|
@@ -22,6 +24,7 @@ declare const VfCheckbox_base: (new (...args: any[]) => import("../position.js")
|
|
|
22
24
|
* form delegation and framework bindings hear it.
|
|
23
25
|
*/
|
|
24
26
|
export declare class VfCheckbox extends VfCheckbox_base {
|
|
27
|
+
#private;
|
|
25
28
|
static styles: import("lit").CSSResult[];
|
|
26
29
|
/** Whether the checkbox is checked. */
|
|
27
30
|
checked: boolean;
|
|
@@ -29,6 +32,8 @@ export declare class VfCheckbox extends VfCheckbox_base {
|
|
|
29
32
|
name: string;
|
|
30
33
|
/** Value submitted with the form while checked. */
|
|
31
34
|
value: string;
|
|
35
|
+
/** Whether the slot holds non-whitespace content; gates the label row. */
|
|
36
|
+
private _hasLabel;
|
|
32
37
|
/** `required` on a checkbox means it must be checked, as on a native one. */
|
|
33
38
|
protected get valueMissing(): boolean;
|
|
34
39
|
/** The message a native `<input type="checkbox" required>` reports. */
|
|
@@ -10,10 +10,10 @@ import { CHECKBOX_X as l, glyphSvg as u } from "../glyphs.js";
|
|
|
10
10
|
import { VfFormControl as d } from "../form-control.js";
|
|
11
11
|
import { VfToggleControl as f } from "../toggle-control.js";
|
|
12
12
|
import { css as p, html as m } from "lit";
|
|
13
|
-
import { property as h } from "lit/decorators.js";
|
|
14
|
-
import { classMap as
|
|
13
|
+
import { property as h, state as g } from "lit/decorators.js";
|
|
14
|
+
import { classMap as _ } from "lit/directives/class-map.js";
|
|
15
15
|
//#region src/components/vf-checkbox.ts
|
|
16
|
-
var
|
|
16
|
+
var v = class extends n(f(d)) {
|
|
17
17
|
static {
|
|
18
18
|
this.styles = [
|
|
19
19
|
i,
|
|
@@ -80,7 +80,7 @@ var _ = class extends n(f(d)) {
|
|
|
80
80
|
return "Please check this box if you want to proceed.";
|
|
81
81
|
}
|
|
82
82
|
constructor() {
|
|
83
|
-
super(), this.checked = !1, this.name = "", this.value = "on", this.internals.role = "checkbox";
|
|
83
|
+
super(), this.checked = !1, this.name = "", this.value = "on", this._hasLabel = !1, this.internals.role = "checkbox";
|
|
84
84
|
}
|
|
85
85
|
connectedCallback() {
|
|
86
86
|
super.connectedCallback(), this.latchFormDefault(this.checked);
|
|
@@ -95,7 +95,7 @@ var _ = class extends n(f(d)) {
|
|
|
95
95
|
let e = this.isDisabled;
|
|
96
96
|
return m`
|
|
97
97
|
<span
|
|
98
|
-
class=${
|
|
98
|
+
class=${_({
|
|
99
99
|
box: !0,
|
|
100
100
|
dim: e,
|
|
101
101
|
"vf-snap": !0
|
|
@@ -105,15 +105,23 @@ var _ = class extends n(f(d)) {
|
|
|
105
105
|
>
|
|
106
106
|
${u(l, "check")}
|
|
107
107
|
</span>
|
|
108
|
-
<span
|
|
108
|
+
<span
|
|
109
|
+
class=${_({
|
|
109
110
|
label: !0,
|
|
110
111
|
dim: e,
|
|
112
|
+
empty: !this._hasLabel,
|
|
111
113
|
"vf-snap": !0
|
|
112
|
-
})}
|
|
113
|
-
|
|
114
|
+
})}
|
|
115
|
+
part="label"
|
|
116
|
+
>
|
|
117
|
+
<slot @slotchange=${this.#e}></slot>
|
|
114
118
|
</span>
|
|
115
119
|
`;
|
|
116
120
|
}
|
|
121
|
+
#e(e) {
|
|
122
|
+
let t = e.target;
|
|
123
|
+
this._hasLabel = t.assignedNodes({ flatten: !0 }).some((e) => e.nodeType === Node.ELEMENT_NODE || !!e.textContent?.trim());
|
|
124
|
+
}
|
|
117
125
|
updated(e) {
|
|
118
126
|
super.updated(e), (e.has("checked") || e.has("value") || this.disabledChanged(e)) && this.syncFormValue(this.checked ? this.value : null);
|
|
119
127
|
}
|
|
@@ -130,6 +138,6 @@ var _ = class extends n(f(d)) {
|
|
|
130
138
|
t([h({
|
|
131
139
|
type: Boolean,
|
|
132
140
|
reflect: !0
|
|
133
|
-
})],
|
|
141
|
+
})], v.prototype, "checked", void 0), t([h({ reflect: !0 })], v.prototype, "name", void 0), t([h()], v.prototype, "value", void 0), t([g()], v.prototype, "_hasLabel", void 0), v = t([e("vf-checkbox")], v);
|
|
134
142
|
//#endregion
|
|
135
|
-
export {
|
|
143
|
+
export { v as VfCheckbox };
|
|
@@ -71,10 +71,17 @@ declare const VfIcon_base: (new (...args: any[]) => import("../position.js").VfP
|
|
|
71
71
|
* precisely an image plus its mask — so inverting it flips ink and fill and
|
|
72
72
|
* leaves the surround alone, which is the whole of the classic selected
|
|
73
73
|
* appearance. `filter: invert(1)` reproduces it exactly for 1-bit art. Color
|
|
74
|
-
* art
|
|
75
|
-
* System 7
|
|
76
|
-
*
|
|
77
|
-
*
|
|
74
|
+
* art would invert into a photographic negative, which was never what
|
|
75
|
+
* System 7 showed: declare `color` and selection **darkens** the art
|
|
76
|
+
* instead — Icon Utilities' ttSelected transform, every color blended
|
|
77
|
+
* halfway toward black (`brightness(0.5)`), whites going gray, the
|
|
78
|
+
* transparent surround still untouched. The declaration is the consumer's
|
|
79
|
+
* because the component cannot tell color art from a mask by looking at a
|
|
80
|
+
* slotted image. It covers whatever the cell shows, the derived open ghost
|
|
81
|
+
* included, so a color icon has one selected treatment open or closed. The
|
|
82
|
+
* label plate inverts to the `--vf-highlight` pair either way, sharing one
|
|
83
|
+
* selection color with `vf-list-item` — the selected name was inverted
|
|
84
|
+
* whatever the art.
|
|
78
85
|
*
|
|
79
86
|
* ### Open is derived, not shipped
|
|
80
87
|
*
|
|
@@ -265,6 +272,14 @@ export declare class VfIcon extends VfIcon_base {
|
|
|
265
272
|
selectable: boolean;
|
|
266
273
|
/** Whether the icon is selected: the art inverts and the plate goes black. */
|
|
267
274
|
selected: boolean;
|
|
275
|
+
/**
|
|
276
|
+
* Declares the slotted art a **color icon**, so selection darkens it — the
|
|
277
|
+
* ttSelected transform, every color blended halfway toward black — instead
|
|
278
|
+
* of inverting it into a photographic negative (see the class doc). Yours
|
|
279
|
+
* to declare because the component cannot tell color art from a 1-bit mask
|
|
280
|
+
* by looking at a slotted image. The label plate inverts either way.
|
|
281
|
+
*/
|
|
282
|
+
color: boolean;
|
|
268
283
|
/**
|
|
269
284
|
* The icon's window is on screen, so the art paints as the Finder's open
|
|
270
285
|
* ghost — outline held, interior re-filled with the kit's loose dither —
|
|
@@ -20,7 +20,7 @@ var C = {
|
|
|
20
20
|
small: 16
|
|
21
21
|
}, w = 1, T = 8, E = (e, t) => t <= 0 ? Math.max(e, 0) : Math.min(Math.max(e, 0), t), D = class extends o(_) {
|
|
22
22
|
constructor(...e) {
|
|
23
|
-
super(...e), this.label = "", this.size = "large", this.selectable = !1, this.selected = !1, this.open = !1, this.movable = !1, this.editable = !1, this.maxlength = 31, this.scale = new t(this), this.gridSnap = new d(this), this.focusRule = new h(this), this._editing = !1, this._draft = "", this.#e = 0, this._ghost = null, this.#t = null, this.#n = this.attachInternals(), this.#i = "", this.#a = "", this.#o = 0, this.#s = -Infinity, this.#c = new f(this, () => [[
|
|
23
|
+
super(...e), this.label = "", this.size = "large", this.selectable = !1, this.selected = !1, this.color = !1, this.open = !1, this.movable = !1, this.editable = !1, this.maxlength = 31, this.scale = new t(this), this.gridSnap = new d(this), this.focusRule = new h(this), this._editing = !1, this._draft = "", this.#e = 0, this._ghost = null, this.#t = null, this.#n = this.attachInternals(), this.#i = "", this.#a = "", this.#o = 0, this.#s = -Infinity, this.#c = new f(this, () => [[
|
|
24
24
|
document,
|
|
25
25
|
"pointerdown",
|
|
26
26
|
this.#A,
|
|
@@ -128,6 +128,13 @@ var C = {
|
|
|
128
128
|
:host([selected]) .art {
|
|
129
129
|
filter: invert(1);
|
|
130
130
|
}
|
|
131
|
+
/* A color icon's selection darkens instead — ttSelected, colors
|
|
132
|
+
blended halfway toward black — since a photographic negative was
|
|
133
|
+
never what System 7 showed for color art (see the class doc). One
|
|
134
|
+
treatment for whatever the cell shows, the open ghost included. */
|
|
135
|
+
:host([selected][color]) .art {
|
|
136
|
+
filter: brightness(0.5);
|
|
137
|
+
}
|
|
131
138
|
/* The open ghost replaces the slotted art while there is one — the
|
|
132
139
|
slot stays in the tree (it is where the art loads and re-loads
|
|
133
140
|
from) but paints nothing. Gated on the class, not :host([open]):
|
|
@@ -496,6 +503,9 @@ i([x()], D.prototype, "label", void 0), i([x({ reflect: !0 })], D.prototype, "si
|
|
|
496
503
|
})], D.prototype, "selected", void 0), i([x({
|
|
497
504
|
type: Boolean,
|
|
498
505
|
reflect: !0
|
|
506
|
+
})], D.prototype, "color", void 0), i([x({
|
|
507
|
+
type: Boolean,
|
|
508
|
+
reflect: !0
|
|
499
509
|
})], D.prototype, "open", void 0), i([x({
|
|
500
510
|
type: Boolean,
|
|
501
511
|
reflect: !0
|
|
@@ -43,6 +43,14 @@ export declare class VfMenuBar extends VfMenuBar_base {
|
|
|
43
43
|
* mask was.
|
|
44
44
|
*/
|
|
45
45
|
rounded: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Makes every slotted menu's item `shortcut`s live key equivalents — one
|
|
48
|
+
* declaration for the whole bar, the way MenuKey() answered for every menu
|
|
49
|
+
* at once. See `vf-menu.shortcuts` (the per-menu grant) and
|
|
50
|
+
* `vf-menu-item.shortcut` for the claim contract. Off by default: key
|
|
51
|
+
* equivalents are page-global, and only *the* menu bar should own them.
|
|
52
|
+
*/
|
|
53
|
+
shortcuts: boolean;
|
|
46
54
|
private _menus;
|
|
47
55
|
connectedCallback(): void;
|
|
48
56
|
disconnectedCallback(): void;
|
|
@@ -13,7 +13,7 @@ import { property as h, queryAssignedElements as g } from "lit/decorators.js";
|
|
|
13
13
|
//#region src/components/vf-menu-bar.ts
|
|
14
14
|
var _ = class extends r(d) {
|
|
15
15
|
constructor(...e) {
|
|
16
|
-
super(...e), this.scale = new t(this), this.gridSnap = new a(this), this.label = "", this.rounded = !1, this.#e = null, this.#t = this.attachInternals(), this.#n = new l(), this.#r = null, this.#i = new o(this, () => [[
|
|
16
|
+
super(...e), this.scale = new t(this), this.gridSnap = new a(this), this.label = "", this.rounded = !1, this.shortcuts = !1, this.#e = null, this.#t = this.attachInternals(), this.#n = new l(), this.#r = null, this.#i = new o(this, () => [[
|
|
17
17
|
document,
|
|
18
18
|
"pointerdown",
|
|
19
19
|
this.#h,
|
|
@@ -228,7 +228,10 @@ var _ = class extends r(d) {
|
|
|
228
228
|
n([h()], _.prototype, "label", void 0), n([h({
|
|
229
229
|
type: Boolean,
|
|
230
230
|
reflect: !0
|
|
231
|
-
})], _.prototype, "rounded", void 0), n([
|
|
231
|
+
})], _.prototype, "rounded", void 0), n([h({
|
|
232
|
+
type: Boolean,
|
|
233
|
+
reflect: !0
|
|
234
|
+
})], _.prototype, "shortcuts", void 0), n([g({
|
|
232
235
|
selector: "vf-menu",
|
|
233
236
|
flatten: !0
|
|
234
237
|
})], _.prototype, "_menus", void 0), _ = n([e("vf-menu-bar")], _);
|