vintage-frames 0.1.1 → 0.2.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 +290 -38
- package/dist/components/vf-button.d.ts +1 -1
- package/dist/components/vf-container.d.ts +2 -2
- package/dist/components/vf-desktop.d.ts +1 -1
- package/dist/components/vf-fieldset.d.ts +1 -1
- package/dist/components/vf-fieldset.js +6 -1
- package/dist/components/vf-grid.d.ts +1 -1
- package/dist/components/vf-icon.d.ts +1 -1
- package/dist/components/vf-img.d.ts +1 -1
- package/dist/components/vf-label.d.ts +1 -1
- package/dist/components/vf-list-item.d.ts +9 -1
- package/dist/components/vf-list-item.js +15 -14
- package/dist/components/vf-list.d.ts +1 -1
- package/dist/components/vf-menu-bar.d.ts +1 -1
- package/dist/components/vf-menu-item.d.ts +10 -1
- package/dist/components/vf-menu-item.js +35 -34
- package/dist/components/vf-menu.d.ts +11 -2
- package/dist/components/vf-menu.js +33 -32
- package/dist/components/vf-option.d.ts +11 -1
- package/dist/components/vf-option.js +16 -15
- package/dist/components/vf-paragraph.d.ts +3 -3
- package/dist/components/vf-progress-bar.d.ts +1 -1
- package/dist/components/vf-scroll-area.d.ts +1 -1
- package/dist/components/vf-select.d.ts +1 -1
- package/dist/components/vf-separator.d.ts +1 -1
- package/dist/components/vf-slider.d.ts +1 -1
- package/dist/components/vf-stack.d.ts +27 -9
- package/dist/components/vf-stack.js +30 -8
- package/dist/components/vf-swatch.d.ts +1 -1
- package/dist/components/vf-window.d.ts +1 -1
- package/dist/cross-center.d.ts +76 -0
- package/dist/cross-center.js +69 -0
- package/dist/define.d.ts +2 -2
- package/dist/define.js +1 -1
- package/dist/grid-snap.d.ts +2 -24
- package/dist/grid-snap.js +7 -33
- package/dist/index.d.ts +5 -5
- package/dist/index.js +50 -50
- package/dist/position.d.ts +11 -2
- package/dist/styles/recipes/host.js +14 -1
- package/dist/styles/recipes/toggle.js +16 -0
- package/dist/text-control.d.ts +1 -1
- package/docs/SPEC.md +10 -9
- package/editor/vscode.html-custom-data.json +48 -8
- package/editor/web-types.json +92 -12
- package/package.json +1 -3
package/custom-elements.json
CHANGED
|
@@ -322,7 +322,7 @@
|
|
|
322
322
|
"privacy": "private",
|
|
323
323
|
"readonly": true,
|
|
324
324
|
"default": "new GridSnapController(this)",
|
|
325
|
-
"description": "Device-pixel grid snapping
|
|
325
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
326
326
|
},
|
|
327
327
|
{
|
|
328
328
|
"kind": "field",
|
|
@@ -1355,7 +1355,7 @@
|
|
|
1355
1355
|
"privacy": "private",
|
|
1356
1356
|
"readonly": true,
|
|
1357
1357
|
"default": "new GridSnapController(this)",
|
|
1358
|
-
"description": "Device-pixel grid snapping
|
|
1358
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts.",
|
|
1359
1359
|
"inheritedFrom": {
|
|
1360
1360
|
"name": "VfToggleControl",
|
|
1361
1361
|
"module": "src/toggle-control.ts"
|
|
@@ -1946,7 +1946,7 @@
|
|
|
1946
1946
|
"declarations": [
|
|
1947
1947
|
{
|
|
1948
1948
|
"kind": "class",
|
|
1949
|
-
"description": "`<vf-container>` — a box that is nothing but its declared size.\n\nThe kit's positioned-placement story (src/position.ts) ends with one line of\nCSS it can't write for you: children placed with `top`/`left` need a\npositioned ancestor, and while every kit container is one — a window body, a\nstack, a fieldset — a region of *your own* needs `position: relative` in a\nstylesheet. This component is that region as an element: declare `width` and\n`height` in whole system px, slot anything into it, place children against\nits origin. A DITL's enclosing rectangle, with nothing drawn in it.\n\n```html\n<vf-container width=\"200\" height=\"120\">\n <vf-icon label=\"System\" width=\"64\" top=\"8\" left=\"12\">…</vf-icon>\n <vf-icon label=\"Finder\" width=\"64\" top=\"8\" left=\"104\">…</vf-icon>\n</vf-container>\n```\n\nThe rectangle is the whole API — `width`/`height` here, plus the `top`/`left`\npair nearly every component takes (VfPositioned), so a container is\nitself placeable: inside a window, a desktop, or another container, at whole\nsystem px that keep its box on the device-pixel grid by construction.\n\n**It is not a `vf-stack`.** The stack is a flexbox with opinions — it\ndistributes children along an axis, compiles `fill-width`/`fill-height` into\nflex, defaults a cross-axis alignment. This box has no layout opinion at\nall: in-flow children get normal flow, placed children get a coordinate\nsystem, and that is the whole API. Reach for it when the stack's opinions\nare the thing in the way — a field of placed icons, a fixed stage for\nabsolutely-positioned art, a consumer's own composition that brings its\nlayout with it.\n\n**The declared size is the layout.** `width`/`height` land on the host as a\nlive `calc(var(--vf-scale, 1) * Npx)` (VfSized), so the box scales\nwith the display and sits on the device-pixel grid by construction. Content\nthat outgrows the box overflows it rather than growing it — the number is\nthe layout, and content that doesn't fit is a number to raise. Leave a\ndimension off and that axis shrink-wraps: `fit-content`, not the parent's\nwidth, because a layout box that silently claimed a size nobody declared\nwould be inventing one (the `vf-stack` rule, held here too).\n\n**It paints nothing and means nothing.** No border, background, role,\nkeyboard behavior or selection — what it holds decides what it is.\n\n**It holds its box on the device-pixel grid** — with a `GridSnapController`.\nA container's box is itself the consumer's coordinate system, including for\nnon-`vf` content that cannot correct itself, so the box is the thing to\nhold on the grid. The shadow box below owns the `position: relative` anchor\nand the `vf-snap` class together, so
|
|
1949
|
+
"description": "`<vf-container>` — a box that is nothing but its declared size.\n\nThe kit's positioned-placement story (src/position.ts) ends with one line of\nCSS it can't write for you: children placed with `top`/`left` need a\npositioned ancestor, and while every kit container is one — a window body, a\nstack, a fieldset — a region of *your own* needs `position: relative` in a\nstylesheet. This component is that region as an element: declare `width` and\n`height` in whole system px, slot anything into it, place children against\nits origin. A DITL's enclosing rectangle, with nothing drawn in it.\n\n```html\n<vf-container width=\"200\" height=\"120\">\n <vf-icon label=\"System\" width=\"64\" top=\"8\" left=\"12\">…</vf-icon>\n <vf-icon label=\"Finder\" width=\"64\" top=\"8\" left=\"104\">…</vf-icon>\n</vf-container>\n```\n\nThe rectangle is the whole API — `width`/`height` here, plus the `top`/`left`\npair nearly every component takes (VfPositioned), so a container is\nitself placeable: inside a window, a desktop, or another container, at whole\nsystem px that keep its box on the device-pixel grid by construction.\n\n**It is not a `vf-stack`.** The stack is a flexbox with opinions — it\ndistributes children along an axis, compiles `fill-width`/`fill-height` into\nflex, defaults a cross-axis alignment. This box has no layout opinion at\nall: in-flow children get normal flow, placed children get a coordinate\nsystem, and that is the whole API. Reach for it when the stack's opinions\nare the thing in the way — a field of placed icons, a fixed stage for\nabsolutely-positioned art, a consumer's own composition that brings its\nlayout with it.\n\n**The declared size is the layout.** `width`/`height` land on the host as a\nlive `calc(var(--vf-scale, 1) * Npx)` (VfSized), so the box scales\nwith the display and sits on the device-pixel grid by construction. Content\nthat outgrows the box overflows it rather than growing it — the number is\nthe layout, and content that doesn't fit is a number to raise. Leave a\ndimension off and that axis shrink-wraps: `fit-content`, not the parent's\nwidth, because a layout box that silently claimed a size nobody declared\nwould be inventing one (the `vf-stack` rule, held here too).\n\n**It paints nothing and means nothing.** No border, background, role,\nkeyboard behavior or selection — what it holds decides what it is.\n\n**It holds its box on the device-pixel grid** — with a `GridSnapController`.\nA container's box is itself the consumer's coordinate system, including for\nnon-`vf` content that cannot correct itself, so the box is the thing to\nhold on the grid. The shadow box below owns the `position: relative` anchor\nand the `vf-snap` class together, so the correction\nmoves the whole coordinate system — everything placed against it rides\nalong instead of being re-corrected child by child. (`vf-stack` shipped\nwithout a controller on the theory that slotted `vf-*` children correct\ntheir own origins; this component is where that theory's gap — consumer\ncontent — became visible, and the stack has since adopted the same\narrangement.)\n\nLike the stack it is **typographically transparent**: `vfBase`'s chrome\ndress is returned to `inherit` on the host, so wrapping content in a sized\nbox changes nothing about how that content reads.\n\n`fill-width` / `fill-height` work here the way they do everywhere: read\nabout the host (be as big as *its* parent allows), and compiled for slotted\nchildren — `width: 100%` in normal flow, so a child filling the cross of a\ndeclared box needs no stylesheet. A height fill needs a declared `height`\nto resolve against; with none it is inert, not an error.",
|
|
1950
1950
|
"name": "VfContainer",
|
|
1951
1951
|
"slots": [
|
|
1952
1952
|
{
|
|
@@ -1969,7 +1969,7 @@
|
|
|
1969
1969
|
"privacy": "private",
|
|
1970
1970
|
"readonly": true,
|
|
1971
1971
|
"default": "new GridSnapController(this)",
|
|
1972
|
-
"description": "Hold the box on the device-pixel grid
|
|
1972
|
+
"description": "Hold the box on the device-pixel grid — see the\nclass doc. The host is what gets measured; `.box` (vf-snap) is where the\ncorrection lands."
|
|
1973
1973
|
},
|
|
1974
1974
|
{
|
|
1975
1975
|
"kind": "field",
|
|
@@ -2220,7 +2220,7 @@
|
|
|
2220
2220
|
"privacy": "private",
|
|
2221
2221
|
"readonly": true,
|
|
2222
2222
|
"default": "new GridSnapController(this)",
|
|
2223
|
-
"description": "Device-pixel grid snapping
|
|
2223
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
2224
2224
|
},
|
|
2225
2225
|
{
|
|
2226
2226
|
"kind": "field",
|
|
@@ -3445,7 +3445,7 @@
|
|
|
3445
3445
|
"privacy": "private",
|
|
3446
3446
|
"readonly": true,
|
|
3447
3447
|
"default": "new GridSnapController(this)",
|
|
3448
|
-
"description": "Device-pixel grid snapping
|
|
3448
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
3449
3449
|
},
|
|
3450
3450
|
{
|
|
3451
3451
|
"kind": "field",
|
|
@@ -3697,7 +3697,7 @@
|
|
|
3697
3697
|
"privacy": "private",
|
|
3698
3698
|
"readonly": true,
|
|
3699
3699
|
"default": "new GridSnapController(this)",
|
|
3700
|
-
"description": "Device-pixel grid snapping
|
|
3700
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
3701
3701
|
},
|
|
3702
3702
|
{
|
|
3703
3703
|
"kind": "field",
|
|
@@ -4007,7 +4007,7 @@
|
|
|
4007
4007
|
"privacy": "private",
|
|
4008
4008
|
"readonly": true,
|
|
4009
4009
|
"default": "new GridSnapController(this)",
|
|
4010
|
-
"description": "Device-pixel grid snapping
|
|
4010
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
4011
4011
|
},
|
|
4012
4012
|
{
|
|
4013
4013
|
"kind": "field",
|
|
@@ -4045,7 +4045,7 @@
|
|
|
4045
4045
|
"text": "number"
|
|
4046
4046
|
},
|
|
4047
4047
|
"default": "0",
|
|
4048
|
-
"description": "The plate's width in whole, EVEN system px — 0 until the text is measured.\nSee #measurePlate; this is what keeps every name on the grid.\n\nDeliberately NOT `@state()`. The width can only be known by rendering the\nname and measuring it, so a reactive field would make every icon render\ntwice — once to measure, once to deliver one number back — and Lit's\nchange-in-update warning is exactly that round trip being spotted. It\nfeeds a single inline width and nothing else, so #measurePlate\nwrites it straight to the plate instead, the ownership
|
|
4048
|
+
"description": "The plate's width in whole, EVEN system px — 0 until the text is measured.\nSee #measurePlate; this is what keeps every name on the grid.\n\nDeliberately NOT `@state()`. The width can only be known by rendering the\nname and measuring it, so a reactive field would make every icon render\ntwice — once to measure, once to deliver one number back — and Lit's\nchange-in-update warning is exactly that round trip being spotted. It\nfeeds a single inline width and nothing else, so #measurePlate\nwrites it straight to the plate instead, the ownership the grid snapper\nhas over `--vf-snap-dx`/`-dy`. The template still reads it so a caption\nLit re-creates (one leaving `_editing`, say) is born at the settled width\nrather than flashing through the unmeasured one."
|
|
4049
4049
|
},
|
|
4050
4050
|
{
|
|
4051
4051
|
"kind": "field",
|
|
@@ -4626,7 +4626,7 @@
|
|
|
4626
4626
|
"privacy": "private",
|
|
4627
4627
|
"readonly": true,
|
|
4628
4628
|
"default": "new GridSnapController(this)",
|
|
4629
|
-
"description": "Device-pixel grid snapping
|
|
4629
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
4630
4630
|
},
|
|
4631
4631
|
{
|
|
4632
4632
|
"kind": "field",
|
|
@@ -4857,7 +4857,7 @@
|
|
|
4857
4857
|
"privacy": "private",
|
|
4858
4858
|
"readonly": true,
|
|
4859
4859
|
"default": "new GridSnapController(this)",
|
|
4860
|
-
"description": "Device-pixel grid snapping
|
|
4860
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
4861
4861
|
},
|
|
4862
4862
|
{
|
|
4863
4863
|
"kind": "field",
|
|
@@ -5134,7 +5134,7 @@
|
|
|
5134
5134
|
"name": "VfListItem",
|
|
5135
5135
|
"cssParts": [
|
|
5136
5136
|
{
|
|
5137
|
-
"description": "The text span beside the icon gutter (ellipsizes).",
|
|
5137
|
+
"description": "The text span beside the icon gutter (ellipsizes). Takes `top`/`left` like every other element ({@link VfPositioned}), for the consumer who wants a row somewhere other than a list. Inside its parent `<vf-list>` the rows stack in flow, so stating an origin lifts that row out of the stack and the ones below it close the gap — the placement doing what it says, but not how a list box is laid out.",
|
|
5138
5138
|
"name": "text"
|
|
5139
5139
|
}
|
|
5140
5140
|
],
|
|
@@ -5211,6 +5211,32 @@
|
|
|
5211
5211
|
"text": "string"
|
|
5212
5212
|
},
|
|
5213
5213
|
"default": "'option'"
|
|
5214
|
+
},
|
|
5215
|
+
{
|
|
5216
|
+
"kind": "field",
|
|
5217
|
+
"name": "top",
|
|
5218
|
+
"type": {
|
|
5219
|
+
"text": "number | null | undefined"
|
|
5220
|
+
},
|
|
5221
|
+
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
5222
|
+
"attribute": "top",
|
|
5223
|
+
"inheritedFrom": {
|
|
5224
|
+
"name": "VfPositioned",
|
|
5225
|
+
"module": "src/position.ts"
|
|
5226
|
+
}
|
|
5227
|
+
},
|
|
5228
|
+
{
|
|
5229
|
+
"kind": "field",
|
|
5230
|
+
"name": "left",
|
|
5231
|
+
"type": {
|
|
5232
|
+
"text": "number | null | undefined"
|
|
5233
|
+
},
|
|
5234
|
+
"description": "Offset from the left of the positioning parent, in whole system px.\nSee top.",
|
|
5235
|
+
"attribute": "left",
|
|
5236
|
+
"inheritedFrom": {
|
|
5237
|
+
"name": "VfPositioned",
|
|
5238
|
+
"module": "src/position.ts"
|
|
5239
|
+
}
|
|
5214
5240
|
}
|
|
5215
5241
|
],
|
|
5216
5242
|
"attributes": [
|
|
@@ -5240,6 +5266,36 @@
|
|
|
5240
5266
|
"default": "false",
|
|
5241
5267
|
"description": "Disables the row: dimmed text, not selectable or focusable.",
|
|
5242
5268
|
"fieldName": "disabled"
|
|
5269
|
+
},
|
|
5270
|
+
{
|
|
5271
|
+
"name": "top",
|
|
5272
|
+
"type": {
|
|
5273
|
+
"text": "number | null | undefined"
|
|
5274
|
+
},
|
|
5275
|
+
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
5276
|
+
"fieldName": "top",
|
|
5277
|
+
"inheritedFrom": {
|
|
5278
|
+
"name": "VfPositioned",
|
|
5279
|
+
"module": "src/position.ts"
|
|
5280
|
+
}
|
|
5281
|
+
},
|
|
5282
|
+
{
|
|
5283
|
+
"name": "left",
|
|
5284
|
+
"type": {
|
|
5285
|
+
"text": "number | null | undefined"
|
|
5286
|
+
},
|
|
5287
|
+
"description": "Offset from the left of the positioning parent, in whole system px.\nSee top.",
|
|
5288
|
+
"fieldName": "left",
|
|
5289
|
+
"inheritedFrom": {
|
|
5290
|
+
"name": "VfPositioned",
|
|
5291
|
+
"module": "src/position.ts"
|
|
5292
|
+
}
|
|
5293
|
+
}
|
|
5294
|
+
],
|
|
5295
|
+
"mixins": [
|
|
5296
|
+
{
|
|
5297
|
+
"name": "VfPositioned",
|
|
5298
|
+
"module": "/src/position.js"
|
|
5243
5299
|
}
|
|
5244
5300
|
],
|
|
5245
5301
|
"superclass": {
|
|
@@ -5318,7 +5374,7 @@
|
|
|
5318
5374
|
"privacy": "private",
|
|
5319
5375
|
"readonly": true,
|
|
5320
5376
|
"default": "new GridSnapController(this)",
|
|
5321
|
-
"description": "Device-pixel grid snapping
|
|
5377
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
5322
5378
|
},
|
|
5323
5379
|
{
|
|
5324
5380
|
"kind": "field",
|
|
@@ -5844,7 +5900,7 @@
|
|
|
5844
5900
|
"privacy": "private",
|
|
5845
5901
|
"readonly": true,
|
|
5846
5902
|
"default": "new GridSnapController(this)",
|
|
5847
|
-
"description": "Device-pixel grid snapping
|
|
5903
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
5848
5904
|
},
|
|
5849
5905
|
{
|
|
5850
5906
|
"kind": "field",
|
|
@@ -6198,7 +6254,7 @@
|
|
|
6198
6254
|
"declarations": [
|
|
6199
6255
|
{
|
|
6200
6256
|
"kind": "class",
|
|
6201
|
-
"description": "`<vf-menu-item>` — a single command inside a `<vf-menu>` panel.\n\nRenders the classic System 7 menu row: optional ✓ check in the\n`--vf-select-gutter` left column (16px, shared with vf-select/vf-option),\nlabel, and the keyboard shortcut left-aligned in a right-anchored column,\nso every ⌘ lands at the same x. On activation the item performs the classic\n3-blink inversion (~250ms), then dispatches `vf-menu-select` and asks its\nancestors to close the menu.",
|
|
6257
|
+
"description": "`<vf-menu-item>` — a single command inside a `<vf-menu>` panel.\n\nRenders the classic System 7 menu row: optional ✓ check in the\n`--vf-select-gutter` left column (16px, shared with vf-select/vf-option),\nlabel, and the keyboard shortcut left-aligned in a right-anchored column,\nso every ⌘ lands at the same x. On activation the item performs the classic\n3-blink inversion (~250ms), then dispatches `vf-menu-select` and asks its\nancestors to close the menu.\n\nTakes `top`/`left` like every other element (VfPositioned), for the\nconsumer who wants a row somewhere other than a pulldown. Inside its parent\n`<vf-menu>` the panel is as wide as its widest row and stacks them in flow,\nso stating an origin takes that row out of both: it no longer contributes to\nthe panel's width and the rows below close the gap. The placement doing what\nit says — but not how a pulldown is laid out.",
|
|
6202
6258
|
"name": "VfMenuItem",
|
|
6203
6259
|
"cssProperties": [
|
|
6204
6260
|
{
|
|
@@ -6475,6 +6531,32 @@
|
|
|
6475
6531
|
"text": "void"
|
|
6476
6532
|
}
|
|
6477
6533
|
}
|
|
6534
|
+
},
|
|
6535
|
+
{
|
|
6536
|
+
"kind": "field",
|
|
6537
|
+
"name": "top",
|
|
6538
|
+
"type": {
|
|
6539
|
+
"text": "number | null | undefined"
|
|
6540
|
+
},
|
|
6541
|
+
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
6542
|
+
"attribute": "top",
|
|
6543
|
+
"inheritedFrom": {
|
|
6544
|
+
"name": "VfPositioned",
|
|
6545
|
+
"module": "src/position.ts"
|
|
6546
|
+
}
|
|
6547
|
+
},
|
|
6548
|
+
{
|
|
6549
|
+
"kind": "field",
|
|
6550
|
+
"name": "left",
|
|
6551
|
+
"type": {
|
|
6552
|
+
"text": "number | null | undefined"
|
|
6553
|
+
},
|
|
6554
|
+
"description": "Offset from the left of the positioning parent, in whole system px.\nSee top.",
|
|
6555
|
+
"attribute": "left",
|
|
6556
|
+
"inheritedFrom": {
|
|
6557
|
+
"name": "VfPositioned",
|
|
6558
|
+
"module": "src/position.ts"
|
|
6559
|
+
}
|
|
6478
6560
|
}
|
|
6479
6561
|
],
|
|
6480
6562
|
"events": [
|
|
@@ -6536,6 +6618,36 @@
|
|
|
6536
6618
|
},
|
|
6537
6619
|
"description": "Value reported in the `vf-menu-select` event detail. Defaults to the item's\ntrimmed text content when unset.",
|
|
6538
6620
|
"fieldName": "value"
|
|
6621
|
+
},
|
|
6622
|
+
{
|
|
6623
|
+
"name": "top",
|
|
6624
|
+
"type": {
|
|
6625
|
+
"text": "number | null | undefined"
|
|
6626
|
+
},
|
|
6627
|
+
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
6628
|
+
"fieldName": "top",
|
|
6629
|
+
"inheritedFrom": {
|
|
6630
|
+
"name": "VfPositioned",
|
|
6631
|
+
"module": "src/position.ts"
|
|
6632
|
+
}
|
|
6633
|
+
},
|
|
6634
|
+
{
|
|
6635
|
+
"name": "left",
|
|
6636
|
+
"type": {
|
|
6637
|
+
"text": "number | null | undefined"
|
|
6638
|
+
},
|
|
6639
|
+
"description": "Offset from the left of the positioning parent, in whole system px.\nSee top.",
|
|
6640
|
+
"fieldName": "left",
|
|
6641
|
+
"inheritedFrom": {
|
|
6642
|
+
"name": "VfPositioned",
|
|
6643
|
+
"module": "src/position.ts"
|
|
6644
|
+
}
|
|
6645
|
+
}
|
|
6646
|
+
],
|
|
6647
|
+
"mixins": [
|
|
6648
|
+
{
|
|
6649
|
+
"name": "VfPositioned",
|
|
6650
|
+
"module": "/src/position.js"
|
|
6539
6651
|
}
|
|
6540
6652
|
],
|
|
6541
6653
|
"superclass": {
|
|
@@ -6571,7 +6683,7 @@
|
|
|
6571
6683
|
"declarations": [
|
|
6572
6684
|
{
|
|
6573
6685
|
"kind": "class",
|
|
6574
|
-
"description": "`<vf-menu>` — a pull-down menu: a bar label plus a dropped panel of\n`<vf-menu-item>` / `<vf-separator>` children.\n\nInside a `<vf-menu-bar>` the bar coordinates open state (only one menu open,\nhover-switching, outside-click/Escape dismissal) and owns the pointer\ngesture, which may travel between its menus. Used standalone, the menu\ntoggles itself on label click and manages its own dismissal, its own press\ngesture and item keyboard navigation (ArrowUp/ArrowDown, Home/End, and the\nshared first-letter type-ahead — src/type-ahead.ts) while open.\n\nPointer — the two styles `vf-select` supports, on the same terms (see\nsrc/menu-press.ts): the System 7 press-drag-release (press the title, slide\nonto a command, release over it) and a modern quick tap that leaves the menu\ndropped for a second click.",
|
|
6686
|
+
"description": "`<vf-menu>` — a pull-down menu: a bar label plus a dropped panel of\n`<vf-menu-item>` / `<vf-separator>` children.\n\nInside a `<vf-menu-bar>` the bar coordinates open state (only one menu open,\nhover-switching, outside-click/Escape dismissal) and owns the pointer\ngesture, which may travel between its menus. Used standalone, the menu\ntoggles itself on label click and manages its own dismissal, its own press\ngesture and item keyboard navigation (ArrowUp/ArrowDown, Home/End, and the\nshared first-letter type-ahead — src/type-ahead.ts) while open.\n\nPointer — the two styles `vf-select` supports, on the same terms (see\nsrc/menu-press.ts): the System 7 press-drag-release (press the title, slide\nonto a command, release over it) and a modern quick tap that leaves the menu\ndropped for a second click.\n\nTakes `top`/`left` like every other element (VfPositioned) — the\nnatural fit being a standalone menu, which is a free-standing menu button and\nplaces like any other control. The panel is anchored to the host's own box\n(`top: 100%`), so it follows a placed menu down without any further work.\nInside a `<vf-menu-bar>`, the bar lays its titles out in flow — placing one\nlifts it off the bar and the titles beside it close the gap.",
|
|
6575
6687
|
"name": "VfMenu",
|
|
6576
6688
|
"cssProperties": [
|
|
6577
6689
|
{
|
|
@@ -6619,7 +6731,7 @@
|
|
|
6619
6731
|
"privacy": "private",
|
|
6620
6732
|
"readonly": true,
|
|
6621
6733
|
"default": "new GridSnapController(this)",
|
|
6622
|
-
"description": "Device-pixel grid snapping
|
|
6734
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
6623
6735
|
},
|
|
6624
6736
|
{
|
|
6625
6737
|
"kind": "field",
|
|
@@ -6918,6 +7030,32 @@
|
|
|
6918
7030
|
}
|
|
6919
7031
|
},
|
|
6920
7032
|
"description": "Focuses the first enabled item once the panel is visible. The reflected\n`open` attribute (which un-hides the panel) only lands on the host in the\nnext Lit update, so focusing synchronously would silently no-op."
|
|
7033
|
+
},
|
|
7034
|
+
{
|
|
7035
|
+
"kind": "field",
|
|
7036
|
+
"name": "top",
|
|
7037
|
+
"type": {
|
|
7038
|
+
"text": "number | null | undefined"
|
|
7039
|
+
},
|
|
7040
|
+
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
7041
|
+
"attribute": "top",
|
|
7042
|
+
"inheritedFrom": {
|
|
7043
|
+
"name": "VfPositioned",
|
|
7044
|
+
"module": "src/position.ts"
|
|
7045
|
+
}
|
|
7046
|
+
},
|
|
7047
|
+
{
|
|
7048
|
+
"kind": "field",
|
|
7049
|
+
"name": "left",
|
|
7050
|
+
"type": {
|
|
7051
|
+
"text": "number | null | undefined"
|
|
7052
|
+
},
|
|
7053
|
+
"description": "Offset from the left of the positioning parent, in whole system px.\nSee top.",
|
|
7054
|
+
"attribute": "left",
|
|
7055
|
+
"inheritedFrom": {
|
|
7056
|
+
"name": "VfPositioned",
|
|
7057
|
+
"module": "src/position.ts"
|
|
7058
|
+
}
|
|
6921
7059
|
}
|
|
6922
7060
|
],
|
|
6923
7061
|
"attributes": [
|
|
@@ -6938,6 +7076,36 @@
|
|
|
6938
7076
|
"default": "false",
|
|
6939
7077
|
"description": "Whether the panel is dropped. Reflected. Managed by the parent\n`vf-menu-bar` when present, otherwise by the menu itself.",
|
|
6940
7078
|
"fieldName": "open"
|
|
7079
|
+
},
|
|
7080
|
+
{
|
|
7081
|
+
"name": "top",
|
|
7082
|
+
"type": {
|
|
7083
|
+
"text": "number | null | undefined"
|
|
7084
|
+
},
|
|
7085
|
+
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
7086
|
+
"fieldName": "top",
|
|
7087
|
+
"inheritedFrom": {
|
|
7088
|
+
"name": "VfPositioned",
|
|
7089
|
+
"module": "src/position.ts"
|
|
7090
|
+
}
|
|
7091
|
+
},
|
|
7092
|
+
{
|
|
7093
|
+
"name": "left",
|
|
7094
|
+
"type": {
|
|
7095
|
+
"text": "number | null | undefined"
|
|
7096
|
+
},
|
|
7097
|
+
"description": "Offset from the left of the positioning parent, in whole system px.\nSee top.",
|
|
7098
|
+
"fieldName": "left",
|
|
7099
|
+
"inheritedFrom": {
|
|
7100
|
+
"name": "VfPositioned",
|
|
7101
|
+
"module": "src/position.ts"
|
|
7102
|
+
}
|
|
7103
|
+
}
|
|
7104
|
+
],
|
|
7105
|
+
"mixins": [
|
|
7106
|
+
{
|
|
7107
|
+
"name": "VfPositioned",
|
|
7108
|
+
"module": "/src/position.js"
|
|
6941
7109
|
}
|
|
6942
7110
|
],
|
|
6943
7111
|
"superclass": {
|
|
@@ -7384,7 +7552,7 @@
|
|
|
7384
7552
|
"privacy": "protected",
|
|
7385
7553
|
"readonly": true,
|
|
7386
7554
|
"default": "new GridSnapController(this)",
|
|
7387
|
-
"description": "Device-pixel grid snapping
|
|
7555
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts.",
|
|
7388
7556
|
"inheritedFrom": {
|
|
7389
7557
|
"name": "VfTextControlBase",
|
|
7390
7558
|
"module": "src/text-control.ts"
|
|
@@ -8283,7 +8451,7 @@
|
|
|
8283
8451
|
"declarations": [
|
|
8284
8452
|
{
|
|
8285
8453
|
"kind": "class",
|
|
8286
|
-
"description": "`<vf-option>` — a single choice inside a `<vf-select>` popup menu.\n\nA light-DOM child of `<vf-select>` (slotted into the popup panel). Renders\nits slotted label at menu-item metrics (16px row — the pill's content height,\nso a selected option overlays the closed pill exactly; the left checkmark gutter is\n`--vf-select-gutter`, shared with the closed control's left inset so the value\ndoesn't shift on open). The parent select manages `selected` and the transient\n`active` highlight, and slots this element into its popup panel.\n\nThe host carries `role=\"option\"` with `aria-selected`/`aria-disabled
|
|
8454
|
+
"description": "`<vf-option>` — a single choice inside a `<vf-select>` popup menu.\n\nA light-DOM child of `<vf-select>` (slotted into the popup panel). Renders\nits slotted label at menu-item metrics (16px row — the pill's content height,\nso a selected option overlays the closed pill exactly; the left checkmark gutter is\n`--vf-select-gutter`, shared with the closed control's left inset so the value\ndoesn't shift on open). The parent select manages `selected` and the transient\n`active` highlight, and slots this element into its popup panel.\n\nThe host carries `role=\"option\"` with `aria-selected`/`aria-disabled`.\n\nTakes `top`/`left` like every other element (VfPositioned), for the\nconsumer who wants one somewhere other than a popup row. Inside its parent\n`<vf-select>` it is a row the panel measures and scrolls in flow, so stating\nan origin there takes it out of that measurement: the panel stops counting it\ntoward its own width and its scroll clamp, and the rows below close the gap.\nThat is the placement doing exactly what it says — not a bug — but it is not\nhow a popup is laid out.",
|
|
8287
8455
|
"name": "VfOption",
|
|
8288
8456
|
"cssProperties": [
|
|
8289
8457
|
{
|
|
@@ -8368,6 +8536,32 @@
|
|
|
8368
8536
|
"text": "string"
|
|
8369
8537
|
},
|
|
8370
8538
|
"default": "'option'"
|
|
8539
|
+
},
|
|
8540
|
+
{
|
|
8541
|
+
"kind": "field",
|
|
8542
|
+
"name": "top",
|
|
8543
|
+
"type": {
|
|
8544
|
+
"text": "number | null | undefined"
|
|
8545
|
+
},
|
|
8546
|
+
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
8547
|
+
"attribute": "top",
|
|
8548
|
+
"inheritedFrom": {
|
|
8549
|
+
"name": "VfPositioned",
|
|
8550
|
+
"module": "src/position.ts"
|
|
8551
|
+
}
|
|
8552
|
+
},
|
|
8553
|
+
{
|
|
8554
|
+
"kind": "field",
|
|
8555
|
+
"name": "left",
|
|
8556
|
+
"type": {
|
|
8557
|
+
"text": "number | null | undefined"
|
|
8558
|
+
},
|
|
8559
|
+
"description": "Offset from the left of the positioning parent, in whole system px.\nSee top.",
|
|
8560
|
+
"attribute": "left",
|
|
8561
|
+
"inheritedFrom": {
|
|
8562
|
+
"name": "VfPositioned",
|
|
8563
|
+
"module": "src/position.ts"
|
|
8564
|
+
}
|
|
8371
8565
|
}
|
|
8372
8566
|
],
|
|
8373
8567
|
"attributes": [
|
|
@@ -8406,6 +8600,36 @@
|
|
|
8406
8600
|
"default": "false",
|
|
8407
8601
|
"description": "Transient highlight (hover / keyboard cursor) — full-row inversion.\nManaged by the parent `<vf-select>`; not part of the authoring API.",
|
|
8408
8602
|
"fieldName": "active"
|
|
8603
|
+
},
|
|
8604
|
+
{
|
|
8605
|
+
"name": "top",
|
|
8606
|
+
"type": {
|
|
8607
|
+
"text": "number | null | undefined"
|
|
8608
|
+
},
|
|
8609
|
+
"description": "Offset from the top of the positioning parent, in whole system px.\nSetting this (or `left`) absolutely positions the element within its\nparent; the coordinate left unset is 0. Remove both to return the\nelement to normal flow.",
|
|
8610
|
+
"fieldName": "top",
|
|
8611
|
+
"inheritedFrom": {
|
|
8612
|
+
"name": "VfPositioned",
|
|
8613
|
+
"module": "src/position.ts"
|
|
8614
|
+
}
|
|
8615
|
+
},
|
|
8616
|
+
{
|
|
8617
|
+
"name": "left",
|
|
8618
|
+
"type": {
|
|
8619
|
+
"text": "number | null | undefined"
|
|
8620
|
+
},
|
|
8621
|
+
"description": "Offset from the left of the positioning parent, in whole system px.\nSee top.",
|
|
8622
|
+
"fieldName": "left",
|
|
8623
|
+
"inheritedFrom": {
|
|
8624
|
+
"name": "VfPositioned",
|
|
8625
|
+
"module": "src/position.ts"
|
|
8626
|
+
}
|
|
8627
|
+
}
|
|
8628
|
+
],
|
|
8629
|
+
"mixins": [
|
|
8630
|
+
{
|
|
8631
|
+
"name": "VfPositioned",
|
|
8632
|
+
"module": "/src/position.js"
|
|
8409
8633
|
}
|
|
8410
8634
|
],
|
|
8411
8635
|
"superclass": {
|
|
@@ -8441,7 +8665,7 @@
|
|
|
8441
8665
|
"declarations": [
|
|
8442
8666
|
{
|
|
8443
8667
|
"kind": "class",
|
|
8444
|
-
"description": "`<vf-paragraph>` — a paragraph of copy on the kit's body face and grid.\n\nThe installer's welcome text, a dialog's explanation, an article's prose:\nanything a page would otherwise set with a `<p>` and hope the leading landed\nsomewhere sensible. What it adds over that `<p>`:\n\n- the **Geneva body face** by default (`face=\"display\"` switches to\n the Chicago-style chrome face);\n- a **whole-system-pixel line box at the face's native pitch** —\n `--vf-paragraph-line-height`: 12px for the body face (Geneva 9's own\n strike line) and 16px under `face=\"display\"` (Chicago 12's — ascent 12 +\n descent 3 + leading 1, the pitch a real dialog wrapped its copy on).\n Whole pixels are the point of the component: line boxes are the single\n biggest source of off-grid layout, because a ratio resolves to whatever\n it resolves to (`1.65 × 17px = 28.05px`) and every line of prose nudges\n everything after it further off the device-pixel grid, smearing 1-bit\n borders and bitmap glyph stems (docs/SIZING.md rule 2). A\n whole-pixel line box accumulates whole offsets;\n- its own GridSnapController, so it holds its own origin
|
|
8668
|
+
"description": "`<vf-paragraph>` — a paragraph of copy on the kit's body face and grid.\n\nThe installer's welcome text, a dialog's explanation, an article's prose:\nanything a page would otherwise set with a `<p>` and hope the leading landed\nsomewhere sensible. What it adds over that `<p>`:\n\n- the **Geneva body face** by default (`face=\"display\"` switches to\n the Chicago-style chrome face);\n- a **whole-system-pixel line box at the face's native pitch** —\n `--vf-paragraph-line-height`: 12px for the body face (Geneva 9's own\n strike line) and 16px under `face=\"display\"` (Chicago 12's — ascent 12 +\n descent 3 + leading 1, the pitch a real dialog wrapped its copy on).\n Whole pixels are the point of the component: line boxes are the single\n biggest source of off-grid layout, because a ratio resolves to whatever\n it resolves to (`1.65 × 17px = 28.05px`) and every line of prose nudges\n everything after it further off the device-pixel grid, smearing 1-bit\n borders and bitmap glyph stems (docs/SIZING.md rule 2). A\n whole-pixel line box accumulates whole offsets;\n- its own GridSnapController, so it holds its own origin\n wherever the page puts it;\n- a **declared box** when the layout wants one — `width`/`height` in whole\n system px (VfSized). In flow a paragraph takes its container's\n width, which is usually right; a *placed* one (`top`/`left`) shrink-wraps\n its longest line instead — a fractional glyph-run width, wrapped wherever\n the parent's edge happens to fall — so a DITL-style layout states the\n measure the copy wraps to, whole and on the grid.\n\nThe shadow root renders a real `<p>`, so the copy keeps paragraph semantics\nfor assistive tech, and — unlike the kit's chrome — the text is selectable.\nThere is no margin: per SPEC §2 a component adds nothing outside its own box,\nso paragraph spacing is the page's (a `gap` on the column, or a margin on the\nhost — kept a whole number of pixels, like everything else in the contract).",
|
|
8445
8669
|
"name": "VfParagraph",
|
|
8446
8670
|
"cssProperties": [
|
|
8447
8671
|
{
|
|
@@ -8484,7 +8708,7 @@
|
|
|
8484
8708
|
"privacy": "private",
|
|
8485
8709
|
"readonly": true,
|
|
8486
8710
|
"default": "new GridSnapController(this)",
|
|
8487
|
-
"description": "Device-pixel grid snapping
|
|
8711
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
8488
8712
|
},
|
|
8489
8713
|
{
|
|
8490
8714
|
"kind": "field",
|
|
@@ -8712,7 +8936,7 @@
|
|
|
8712
8936
|
"privacy": "private",
|
|
8713
8937
|
"readonly": true,
|
|
8714
8938
|
"default": "new GridSnapController(this)",
|
|
8715
|
-
"description": "Device-pixel grid snapping
|
|
8939
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
8716
8940
|
},
|
|
8717
8941
|
{
|
|
8718
8942
|
"kind": "field",
|
|
@@ -9910,7 +10134,7 @@
|
|
|
9910
10134
|
"privacy": "private",
|
|
9911
10135
|
"readonly": true,
|
|
9912
10136
|
"default": "new GridSnapController(this)",
|
|
9913
|
-
"description": "Device-pixel grid snapping
|
|
10137
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts.",
|
|
9914
10138
|
"inheritedFrom": {
|
|
9915
10139
|
"name": "VfToggleControl",
|
|
9916
10140
|
"module": "src/toggle-control.ts"
|
|
@@ -10134,7 +10358,7 @@
|
|
|
10134
10358
|
"privacy": "private",
|
|
10135
10359
|
"readonly": true,
|
|
10136
10360
|
"default": "new GridSnapController(this)",
|
|
10137
|
-
"description": "Device-pixel grid snapping
|
|
10361
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
10138
10362
|
},
|
|
10139
10363
|
{
|
|
10140
10364
|
"kind": "field",
|
|
@@ -10534,7 +10758,7 @@
|
|
|
10534
10758
|
"privacy": "private",
|
|
10535
10759
|
"readonly": true,
|
|
10536
10760
|
"default": "new GridSnapController(this)",
|
|
10537
|
-
"description": "Device-pixel grid snapping
|
|
10761
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
10538
10762
|
},
|
|
10539
10763
|
{
|
|
10540
10764
|
"kind": "field",
|
|
@@ -12006,7 +12230,7 @@
|
|
|
12006
12230
|
"privacy": "private",
|
|
12007
12231
|
"readonly": true,
|
|
12008
12232
|
"default": "new GridSnapController(this)",
|
|
12009
|
-
"description": "Device-pixel grid snapping
|
|
12233
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
12010
12234
|
},
|
|
12011
12235
|
{
|
|
12012
12236
|
"kind": "field",
|
|
@@ -12243,7 +12467,7 @@
|
|
|
12243
12467
|
"privacy": "private",
|
|
12244
12468
|
"readonly": true,
|
|
12245
12469
|
"default": "new GridSnapController(this)",
|
|
12246
|
-
"description": "Device-pixel grid snapping
|
|
12470
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
12247
12471
|
},
|
|
12248
12472
|
{
|
|
12249
12473
|
"kind": "field",
|
|
@@ -13074,7 +13298,7 @@
|
|
|
13074
13298
|
"declarations": [
|
|
13075
13299
|
{
|
|
13076
13300
|
"kind": "class",
|
|
13077
|
-
"description": "`<vf-stack>` — arrange things inside a window, in system pixels.\n\nA window body is the one place the kit stopped short: every control inside it\nis authored in system px, but the *spaces between* them were the consumer's\nproblem, written by hand as `calc(var(--vf-scale, 1) * 12px)`. This is that\ncalculation, as a component — a flexbox whose `gap`, `pad`, `width` and\n`height` are declared in whole system px and converted internally:\n\n```html\n<vf-stack gap=\"12\"> <!-- a column -->\n <vf-stack fill-width direction=\"row\" gap=\"8\"> <!-- a labeled field -->\n <vf-label width=\"80\" for=\"name\">Name:</vf-label>\n <vf-text-field id=\"name\" fill-width></vf-text-field>\n </vf-stack>\n <vf-stack fill-width place=\"end\"> <!-- an action row -->\n <vf-button-group>\n <vf-button>Cancel</vf-button>\n <vf-button variant=\"default\">Save</vf-button>\n </vf-button-group>\n </vf-stack>\n</vf-stack>\n```\n\n**Why this can't just be page CSS.** Scaling is default-on and *per\ncomponent*: `ScaleController` sets `--vf-scale` on the component's own host,\nnot on the document. So `var(--vf-scale, 1)` in a consumer's stylesheet\nresolves only where the rule's element happens to sit inside a `vf-*`\nancestor and inherit it — true inside a window body, false for a plain\n`<div>` holding two buttons on an ordinary page, where the fallback `1` wins\nand the gap renders at 8px around 3×-sized buttons with no warning. A page\nthat hasn't called `applyScale()` has no way to write \"8 system px\" at all.\nA component always can, because it *is* the scope — which is also why this\none carries a ScaleController of its own: without it a lone stack\nwould resolve its own gap against that same fallback while its children each\nself-scaled around it.\n\n**Whole system px is the only expressible value**, so the gap half of the\nlayout contract (docs/SIZING.md rule 2) stops being a rule to remember. Declaring\n`width`/`height` covers the size half of rule 3 as well.\n\n**The geometry is governed by the content.** A column is as wide as its\nwidest child and a row as tall as its tallest; children keep the size they\ndrew themselves at (`flex: 0 0 auto` — no growing, no shrinking). System 7\nboxes are the size they are: a push button is as wide as its label, a popup\nmenu hugs its widest option, and a window is a fixed box whose overflow is\nclipped at the frame, not a layout that squeezes its controls to fit. The\nstack distributes; it does not resize. That is why the box shrink-wraps\n(`fit-content`) rather than claiming its parent's whole width — a layout box\nthat did would be inventing a size nobody declared.\n\n**`fill-width` / `fill-height` are how a child asks for more**, as bare\nattributes on consumer DOM the way `nosnap` opts an element out of snapping:\n\n```html\n<vf-text-field fill-width></vf-text-field>\n```\n\nEach names the *outcome*, not the axis, so the markup means the same thing\nwherever it lands; the stack does the flexbox translation, which is the whole\nreason to have a component. One rule to learn, about geometry rather than\nvocabulary: **the cross axis always has a size, the main axis only has slack\nif you declared one.** So `fill-width` always works in a column (the width is\nthe widest child's) and needs a declared `width` in a row; `fill-height` is\nexactly the other way round. A fill with nothing to take is inert, not an\nerror. Two children filling along the main axis end up *equal* — the zeroed\nflex basis is what lets them divide the slack rather than keep their natural\nsizes — and a child that declares its own size shouldn't also ask to fill it.\n\nA stack reads the same two attributes about *itself*, for the parents that\naren't stacks: a window body, a fieldset, a scroll well, a grid cell. That is\nwhere a panel's width enters the tree, and from there `fill-width` hands it\ndown a level at a time.\n\n**It paints nothing and means nothing.** No border, no background, no role,\nno keyboard behavior — what it holds decides what it is, as with\nVfGrid.\n\n**It holds its box on the device-pixel grid** — the `vf-container`\narrangement, adopted here after first shipping without it. The original\nreasoning (\"no ink of its own, and slotted `vf-*` children correct their own\norigins\") accounted only for kit children: a stack is a positioned ancestor\nand a layout box for *anything*, and consumer content inside it — a div, an\n`<img>`, a run of text — has no controller of its own. So the flex\ncontainer, the placed-child anchor and the `vf-snap` class live on one\nshadow box, and
|
|
13301
|
+
"description": "`<vf-stack>` — arrange things inside a window, in system pixels.\n\nA window body is the one place the kit stopped short: every control inside it\nis authored in system px, but the *spaces between* them were the consumer's\nproblem, written by hand as `calc(var(--vf-scale, 1) * 12px)`. This is that\ncalculation, as a component — a flexbox whose `gap`, `pad`, `width` and\n`height` are declared in whole system px and converted internally:\n\n```html\n<vf-stack gap=\"12\"> <!-- a column -->\n <vf-stack fill-width direction=\"row\" gap=\"8\"> <!-- a labeled field -->\n <vf-label width=\"80\" for=\"name\">Name:</vf-label>\n <vf-text-field id=\"name\" fill-width></vf-text-field>\n </vf-stack>\n <vf-stack fill-width place=\"end\"> <!-- an action row -->\n <vf-button-group>\n <vf-button>Cancel</vf-button>\n <vf-button variant=\"default\">Save</vf-button>\n </vf-button-group>\n </vf-stack>\n</vf-stack>\n```\n\n**Why this can't just be page CSS.** Scaling is default-on and *per\ncomponent*: `ScaleController` sets `--vf-scale` on the component's own host,\nnot on the document. So `var(--vf-scale, 1)` in a consumer's stylesheet\nresolves only where the rule's element happens to sit inside a `vf-*`\nancestor and inherit it — true inside a window body, false for a plain\n`<div>` holding two buttons on an ordinary page, where the fallback `1` wins\nand the gap renders at 8px around 3×-sized buttons with no warning. A page\nthat hasn't called `applyScale()` has no way to write \"8 system px\" at all.\nA component always can, because it *is* the scope — which is also why this\none carries a ScaleController of its own: without it a lone stack\nwould resolve its own gap against that same fallback while its children each\nself-scaled around it.\n\n**Whole system px is the only expressible value**, so the gap half of the\nlayout contract (docs/SIZING.md rule 2) stops being a rule to remember. Declaring\n`width`/`height` covers the size half of rule 3 as well.\n\n**The geometry is governed by the content.** A column is as wide as its\nwidest child and a row as tall as its tallest; children keep the size they\ndrew themselves at (`flex: 0 0 auto` — no growing, no shrinking). System 7\nboxes are the size they are: a push button is as wide as its label, a popup\nmenu hugs its widest option, and a window is a fixed box whose overflow is\nclipped at the frame, not a layout that squeezes its controls to fit. The\nstack distributes; it does not resize. That is why the box shrink-wraps\n(`fit-content`) rather than claiming its parent's whole width — a layout box\nthat did would be inventing a size nobody declared.\n\n**`fill-width` / `fill-height` are how a child asks for more**, as bare\nattributes on consumer DOM the way `nosnap` opts an element out of snapping:\n\n```html\n<vf-text-field fill-width></vf-text-field>\n```\n\nEach names the *outcome*, not the axis, so the markup means the same thing\nwherever it lands; the stack does the flexbox translation, which is the whole\nreason to have a component. One rule to learn, about geometry rather than\nvocabulary: **the cross axis always has a size, the main axis only has slack\nif you declared one.** So `fill-width` always works in a column (the width is\nthe widest child's) and needs a declared `width` in a row; `fill-height` is\nexactly the other way round. A fill with nothing to take is inert, not an\nerror. Two children filling along the main axis end up *equal* — the zeroed\nflex basis is what lets them divide the slack rather than keep their natural\nsizes — and a child that declares its own size shouldn't also ask to fill it.\n\nA stack reads the same two attributes about *itself*, for the parents that\naren't stacks: a window body, a fieldset, a scroll well, a grid cell. That is\nwhere a panel's width enters the tree, and from there `fill-width` hands it\ndown a level at a time.\n\n**It paints nothing and means nothing.** No border, no background, no role,\nno keyboard behavior — what it holds decides what it is, as with\nVfGrid.\n\n**It holds its box on the device-pixel grid** — the `vf-container`\narrangement, adopted here after first shipping without it. The original\nreasoning (\"no ink of its own, and slotted `vf-*` children correct their own\norigins\") accounted only for kit children: a stack is a positioned ancestor\nand a layout box for *anything*, and consumer content inside it — a div, an\n`<img>`, a run of text — has no controller of its own. So the flex\ncontainer, the placed-child anchor and the `vf-snap` class live on one\nshadow box, and the correction moves the stack's\nwhole coordinate system; children (kit or not) ride it, and the sweep's\noutermost-first order means the kit children then find nothing left to\ncorrect. What this deliberately does not fix: a text-governed child width\nmid-row still shifts later siblings fractionally (their own controllers\ncover that).\n\n**Centering lands on whole system px as well** — halving an odd count of free\nsystem px gives a half, which no container can round in CSS. See\nCrossCenterController.\n\nIt is also the kit's one **typographically transparent** component: `vfBase`'s\nchrome face, ratio line box, color and non-selectability are all reset to\n`inherit` on the host. Wrapping content in a layout box must not change how\nthat content reads — inside a window it goes on inheriting the window's face\nexactly as before, and on a plain page it leaves the page's typography (and\nits whole-pixel line boxes) alone.\n\nWhat it deliberately does **not** do: equalize its children's widths. A row of\nbuttons still belongs in a `vf-button-group`, which sizes them all to the\nwidest and aligns their *faces* rather than the `variant=\"default\"` ring\nboxes a plain flex row would line up.",
|
|
13078
13302
|
"name": "VfStack",
|
|
13079
13303
|
"slots": [
|
|
13080
13304
|
{
|
|
@@ -13119,7 +13343,7 @@
|
|
|
13119
13343
|
"type": {
|
|
13120
13344
|
"text": "VfStackPlace | undefined"
|
|
13121
13345
|
},
|
|
13122
|
-
"description": "Where the children sit across the stack — `start`, `center` or `end`.\nUnset resolves per direction: `start` down a column, `center` across a row.\n\nNamed `place` rather than `align` for a reason worth keeping in the source:\n`align` is a legacy HTML presentation attribute, and Blink maps it to\n`text-align` on any element, so the cross-axis switch used to re-align every\nrun of copy inside the stack (see the `text-align` reset above).\n\
|
|
13346
|
+
"description": "Where the children sit across the stack — `start`, `center` or `end`.\nUnset resolves per direction: `start` down a column, `center` across a row.\n\nNamed `place` rather than `align` for a reason worth keeping in the source:\n`align` is a legacy HTML presentation attribute, and Blink maps it to\n`text-align` on any element, so the cross-axis switch used to re-align every\nrun of copy inside the stack (see the `text-align` reset above).\n\nCentering divides the free space in two, so an odd count of system px would\nland a child on a half — a 16px caption centered in a row set by the\n25-system-px `vf-number-field` sits at 4.5. CrossCenterController\nsteps that back onto whole system px, the exact half going toward the start\nthe way QuickDraw's `div 2` did; `place=\"start\"` is still the way to ask\nfor no centering at all.",
|
|
13123
13347
|
"attribute": "place",
|
|
13124
13348
|
"reflects": true
|
|
13125
13349
|
},
|
|
@@ -13137,7 +13361,7 @@
|
|
|
13137
13361
|
"privacy": "private",
|
|
13138
13362
|
"readonly": true,
|
|
13139
13363
|
"default": "new GridSnapController(this)",
|
|
13140
|
-
"description": "Hold the box on the device-pixel grid
|
|
13364
|
+
"description": "Hold the box on the device-pixel grid — see the\nclass doc for why the original no-controller decision was reversed. The\nhost is what gets measured; `.box` (vf-snap) is where the correction\nlands, taking the whole coordinate system with it."
|
|
13141
13365
|
},
|
|
13142
13366
|
{
|
|
13143
13367
|
"kind": "field",
|
|
@@ -13149,6 +13373,34 @@
|
|
|
13149
13373
|
"readonly": true,
|
|
13150
13374
|
"description": "The shadow flex box `gap`/`pad` write to; exists from the first render."
|
|
13151
13375
|
},
|
|
13376
|
+
{
|
|
13377
|
+
"kind": "field",
|
|
13378
|
+
"name": "childSlot",
|
|
13379
|
+
"type": {
|
|
13380
|
+
"text": "HTMLSlotElement"
|
|
13381
|
+
},
|
|
13382
|
+
"privacy": "private",
|
|
13383
|
+
"readonly": true,
|
|
13384
|
+
"description": "The slot the children arrive through. (`slot` itself is HTMLElement's.)"
|
|
13385
|
+
},
|
|
13386
|
+
{
|
|
13387
|
+
"kind": "field",
|
|
13388
|
+
"name": "crossCenter",
|
|
13389
|
+
"privacy": "private",
|
|
13390
|
+
"readonly": true,
|
|
13391
|
+
"default": "new CrossCenterController(this, () => ({ box: this.box, slot: this.childSlot, axis: this.centersChildren ? this.direction === 'row' ? 'y' : 'x' : null, }))",
|
|
13392
|
+
"description": "Keeps cross-axis centering on whole system px (src/cross-center.ts).\nA null axis is the inert state — no observers, nothing held — which is\nevery column that starts its children, i.e. the default."
|
|
13393
|
+
},
|
|
13394
|
+
{
|
|
13395
|
+
"kind": "field",
|
|
13396
|
+
"name": "centersChildren",
|
|
13397
|
+
"type": {
|
|
13398
|
+
"text": "boolean"
|
|
13399
|
+
},
|
|
13400
|
+
"privacy": "private",
|
|
13401
|
+
"description": "Mirrors the stylesheet's alignment selectors: a row centers unless `place`\nnames something else, a column only when it says `center`, and an\nunrecognized value lands on the direction's default in both places.",
|
|
13402
|
+
"readonly": true
|
|
13403
|
+
},
|
|
13152
13404
|
{
|
|
13153
13405
|
"kind": "field",
|
|
13154
13406
|
"name": "width",
|
|
@@ -13234,7 +13486,7 @@
|
|
|
13234
13486
|
"type": {
|
|
13235
13487
|
"text": "VfStackPlace | undefined"
|
|
13236
13488
|
},
|
|
13237
|
-
"description": "Where the children sit across the stack — `start`, `center` or `end`.\nUnset resolves per direction: `start` down a column, `center` across a row.\n\nNamed `place` rather than `align` for a reason worth keeping in the source:\n`align` is a legacy HTML presentation attribute, and Blink maps it to\n`text-align` on any element, so the cross-axis switch used to re-align every\nrun of copy inside the stack (see the `text-align` reset above).\n\
|
|
13489
|
+
"description": "Where the children sit across the stack — `start`, `center` or `end`.\nUnset resolves per direction: `start` down a column, `center` across a row.\n\nNamed `place` rather than `align` for a reason worth keeping in the source:\n`align` is a legacy HTML presentation attribute, and Blink maps it to\n`text-align` on any element, so the cross-axis switch used to re-align every\nrun of copy inside the stack (see the `text-align` reset above).\n\nCentering divides the free space in two, so an odd count of system px would\nland a child on a half — a 16px caption centered in a row set by the\n25-system-px `vf-number-field` sits at 4.5. CrossCenterController\nsteps that back onto whole system px, the exact half going toward the start\nthe way QuickDraw's `div 2` did; `place=\"start\"` is still the way to ask\nfor no centering at all.",
|
|
13238
13490
|
"fieldName": "place"
|
|
13239
13491
|
},
|
|
13240
13492
|
{
|
|
@@ -13436,7 +13688,7 @@
|
|
|
13436
13688
|
"privacy": "private",
|
|
13437
13689
|
"readonly": true,
|
|
13438
13690
|
"default": "new GridSnapController(this)",
|
|
13439
|
-
"description": "Device-pixel grid snapping
|
|
13691
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
13440
13692
|
},
|
|
13441
13693
|
{
|
|
13442
13694
|
"kind": "field",
|
|
@@ -14429,7 +14681,7 @@
|
|
|
14429
14681
|
"privacy": "protected",
|
|
14430
14682
|
"readonly": true,
|
|
14431
14683
|
"default": "new GridSnapController(this)",
|
|
14432
|
-
"description": "Device-pixel grid snapping
|
|
14684
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts.",
|
|
14433
14685
|
"inheritedFrom": {
|
|
14434
14686
|
"name": "VfTextControlBase",
|
|
14435
14687
|
"module": "src/text-control.ts"
|
|
@@ -15527,7 +15779,7 @@
|
|
|
15527
15779
|
"privacy": "protected",
|
|
15528
15780
|
"readonly": true,
|
|
15529
15781
|
"default": "new GridSnapController(this)",
|
|
15530
|
-
"description": "Device-pixel grid snapping
|
|
15782
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts.",
|
|
15531
15783
|
"inheritedFrom": {
|
|
15532
15784
|
"name": "VfTextControlBase",
|
|
15533
15785
|
"module": "src/text-control.ts"
|
|
@@ -16578,7 +16830,7 @@
|
|
|
16578
16830
|
"privacy": "private",
|
|
16579
16831
|
"readonly": true,
|
|
16580
16832
|
"default": "new GridSnapController(this)",
|
|
16581
|
-
"description": "Device-pixel grid snapping
|
|
16833
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
16582
16834
|
},
|
|
16583
16835
|
{
|
|
16584
16836
|
"kind": "field",
|
|
@@ -18058,7 +18310,7 @@
|
|
|
18058
18310
|
"privacy": "protected",
|
|
18059
18311
|
"readonly": true,
|
|
18060
18312
|
"default": "new GridSnapController(this)",
|
|
18061
|
-
"description": "Device-pixel grid snapping
|
|
18313
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
18062
18314
|
},
|
|
18063
18315
|
{
|
|
18064
18316
|
"kind": "field",
|
|
@@ -18950,7 +19202,7 @@
|
|
|
18950
19202
|
"privacy": "private",
|
|
18951
19203
|
"readonly": true,
|
|
18952
19204
|
"default": "new GridSnapController(this)",
|
|
18953
|
-
"description": "Device-pixel grid snapping
|
|
19205
|
+
"description": "Device-pixel grid snapping; see src/grid-snap.ts."
|
|
18954
19206
|
},
|
|
18955
19207
|
{
|
|
18956
19208
|
"kind": "field",
|
|
@@ -19487,7 +19739,7 @@
|
|
|
19487
19739
|
},
|
|
19488
19740
|
{
|
|
19489
19741
|
"kind": "mixin",
|
|
19490
|
-
"description": "Explicit placement — `top`/`left` in whole system px, on (
|
|
19742
|
+
"description": "Explicit placement — `top`/`left` in whole system px, on **every** component.\n\nNo exceptions, deliberately. These are web components, and a consumer may put\none wherever they like; the kit does not get to decide that a `vf-option` is\nonly ever a popup row. The rows a container normally owns (`vf-option`,\n`vf-menu-item`, `vf-list-item`) and a bar's `vf-menu` take the pair on the\nsame terms as anything else — and stating an origin on one *inside* its\nmanaging parent does take it out of that parent's flow layout, which is the\nplacement working, not failing. Each of those components documents what its\ncontainer stops doing for it. `vf-dialog` takes the pair in viewport\ncoordinates, the one difference the platform forces (see modal-dialog.ts).\n\nA DITL resource laid a dialog out as a list of items, each with a rectangle\nin the window's own coordinates; arranging controls by stating where they go\nis as native to System 7 as stacking them. This mixin is that mechanism:\ndeclaring `top` or `left` takes the element out of normal flow and\nabsolutely positions it within its parent, both coordinates in the art's own\nunit so the position scales with the display like every other metric. A\nwindow or dialog body can be laid out either way — a tree of `vf-stack`s, or\npositioned children — with no stylesheet in either case.\n\nMechanics, mirroring how `vf-stack` writes its declared size:\n\n- Setting either property writes `position: absolute` and both offsets onto\n the host's inline style as `calc(var(--vf-scale, 1) * Npx)` — live against\n the display, resolved at paint time. The coordinate left unset is 0.\n- `right`/`bottom` are released to `auto` and `margin` zeroed, so the stated\n offsets are the whole story — an auto-width box with both edges set would\n stretch rather than sit (the `vf-icon` seed logic, generalized).\n- Unsetting both returns the element to normal flow: every inline\n declaration this wrote is removed, and stylesheet values resume.\n\nThe anchor is CSS's own: the nearest positioned ancestor's padding box. The\nkit's containers are all deliberate anchors — a desktop's raster, a window's\ncontent region (the frame's inner edge, below the title bar — the 12px body\ninset governs flow content only, exactly the DITL convention), a dialog's\ncontent area, a stack's box, a fieldset's border box, a scroll area's\nscrolled plane. In a non-kit parent, give the parent `position: relative`,\nthe one line of CSS this feature can't write for you.\n\nThe writing rides a ReactiveController (`hostUpdated`) rather than\nan `updated()` override, for a lifecycle reason worth keeping in the source:\nthe mixin sits *under* each component class, and most components override\n`updated()` without calling `super.updated()` — Lit's base is a no-op, so\nnothing ever forced the call — which would silently shadow a mixin-level\noverride. A controller is invoked by ReactiveElement itself, after every\nupdate, no matter what the subclass does.\n\nA gesture writes **through these properties**: `vf-window`'s title-bar drag\nand `vf-icon`'s drag and arrow nudge hand their new origin to a\nPlacementController, which snaps it onto the placement lattice and\nsets `left`/`top`. A moved element is therefore placed exactly the way an\nauthored one is — a live `calc()` in the art's own unit — and stays where it\nwas dropped when the zoom or the display changes what a system px costs.\n\nIt did not always. Writing the resolved CSS px straight to the inline style\nfroze the coordinate in the wrong unit: `--vf-scale` moved under it at every\nzoom step and the same constant read back as a different number of system px,\nso moved windows and icons slid off the grid the rest of the kit stayed on\n(by `3z / round(3z)` — 10% at 110% zoom, where nothing else moves at all).\n\nSetting a property yourself is still the deliberate way to re-place a moved\nelement. The controller re-applies **only when the values changed**, so an\nunrelated update — a heading change, a desktop toggling `active` — never\nre-asserts a coordinate and costs nothing.",
|
|
19491
19743
|
"name": "VfPositioned",
|
|
19492
19744
|
"members": [
|
|
19493
19745
|
{
|