@fusion.dev/helix-docs 0.142.1 → 0.143.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.
@@ -19,10 +19,11 @@ accessible only when you also handle your parts.
19
19
  Every component implements the keyboard pattern for its role. You do not write
20
20
  any of it:
21
21
 
22
- - Arrow keys move within \`Tabs\`, \`Listbox\`, and \`Menu\`.
22
+ - Arrow keys move within \`Tabs\`, \`Listbox\`, \`Menu\`, \`Select\`, \`Combobox\`, and
23
+ the days of a date picker.
23
24
  - \`Escape\` closes an overlay.
24
25
  - \`Home\` and \`End\` go to the first and last item.
25
- - Typing jumps to a matching item.
26
+ - In \`Listbox\`, \`Select\`, \`Menu\`, and \`Tree\`, typing jumps to a matching item.
26
27
 
27
28
  ### Focus
28
29
 
@@ -107,11 +108,24 @@ and is read where it sits. Neither component is a variant of the other.
107
108
 
108
109
  \`aria-labelledby\` and \`aria-describedby\` inside a shadow root cannot point to an
109
110
  id in your document. The browser drops the reference silently and reports no
110
- error. For this reason, every control renders its own label, and connecting two
111
- components by id does not work. See [Forms and validation](./forms).
111
+ error. For this reason, every control renders its own label. See
112
+ [Forms and validation](./forms).
112
113
 
113
- A \`<label for>\` in your markup cannot reach into a shadow root either, so it
114
- does not name a Helix control. Use the control's own \`label\`.
114
+ **What you write on the host reaches the control inside it.** The form controls,
115
+ \`Button\`, and \`IconButton\` carry these down to the element a screen reader is on:
116
+
117
+ - \`aria-labelledby\` and \`aria-describedby\`, as element references, so the ids
118
+ you name in your document resolve.
119
+ - A \`<label for>\` that points at the host, or a \`<label>\` around it, when the
120
+ control has no \`label\` of its own.
121
+ - \`aria-expanded\`, \`aria-haspopup\`, \`aria-controls\`, \`aria-invalid\`, and
122
+ \`aria-pressed\`.
123
+ - \`aria-label\` on \`Button\`, \`IconButton\`, and \`Switch\`. A field renders its
124
+ \`aria-label\` as a hidden label.
125
+
126
+ A \`<label>\` around a control also reads the words inside the control, such as
127
+ the names of its buttons. Use \`<label for>\` or the control's own \`label\` to name
128
+ it with your words alone.
115
129
 
116
130
  When a relationship has to cross the boundary, the components use
117
131
  \`ElementInternals\` and element-reference properties. They are the only mechanism
@@ -335,8 +349,8 @@ customElements.define('acme-combobox', AcmeCombobox)
335
349
  \`\`\`
336
350
 
337
351
  That one line sets the prefix. The styled tier sets its prefix the same way, with
338
- \`static override tier = 'helix-'\` and nothing else. The static appears 116 times
339
- in the headless manifest, so you can find it there.
352
+ \`static override tier = 'helix-'\` and nothing else. Every element in the
353
+ headless manifest carries the static, so you can find it there.
340
354
 
341
355
  ## Register every component a component renders
342
356
 
@@ -404,24 +418,26 @@ Use \`visibility\` so the page does not reflow when the definitions arrive.
404
418
 
405
419
  ### Typings for your tags
406
420
 
407
- \`@fusion.dev/helix-cem\` is the generator we use for our own typings. It reads
408
- your package and writes \`jsx.d.ts\`, \`vue.d.ts\`, and \`svelte.d.ts\` for your tags,
409
- with every member your subclasses inherit from ours. Add a \`cem.config.ts\`
410
- beside your \`package.json\`:
411
-
412
- \`\`\`ts
413
- import type { HelixCemOptions } from '@fusion.dev/helix-cem'
421
+ Your typings come from a manifest of your package. \`helix manifest build\`, in
422
+ \`@fusion.dev/helix-cli\`, writes one that includes every member your subclasses
423
+ inherit from ours. Name each Helix package you extend and where its manifest is:
414
424
 
415
- export default {
416
- frameworkTypes: true,
417
- packageName: 'acme-system',
418
- tier: 'styled',
419
- } satisfies HelixCemOptions
425
+ \`\`\`sh
426
+ helix manifest build . --tier styled \\
427
+ --dependency @fusion.dev/helix=node_modules/@fusion.dev/helix/custom-elements.json \\
428
+ --dependency @fusion.dev/helix-headless=node_modules/@fusion.dev/helix-headless/custom-elements.json \\
429
+ --dependency @fusion.dev/helix-core=node_modules/@fusion.dev/helix-core/custom-elements.json \\
430
+ > custom-elements.json
420
431
  \`\`\`
421
432
 
422
- Then run \`bun --bun helix-cem\`. It finds the classes you extend through your
423
- \`dependencies\`. The typings for \`acme-combobox\` then include the hundred or so
424
- members it inherits, as well as the two you wrote.
433
+ Then run a typings generator over it. Our own typings start from
434
+ \`@wc-toolkit/jsx-types\` and \`@wc-toolkit/vuejs-types\`. The typings for
435
+ \`acme-combobox\` then include the hundred or so members it inherits, as well as
436
+ the two you wrote.
437
+
438
+ \`@fusion.dev/helix-cem\`, the step that runs those generators for our packages
439
+ and corrects what they write, is not published. It is build tooling for this
440
+ repository.
425
441
 
426
442
  ### The tag map
427
443
 
@@ -576,6 +592,32 @@ table should not be seen, hide it visually, and the data is still there:
576
592
  The table's caption becomes the chart's accessible name unless you set \`label\`.
577
593
  The caption usually has the right words already.
578
594
 
595
+ Each chart writes a short summary for screen readers, which starts with that
596
+ name. The drawing is hidden from screen readers, and the summary gives the one
597
+ reading a chart is usually read for:
598
+
599
+ - \`Bar Chart\`: each series' highest reading.
600
+ - \`Line Chart\`: each series' latest reading.
601
+ - \`Area Chart\`: the latest total and each part's share of it.
602
+ - \`Donut Chart\`: each slice's share of the whole.
603
+ - \`Scatter Chart\`: each series' number of points and how strongly the two
604
+ measures relate.
605
+
606
+ \`Heatmap\` is an image with that name. \`Sparkline\` takes a \`label\` of its own.
607
+
608
+ ## Tables that change
609
+
610
+ A chart follows its table. It redraws when you edit a cell, add a row, or
611
+ replace the table with a new one under the same id. It also draws a table that
612
+ arrives after the chart does, such as one a framework renders once its data
613
+ loads.
614
+
615
+ A blank cell, or one that does not hold a number, is a gap in its series. The
616
+ row keeps its place on the axis, a line breaks at the gap, a bar chart draws no
617
+ bar there, and a heatmap draws the cell with no tone. The readings after the gap
618
+ stay under their own labels, and the tooltip for that row still shows the
619
+ row's cells.
620
+
579
621
  ## Series colors
580
622
 
581
623
  Helix has twenty-four series color tokens, in order, from
@@ -804,8 +846,8 @@ title: Color
804
846
 
805
847
  # Color
806
848
 
807
- Seventy-four of the library's 185 tokens are colors, and they make up most of a
808
- theme. Each color token is named for its role. No token is named for how it
849
+ Colors are the largest group of the library's tokens, and they make up most of
850
+ a theme. Each color token is named for its role. No token is named for how it
809
851
  looks, because a name like \`--brand-blue-500\` becomes wrong as soon as you change
810
852
  the theme.
811
853
 
@@ -1066,11 +1108,18 @@ for a slot of the same name. Helix never renders both.
1066
1108
 
1067
1109
  \`\`\`html
1068
1110
  <!-- The property -->
1069
- <helix-tooltip content="Save"></helix-tooltip>
1111
+ <helix-tooltip
1112
+ content="Save"
1113
+ for="save"
1114
+ id="save-tip"
1115
+ ></helix-tooltip>
1070
1116
 
1071
1117
  <!-- The slot, which replaces it -->
1072
- <helix-tooltip>
1073
- <strong>Save</strong>, or press <helix-kbd>⌘S</helix-kbd>
1118
+ <helix-tooltip
1119
+ for="save"
1120
+ id="save-tip"
1121
+ >
1122
+ <span slot="content"><strong>Save</strong>, or press <helix-kbd>⌘S</helix-kbd></span>
1074
1123
  </helix-tooltip>
1075
1124
  \`\`\`
1076
1125
 
@@ -1084,8 +1133,9 @@ examples put the closing tag on the same line as the opening tag.
1084
1133
 
1085
1134
  ## Set a button's width with the layout
1086
1135
 
1087
- A button has no \`width\` or \`fill\` property, for the same reason it has no \`size\`
1088
- property. How wide a control is depends on the region it is in.
1136
+ A button has no \`fill\` property and no \`size\` property. How wide a control is
1137
+ depends on the region it is in. \`width="full"\` fills the row a button sits in,
1138
+ and the layout decides everything else.
1089
1139
 
1090
1140
  A button already stretches in a column flex or a grid, because a stretch-aligned
1091
1141
  parent stretches its children:
@@ -1163,8 +1213,8 @@ and then a second attribute to hide it is the same as having no visible label.
1163
1213
 
1164
1214
  \`Option\`, \`Listbox\`, and \`Select\` are three families so that the keyboard
1165
1215
  handling, the filtering, the multi-select rules, and the active-item tracking
1166
- are written once. \`Select\` renders a \`Listbox\` internally. A future combobox
1167
- will too, and so would a command palette.
1216
+ are written once. \`Select\` renders a \`Listbox\` internally, and so does \`Combobox\`. A command
1217
+ palette would too.
1168
1218
 
1169
1219
  For the same reason, we wrote \`DrilldownController\`. Since it was first written,
1170
1220
  \`Menu\` had held a page stack and derived its rows, and none of that code
@@ -1376,6 +1426,10 @@ against a dispatch, so every event you can listen for is documented.
1376
1426
  | \`helix-before-change\` | A value is about to change, cancelable |
1377
1427
  | \`helix-before-toggle\` | A checked state is about to flip, cancelable |
1378
1428
  | \`helix-before-open\`, \`helix-before-close\` | An open state is about to change, cancelable |
1429
+ | \`helix-before-activate\`, \`helix-activate\` | A set is about to make a different child current, cancelable, and then did |
1430
+ | \`helix-before-pin\`, \`helix-pin\` | A chat transcript is about to be pinned to the bottom or let go of it, cancelable, and then was |
1431
+ | \`helix-before-resize\`, \`helix-resized\` | A splitter's divider is about to settle, cancelable, and then did |
1432
+ | \`helix-before-collapse\`, \`helix-collapse\` | A splitter's pane is about to shut or reopen, cancelable, and then did |
1379
1433
  | \`helix-select\` | An item was chosen from a set |
1380
1434
  | \`helix-dismiss\` | A user asked for something to close |
1381
1435
  | \`helix-next\`, \`helix-previous\` | Movement through a sequence |
@@ -1392,12 +1446,36 @@ Every stateful component also sends native events once the change is applied:
1392
1446
 
1393
1447
  - \`input\` and \`change\` on a value control
1394
1448
  - \`toggle\` on anything that opens, carrying \`newState\` and \`oldState\` as
1395
- \`<details>\` does
1449
+ \`<details>\` does. It is a \`ToggleEvent\` in browsers that have one, and it is
1450
+ sent whether the change came from a reader or from assigning \`open\`
1396
1451
  - \`close\` on a dialog
1397
1452
  - \`load\` and \`error\` on an image
1398
1453
 
1399
1454
  Each component's page lists the events it dispatches, with the class and the
1400
- detail.
1455
+ detail. The table above lists the common ones.
1456
+
1457
+ ## Requests under a plain name
1458
+
1459
+ A few events with no \`before\` in their name are also cancelable requests. Each
1460
+ is sent before the change, and you refuse the change with \`preventDefault()\`:
1461
+
1462
+ - \`helix-navigate\` on Pagination, Data Table, and Date Picker
1463
+ - \`helix-sort\`, \`helix-filter\`, \`helix-select\`, and \`helix-reorder\` on Data Table
1464
+ - \`helix-select\` on Carousel
1465
+
1466
+ Each of these requests had its name before the library had a word for the
1467
+ notification, so the notification has its own name. It is sent after the
1468
+ change, is not cancelable, and carries the new state:
1469
+
1470
+ - \`helix-activate\` after the page moves on Pagination and Data Table, and after
1471
+ the slide moves on Carousel
1472
+ - \`helix-sorted\`, \`helix-filtered\`, \`helix-selected\`, and \`helix-reordered\` on
1473
+ Data Table
1474
+ - \`input\` and \`change\` together on Pagination Size, as a native \`<select>\`
1475
+ sends them
1476
+
1477
+ A request that is refused sends no notification. Date Picker's \`helix-navigate\`
1478
+ moves the month on show, and the month sends no notification.
1401
1479
 
1402
1480
  ## Events in a framework
1403
1481
 
@@ -1510,23 +1588,62 @@ participants:
1510
1588
  ></helix-input>
1511
1589
  \`\`\`
1512
1590
 
1513
- Submitting an empty form is blocked, and the browser points to the control.
1514
- \`checkValidity()\`, \`reportValidity()\`, and \`:invalid\` work as they do for native
1515
- controls.
1591
+ Submitting an empty form is blocked, and the browser moves focus to the control
1592
+ and shows its message there. Each control has the validity API of a native
1593
+ control:
1594
+
1595
+ - \`checkValidity()\` and \`reportValidity()\`
1596
+ - \`setCustomValidity(message)\`
1597
+ - \`validity\`, \`validationMessage\`, and \`willValidate\`
1598
+
1599
+ \`:invalid\` matches the control as it matches a native one.
1516
1600
 
1517
- \`feedback\` replaces the browser's message. When \`feedback\` is empty, the
1518
- browser shows its own message, which is localized and familiar. When you set it,
1519
- the control shows the message in the words your product uses:
1601
+ \`value-missing-message\` replaces the browser's message for a required control
1602
+ that is empty. When it is not set, the browser shows its own message, which is
1603
+ localized and familiar:
1520
1604
 
1521
1605
  \`\`\`html
1522
1606
  <helix-input
1523
- feedback="We need this to send your receipt."
1524
1607
  label="Email"
1525
1608
  name="email"
1526
1609
  required
1610
+ value-missing-message="We need this to send your receipt."
1527
1611
  ></helix-input>
1528
1612
  \`\`\`
1529
1613
 
1614
+ **\`feedback\` says what is wrong, and the form does not submit while it is
1615
+ set.** Use it for a verdict the browser cannot reach, such as one your server
1616
+ returned. The control shows the message under itself and is invalid until you
1617
+ clear \`feedback\`:
1618
+
1619
+ \`\`\`html
1620
+ <helix-input
1621
+ feedback="That name is taken."
1622
+ label="Username"
1623
+ name="username"
1624
+ ></helix-input>
1625
+ \`\`\`
1626
+
1627
+ \`setCustomValidity()\` blocks the form in the same way, and the control shows
1628
+ its message once the reader has edited the field.
1629
+
1630
+ ## Focus and Enter
1631
+
1632
+ \`focus()\` on a control moves focus to the element a reader would reach with
1633
+ Tab, and pressing a \`<label>\` that names the control does the same. In a group,
1634
+ that is the chosen radio, or the first one when nothing is chosen.
1635
+
1636
+ Pressing Enter in a single-line field submits its form, as Enter in a native
1637
+ text field does. These fields do it:
1638
+
1639
+ - \`Input\`, \`NumberInput\`, and \`PinInput\`
1640
+ - \`DateInput\`, \`TimeInput\`, and \`ColorInput\`
1641
+ - \`Combobox\`, while its list is closed
1642
+
1643
+ The form's first submit button is pressed, and a \`helix-button type="submit"\`
1644
+ counts as one, for a native field too. A form with no submit button is
1645
+ submitted when it has only one text field.
1646
+
1530
1647
  \`Radio.Group\` and \`Toggle.Group\` take part in the form for their members. Each
1531
1648
  group owns the \`name\`, the \`value\`, and the validity. A single radio is an
1532
1649
  answer, and the group is the control it answers. \`Checkbox.Group\` works the
@@ -1620,7 +1737,7 @@ Add the frame, with an element inside it for the renderer to draw in:
1620
1737
  Give the frame its notes and links, make the renderer, and connect the two:
1621
1738
 
1622
1739
  \`\`\`js
1623
- import '@fusion.dev/helix'
1740
+ import '@fusion.dev/helix/graph'
1624
1741
  import { connectGraph } from '@fusion.dev/helix-graph'
1625
1742
  import { sigmaDriver } from '@fusion.dev/helix-graph/sigma'
1626
1743
  import Graph from 'graphology'
@@ -1775,7 +1892,10 @@ is a button that shows or hides the group's notes, in the drawing and in the
1775
1892
  list:
1776
1893
 
1777
1894
  \`\`\`html
1778
- <helix-graph label="Company notes" legend>
1895
+ <helix-graph
1896
+ label="Company notes"
1897
+ legend
1898
+ >
1779
1899
  <div></div>
1780
1900
  </helix-graph>
1781
1901
  \`\`\`
@@ -1823,7 +1943,10 @@ and the frame brings it into view with its neighbors. Start with one selected
1823
1943
  with \`default-active\`:
1824
1944
 
1825
1945
  \`\`\`html
1826
- <helix-graph default-active="roadmap" label="Research notes">
1946
+ <helix-graph
1947
+ default-active="roadmap"
1948
+ label="Research notes"
1949
+ >
1827
1950
  <div></div>
1828
1951
  </helix-graph>
1829
1952
  \`\`\`
@@ -1835,7 +1958,11 @@ Set \`depth\` to show only the notes within that many links of the selected one,
1835
1958
  for a graph too large to read at once:
1836
1959
 
1837
1960
  \`\`\`html
1838
- <helix-graph default-active="roadmap" depth="2" label="Research notes">
1961
+ <helix-graph
1962
+ default-active="roadmap"
1963
+ depth="2"
1964
+ label="Research notes"
1965
+ >
1839
1966
  <div></div>
1840
1967
  </helix-graph>
1841
1968
  \`\`\`
@@ -1908,7 +2035,10 @@ finger moves it. A graph embedded in a page takes the wheel from a reader who
1908
2035
  is scrolling past it. Set \`gestures\` on the frame to share them:
1909
2036
 
1910
2037
  \`\`\`html
1911
- <helix-graph gestures="cooperative" label="Research notes">
2038
+ <helix-graph
2039
+ gestures="cooperative"
2040
+ label="Research notes"
2041
+ >
1912
2042
  <div></div>
1913
2043
  </helix-graph>
1914
2044
  \`\`\`
@@ -1929,7 +2059,11 @@ drawing takes all of it, as at the top of a page. A Notes button among the
1929
2059
  controls opens them over the drawing:
1930
2060
 
1931
2061
  \`\`\`html
1932
- <helix-graph gestures="cooperative" label="Research notes" no-panel>
2062
+ <helix-graph
2063
+ gestures="cooperative"
2064
+ label="Research notes"
2065
+ no-panel
2066
+ >
1933
2067
  <div></div>
1934
2068
  </helix-graph>
1935
2069
  \`\`\`
@@ -1998,7 +2132,8 @@ leaves removing it to your framework.
1998
2132
  minus keys zoom it. Set \`controls="pan zoom fullscreen"\` to add buttons that
1999
2133
  move it.
2000
2134
  - The list is a listbox, named by \`notes-label\`. Arrow keys, Home, End, Page
2001
- Up, and Page Down move through it, and Enter or Space selects a note.
2135
+ Up, and Page Down move through it, typing a letter moves to the next note
2136
+ whose name starts with it, and Enter or Space selects a note.
2002
2137
  - In the search field, Down moves into the list, and Escape empties the search.
2003
2138
  With \`no-panel\`, Escape on an empty search closes the list.
2004
2139
  - Screen readers read the selected note first, then how each other note links
@@ -2254,15 +2389,15 @@ Each file has its own export. If you bring your own reset or your own ramp,
2254
2389
  import the two files you want and skip \`helix.css\`.
2255
2390
 
2256
2391
  - **\`primitives.css\`** holds the raw ramp that the semantic layer is derived
2257
- from. The seven \`--helix-seed-*\` properties are read here. Your own code
2258
- should not name a primitive, and leaving the file out does not enforce that.
2259
- \`tokens.css\` refers to a primitive 297 times, so without \`primitives.css\`
2260
- every semantic token resolves to nothing. We measured a page without it:
2392
+ from. The \`--helix-seed-*\` properties are read here. Your own code should
2393
+ not name a primitive, and leaving the file out does not enforce that.
2394
+ \`tokens.css\` refers to the primitives throughout, so without
2395
+ \`primitives.css\` every semantic token resolves to nothing. We measured a page without it:
2261
2396
  \`--helix-color-background\` computes to \`rgba(0, 0, 0, 0)\`, and so does every
2262
2397
  other color. [Theming](theming.mdx) also depends on this file, because without
2263
2398
  it, setting \`--helix-seed-brand\` changes nothing.
2264
- - **\`tokens.css\`** declares the semantic layer: 185 custom properties in 15
2265
- categories, plus \`color-scheme: light dark\` on \`:root\`. The files below read
2399
+ - **\`tokens.css\`** declares the semantic layer, the custom properties grouped
2400
+ by category, plus \`color-scheme: light dark\` on \`:root\`. The files below read
2266
2401
  from it, and it reads from \`primitives.css\`.
2267
2402
  - **\`base.css\`** holds the element reset, the type scale on bare \`h1\` through
2268
2403
  \`h6\`, and the recipes for markup that Helix does not render. It reads tokens.
@@ -2277,25 +2412,23 @@ components. The order then stays visible in one place.
2277
2412
 
2278
2413
  ## Register the elements
2279
2414
 
2280
- \`\`\`ts
2281
- import '@fusion.dev/helix'
2282
- \`\`\`
2283
-
2284
- This import has a side effect: it calls \`customElements.define\` once for every
2285
- element. You can run it more than once. A second \`define\` for the same tag
2286
- throws an error and stops the rest of the module, so the helper behind the
2287
- import checks the registry first.
2288
-
2289
- To register only some elements, import them from subpaths:
2415
+ Import each family you use from its subpath:
2290
2416
 
2291
2417
  \`\`\`ts
2292
2418
  import '@fusion.dev/helix/button'
2293
2419
  import '@fusion.dev/helix/dialog'
2294
2420
  \`\`\`
2295
2421
 
2296
- Import from subpaths when you use a few components. The package has side
2297
- effects by design, so a bundler keeps everything you import. The whole-package
2298
- import registers every element, and a subpath registers only its family.
2422
+ Each import has a side effect: it calls \`customElements.define\` for the
2423
+ elements of that family, and for the families they render. You can run it more
2424
+ than once. A second \`define\` for the same tag throws an error and stops the rest
2425
+ of the module, so the helper behind the import checks the registry first.
2426
+
2427
+ The package has side effects by design, so a bundler keeps everything you
2428
+ import. \`import '@fusion.dev/helix'\` registers every element in the library,
2429
+ which is the whole library in your bundle. Use it for a prototype, and use
2430
+ subpaths in an app. [Metrics](./metrics) lists the size of each family and of
2431
+ the whole package.
2299
2432
 
2300
2433
  ## Check the installation
2301
2434
 
@@ -2502,12 +2635,12 @@ reason.
2502
2635
  bun add @fusion.dev/helix @fusion.dev/helix-styles
2503
2636
  \`\`\`
2504
2637
 
2505
- Add two imports at your app root, in this order. Then you can use the elements
2506
- anywhere:
2638
+ Import the stylesheet at your app root, then each family you use. Then you can
2639
+ use those elements anywhere:
2507
2640
 
2508
2641
  \`\`\`ts
2509
2642
  import '@fusion.dev/helix-styles/helix.css'
2510
- import '@fusion.dev/helix'
2643
+ import '@fusion.dev/helix/accordion'
2511
2644
  \`\`\`
2512
2645
 
2513
2646
  \`\`\`html
@@ -2635,8 +2768,8 @@ Six families format numbers or dates and take a \`locale\`:
2635
2768
 
2636
2769
  | | |
2637
2770
  |---|---|
2638
- | \`Date Input\`, \`Date Picker\` | Date formats and first day of week |
2639
- | \`Time Input\`, \`Time Picker\` | 12 or 24 hour, and separators |
2771
+ | \`Date Input\`, \`Date Picker\` | Date formats, and the first day of the week where \`first-day-of-week\` is not set |
2772
+ | \`Time Input\`, \`Time Picker\` | 12 or 24 hour, separators, and the AM and PM on the wheels |
2640
2773
  | \`Pagination\` | Grouped thousands in page numbers |
2641
2774
  | \`File Input\` | File sizes |
2642
2775
 
@@ -2651,6 +2784,15 @@ If you do not set \`locale\`, these controls use the browser's locale, which is
2651
2784
  usually correct. Set \`locale\` when your users choose your application's
2652
2785
  language separately from the language of their operating system.
2653
2786
 
2787
+ The first day of the week comes from \`Intl.Locale\`'s week information, which
2788
+ Firefox does not provide. There, and where you set no \`locale\`, the week starts
2789
+ on Sunday. Set \`first-day-of-week\` to choose the day yourself.
2790
+
2791
+ \`locale\` formats dates, times, and numbers. It does not translate the words a
2792
+ control speaks, such as "Previous month" on a calendar or "Hour" on a time
2793
+ wheel. Set those through their properties, such as \`previous-label\` and
2794
+ \`next-label\` on Date Picker and Date Input, and \`hour-label\` on Time Picker.
2795
+
2654
2796
  Formatting uses \`Intl\`, so Helix bundles no locale data, and you have nothing to
2655
2797
  keep up to date.
2656
2798
 
@@ -2680,8 +2822,13 @@ it reports:
2680
2822
  - \`bad-input-message\`
2681
2823
  - \`range-underflow-message\`
2682
2824
  - \`range-overflow-message\`
2825
+ - \`step-mismatch-message\`
2683
2826
  - \`too-short-message\`
2684
2827
 
2828
+ Date Picker, Date Input, Time Picker, and Time Input also take
2829
+ \`unavailable-message\`, for a date or time that \`disable-dates\`, \`disable-days\`,
2830
+ or \`disable-times\` rules out.
2831
+
2685
2832
  A message appears in the browser's own validation bubble and on the line under
2686
2833
  the field. \`feedback\` does not reach the bubble. If you do not set a message, a
2687
2834
  text field shows the browser's own message, which is already in your user's
@@ -2774,7 +2921,7 @@ Add the map frame, an element for MapLibre to draw in, and your places:
2774
2921
  Create the map with a style from your theme, then connect it to the frame:
2775
2922
 
2776
2923
  \`\`\`js
2777
- import '@fusion.dev/helix'
2924
+ import '@fusion.dev/helix/map'
2778
2925
  import 'maplibre-gl/dist/maplibre-gl.css'
2779
2926
  import { colorsReady, connectMap } from '@fusion.dev/helix-map'
2780
2927
  import { followTheme, mapLibreDriver, mapLibreStyle } from '@fusion.dev/helix-map/maplibre'
@@ -2899,7 +3046,11 @@ is the map's. Give the container a position, such as \`position: relative\`:
2899
3046
 
2900
3047
  \`\`\`html
2901
3048
  <section class="hero">
2902
- <helix-map fill credit-placement="bottom-end" label="Downtown Austin">
3049
+ <helix-map
3050
+ credit-placement="bottom-end"
3051
+ fill
3052
+ label="Downtown Austin"
3053
+ >
2903
3054
  <div id="map"></div>
2904
3055
  </helix-map>
2905
3056
  <div class="hero-words">
@@ -2973,7 +3124,10 @@ A map embedded in a page, such as a hero, takes the wheel from a reader who is
2973
3124
  scrolling past it. Set \`gestures\` on the frame to share them:
2974
3125
 
2975
3126
  \`\`\`html
2976
- <helix-map gestures="cooperative" label="Downtown Austin">
3127
+ <helix-map
3128
+ gestures="cooperative"
3129
+ label="Downtown Austin"
3130
+ >
2977
3131
  <div id="map"></div>
2978
3132
  </helix-map>
2979
3133
  \`\`\`
@@ -3225,7 +3379,10 @@ is a map type, which the frame's \`map-type\` attribute chooses:
3225
3379
  - \`satellite\`: the imagery alone, without the roads and names.
3226
3380
 
3227
3381
  With \`layers\` in the frame's \`controls\`, the layers menu opens with a card for
3228
- each map type, showing a picture of the map in it. Set \`max-zoom\` to the deepest
3382
+ each map type, showing a picture of the map in it. Choosing a card sends
3383
+ \`helix-before-change\` with the type's name, \`standard\`, \`hybrid\`, or
3384
+ \`satellite\`, and \`change\` once \`map-type\` holds it. Cancel the first to keep the
3385
+ current type, or listen for the second to store the choice. Set \`max-zoom\` to the deepest
3229
3386
  zoom your provider has tiles for, and the map enlarges those tiles when a user
3230
3387
  zooms in further.
3231
3388
 
@@ -3298,6 +3455,10 @@ tile is lit while its layer is shown. Pressing a tile sets its layer's \`hidden\
3298
3455
  attribute, and \`connectMap\` does not draw a hidden layer. Write \`hidden\` on a
3299
3456
  layer to start it turned off.
3300
3457
 
3458
+ Before it sets \`hidden\`, a tile sends \`helix-before-toggle\` from the layer, with
3459
+ \`checked\` true when the layer is to be shown. Store the choice from it, or
3460
+ cancel it to keep the layer as it is.
3461
+
3301
3462
  Give layers the same \`group\` to show them as one tile, such as a route and the
3302
3463
  dotted legs at its ends. The tile takes the name of the first layer in the
3303
3464
  group, and shows or hides every layer in it. Keep labels short, such as
@@ -3405,7 +3566,7 @@ on its own.
3405
3566
 
3406
3567
  | | Raw | Gzip | Brotli |
3407
3568
  |---|---|---|---|
3408
- | Lit and \`@fusion.dev/helix-core\` | 186,211 | 59,377 | 50,257 |
3569
+ | Lit and \`@fusion.dev/helix-core\` | 147,394 | 45,659 | 39,405 |
3409
3570
 
3410
3571
  ## Whole packages
3411
3572
 
@@ -3416,12 +3577,12 @@ either barrel. The per-component tables show what your page pays.
3416
3577
 
3417
3578
  | Package | Raw | Gzip | Brotli | |
3418
3579
  |---|---|---|---|---|
3419
- | \`@fusion.dev/helix-core\` | 185,764 | 59,007 | 50,046 | The element base class, mixins, decorators, and floating positioning. |
3420
- | \`@fusion.dev/helix-headless\` | 749,093 | 194,398 | 150,798 | Every headless family. The barrel entry includes all of them. |
3421
- | \`@fusion.dev/helix-icons\` | 55,565 | 17,727 | 14,864 | The whole glyph set. |
3580
+ | \`@fusion.dev/helix-core\` | 146,947 | 45,293 | 39,172 | The element base class, mixins, decorators, and floating positioning. |
3581
+ | \`@fusion.dev/helix-headless\` | 833,065 | 218,034 | 167,434 | Every headless family. The barrel entry includes all of them. |
3582
+ | \`@fusion.dev/helix-icons\` | 55,738 | 17,784 | 15,143 | The whole glyph set. |
3422
3583
  | \`@fusion.dev/helix-theme\` | 3,626 | 1,597 | 1,384 | The JavaScript that runs the derivation engine. Most sites run it at build time, and a theme switcher runs it in the browser. |
3423
3584
  | \`fusion_helix_theme_bg.wasm\` | 490,270 | 155,600 | 125,779 | The derivation engine itself, in WebAssembly. The entry above loads it when the engine runs. |
3424
- | \`@fusion.dev/helix\` | 1,296,493 | 303,276 | 221,718 | Every styled family. |
3585
+ | \`@fusion.dev/helix\` | 1,349,191 | 315,452 | 227,193 | Every styled family. |
3425
3586
  | \`lit\` | 15,394 | 6,118 | 5,460 | Lit itself, listed so you can subtract it from every row above. |
3426
3587
 
3427
3588
  ## Stylesheets
@@ -3442,61 +3603,63 @@ shows the whole cost of using the base layer on its own.
3442
3603
 
3443
3604
  ## What the numbers say
3444
3605
 
3445
- **Most of your first component is the shared runtime.** The median styled family is 21,977 bytes gzipped alone, and it adds 2,263 to a page that already has Helix. The shared runtime is 90 percent of the first component, and the component itself is 10 percent. Ten typical components cost the first number once, plus nine of the added number. The two columns in the tables below let you work that out for your own components.
3606
+ **Most of your first component is the shared runtime.** The median styled family is 16,274 bytes gzipped alone, and it adds 2,322 to a page that already has Helix. The shared runtime is 86 percent of the first component, and the component itself is 14 percent. Ten typical components cost the first number once, plus nine of the added number. The two columns in the tables below let you work that out for your own components.
3446
3607
 
3447
- Across the 104 styled components, the smallest is \`code\` at 10,492 bytes gzipped alone, and the largest is \`data-table\` at 64,440. Every family together is 303,276.
3608
+ Across the 104 styled components, the smallest is \`code\` at 10,625 bytes gzipped alone, and the largest is \`data-table\` at 54,367. Every family together is 315,452.
3448
3609
 
3449
- No family imports a barrel. The \`barrels\` rule in \`fusion workspace\` enforces that. \`@fusion.dev/helix-headless\` marks every module in \`dist\` as having side effects, which is true of a file that calls \`customElements.define\`. A bundler can remove none of it. One \`import { HelixHeadlessButton } from '@fusion.dev/helix-headless'\` costs 194,398 bytes gzipped, whatever else the page imports. That is 9 times the median family above. All 104 styled families import the headless family they extend directly. The rule checks the shape of the import, so it applies to any package that sets \`sideEffects\`, whatever its name.
3610
+ No family imports a barrel. The \`barrels\` rule in \`fusion workspace\` enforces that. \`@fusion.dev/helix-headless\` marks every module in \`dist\` as having side effects, which is true of a file that calls \`customElements.define\`. A bundler can remove none of it. One \`import { HelixHeadlessButton } from '@fusion.dev/helix-headless'\` costs 218,034 bytes gzipped, whatever else the page imports. That is 13 times the median family above. All 104 styled families import the headless family they extend directly. The rule checks the shape of the import, so it applies to any package that sets \`sideEffects\`, whatever its name.
3450
3611
 
3451
- The headless tier never had the problem, so it serves as the control. \`@fusion.dev/helix-core\` is \`sideEffects: false\`, and the median headless family is 22,536 bytes gzipped alone.
3612
+ The headless tier never had the problem, so it serves as the control. \`@fusion.dev/helix-core\` is \`sideEffects: false\`, and the median headless family is 15,324 bytes gzipped alone.
3452
3613
 
3453
3614
  ## Compared with other systems
3454
3615
 
3455
- We compare Helix with four other libraries of custom elements. \`turbo run peers\` measured them on 2026-08-24. It installs pinned versions into \`.local\` and bundles them with the same harness as the tables above. The Helix rows are measured on every run of \`bun run gen:metrics\`, so they always match this repository.
3616
+ We compare Helix with the libraries of custom elements listed under the table. \`turbo run peers\` measured them on 2026-08-24. It installs pinned versions into \`.local\` and bundles them with the same harness as the tables above. The Helix rows are measured on every run of \`bun run gen:metrics\`, so they always match this repository.
3456
3617
 
3457
3618
  Every system in the table is built on Lit. The runtime is the same library in every column, so the differences come from the components. React component libraries are left out, because comparing a custom element with a React component would measure the framework.
3458
3619
 
3459
- The table has no whole-library row. That row would compare how many components each vendor ships and how each vendor counts a component. It would look like a measurement and mean little. The table compares five components that every system has.
3620
+ The table has no whole-library row. That row would compare how many components each vendor ships and how each vendor counts a component. It would look like a measurement and mean little. The table compares components that most systems ship, and a system without one says so.
3460
3621
 
3461
3622
  | Component | System | Raw | Gzip | Brotli |
3462
3623
  |---|---|---|---|---|
3463
- | \`button\` | **Helix** | 45,627 | 13,160 | 11,597 |
3624
+ | \`button\` | **Helix** | 52,405 | 14,962 | 13,154 |
3464
3625
  | | Carbon | 133,058 | 20,959 | 17,685 |
3465
3626
  | | Material Web | 47,060 | 14,173 | 12,591 |
3466
3627
  | | Shoelace | 62,628 | 18,287 | 15,805 |
3467
3628
  | | Spectrum | 98,792 | 22,045 | 18,674 |
3468
- | \`checkbox\` | **Helix** | 50,794 | 14,480 | 12,734 |
3629
+ | \`checkbox\` | **Helix** | 57,661 | 16,224 | 14,282 |
3469
3630
  | | Carbon | 60,255 | 15,609 | 13,550 |
3470
3631
  | | Material Web | 43,785 | 13,556 | 12,015 |
3471
3632
  | | Shoelace | 47,614 | 15,177 | 13,301 |
3472
3633
  | | Spectrum | 62,492 | 15,437 | 13,481 |
3473
- | \`dialog\` | **Helix** | 42,582 | 12,668 | 11,151 |
3634
+ | \`dialog\` | **Helix** | 48,373 | 14,225 | 12,495 |
3474
3635
  | | Carbon | 510,866 | 67,390 | 39,189 |
3475
3636
  | | Material Web | 34,238 | 11,510 | 10,229 |
3476
3637
  | | Shoelace | 52,754 | 17,698 | 15,554 |
3477
3638
  | | Spectrum | 155,708 | 31,899 | 26,262 |
3478
- | \`radio\` | **Helix** | 54,213 | 14,925 | 13,136 |
3639
+ | \`radio\` | **Helix** | 61,642 | 16,891 | 14,906 |
3479
3640
  | | Carbon | 63,055 | 16,887 | 14,605 |
3480
3641
  | | Material Web | 41,044 | 13,234 | 11,757 |
3481
3642
  | | Shoelace | 34,865 | 12,027 | 10,559 |
3482
3643
  | | Spectrum | 38,685 | 10,660 | 9,370 |
3483
- | \`switch\` | **Helix** | 47,784 | 13,981 | 12,292 |
3644
+ | \`switch\` | **Helix** | 54,591 | 15,726 | 13,799 |
3484
3645
  | | Carbon | 69,423 | 17,127 | 14,764 |
3485
3646
  | | Material Web | 50,155 | 14,577 | 12,935 |
3486
3647
  | | Shoelace | 37,833 | 11,814 | 10,568 |
3487
3648
  | | Spectrum | 62,322 | 15,059 | 13,321 |
3488
- | \`tabs\` | **Helix** | 48,895 | 14,049 | 12,334 |
3649
+ | \`tabs\` | **Helix** | 54,198 | 15,497 | 13,584 |
3489
3650
  | | Carbon | 578,766 | 73,537 | 43,235 |
3490
3651
  | | Material Web | 38,883 | 12,820 | 11,368 |
3491
3652
  | | Shoelace | 54,573 | 17,140 | 15,068 |
3492
3653
  | | Spectrum | 64,875 | 18,298 | 16,283 |
3493
- | \`tooltip\` | **Helix** | 69,601 | 22,599 | 19,950 |
3654
+ | \`tooltip\` | **Helix** | 72,456 | 23,199 | 20,502 |
3494
3655
  | | Carbon | 189,382 | 30,354 | 22,273 |
3495
3656
  | | Material Web | | not shipped | |
3496
3657
  | | Shoelace | 57,412 | 20,220 | 17,933 |
3497
3658
  | | Spectrum | 136,599 | 40,552 | 35,286 |
3498
3659
 
3499
- At least one system is smaller than Helix on \`checkbox\`, \`dialog\`, \`radio\`, \`switch\`, \`tabs\`, \`tooltip\`. The largest gap is radio against Spectrum, at 4,265 bytes gzipped. 8 of 28 peer measurements are smaller than the Helix row.
3660
+ At least one system is smaller than Helix on \`button\`, \`checkbox\`, \`dialog\`, \`radio\`, \`switch\`, \`tabs\`, \`tooltip\`. The largest gap is radio against Spectrum, at 6,231 bytes gzipped. 15 of 27 peer measurements are smaller than the Helix row.
3661
+
3662
+ Helix's \`radio\` family includes Radio Group, so its row carries an element that some peer rows measure without.
3500
3663
 
3501
3664
  - **Carbon** \`@carbon/web-components@2.61.0\`. Its dialog is Modal, its radio is Radio Button, and its switch is Toggle.
3502
3665
  - **Material Web** \`@material/web@2.5.0\`. Ships no tooltip. Its button is measured as the filled one, there being no single button element.
@@ -3540,104 +3703,104 @@ Structure, accessibility, state, and form participation. It has no presentation
3540
3703
 
3541
3704
  | Family | Alone raw | Alone gzip | Alone brotli | Added raw | Added gzip | Added brotli |
3542
3705
  |---|---|---|---|---|---|---|
3543
- | \`accordion\` | 94,146 | 30,683 | 25,054 | 2,875 | 725 | 591 |
3544
- | \`announcement\` | 91,561 | 29,855 | 24,344 | 1,386 | 365 | 315 |
3545
- | \`app-header\` | 35,147 | 10,774 | 9,482 | 1,248 | 261 | 267 |
3546
- | \`area-chart\` | 81,239 | 26,784 | 23,616 | 11,166 | 3,382 | 2,736 |
3547
- | \`avatar\` | 37,234 | 11,388 | 10,035 | 3,296 | 894 | 740 |
3548
- | \`badge\` | 34,683 | 10,703 | 9,380 | 1,163 | 301 | 227 |
3549
- | \`bar-chart\` | 82,848 | 27,158 | 23,952 | 12,769 | 3,695 | 3,195 |
3550
- | \`blockquote\` | 34,697 | 10,730 | 9,428 | 774 | 177 | 163 |
3551
- | \`breadcrumbs\` | 90,601 | 29,203 | 23,965 | 1,965 | 444 | 405 |
3552
- | \`button\` | 39,369 | 11,986 | 10,530 | 3,195 | 817 | 682 |
3553
- | \`button-group\` | 34,553 | 10,610 | 9,316 | 661 | 141 | 91 |
3554
- | \`callout\` | 89,781 | 29,091 | 23,899 | 975 | 274 | 278 |
3555
- | \`canvas\` | 95,827 | 28,300 | 24,815 | 50,036 | 14,960 | 12,555 |
3556
- | \`card\` | 34,587 | 10,627 | 9,339 | 694 | 140 | 89 |
3557
- | \`carousel\` | 100,004 | 32,186 | 26,392 | 10,943 | 2,734 | 2,326 |
3558
- | \`chat\` | 113,488 | 37,075 | 30,397 | 17,449 | 5,101 | 4,303 |
3559
- | \`checkbox\` | 44,186 | 13,038 | 11,447 | 2,821 | 784 | 591 |
3560
- | \`checkbox-group\` | 47,310 | 13,724 | 12,070 | 5,425 | 1,366 | 1,117 |
3561
- | \`code\` | 33,172 | 10,193 | 8,966 | 451 | 78 | 40 |
3562
- | \`code-block\` | 135,605 | 44,216 | 37,288 | 17,443 | 4,511 | 3,880 |
3563
- | \`color-input\` | 153,586 | 48,220 | 40,723 | 25,853 | 6,032 | 5,036 |
3564
- | \`color-picker\` | 119,956 | 37,674 | 30,975 | 19,676 | 4,708 | 3,949 |
3565
- | \`combobox\` | 148,369 | 46,880 | 39,435 | 21,175 | 5,214 | 4,226 |
3566
- | \`command\` | 118,287 | 36,946 | 30,260 | 18,064 | 4,594 | 3,744 |
3567
- | \`copy-button\` | 130,185 | 42,566 | 35,820 | 12,019 | 2,957 | 2,432 |
3568
- | \`data-table\` | 188,875 | 57,528 | 48,563 | 57,535 | 14,589 | 12,192 |
3569
- | \`date-input\` | 146,628 | 46,372 | 38,994 | 19,212 | 4,832 | 4,047 |
3570
- | \`date-picker\` | 101,780 | 32,896 | 26,931 | 9,900 | 2,706 | 2,203 |
3571
- | \`description-list\` | 34,656 | 10,565 | 9,269 | 1,132 | 172 | 155 |
3572
- | \`dialog\` | 38,205 | 11,660 | 10,266 | 2,717 | 777 | 650 |
3573
- | \`divider\` | 34,903 | 10,810 | 9,498 | 981 | 255 | 196 |
3574
- | \`donut-chart\` | 78,982 | 25,782 | 22,727 | 10,339 | 2,970 | 2,540 |
3575
- | \`drawer\` | 36,958 | 11,299 | 9,931 | 1,761 | 470 | 398 |
3576
- | \`drilldown\` | 98,646 | 32,043 | 26,104 | 5,704 | 1,493 | 1,176 |
3577
- | \`empty\` | 35,150 | 10,853 | 9,531 | 956 | 243 | 163 |
3578
- | \`file-input\` | 102,144 | 32,877 | 26,856 | 6,266 | 1,808 | 1,396 |
3579
- | \`filter-input\` | 158,975 | 49,595 | 41,937 | 28,070 | 6,799 | 5,629 |
3580
- | \`format-date\` | 38,166 | 11,770 | 10,393 | 2,868 | 694 | 582 |
3581
- | \`graph\` | 116,500 | 37,045 | 30,487 | 11,480 | 3,231 | 2,788 |
3582
- | \`heatmap\` | 80,204 | 25,983 | 22,886 | 10,997 | 2,991 | 2,539 |
3583
- | \`icon\` | 89,288 | 28,883 | 23,689 | 1,018 | 246 | 208 |
3584
- | \`icon-button\` | 39,768 | 12,019 | 10,552 | 3,594 | 858 | 630 |
3585
- | \`image\` | 36,726 | 11,157 | 9,803 | 3,157 | 812 | 638 |
3586
- | \`input\` | 101,182 | 32,362 | 26,507 | 4,746 | 1,276 | 977 |
3587
- | \`kbd\` | 36,507 | 11,395 | 10,035 | 2,976 | 915 | 738 |
3588
- | \`legend\` | 38,559 | 11,901 | 10,461 | 1,080 | 277 | 260 |
3589
- | \`lightbox\` | 42,999 | 12,950 | 11,347 | 4,807 | 1,236 | 1,042 |
3590
- | \`line-chart\` | 80,779 | 26,487 | 23,389 | 10,792 | 3,086 | 2,597 |
3591
- | \`list\` | 35,609 | 10,806 | 9,494 | 1,726 | 333 | 276 |
3592
- | \`listbox\` | 109,996 | 35,061 | 28,605 | 11,263 | 3,065 | 2,451 |
3593
- | \`loader\` | 34,793 | 10,731 | 9,434 | 900 | 231 | 145 |
3594
- | \`map\` | 135,023 | 40,242 | 33,379 | 33,030 | 7,708 | 6,231 |
3595
- | \`megamenu\` | 65,092 | 21,481 | 18,897 | 4,941 | 1,278 | 1,033 |
3596
- | \`menu\` | 128,815 | 42,454 | 35,618 | 8,856 | 2,188 | 1,829 |
3597
- | \`meter\` | 37,983 | 11,583 | 10,180 | 4,100 | 1,064 | 940 |
3598
- | \`navigation\` | 36,542 | 11,280 | 9,892 | 1,417 | 341 | 301 |
3599
- | \`notifications\` | 105,825 | 33,645 | 27,464 | 11,384 | 2,617 | 2,170 |
3600
- | \`number-input\` | 104,106 | 33,173 | 27,093 | 7,671 | 1,991 | 1,556 |
3601
- | \`object-inspector\` | 143,395 | 46,771 | 39,449 | 19,705 | 5,249 | 4,382 |
3602
- | \`option\` | 36,848 | 11,172 | 9,859 | 2,959 | 666 | 414 |
3603
- | \`outline\` | 39,911 | 12,458 | 10,978 | 4,628 | 1,326 | 1,080 |
3604
- | \`pagination\` | 152,465 | 47,582 | 40,030 | 27,823 | 6,528 | 5,329 |
3605
- | \`pin-input\` | 46,366 | 13,784 | 12,137 | 5,242 | 1,563 | 1,171 |
3606
- | \`popover\` | 62,296 | 20,725 | 18,214 | 1,899 | 513 | 488 |
3607
- | \`progress\` | 35,834 | 11,003 | 9,678 | 1,951 | 490 | 464 |
3608
- | \`qr-code\` | 46,483 | 15,044 | 13,242 | 12,984 | 4,828 | 4,059 |
3609
- | \`quote\` | 34,076 | 10,491 | 9,221 | 552 | 119 | 67 |
3610
- | \`radio\` | 45,916 | 13,428 | 11,812 | 2,874 | 726 | 578 |
3611
- | \`rating\` | 48,121 | 14,398 | 12,675 | 6,689 | 1,880 | 1,538 |
3612
- | \`scatter-chart\` | 80,683 | 26,413 | 23,275 | 11,471 | 3,371 | 2,830 |
3613
- | \`scroll-area\` | 36,319 | 11,164 | 9,809 | 2,743 | 736 | 655 |
3614
- | \`select\` | 140,575 | 45,037 | 37,796 | 16,146 | 4,083 | 3,351 |
3615
- | \`skeleton\` | 33,265 | 10,227 | 8,965 | 544 | 106 | 45 |
3616
- | \`skip-link\` | 34,855 | 10,796 | 9,475 | 1,178 | 334 | 243 |
3617
- | \`slider\` | 46,905 | 13,806 | 12,176 | 5,628 | 1,517 | 1,238 |
3618
- | \`sparkline\` | 40,978 | 12,925 | 11,386 | 2,387 | 794 | 744 |
3619
- | \`speed-dial\` | 120,323 | 40,071 | 33,736 | 3,743 | 918 | 690 |
3620
- | \`splitter\` | 44,358 | 13,240 | 11,678 | 10,283 | 2,587 | 2,196 |
3621
- | \`stat\` | 35,041 | 10,666 | 9,363 | 1,148 | 185 | 79 |
3622
- | \`steps\` | 98,861 | 31,677 | 25,901 | 6,295 | 1,470 | 1,224 |
3623
- | \`switch\` | 43,417 | 12,921 | 11,362 | 1,650 | 514 | 364 |
3624
- | \`table\` | 100,971 | 32,855 | 26,742 | 10,159 | 2,795 | 2,312 |
3625
- | \`tabs\` | 42,654 | 12,774 | 11,190 | 3,925 | 822 | 664 |
3626
- | \`tag\` | 90,014 | 29,133 | 23,798 | 908 | 198 | 207 |
3627
- | \`textarea\` | 45,604 | 13,423 | 11,778 | 3,997 | 1,063 | 806 |
3628
- | \`time-input\` | 159,758 | 49,619 | 41,795 | 29,051 | 7,093 | 5,869 |
3629
- | \`time-picker\` | 118,842 | 37,643 | 30,852 | 19,136 | 5,108 | 4,201 |
3630
- | \`timeline\` | 90,450 | 29,131 | 23,931 | 1,809 | 362 | 265 |
3631
- | \`toast\` | 93,807 | 30,268 | 24,715 | 4,078 | 949 | 780 |
3632
- | \`toggle\` | 47,603 | 13,959 | 12,288 | 3,342 | 815 | 573 |
3633
- | \`toolbar\` | 36,647 | 11,354 | 9,978 | 2,624 | 704 | 576 |
3634
- | \`tooltip\` | 66,523 | 21,821 | 19,323 | 6,494 | 1,749 | 1,431 |
3635
- | \`tour\` | 72,280 | 23,251 | 20,408 | 11,097 | 2,772 | 2,303 |
3636
- | \`tree\` | 100,665 | 32,488 | 26,473 | 7,224 | 1,878 | 1,567 |
3637
- | \`trend\` | 89,328 | 28,928 | 23,780 | 1,056 | 268 | 266 |
3638
- | \`video\` | 157,146 | 49,284 | 41,734 | 32,577 | 7,665 | 6,638 |
3639
- | \`video-playlist\` | 136,305 | 44,054 | 36,962 | 14,942 | 3,424 | 2,916 |
3640
- | \`virtual-list\` | 40,597 | 12,666 | 11,132 | 2,413 | 719 | 592 |
3706
+ | \`accordion\` | 44,531 | 13,582 | 11,941 | 4,240 | 1,093 | 965 |
3707
+ | \`announcement\` | 40,486 | 12,371 | 10,871 | 1,633 | 411 | 327 |
3708
+ | \`app-header\` | 37,144 | 11,124 | 9,797 | 1,800 | 423 | 376 |
3709
+ | \`area-chart\` | 84,922 | 27,615 | 24,332 | 12,158 | 3,566 | 3,076 |
3710
+ | \`avatar\` | 39,247 | 11,727 | 10,328 | 3,928 | 1,078 | 898 |
3711
+ | \`badge\` | 35,973 | 10,839 | 9,528 | 1,163 | 286 | 239 |
3712
+ | \`bar-chart\` | 87,483 | 28,346 | 24,948 | 14,313 | 4,165 | 3,520 |
3713
+ | \`blockquote\` | 36,125 | 10,913 | 9,590 | 912 | 215 | 232 |
3714
+ | \`breadcrumbs\` | 38,342 | 11,545 | 10,147 | 2,248 | 526 | 490 |
3715
+ | \`button\` | 46,146 | 13,778 | 12,078 | 3,934 | 981 | 779 |
3716
+ | \`button-group\` | 35,843 | 10,745 | 9,443 | 661 | 128 | 127 |
3717
+ | \`callout\` | 38,540 | 11,805 | 10,378 | 1,132 | 292 | 275 |
3718
+ | \`canvas\` | 97,775 | 28,702 | 25,080 | 50,696 | 15,190 | 12,742 |
3719
+ | \`card\` | 35,877 | 10,756 | 9,453 | 694 | 138 | 159 |
3720
+ | \`carousel\` | 48,862 | 14,558 | 12,859 | 12,339 | 3,052 | 2,586 |
3721
+ | \`chat\` | 63,648 | 19,423 | 17,122 | 18,372 | 5,274 | 4,374 |
3722
+ | \`checkbox\` | 51,033 | 14,772 | 13,004 | 2,870 | 730 | 530 |
3723
+ | \`checkbox-group\` | 54,983 | 15,722 | 13,809 | 6,298 | 1,561 | 1,189 |
3724
+ | \`code\` | 34,462 | 10,329 | 9,052 | 451 | 78 | 66 |
3725
+ | \`code-block\` | 91,328 | 28,695 | 25,278 | 20,194 | 5,201 | 4,342 |
3726
+ | \`color-input\` | 113,740 | 33,688 | 29,591 | 30,723 | 7,328 | 6,007 |
3727
+ | \`color-picker\` | 77,625 | 22,365 | 19,720 | 23,960 | 6,012 | 4,933 |
3728
+ | \`combobox\` | 110,175 | 32,674 | 28,735 | 27,570 | 6,721 | 5,437 |
3729
+ | \`command\` | 77,258 | 21,751 | 19,099 | 22,515 | 5,705 | 4,731 |
3730
+ | \`copy-button\` | 85,373 | 26,991 | 23,792 | 14,235 | 3,495 | 2,911 |
3731
+ | \`data-table\` | 160,226 | 46,170 | 39,965 | 73,874 | 18,970 | 15,490 |
3732
+ | \`date-input\` | 107,976 | 31,846 | 28,112 | 24,131 | 6,002 | 4,918 |
3733
+ | \`date-picker\` | 55,612 | 16,519 | 14,611 | 12,474 | 3,302 | 2,786 |
3734
+ | \`description-list\` | 35,946 | 10,698 | 9,382 | 1,132 | 189 | 137 |
3735
+ | \`dialog\` | 43,992 | 13,200 | 11,608 | 3,984 | 1,123 | 931 |
3736
+ | \`divider\` | 36,193 | 10,944 | 9,595 | 981 | 222 | 228 |
3737
+ | \`donut-chart\` | 82,994 | 26,781 | 23,563 | 11,658 | 3,272 | 2,857 |
3738
+ | \`drawer\` | 42,522 | 12,827 | 11,244 | 2,805 | 757 | 618 |
3739
+ | \`drilldown\` | 50,555 | 15,348 | 13,508 | 6,373 | 1,581 | 1,291 |
3740
+ | \`empty\` | 36,631 | 11,057 | 9,703 | 956 | 225 | 155 |
3741
+ | \`file-input\` | 57,808 | 17,236 | 15,191 | 7,749 | 2,238 | 1,839 |
3742
+ | \`filter-input\` | 117,407 | 34,721 | 30,452 | 30,511 | 7,397 | 6,060 |
3743
+ | \`format-date\` | 40,640 | 12,232 | 10,797 | 3,377 | 828 | 692 |
3744
+ | \`graph\` | 68,708 | 20,592 | 18,136 | 14,807 | 4,455 | 3,798 |
3745
+ | \`heatmap\` | 86,523 | 27,639 | 24,240 | 12,260 | 3,220 | 2,671 |
3746
+ | \`icon\` | 91,862 | 29,593 | 24,502 | 54,441 | 18,378 | 14,882 |
3747
+ | \`icon-button\` | 46,545 | 13,805 | 12,130 | 4,333 | 1,026 | 867 |
3748
+ | \`image\` | 38,130 | 11,314 | 9,951 | 3,269 | 814 | 659 |
3749
+ | \`input\` | 56,582 | 16,890 | 14,728 | 7,173 | 2,187 | 1,677 |
3750
+ | \`kbd\` | 37,867 | 11,557 | 10,155 | 3,046 | 944 | 718 |
3751
+ | \`legend\` | 40,520 | 12,217 | 10,753 | 1,236 | 321 | 295 |
3752
+ | \`lightbox\` | 45,844 | 13,576 | 11,891 | 5,077 | 1,309 | 1,118 |
3753
+ | \`line-chart\` | 85,212 | 27,603 | 24,422 | 12,296 | 3,456 | 2,971 |
3754
+ | \`list\` | 36,939 | 10,945 | 9,627 | 1,766 | 336 | 329 |
3755
+ | \`listbox\` | 66,528 | 19,325 | 17,038 | 14,139 | 3,691 | 3,035 |
3756
+ | \`loader\` | 36,083 | 10,861 | 9,521 | 900 | 227 | 240 |
3757
+ | \`map\` | 88,696 | 24,546 | 21,300 | 37,987 | 9,713 | 7,564 |
3758
+ | \`megamenu\` | 67,375 | 21,873 | 19,259 | 5,166 | 1,282 | 1,024 |
3759
+ | \`menu\` | 82,759 | 26,552 | 23,307 | 10,756 | 2,601 | 2,146 |
3760
+ | \`meter\` | 39,466 | 11,802 | 10,380 | 4,291 | 1,113 | 939 |
3761
+ | \`navigation\` | 40,361 | 12,268 | 10,700 | 1,587 | 356 | 265 |
3762
+ | \`notifications\` | 57,176 | 16,480 | 14,524 | 13,049 | 3,035 | 2,600 |
3763
+ | \`number-input\` | 58,602 | 17,009 | 14,994 | 9,198 | 2,335 | 1,925 |
3764
+ | \`object-inspector\` | 101,188 | 31,909 | 28,027 | 23,851 | 6,367 | 5,237 |
3765
+ | \`option\` | 38,177 | 11,313 | 9,938 | 3,000 | 597 | 472 |
3766
+ | \`outline\` | 41,276 | 12,620 | 11,097 | 4,703 | 1,317 | 1,096 |
3767
+ | \`pagination\` | 115,172 | 34,200 | 29,842 | 36,108 | 8,978 | 7,303 |
3768
+ | \`pin-input\` | 53,468 | 15,598 | 13,735 | 5,546 | 1,588 | 1,250 |
3769
+ | \`popover\` | 67,088 | 21,955 | 19,298 | 2,360 | 546 | 437 |
3770
+ | \`progress\` | 37,468 | 11,283 | 9,925 | 2,293 | 599 | 516 |
3771
+ | \`qr-code\` | 48,159 | 15,300 | 13,444 | 13,372 | 4,976 | 4,151 |
3772
+ | \`quote\` | 35,366 | 10,620 | 9,333 | 552 | 137 | 116 |
3773
+ | \`radio\` | 53,348 | 15,393 | 13,602 | 3,454 | 859 | 704 |
3774
+ | \`rating\` | 57,759 | 17,167 | 15,141 | 7,025 | 1,930 | 1,642 |
3775
+ | \`scatter-chart\` | 84,344 | 27,236 | 23,963 | 12,438 | 3,562 | 3,042 |
3776
+ | \`scroll-area\` | 37,609 | 11,305 | 9,932 | 2,743 | 716 | 619 |
3777
+ | \`select\` | 99,650 | 30,319 | 26,661 | 20,882 | 5,227 | 4,248 |
3778
+ | \`skeleton\` | 35,927 | 10,769 | 9,479 | 744 | 154 | 156 |
3779
+ | \`skip-link\` | 36,528 | 11,065 | 9,725 | 1,562 | 459 | 356 |
3780
+ | \`slider\` | 54,718 | 15,853 | 13,964 | 6,551 | 1,688 | 1,378 |
3781
+ | \`sparkline\` | 42,823 | 13,199 | 11,635 | 2,387 | 776 | 634 |
3782
+ | \`speed-dial\` | 70,296 | 23,092 | 20,399 | 4,222 | 981 | 741 |
3783
+ | \`splitter\` | 48,695 | 14,346 | 12,659 | 10,974 | 2,631 | 2,364 |
3784
+ | \`stat\` | 36,680 | 10,934 | 9,626 | 1,498 | 323 | 267 |
3785
+ | \`steps\` | 52,437 | 15,470 | 13,601 | 7,665 | 1,866 | 1,437 |
3786
+ | \`switch\` | 50,222 | 14,655 | 12,858 | 1,658 | 440 | 340 |
3787
+ | \`table\` | 55,545 | 16,720 | 14,777 | 14,836 | 4,124 | 3,515 |
3788
+ | \`tabs\` | 47,579 | 14,153 | 12,437 | 4,025 | 831 | 670 |
3789
+ | \`tag\` | 39,281 | 11,904 | 10,482 | 1,502 | 355 | 270 |
3790
+ | \`textarea\` | 52,411 | 15,190 | 13,395 | 4,004 | 1,010 | 798 |
3791
+ | \`time-input\` | 122,739 | 35,784 | 31,347 | 34,903 | 8,541 | 7,113 |
3792
+ | \`time-picker\` | 77,815 | 22,421 | 19,721 | 24,273 | 6,323 | 5,284 |
3793
+ | \`timeline\` | 38,338 | 11,513 | 10,124 | 2,239 | 492 | 462 |
3794
+ | \`toast\` | 46,209 | 13,943 | 12,268 | 6,631 | 1,725 | 1,325 |
3795
+ | \`toggle\` | 55,270 | 15,967 | 14,097 | 3,859 | 918 | 828 |
3796
+ | \`toolbar\` | 41,802 | 12,830 | 11,234 | 4,134 | 1,227 | 968 |
3797
+ | \`tooltip\` | 69,378 | 22,430 | 19,869 | 7,373 | 1,948 | 1,646 |
3798
+ | \`tour\` | 81,985 | 25,759 | 22,618 | 12,789 | 3,163 | 2,598 |
3799
+ | \`tree\` | 53,094 | 15,962 | 14,019 | 8,342 | 2,132 | 1,862 |
3800
+ | \`trend\` | 37,851 | 11,482 | 10,080 | 2,134 | 536 | 482 |
3801
+ | \`video\` | 117,688 | 35,512 | 31,035 | 41,045 | 10,341 | 8,533 |
3802
+ | \`video-playlist\` | 90,918 | 28,242 | 24,787 | 17,517 | 4,073 | 3,420 |
3803
+ | \`virtual-list\` | 46,217 | 14,195 | 12,467 | 3,995 | 1,234 | 973 |
3641
3804
 
3642
3805
  ### Styled tier
3643
3806
 
@@ -3645,110 +3808,110 @@ The headless tier plus presentation. \`bun add @fusion.dev/helix\` installs this
3645
3808
 
3646
3809
  | Family | Alone raw | Alone gzip | Alone brotli | Added raw | Added gzip | Added brotli |
3647
3810
  |---|---|---|---|---|---|---|
3648
- | \`accordion\` | 97,484 | 31,527 | 25,776 | 6,204 | 1,540 | 1,328 |
3649
- | \`announcement\` | 96,325 | 30,966 | 25,283 | 6,133 | 1,434 | 1,318 |
3650
- | \`app-header\` | 39,037 | 11,664 | 10,286 | 5,121 | 1,173 | 1,019 |
3651
- | \`area-chart\` | 88,624 | 28,374 | 24,968 | 18,528 | 4,996 | 4,058 |
3652
- | \`aura\` | 102,182 | 34,152 | 29,605 | 65,492 | 23,022 | 19,750 |
3653
- | \`avatar\` | 40,820 | 12,142 | 10,694 | 6,872 | 1,666 | 1,415 |
3654
- | \`badge\` | 38,056 | 11,452 | 10,036 | 4,519 | 1,047 | 893 |
3655
- | \`bar-chart\` | 95,653 | 29,690 | 26,159 | 25,550 | 6,313 | 5,327 |
3656
- | \`blockquote\` | 35,853 | 11,018 | 9,681 | 1,914 | 481 | 403 |
3657
- | \`breadcrumbs\` | 94,168 | 30,039 | 24,642 | 5,518 | 1,237 | 1,066 |
3658
- | \`button\` | 45,627 | 13,160 | 11,597 | 9,435 | 2,012 | 1,659 |
3659
- | \`button-group\` | 36,229 | 10,990 | 9,645 | 2,320 | 527 | 443 |
3660
- | \`callout\` | 91,867 | 29,665 | 24,423 | 3,044 | 803 | 731 |
3661
- | \`canvas\` | 116,132 | 32,041 | 27,998 | 70,330 | 18,726 | 15,747 |
3662
- | \`card\` | 37,868 | 11,465 | 10,070 | 3,963 | 988 | 908 |
3663
- | \`carousel\` | 110,792 | 33,934 | 27,953 | 21,720 | 4,518 | 3,933 |
3664
- | \`chat\` | 127,645 | 39,596 | 32,691 | 31,592 | 7,644 | 6,509 |
3665
- | \`checkbox\` | 50,794 | 14,480 | 12,734 | 9,413 | 2,243 | 1,860 |
3666
- | \`checkbox-group\` | 49,591 | 14,307 | 12,571 | 7,692 | 1,940 | 1,568 |
3667
- | \`code\` | 34,249 | 10,492 | 9,227 | 1,511 | 372 | 429 |
3668
- | \`code-block\` | 152,056 | 47,072 | 39,635 | 33,873 | 7,293 | 6,180 |
3669
- | \`color-input\` | 187,784 | 53,477 | 45,370 | 60,032 | 11,436 | 9,730 |
3670
- | \`color-picker\` | 148,452 | 42,352 | 35,092 | 48,165 | 9,437 | 8,006 |
3671
- | \`combobox\` | 163,625 | 49,537 | 41,748 | 36,412 | 7,971 | 6,635 |
3672
- | \`command\` | 129,039 | 39,047 | 32,120 | 28,805 | 6,715 | 5,685 |
3673
- | \`copy-button\` | 140,190 | 44,376 | 37,397 | 22,010 | 4,707 | 3,910 |
3674
- | \`data-table\` | 227,144 | 64,440 | 54,220 | 95,535 | 21,432 | 17,484 |
3675
- | \`date-input\` | 162,787 | 49,388 | 41,706 | 35,359 | 7,915 | 6,652 |
3676
- | \`date-picker\` | 107,397 | 34,083 | 27,876 | 15,499 | 3,869 | 3,190 |
3677
- | \`description-list\` | 37,034 | 11,136 | 9,766 | 3,502 | 769 | 609 |
3678
- | \`dialog\` | 42,582 | 12,668 | 11,151 | 7,079 | 1,783 | 1,532 |
3679
- | \`divider\` | 37,059 | 11,328 | 9,883 | 3,120 | 770 | 646 |
3680
- | \`donut-chart\` | 88,088 | 27,652 | 24,389 | 19,422 | 4,911 | 4,172 |
3681
- | \`drawer\` | 41,221 | 12,297 | 10,794 | 6,007 | 1,482 | 1,303 |
3682
- | \`drilldown\` | 103,343 | 33,143 | 27,029 | 10,391 | 2,513 | 2,074 |
3683
- | \`empty\` | 36,590 | 11,298 | 9,906 | 2,380 | 703 | 620 |
3684
- | \`file-input\` | 113,670 | 35,206 | 28,887 | 17,794 | 4,073 | 3,440 |
3685
- | \`filter-input\` | 187,314 | 54,146 | 45,740 | 56,402 | 11,409 | 9,637 |
3686
- | \`flex\` | 35,610 | 10,843 | 9,523 | 2,078 | 453 | 408 |
3687
- | \`format-date\` | 38,814 | 11,918 | 10,519 | 3,498 | 870 | 748 |
3688
- | \`graph\` | 131,342 | 39,599 | 32,592 | 26,303 | 5,764 | 4,990 |
3689
- | \`grid\` | 36,203 | 11,032 | 9,705 | 2,667 | 625 | 643 |
3690
- | \`heatmap\` | 87,000 | 27,374 | 24,210 | 17,773 | 4,424 | 3,659 |
3691
- | \`icon\` | 89,994 | 29,073 | 23,848 | 1,707 | 413 | 305 |
3692
- | \`icon-button\` | 45,786 | 13,032 | 11,449 | 9,596 | 1,871 | 1,580 |
3693
- | \`image\` | 38,428 | 11,636 | 10,225 | 4,841 | 1,286 | 1,127 |
3694
- | \`input\` | 107,548 | 33,803 | 27,644 | 11,102 | 2,659 | 2,157 |
3695
- | \`kbd\` | 37,919 | 11,849 | 10,407 | 4,373 | 1,374 | 1,189 |
3696
- | \`legend\` | 43,375 | 13,019 | 11,400 | 5,790 | 1,390 | 1,086 |
3697
- | \`lightbox\` | 46,011 | 13,700 | 11,994 | 7,803 | 1,989 | 1,683 |
3698
- | \`line-chart\` | 90,551 | 28,485 | 25,135 | 20,543 | 5,162 | 4,264 |
3699
- | \`list\` | 39,692 | 11,750 | 10,324 | 5,799 | 1,305 | 1,114 |
3700
- | \`listbox\` | 114,516 | 36,116 | 29,507 | 15,768 | 4,063 | 3,221 |
3701
- | \`loader\` | 37,959 | 11,498 | 10,113 | 4,051 | 994 | 834 |
3702
- | \`map\` | 172,078 | 45,778 | 38,148 | 70,072 | 13,195 | 11,085 |
3703
- | \`megamenu\` | 69,973 | 22,584 | 19,936 | 9,806 | 2,358 | 1,997 |
3704
- | \`menu\` | 136,343 | 44,103 | 37,043 | 16,360 | 3,788 | 3,186 |
3705
- | \`meter\` | 43,381 | 12,723 | 11,220 | 9,480 | 2,236 | 1,914 |
3706
- | \`navigation\` | 38,193 | 11,742 | 10,282 | 3,051 | 805 | 620 |
3707
- | \`notifications\` | 118,939 | 36,071 | 29,612 | 24,488 | 5,037 | 4,312 |
3708
- | \`number-input\` | 108,991 | 34,360 | 28,086 | 12,537 | 3,136 | 2,557 |
3709
- | \`object-inspector\` | 157,035 | 49,044 | 41,504 | 33,323 | 7,594 | 6,393 |
3710
- | \`option\` | 40,102 | 12,078 | 10,643 | 6,203 | 1,566 | 1,334 |
3711
- | \`orb\` | 44,808 | 14,467 | 12,771 | 8,624 | 3,203 | 2,835 |
3712
- | \`outline\` | 43,651 | 13,234 | 11,681 | 8,351 | 2,119 | 1,758 |
3713
- | \`pagination\` | 170,448 | 50,616 | 42,743 | 45,787 | 9,637 | 7,927 |
3714
- | \`pin-input\` | 49,531 | 14,596 | 12,865 | 8,390 | 2,385 | 1,883 |
3715
- | \`popover\` | 64,967 | 21,370 | 18,901 | 4,552 | 1,174 | 989 |
3716
- | \`progress\` | 40,863 | 12,174 | 10,744 | 6,962 | 1,676 | 1,392 |
3717
- | \`qr-code\` | 48,148 | 15,475 | 13,623 | 14,629 | 5,257 | 4,395 |
3718
- | \`quote\` | 34,731 | 10,654 | 9,327 | 1,191 | 291 | 196 |
3719
- | \`radio\` | 54,213 | 14,925 | 13,136 | 11,161 | 2,283 | 1,940 |
3720
- | \`rating\` | 52,430 | 15,624 | 13,762 | 10,984 | 3,118 | 2,591 |
3721
- | \`sandbox\` | 70,095 | 18,502 | 16,381 | 35,720 | 7,874 | 6,656 |
3722
- | \`scatter-chart\` | 89,076 | 28,201 | 24,857 | 19,840 | 5,218 | 4,316 |
3723
- | \`scroll-area\` | 39,467 | 11,819 | 10,362 | 5,874 | 1,384 | 1,137 |
3724
- | \`select\` | 153,428 | 47,408 | 39,909 | 28,985 | 6,520 | 5,348 |
3725
- | \`skeleton\` | 35,783 | 10,981 | 9,631 | 2,242 | 595 | 512 |
3726
- | \`skip-link\` | 36,318 | 11,203 | 9,793 | 2,624 | 722 | 554 |
3727
- | \`slider\` | 57,985 | 15,794 | 13,935 | 16,691 | 3,552 | 3,037 |
3728
- | \`sparkline\` | 44,898 | 13,878 | 12,241 | 6,293 | 1,748 | 1,518 |
3729
- | \`speed-dial\` | 127,953 | 41,580 | 34,952 | 11,355 | 2,362 | 1,933 |
3730
- | \`splitter\` | 50,430 | 14,235 | 12,615 | 16,337 | 3,634 | 3,167 |
3731
- | \`stat\` | 38,466 | 11,378 | 10,026 | 4,565 | 917 | 795 |
3732
- | \`steps\` | 112,667 | 34,217 | 28,149 | 20,087 | 3,975 | 3,478 |
3733
- | \`switch\` | 47,784 | 13,981 | 12,292 | 6,002 | 1,571 | 1,310 |
3734
- | \`table\` | 106,565 | 34,049 | 27,890 | 15,748 | 3,973 | 3,393 |
3735
- | \`tabs\` | 48,895 | 14,049 | 12,334 | 10,154 | 2,153 | 1,799 |
3736
- | \`tag\` | 93,365 | 30,080 | 24,587 | 4,244 | 1,063 | 902 |
3737
- | \`text\` | 37,730 | 11,196 | 9,825 | 4,200 | 929 | 755 |
3738
- | \`textarea\` | 49,038 | 14,260 | 12,518 | 7,416 | 1,936 | 1,566 |
3739
- | \`time-input\` | 181,396 | 53,205 | 44,933 | 50,671 | 10,793 | 9,012 |
3740
- | \`time-picker\` | 130,570 | 39,823 | 32,809 | 30,854 | 7,358 | 6,136 |
3741
- | \`timeline\` | 93,763 | 29,912 | 24,574 | 5,110 | 1,131 | 1,009 |
3742
- | \`toast\` | 101,341 | 31,985 | 26,219 | 11,599 | 2,622 | 2,166 |
3743
- | \`toggle\` | 52,798 | 15,150 | 13,346 | 8,526 | 2,062 | 1,697 |
3744
- | \`toolbar\` | 37,939 | 11,649 | 10,233 | 3,899 | 1,022 | 835 |
3745
- | \`tooltip\` | 69,601 | 22,599 | 19,950 | 9,554 | 2,494 | 2,005 |
3746
- | \`tour\` | 81,996 | 24,885 | 21,973 | 20,795 | 4,496 | 3,706 |
3747
- | \`tree\` | 106,515 | 33,905 | 27,724 | 13,067 | 3,290 | 2,734 |
3748
- | \`trend\` | 92,548 | 29,698 | 24,397 | 4,271 | 983 | 799 |
3749
- | \`video\` | 176,566 | 52,762 | 44,815 | 51,979 | 11,228 | 9,627 |
3750
- | \`video-playlist\` | 150,421 | 46,636 | 39,232 | 29,040 | 5,998 | 5,029 |
3751
- | \`virtual-list\` | 41,389 | 12,879 | 11,334 | 3,187 | 935 | 716 |
3811
+ | \`accordion\` | 47,951 | 14,385 | 12,685 | 7,647 | 1,876 | 1,657 |
3812
+ | \`announcement\` | 45,249 | 13,413 | 11,773 | 6,380 | 1,478 | 1,291 |
3813
+ | \`app-header\` | 41,032 | 12,015 | 10,567 | 5,673 | 1,328 | 1,192 |
3814
+ | \`area-chart\` | 92,307 | 29,222 | 25,745 | 19,520 | 5,204 | 4,351 |
3815
+ | \`aura\` | 64,723 | 19,667 | 17,322 | 26,741 | 8,302 | 7,048 |
3816
+ | \`avatar\` | 42,839 | 12,494 | 10,995 | 7,505 | 1,803 | 1,560 |
3817
+ | \`badge\` | 39,387 | 11,595 | 10,171 | 4,560 | 1,062 | 908 |
3818
+ | \`bar-chart\` | 100,458 | 30,942 | 27,249 | 27,266 | 6,771 | 5,807 |
3819
+ | \`blockquote\` | 37,335 | 11,206 | 9,842 | 2,106 | 515 | 440 |
3820
+ | \`breadcrumbs\` | 41,907 | 12,315 | 10,809 | 5,802 | 1,315 | 1,112 |
3821
+ | \`button\` | 52,405 | 14,962 | 13,154 | 10,174 | 2,133 | 1,775 |
3822
+ | \`button-group\` | 37,519 | 11,123 | 9,761 | 2,320 | 525 | 423 |
3823
+ | \`callout\` | 40,626 | 12,341 | 10,828 | 3,201 | 822 | 688 |
3824
+ | \`canvas\` | 118,080 | 32,428 | 28,262 | 70,990 | 18,956 | 15,838 |
3825
+ | \`card\` | 39,179 | 11,594 | 10,187 | 3,984 | 993 | 900 |
3826
+ | \`carousel\` | 59,803 | 16,343 | 14,501 | 23,269 | 4,923 | 4,179 |
3827
+ | \`chat\` | 77,805 | 21,908 | 19,228 | 32,518 | 7,775 | 6,583 |
3828
+ | \`checkbox\` | 57,661 | 16,224 | 14,282 | 9,480 | 2,165 | 1,855 |
3829
+ | \`checkbox-group\` | 57,264 | 16,323 | 14,303 | 8,565 | 2,104 | 1,649 |
3830
+ | \`code\` | 35,539 | 10,625 | 9,315 | 1,511 | 382 | 346 |
3831
+ | \`code-block\` | 108,555 | 31,394 | 27,689 | 37,406 | 7,961 | 6,698 |
3832
+ | \`color-input\` | 146,235 | 38,701 | 34,055 | 63,200 | 12,344 | 10,528 |
3833
+ | \`color-picker\` | 104,421 | 26,675 | 23,558 | 50,744 | 10,385 | 8,771 |
3834
+ | \`combobox\` | 125,460 | 35,408 | 31,146 | 42,836 | 9,441 | 7,779 |
3835
+ | \`command\` | 88,011 | 23,835 | 20,911 | 33,255 | 7,793 | 6,494 |
3836
+ | \`copy-button\` | 96,160 | 28,742 | 25,364 | 25,008 | 5,300 | 4,460 |
3837
+ | \`data-table\` | 201,788 | 54,367 | 45,967 | 115,173 | 27,068 | 21,428 |
3838
+ | \`date-input\` | 124,423 | 34,929 | 30,753 | 40,562 | 9,080 | 7,575 |
3839
+ | \`date-picker\` | 61,514 | 17,671 | 15,668 | 18,358 | 4,490 | 3,781 |
3840
+ | \`description-list\` | 38,324 | 11,260 | 9,897 | 3,503 | 770 | 639 |
3841
+ | \`dialog\` | 48,373 | 14,225 | 12,495 | 8,346 | 2,085 | 1,844 |
3842
+ | \`divider\` | 38,349 | 11,463 | 10,044 | 3,120 | 759 | 684 |
3843
+ | \`donut-chart\` | 92,273 | 28,697 | 25,243 | 20,913 | 5,308 | 4,552 |
3844
+ | \`drawer\` | 47,214 | 13,889 | 12,230 | 7,478 | 1,807 | 1,603 |
3845
+ | \`drilldown\` | 55,252 | 16,372 | 14,402 | 11,057 | 2,563 | 2,233 |
3846
+ | \`empty\` | 38,071 | 11,496 | 10,044 | 2,380 | 680 | 571 |
3847
+ | \`file-input\` | 67,640 | 19,220 | 16,970 | 17,570 | 4,210 | 3,572 |
3848
+ | \`filter-input\` | 144,090 | 39,010 | 34,131 | 57,182 | 11,683 | 9,635 |
3849
+ | \`flex\` | 36,900 | 10,980 | 9,665 | 2,078 | 457 | 439 |
3850
+ | \`format-date\` | 41,288 | 12,373 | 10,931 | 4,007 | 990 | 837 |
3851
+ | \`graph\` | 83,551 | 23,062 | 20,255 | 29,630 | 7,000 | 5,989 |
3852
+ | \`grid\` | 38,354 | 11,548 | 10,200 | 3,533 | 1,030 | 906 |
3853
+ | \`heatmap\` | 93,320 | 29,067 | 25,476 | 19,036 | 4,674 | 3,974 |
3854
+ | \`icon\` | 92,568 | 29,773 | 24,662 | 55,130 | 18,562 | 14,930 |
3855
+ | \`icon-button\` | 53,347 | 14,875 | 13,100 | 11,117 | 2,064 | 1,794 |
3856
+ | \`image\` | 39,824 | 11,785 | 10,344 | 4,945 | 1,293 | 1,039 |
3857
+ | \`input\` | 61,246 | 17,959 | 15,650 | 11,826 | 3,284 | 2,612 |
3858
+ | \`kbd\` | 39,279 | 12,016 | 10,550 | 4,443 | 1,386 | 1,204 |
3859
+ | \`legend\` | 45,375 | 13,337 | 11,678 | 5,946 | 1,422 | 1,189 |
3860
+ | \`lightbox\` | 48,856 | 14,326 | 12,602 | 8,073 | 1,990 | 1,755 |
3861
+ | \`line-chart\` | 95,156 | 29,650 | 26,141 | 22,221 | 5,557 | 4,788 |
3862
+ | \`list\` | 41,161 | 11,917 | 10,489 | 5,979 | 1,337 | 1,217 |
3863
+ | \`listbox\` | 71,045 | 20,352 | 17,918 | 18,646 | 4,741 | 4,008 |
3864
+ | \`loader\` | 39,249 | 11,628 | 10,226 | 4,051 | 1,002 | 935 |
3865
+ | \`map\` | 125,745 | 29,962 | 26,027 | 75,027 | 15,272 | 12,380 |
3866
+ | \`megamenu\` | 72,256 | 22,968 | 20,250 | 10,031 | 2,283 | 2,020 |
3867
+ | \`menu\` | 90,293 | 28,100 | 24,730 | 18,270 | 4,214 | 3,586 |
3868
+ | \`meter\` | 44,944 | 12,921 | 11,402 | 9,751 | 2,216 | 2,011 |
3869
+ | \`navigation\` | 42,012 | 12,721 | 11,159 | 3,221 | 853 | 727 |
3870
+ | \`notifications\` | 70,289 | 18,854 | 16,681 | 26,155 | 5,478 | 4,713 |
3871
+ | \`number-input\` | 63,484 | 18,135 | 16,046 | 14,064 | 3,450 | 2,892 |
3872
+ | \`object-inspector\` | 115,606 | 34,265 | 30,127 | 38,251 | 8,743 | 7,365 |
3873
+ | \`option\` | 41,431 | 12,212 | 10,724 | 6,240 | 1,514 | 1,224 |
3874
+ | \`orb\` | 46,194 | 14,632 | 12,903 | 8,724 | 3,180 | 2,797 |
3875
+ | \`outline\` | 45,016 | 13,393 | 11,774 | 8,426 | 2,070 | 1,864 |
3876
+ | \`pagination\` | 133,156 | 37,272 | 32,511 | 54,070 | 12,052 | 9,905 |
3877
+ | \`pin-input\` | 56,633 | 16,422 | 14,490 | 8,694 | 2,372 | 1,964 |
3878
+ | \`popover\` | 69,759 | 22,630 | 19,856 | 5,013 | 1,233 | 1,032 |
3879
+ | \`progress\` | 42,497 | 12,451 | 10,950 | 7,304 | 1,753 | 1,582 |
3880
+ | \`qr-code\` | 49,827 | 15,727 | 13,822 | 15,020 | 5,415 | 4,508 |
3881
+ | \`quote\` | 36,021 | 10,784 | 9,464 | 1,191 | 310 | 253 |
3882
+ | \`radio\` | 61,642 | 16,891 | 14,906 | 11,739 | 2,361 | 1,936 |
3883
+ | \`rating\` | 62,070 | 18,418 | 16,250 | 11,320 | 3,107 | 2,653 |
3884
+ | \`sandbox\` | 75,289 | 19,932 | 17,597 | 37,267 | 8,230 | 6,967 |
3885
+ | \`scatter-chart\` | 92,737 | 29,041 | 25,603 | 20,807 | 5,409 | 4,602 |
3886
+ | \`scroll-area\` | 40,757 | 11,954 | 10,480 | 5,874 | 1,374 | 1,131 |
3887
+ | \`select\` | 112,503 | 32,698 | 28,696 | 33,721 | 7,651 | 6,284 |
3888
+ | \`skeleton\` | 37,735 | 11,283 | 9,898 | 2,535 | 648 | 562 |
3889
+ | \`skip-link\` | 37,991 | 11,464 | 10,049 | 3,008 | 872 | 685 |
3890
+ | \`slider\` | 65,800 | 17,845 | 15,771 | 17,614 | 3,667 | 3,238 |
3891
+ | \`sparkline\` | 46,743 | 14,146 | 12,494 | 6,294 | 1,716 | 1,553 |
3892
+ | \`speed-dial\` | 132,863 | 42,937 | 36,467 | 65,068 | 20,630 | 16,586 |
3893
+ | \`splitter\` | 54,767 | 15,342 | 13,569 | 17,028 | 3,647 | 3,212 |
3894
+ | \`stat\` | 40,105 | 11,640 | 10,261 | 4,916 | 1,070 | 961 |
3895
+ | \`steps\` | 66,243 | 17,909 | 15,727 | 21,460 | 4,323 | 3,617 |
3896
+ | \`switch\` | 54,591 | 15,726 | 13,799 | 6,010 | 1,518 | 1,356 |
3897
+ | \`table\` | 61,309 | 17,888 | 15,730 | 20,596 | 5,314 | 4,492 |
3898
+ | \`tabs\` | 54,198 | 15,497 | 13,584 | 10,627 | 2,163 | 1,852 |
3899
+ | \`tag\` | 42,632 | 12,773 | 11,210 | 4,838 | 1,239 | 1,112 |
3900
+ | \`text\` | 40,822 | 11,755 | 10,289 | 6,004 | 1,304 | 1,035 |
3901
+ | \`textarea\` | 55,847 | 16,040 | 14,071 | 7,423 | 1,859 | 1,566 |
3902
+ | \`time-input\` | 143,685 | 39,361 | 34,464 | 55,836 | 12,143 | 10,069 |
3903
+ | \`time-picker\` | 89,544 | 24,646 | 21,632 | 35,992 | 8,549 | 7,139 |
3904
+ | \`timeline\` | 41,650 | 12,245 | 10,769 | 5,541 | 1,256 | 1,061 |
3905
+ | \`toast\` | 54,188 | 15,651 | 13,762 | 14,595 | 3,373 | 2,922 |
3906
+ | \`toggle\` | 60,461 | 17,172 | 15,120 | 9,041 | 2,121 | 1,774 |
3907
+ | \`toolbar\` | 43,094 | 13,127 | 11,519 | 5,409 | 1,531 | 1,281 |
3908
+ | \`tooltip\` | 72,456 | 23,199 | 20,502 | 10,433 | 2,644 | 2,223 |
3909
+ | \`tour\` | 91,772 | 27,402 | 24,147 | 22,560 | 4,915 | 4,092 |
3910
+ | \`tree\` | 58,944 | 17,328 | 15,238 | 14,181 | 3,488 | 3,071 |
3911
+ | \`trend\` | 39,374 | 11,903 | 10,444 | 3,639 | 961 | 780 |
3912
+ | \`video\` | 135,406 | 38,723 | 33,819 | 58,745 | 13,560 | 11,359 |
3913
+ | \`video-playlist\` | 103,336 | 30,436 | 26,772 | 29,918 | 6,351 | 5,376 |
3914
+ | \`virtual-list\` | 47,010 | 14,410 | 12,652 | 4,770 | 1,433 | 1,136 |
3752
3915
 
3753
3916
  ## What an install adds to \`node_modules\`
3754
3917
 
@@ -3760,18 +3923,18 @@ stripped column shows the bytes we removed.
3760
3923
 
3761
3924
  | Package | Unpacked | Files | Source maps stripped | Runtime dependencies |
3762
3925
  |---|---|---|---|---|
3763
- | \`@fusion.dev/helix-core\` | 1,219,204 | 179 | 274,659 | \`@floating-ui/dom\`, \`@fusion.dev/helix-icons\` |
3764
- | \`@fusion.dev/helix-headless\` | 13,709,247 | 511 | 1,079,071 | \`@fusion.dev/helix-core\`, \`@fusion.dev/helix-icons\`, \`uqr\` |
3765
- | \`@fusion.dev/helix-icons\` | 150,162 | 21 | 50,346 | \`svgo\` |
3926
+ | \`@fusion.dev/helix-core\` | 1,326,497 | 181 | 307,309 | \`@floating-ui/dom\`, \`@fusion.dev/helix-icons\` |
3927
+ | \`@fusion.dev/helix-headless\` | 14,918,832 | 511 | 1,228,029 | \`@fusion.dev/helix-core\`, \`@fusion.dev/helix-icons\`, \`uqr\` |
3928
+ | \`@fusion.dev/helix-icons\` | 149,615 | 21 | 47,843 | \`svgo\` |
3766
3929
  | \`@fusion.dev/helix-styles\` | 106,097 | 6 | 0 | none |
3767
3930
  | \`@fusion.dev/helix-theme\` | 528,598 | 8 | 5,393 | none |
3768
- | \`@fusion.dev/helix\` | 14,852,492 | 877 | 373,887 | \`@fusion.dev/helix-core\`, \`@fusion.dev/helix-headless\`, \`@fusion.dev/helix-styles\` |
3931
+ | \`@fusion.dev/helix\` | 15,761,419 | 877 | 378,696 | \`@fusion.dev/helix-core\`, \`@fusion.dev/helix-headless\`, \`@fusion.dev/helix-styles\` |
3769
3932
 
3770
3933
  ## Not measured yet
3771
3934
 
3772
3935
  We list these gaps so you know what the numbers above leave out.
3773
3936
 
3774
- - **No whole-library comparison, and no more than five components.** The comparison above covers five components in four systems. Adding a component means choosing the matching element in each system by hand, so we add components one at a time.
3937
+ - **No whole-library comparison, and a short list of components.** Adding a component means choosing the matching element in each system by hand, so we add components one at a time.
3775
3938
  - **The peer numbers are pinned, so they age.** The comparison shows the date they were measured. Run \`turbo run peers\` to refresh them. No check fails when they are old. Another library's release changes nothing in this repository, so a check based on the date would fail for no useful reason.
3776
3939
  - **No first paint.** The timings above measure single components. First paint depends on the whole page, so the app that renders the page should measure it.
3777
3940
  - **No per-component stylesheet bytes.** Each family's CSS is compiled into its JavaScript, so every number above already includes it. \`elements.css\` is the light-DOM layer, and it is in the stylesheet table.
@@ -3943,10 +4106,11 @@ it.
3943
4106
  ## Register the elements
3944
4107
 
3945
4108
  \`\`\`ts
3946
- import '@fusion.dev/helix'
4109
+ import '@fusion.dev/helix/button'
4110
+ import '@fusion.dev/helix/dialog'
3947
4111
  \`\`\`
3948
4112
 
3949
- Import it once, anywhere that runs in the browser. The stylesheets are the same
4113
+ Import each family you use once, anywhere that runs in the browser. The stylesheets are the same
3950
4114
  in every framework, and they are the part most often left out. See
3951
4115
  [Installation](./installation) for the stylesheets.
3952
4116
  `,
@@ -4022,13 +4186,27 @@ checks focus by walking through the shadow roots.
4022
4186
  Nested overlays work because lifecycle events do not bubble.
4023
4187
  \`helix-before-open\` and \`helix-before-close\` do not bubble and are not composed,
4024
4188
  so a menu that closes inside a dialog does not close the dialog. \`Escape\` closes
4025
- the innermost overlay and leaves the others open.
4189
+ the innermost overlay and leaves the others open. The overlay that closes
4190
+ cancels the key press, so a \`Dialog\` or \`Drawer\` around it stays open until you
4191
+ press \`Escape\` again.
4026
4192
 
4027
4193
  ## Where focus goes
4028
4194
 
4029
4195
  A modal overlay keeps \`Tab\` inside itself while it is open, and it returns focus
4030
- to the element that opened it. \`Dialog\` and \`Drawer\` always do this. \`Popover\`
4031
- does it only in its modal mode.
4196
+ to the element that opened it. \`Dialog\` does this, and so does \`Drawer\` unless
4197
+ you set \`modal="false"\`. The page behind a modal \`Dialog\` or \`Drawer\` does not
4198
+ scroll while it is open.
4199
+
4200
+ \`Popover\` does not trap focus. When focus moves out of its trigger and its
4201
+ panel, the popover closes.
4202
+
4203
+ The fields with a panel behave the same way:
4204
+
4205
+ - \`Select\` and \`Combobox\` close their list when \`Tab\` moves focus out.
4206
+ - \`Date Input\`, \`Time Input\`, and \`Color Input\` close their panel when focus
4207
+ leaves the field, and \`Escape\` returns focus to the field.
4208
+ - Opening one of those panels from its trigger, or with \`ArrowDown\`, moves
4209
+ focus into the panel.
4032
4210
 
4033
4211
  **A tooltip never takes focus.** A tooltip only describes a control, so it
4034
4212
  cannot contain a button. For something with a button in it, use a \`Popover\`.
@@ -4379,7 +4557,9 @@ See [State and control](./state-and-control) for the full model.
4379
4557
 
4380
4558
  \`\`\`tsx
4381
4559
  'use client'
4382
- import '@fusion.dev/helix'
4560
+ // One line per family you use.
4561
+ import '@fusion.dev/helix/button'
4562
+ import '@fusion.dev/helix/dialog'
4383
4563
 
4384
4564
  export const HelixElements = () => null
4385
4565
  \`\`\`
@@ -4852,20 +5032,84 @@ without tracking which element sent each event. A pane named \`html\` sets the
4852
5032
  preview's markup, and a pane named \`css\` sets its stylesheet. The sandbox
4853
5033
  ignores a pane with any other name, so that pane only displays its contents.
4854
5034
 
5035
+ A pane's text goes in its \`value\`. The pane renders no children. The sandbox
5036
+ also hands each pane's \`value\` to the preview when it starts, so you write the
5037
+ text once, in the pane. A preview given its own \`source\` keeps it until the
5038
+ first edit.
5039
+
4855
5040
  \`\`\`html
4856
5041
  <helix-sandbox>
4857
5042
  <helix-sandbox-source
4858
5043
  name="html"
4859
5044
  slot="source"
4860
- >…</helix-sandbox-source>
5045
+ value="<p>Hello</p>"
5046
+ ></helix-sandbox-source>
4861
5047
  <helix-sandbox-source
4862
5048
  name="css"
4863
5049
  slot="source"
4864
- >…</helix-sandbox-source>
4865
- <helix-sandbox-preview slot="preview"></helix-sandbox-preview>
5050
+ value="p { color: teal }"
5051
+ ></helix-sandbox-source>
5052
+ <helix-sandbox-preview
5053
+ slot="preview"
5054
+ src="/frame.html"
5055
+ ></helix-sandbox-preview>
4866
5056
  </helix-sandbox>
4867
5057
  \`\`\`
4868
5058
 
5059
+ Cancel \`helix-before-edit\` to refuse an edit. The pane keeps its text, and the
5060
+ preview does not receive the refused one.
5061
+
5062
+ In a source pane, Tab inserts two spaces. Shift+Tab moves focus back, and
5063
+ Escape then Tab moves it forward. The field's description says this to a
5064
+ screen reader.
5065
+
5066
+ ## The frame document
5067
+
5068
+ \`helix-sandbox-preview\` loads \`src\` into a sandboxed frame. You provide that
5069
+ document. It loads the styles and the elements your examples use, and it talks
5070
+ to the preview through \`postMessage\`:
5071
+
5072
+ | Message | Sent by | What it carries |
5073
+ |---|---|---|
5074
+ | \`helix-preview-console\` | The frame | One console call: \`level\` (\`log\`, \`info\`, \`warn\` or \`error\`) and \`text\` |
5075
+ | \`helix-preview-press\` | The frame | Nothing. Send it on \`pointerdown\`, so menus outside the frame close |
5076
+ | \`helix-preview-ready\` | The frame | Nothing. Send it once the listener for renders is in place |
5077
+ | \`helix-preview-render\` | The preview | \`source\`, \`styles\`, \`layout\`, \`direction\` and an optional \`colorMode\` |
5078
+ | \`helix-preview-size\` | The frame | \`size\`, the height of the content in CSS pixels |
5079
+
5080
+ Each message is an object with a \`type\` naming it. The preview sends
5081
+ \`helix-preview-render\` once the frame posts \`helix-preview-ready\` or fires
5082
+ \`load\`, and again after each edit settles. The frame writes \`source\` into its
5083
+ body and \`styles\` into a stylesheet. The preview accepts a message only from
5084
+ its own frame, and only from an opaque origin, so the frame keeps the sandbox
5085
+ it was given. The types are exported from \`@fusion.dev/helix/sandbox\` as
5086
+ \`PreviewMessage\` and its members.
5087
+
5088
+ A minimal frame follows. \`/helix.css\` is the stylesheet from
5089
+ \`@fusion.dev/helix-styles\`, and \`/elements.js\` is a classic script that
5090
+ registers your elements, for the reason under "How the preview is isolated".
5091
+
5092
+ \`\`\`html
5093
+ <!doctype html>
5094
+ <link
5095
+ href="/helix.css"
5096
+ rel="stylesheet"
5097
+ >
5098
+ <script
5099
+ defer
5100
+ src="/elements.js"
5101
+ ></script>
5102
+ <style id="example-styles"></style>
5103
+ <script defer>
5104
+ addEventListener('message', ({ data }) => {
5105
+ if (data?.type !== 'helix-preview-render') return
5106
+ document.getElementById('example-styles').textContent = data.styles
5107
+ document.body.innerHTML = data.source
5108
+ })
5109
+ parent.postMessage({ type: 'helix-preview-ready' }, '*')
5110
+ </script>
5111
+ \`\`\`
5112
+
4869
5113
  ## Console output from the example
4870
5114
 
4871
5115
  Logs from the example appear in the console panel. Logs from the page around it
@@ -4940,7 +5184,7 @@ browser. Load Lit's hydration support before the components:
4940
5184
 
4941
5185
  \`\`\`ts
4942
5186
  import '@lit-labs/ssr-client/lit-element-hydrate-support.js'
4943
- import '@fusion.dev/helix'
5187
+ import '@fusion.dev/helix/button'
4944
5188
  \`\`\`
4945
5189
 
4946
5190
  Hydration assumes the markup already matches the client's first render. If a
@@ -5454,6 +5698,12 @@ current value. The pair comes from the platform. A native input reflects its
5454
5698
  \`value\` *content attribute* to \`defaultValue\`, and it keeps a dirty flag. Once a
5455
5699
  user has typed, the flag stops the attribute from changing the value.
5456
5700
 
5701
+ **A form reset clears a \`value\` or \`checked\` you wrote in markup.** A native
5702
+ \`<input value="Ada">\` resets to \`Ada\`, and \`<helix-input value="Ada">\` resets to
5703
+ empty, because a Helix control resets to \`default-value\` and \`default-checked\`.
5704
+ Write the starting value of a form control as \`default-value\`, or
5705
+ \`default-checked\` for a checkbox or a switch.
5706
+
5457
5707
  ## State is published as a custom state
5458
5708
 
5459
5709
  \`\`\`css
@@ -5468,7 +5718,8 @@ A reflected \`value\` would carry the password past every session-replay masker
5468
5718
  that masks \`.value\` and \`input[value]\`.
5469
5719
 
5470
5720
  Helix publishes the resolved boolean as a custom state, and the attribute keeps
5471
- the value you wrote. There are four custom states:
5721
+ the value you wrote. These are the most common, and each component's reference
5722
+ page lists the states it publishes:
5472
5723
 
5473
5724
  - \`:state(open)\`
5474
5725
  - \`:state(checked)\`
@@ -5625,7 +5876,7 @@ and you do not need a compiler flag.
5625
5876
  Svelte passes objects and arrays as properties on its own:
5626
5877
 
5627
5878
  \`\`\`svelte
5628
- <helix-tabs items={tabs} />
5879
+ <helix-data-table label="People" rows={people} />
5629
5880
  \`\`\`
5630
5881
 
5631
5882
  Svelte's own attributes are typed on every Helix tag as well, so \`onclick\`,
@@ -5928,7 +6179,11 @@ Mark the section so the stylesheet derives its own colors there from the
5928
6179
  section's seeds, in the section's mode, and paint it with its page color:
5929
6180
 
5930
6181
  \`\`\`html
5931
- <section data-band data-color-mode="dark" data-helix-theme>…</section>
6182
+ <section
6183
+ data-band
6184
+ data-color-mode="dark"
6185
+ data-helix-theme
6186
+ >…</section>
5932
6187
  \`\`\`
5933
6188
 
5934
6189
  \`\`\`css
@@ -6504,7 +6759,7 @@ looks enabled while it does not accept input.
6504
6759
 
6505
6760
  \`\`\`ts
6506
6761
  import '@fusion.dev/helix-styles/helix.css'
6507
- import '@fusion.dev/helix'
6762
+ import '@fusion.dev/helix/button'
6508
6763
  \`\`\`
6509
6764
 
6510
6765
  \`helix.css\` combines four files in the order they must load:
@@ -6741,10 +6996,12 @@ button.
6741
6996
  ## Import \`elements.css\` beside the base layer
6742
6997
 
6743
6998
  \`\`\`ts
6744
- import '@fusion.dev/helix-styles/base.css'
6745
6999
  import '@fusion.dev/helix-styles/helix.css'
6746
7000
  \`\`\`
6747
7001
 
7002
+ \`helix.css\` imports \`elements.css\` after the primitives, the tokens, and the
7003
+ base layer. If you import the layers one at a time, import \`elements.css\` last.
7004
+
6748
7005
  \`elements.css\` hides each tag with \`:not(:defined)\` until the element upgrades.
6749
7006
  It uses \`visibility\`, so the page does not reflow. Without it, a card appears as
6750
7007
  unstyled text and then jumps into its card layout.
@@ -6763,6 +7020,24 @@ import '@fusion.dev/helix' // ❌ the barrel
6763
7020
  Import one component family per module, so you do not ship the whole library to
6764
7021
  use a button.
6765
7022
 
7023
+ ## Turn off an attribute that is on by default
7024
+
7025
+ A boolean attribute is off until you write it, with four exceptions. These are
7026
+ on until you write the string \`"false"\`:
7027
+
7028
+ - \`modal\` on Drawer
7029
+ - \`playsinline\` on Video
7030
+ - \`default-pinned\` on Chat
7031
+ - \`tab-indents\` on Sandbox Source
7032
+
7033
+ \`\`\`html
7034
+ <helix-drawer modal="false"></helix-drawer>
7035
+ \`\`\`
7036
+
7037
+ In JSX, \`modal={false}\` sets the property and does the same. Other features
7038
+ that are on by default turn off with an attribute named \`no-\`, such as
7039
+ \`no-copy\`.
7040
+
6766
7041
  ## Declarative shadow DOM is opt-in
6767
7042
 
6768
7043
  The site ships no declarative shadow DOM (DSD). The shadow styles load with the
@@ -7205,7 +7480,8 @@ That works for every Helix element. A string goes through either path, and an
7205
7480
  array or an object goes through the property.
7206
7481
 
7207
7482
  \`\`\`vue
7208
- <helix-tabs :items="items" @helix-before-activate="onActivate" />
7483
+ <helix-data-table label="People" :rows="people" />
7484
+ <helix-tabs @helix-before-activate="onActivate" />
7209
7485
  \`\`\`
7210
7486
 
7211
7487
  \`@helix-before-activate\` binds with \`addEventListener\`, so use the event's own