@fusion.dev/helix-docs 0.142.1 → 0.144.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/content/accessibility.mdx +28 -7
- package/content/building-on-the-headless-tier.mdx +21 -18
- package/content/charting.mdx +26 -0
- package/content/color.mdx +2 -2
- package/content/composition.mdx +15 -7
- package/content/events.mdx +30 -2
- package/content/forms.mdx +46 -7
- package/content/graphs.mdx +25 -7
- package/content/installation.mdx +17 -19
- package/content/introduction.mdx +3 -3
- package/content/localization.mdx +28 -2
- package/content/maps.mdx +18 -4
- package/content/metrics.mdx +230 -228
- package/content/other-frameworks.mdx +3 -2
- package/content/overlays.mdx +44 -3
- package/content/react.mdx +3 -1
- package/content/sandbox.mdx +67 -3
- package/content/server-rendering.mdx +1 -1
- package/content/state-and-control.mdx +8 -1
- package/content/svelte.mdx +1 -1
- package/content/theming.mdx +5 -1
- package/content/using-helix-with-an-agent.mdx +1 -1
- package/content/using-the-elements.mdx +21 -1
- package/content/vue.mdx +2 -1
- package/dist/sources.generated.js +644 -321
- package/package.json +9 -9
|
@@ -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\`,
|
|
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
|
-
-
|
|
26
|
+
- In \`Listbox\`, \`Select\`, \`Menu\`, and \`Tree\`, typing jumps to a matching item.
|
|
26
27
|
|
|
27
28
|
### Focus
|
|
28
29
|
|
|
@@ -66,6 +67,13 @@ words are yours to choose. An icon-only control has no other text to name it:
|
|
|
66
67
|
></helix-icon-button>
|
|
67
68
|
\`\`\`
|
|
68
69
|
|
|
70
|
+
A button or a form control that renders with no name warns once in the console:
|
|
71
|
+
\`<helix-icon-button> has no accessible name\`, followed by the ways to give it
|
|
72
|
+
one. The check runs a moment after the control first renders, so a label your
|
|
73
|
+
framework writes beside the control in the same pass counts. The warning has the
|
|
74
|
+
kind \`missing-name\`, so \`@fusion.dev/helix-diagnostics\` counts it with the
|
|
75
|
+
other runtime events.
|
|
76
|
+
|
|
69
77
|
### \`label\` and \`aria-label\`
|
|
70
78
|
|
|
71
79
|
\`label\` renders visible text and names the control through that text.
|
|
@@ -107,11 +115,24 @@ and is read where it sits. Neither component is a variant of the other.
|
|
|
107
115
|
|
|
108
116
|
\`aria-labelledby\` and \`aria-describedby\` inside a shadow root cannot point to an
|
|
109
117
|
id in your document. The browser drops the reference silently and reports no
|
|
110
|
-
error. For this reason, every control renders its own label
|
|
111
|
-
|
|
118
|
+
error. For this reason, every control renders its own label. See
|
|
119
|
+
[Forms and validation](./forms).
|
|
120
|
+
|
|
121
|
+
**What you write on the host reaches the control inside it.** The form controls,
|
|
122
|
+
\`Button\`, and \`IconButton\` carry these down to the element a screen reader is on:
|
|
123
|
+
|
|
124
|
+
- \`aria-labelledby\` and \`aria-describedby\`, as element references, so the ids
|
|
125
|
+
you name in your document resolve.
|
|
126
|
+
- A \`<label for>\` that points at the host, or a \`<label>\` around it, when the
|
|
127
|
+
control has no \`label\` of its own.
|
|
128
|
+
- \`aria-expanded\`, \`aria-haspopup\`, \`aria-controls\`, \`aria-invalid\`, and
|
|
129
|
+
\`aria-pressed\`.
|
|
130
|
+
- \`aria-label\` on \`Button\`, \`IconButton\`, and \`Switch\`. A field renders its
|
|
131
|
+
\`aria-label\` as a hidden label.
|
|
112
132
|
|
|
113
|
-
A \`<label
|
|
114
|
-
|
|
133
|
+
A \`<label>\` around a control also reads the words inside the control, such as
|
|
134
|
+
the names of its buttons. Use \`<label for>\` or the control's own \`label\` to name
|
|
135
|
+
it with your words alone.
|
|
115
136
|
|
|
116
137
|
When a relationship has to cross the boundary, the components use
|
|
117
138
|
\`ElementInternals\` and element-reference properties. They are the only mechanism
|
|
@@ -335,8 +356,8 @@ customElements.define('acme-combobox', AcmeCombobox)
|
|
|
335
356
|
\`\`\`
|
|
336
357
|
|
|
337
358
|
That one line sets the prefix. The styled tier sets its prefix the same way, with
|
|
338
|
-
\`static override tier = 'helix-'\` and nothing else.
|
|
339
|
-
|
|
359
|
+
\`static override tier = 'helix-'\` and nothing else. Every element in the
|
|
360
|
+
headless manifest carries the static, so you can find it there.
|
|
340
361
|
|
|
341
362
|
## Register every component a component renders
|
|
342
363
|
|
|
@@ -349,12 +370,13 @@ open.
|
|
|
349
370
|
|
|
350
371
|
[//]: # (renders)
|
|
351
372
|
|
|
352
|
-
**
|
|
373
|
+
**28 of the 98 headless families interpolate another family's tag**, across 20 distinct children.
|
|
353
374
|
|
|
354
375
|
| Family | Renders |
|
|
355
376
|
|---|---|
|
|
356
377
|
| \`area-chart\`, \`bar-chart\`, \`copy-button\`, \`donut-chart\`, \`heatmap\`, \`line-chart\`, \`scatter-chart\` | \`tooltip\` |
|
|
357
378
|
| \`chat\` | \`chat-message\` |
|
|
379
|
+
| \`checkbox-group\` | \`checkbox\` |
|
|
358
380
|
| \`code-block\`, \`object-inspector\` | \`copy-button\` |
|
|
359
381
|
| \`color-input\` | \`color-picker\` |
|
|
360
382
|
| \`color-picker\` | \`button\`, \`button-group\`, \`slider\` |
|
|
@@ -404,24 +426,26 @@ Use \`visibility\` so the page does not reflow when the definitions arrive.
|
|
|
404
426
|
|
|
405
427
|
### Typings for your tags
|
|
406
428
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
beside your \`package.json\`:
|
|
429
|
+
Your typings come from a manifest of your package. \`helix manifest build\`, in
|
|
430
|
+
\`@fusion.dev/helix-cli\`, writes one that includes every member your subclasses
|
|
431
|
+
inherit from ours. Name each Helix package you extend and where its manifest is:
|
|
411
432
|
|
|
412
|
-
\`\`\`
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
tier: 'styled',
|
|
419
|
-
} satisfies HelixCemOptions
|
|
433
|
+
\`\`\`sh
|
|
434
|
+
helix manifest build . --tier styled \\
|
|
435
|
+
--dependency @fusion.dev/helix=node_modules/@fusion.dev/helix/custom-elements.json \\
|
|
436
|
+
--dependency @fusion.dev/helix-headless=node_modules/@fusion.dev/helix-headless/custom-elements.json \\
|
|
437
|
+
--dependency @fusion.dev/helix-core=node_modules/@fusion.dev/helix-core/custom-elements.json \\
|
|
438
|
+
> custom-elements.json
|
|
420
439
|
\`\`\`
|
|
421
440
|
|
|
422
|
-
Then run
|
|
423
|
-
\`
|
|
424
|
-
members it inherits, as well as
|
|
441
|
+
Then run a typings generator over it. Our own typings start from
|
|
442
|
+
\`@wc-toolkit/jsx-types\` and \`@wc-toolkit/vuejs-types\`. The typings for
|
|
443
|
+
\`acme-combobox\` then include the hundred or so members it inherits, as well as
|
|
444
|
+
the two you wrote.
|
|
445
|
+
|
|
446
|
+
\`@fusion.dev/helix-cem\`, the step that runs those generators for our packages
|
|
447
|
+
and corrects what they write, is not published. It is build tooling for this
|
|
448
|
+
repository.
|
|
425
449
|
|
|
426
450
|
### The tag map
|
|
427
451
|
|
|
@@ -576,6 +600,32 @@ table should not be seen, hide it visually, and the data is still there:
|
|
|
576
600
|
The table's caption becomes the chart's accessible name unless you set \`label\`.
|
|
577
601
|
The caption usually has the right words already.
|
|
578
602
|
|
|
603
|
+
Each chart writes a short summary for screen readers, which starts with that
|
|
604
|
+
name. The drawing is hidden from screen readers, and the summary gives the one
|
|
605
|
+
reading a chart is usually read for:
|
|
606
|
+
|
|
607
|
+
- \`Bar Chart\`: each series' highest reading.
|
|
608
|
+
- \`Line Chart\`: each series' latest reading.
|
|
609
|
+
- \`Area Chart\`: the latest total and each part's share of it.
|
|
610
|
+
- \`Donut Chart\`: each slice's share of the whole.
|
|
611
|
+
- \`Scatter Chart\`: each series' number of points and how strongly the two
|
|
612
|
+
measures relate.
|
|
613
|
+
|
|
614
|
+
\`Heatmap\` is an image with that name. \`Sparkline\` takes a \`label\` of its own.
|
|
615
|
+
|
|
616
|
+
## Tables that change
|
|
617
|
+
|
|
618
|
+
A chart follows its table. It redraws when you edit a cell, add a row, or
|
|
619
|
+
replace the table with a new one under the same id. It also draws a table that
|
|
620
|
+
arrives after the chart does, such as one a framework renders once its data
|
|
621
|
+
loads.
|
|
622
|
+
|
|
623
|
+
A blank cell, or one that does not hold a number, is a gap in its series. The
|
|
624
|
+
row keeps its place on the axis, a line breaks at the gap, a bar chart draws no
|
|
625
|
+
bar there, and a heatmap draws the cell with no tone. The readings after the gap
|
|
626
|
+
stay under their own labels, and the tooltip for that row still shows the
|
|
627
|
+
row's cells.
|
|
628
|
+
|
|
579
629
|
## Series colors
|
|
580
630
|
|
|
581
631
|
Helix has twenty-four series color tokens, in order, from
|
|
@@ -804,8 +854,8 @@ title: Color
|
|
|
804
854
|
|
|
805
855
|
# Color
|
|
806
856
|
|
|
807
|
-
|
|
808
|
-
theme. Each color token is named for its role. No token is named for how it
|
|
857
|
+
Colors are the largest group of the library's tokens, and they make up most of
|
|
858
|
+
a theme. Each color token is named for its role. No token is named for how it
|
|
809
859
|
looks, because a name like \`--brand-blue-500\` becomes wrong as soon as you change
|
|
810
860
|
the theme.
|
|
811
861
|
|
|
@@ -1066,11 +1116,18 @@ for a slot of the same name. Helix never renders both.
|
|
|
1066
1116
|
|
|
1067
1117
|
\`\`\`html
|
|
1068
1118
|
<!-- The property -->
|
|
1069
|
-
<helix-tooltip
|
|
1119
|
+
<helix-tooltip
|
|
1120
|
+
content="Save"
|
|
1121
|
+
for="save"
|
|
1122
|
+
id="save-tip"
|
|
1123
|
+
></helix-tooltip>
|
|
1070
1124
|
|
|
1071
1125
|
<!-- The slot, which replaces it -->
|
|
1072
|
-
<helix-tooltip
|
|
1073
|
-
|
|
1126
|
+
<helix-tooltip
|
|
1127
|
+
for="save"
|
|
1128
|
+
id="save-tip"
|
|
1129
|
+
>
|
|
1130
|
+
<span slot="content"><strong>Save</strong>, or press <helix-kbd>⌘S</helix-kbd></span>
|
|
1074
1131
|
</helix-tooltip>
|
|
1075
1132
|
\`\`\`
|
|
1076
1133
|
|
|
@@ -1084,8 +1141,9 @@ examples put the closing tag on the same line as the opening tag.
|
|
|
1084
1141
|
|
|
1085
1142
|
## Set a button's width with the layout
|
|
1086
1143
|
|
|
1087
|
-
A button has no \`
|
|
1088
|
-
|
|
1144
|
+
A button has no \`fill\` property and no \`size\` property. How wide a control is
|
|
1145
|
+
depends on the region it is in. \`width="full"\` fills the row a button sits in,
|
|
1146
|
+
and the layout decides everything else.
|
|
1089
1147
|
|
|
1090
1148
|
A button already stretches in a column flex or a grid, because a stretch-aligned
|
|
1091
1149
|
parent stretches its children:
|
|
@@ -1163,8 +1221,8 @@ and then a second attribute to hide it is the same as having no visible label.
|
|
|
1163
1221
|
|
|
1164
1222
|
\`Option\`, \`Listbox\`, and \`Select\` are three families so that the keyboard
|
|
1165
1223
|
handling, the filtering, the multi-select rules, and the active-item tracking
|
|
1166
|
-
are written once. \`Select\` renders a \`Listbox\` internally
|
|
1167
|
-
|
|
1224
|
+
are written once. \`Select\` renders a \`Listbox\` internally, and so does \`Combobox\`. A command
|
|
1225
|
+
palette would too.
|
|
1168
1226
|
|
|
1169
1227
|
For the same reason, we wrote \`DrilldownController\`. Since it was first written,
|
|
1170
1228
|
\`Menu\` had held a page stack and derived its rows, and none of that code
|
|
@@ -1376,6 +1434,10 @@ against a dispatch, so every event you can listen for is documented.
|
|
|
1376
1434
|
| \`helix-before-change\` | A value is about to change, cancelable |
|
|
1377
1435
|
| \`helix-before-toggle\` | A checked state is about to flip, cancelable |
|
|
1378
1436
|
| \`helix-before-open\`, \`helix-before-close\` | An open state is about to change, cancelable |
|
|
1437
|
+
| \`helix-before-activate\`, \`helix-activate\` | A set is about to make a different child current, cancelable, and then did |
|
|
1438
|
+
| \`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 |
|
|
1439
|
+
| \`helix-before-resize\`, \`helix-resized\` | A splitter's divider is about to settle, cancelable, and then did |
|
|
1440
|
+
| \`helix-before-collapse\`, \`helix-collapse\` | A splitter's pane is about to shut or reopen, cancelable, and then did |
|
|
1379
1441
|
| \`helix-select\` | An item was chosen from a set |
|
|
1380
1442
|
| \`helix-dismiss\` | A user asked for something to close |
|
|
1381
1443
|
| \`helix-next\`, \`helix-previous\` | Movement through a sequence |
|
|
@@ -1392,12 +1454,36 @@ Every stateful component also sends native events once the change is applied:
|
|
|
1392
1454
|
|
|
1393
1455
|
- \`input\` and \`change\` on a value control
|
|
1394
1456
|
- \`toggle\` on anything that opens, carrying \`newState\` and \`oldState\` as
|
|
1395
|
-
\`<details>\` does
|
|
1457
|
+
\`<details>\` does. It is a \`ToggleEvent\` in browsers that have one, and it is
|
|
1458
|
+
sent whether the change came from a reader or from assigning \`open\`
|
|
1396
1459
|
- \`close\` on a dialog
|
|
1397
1460
|
- \`load\` and \`error\` on an image
|
|
1398
1461
|
|
|
1399
1462
|
Each component's page lists the events it dispatches, with the class and the
|
|
1400
|
-
detail.
|
|
1463
|
+
detail. The table above lists the common ones.
|
|
1464
|
+
|
|
1465
|
+
## Requests under a plain name
|
|
1466
|
+
|
|
1467
|
+
A few events with no \`before\` in their name are also cancelable requests. Each
|
|
1468
|
+
is sent before the change, and you refuse the change with \`preventDefault()\`:
|
|
1469
|
+
|
|
1470
|
+
- \`helix-navigate\` on Pagination, Data Table, and Date Picker
|
|
1471
|
+
- \`helix-sort\`, \`helix-filter\`, \`helix-select\`, and \`helix-reorder\` on Data Table
|
|
1472
|
+
- \`helix-select\` on Carousel
|
|
1473
|
+
|
|
1474
|
+
Each of these requests had its name before the library had a word for the
|
|
1475
|
+
notification, so the notification has its own name. It is sent after the
|
|
1476
|
+
change, is not cancelable, and carries the new state:
|
|
1477
|
+
|
|
1478
|
+
- \`helix-activate\` after the page moves on Pagination and Data Table, and after
|
|
1479
|
+
the slide moves on Carousel
|
|
1480
|
+
- \`helix-sorted\`, \`helix-filtered\`, \`helix-selected\`, and \`helix-reordered\` on
|
|
1481
|
+
Data Table
|
|
1482
|
+
- \`input\` and \`change\` together on Pagination Size, as a native \`<select>\`
|
|
1483
|
+
sends them
|
|
1484
|
+
|
|
1485
|
+
A request that is refused sends no notification. Date Picker's \`helix-navigate\`
|
|
1486
|
+
moves the month on show, and the month sends no notification.
|
|
1401
1487
|
|
|
1402
1488
|
## Events in a framework
|
|
1403
1489
|
|
|
@@ -1510,23 +1596,62 @@ participants:
|
|
|
1510
1596
|
></helix-input>
|
|
1511
1597
|
\`\`\`
|
|
1512
1598
|
|
|
1513
|
-
Submitting an empty form is blocked, and the browser
|
|
1514
|
-
|
|
1515
|
-
|
|
1599
|
+
Submitting an empty form is blocked, and the browser moves focus to the control
|
|
1600
|
+
and shows its message there. Each control has the validity API of a native
|
|
1601
|
+
control:
|
|
1602
|
+
|
|
1603
|
+
- \`checkValidity()\` and \`reportValidity()\`
|
|
1604
|
+
- \`setCustomValidity(message)\`
|
|
1605
|
+
- \`validity\`, \`validationMessage\`, and \`willValidate\`
|
|
1516
1606
|
|
|
1517
|
-
\`
|
|
1518
|
-
|
|
1519
|
-
|
|
1607
|
+
\`:invalid\` matches the control as it matches a native one.
|
|
1608
|
+
|
|
1609
|
+
\`value-missing-message\` replaces the browser's message for a required control
|
|
1610
|
+
that is empty. When it is not set, the browser shows its own message, which is
|
|
1611
|
+
localized and familiar:
|
|
1520
1612
|
|
|
1521
1613
|
\`\`\`html
|
|
1522
1614
|
<helix-input
|
|
1523
|
-
feedback="We need this to send your receipt."
|
|
1524
1615
|
label="Email"
|
|
1525
1616
|
name="email"
|
|
1526
1617
|
required
|
|
1618
|
+
value-missing-message="We need this to send your receipt."
|
|
1527
1619
|
></helix-input>
|
|
1528
1620
|
\`\`\`
|
|
1529
1621
|
|
|
1622
|
+
**\`feedback\` says what is wrong, and the form does not submit while it is
|
|
1623
|
+
set.** Use it for a verdict the browser cannot reach, such as one your server
|
|
1624
|
+
returned. The control shows the message under itself and is invalid until you
|
|
1625
|
+
clear \`feedback\`:
|
|
1626
|
+
|
|
1627
|
+
\`\`\`html
|
|
1628
|
+
<helix-input
|
|
1629
|
+
feedback="That name is taken."
|
|
1630
|
+
label="Username"
|
|
1631
|
+
name="username"
|
|
1632
|
+
></helix-input>
|
|
1633
|
+
\`\`\`
|
|
1634
|
+
|
|
1635
|
+
\`setCustomValidity()\` blocks the form in the same way, and the control shows
|
|
1636
|
+
its message once the reader has edited the field.
|
|
1637
|
+
|
|
1638
|
+
## Focus and Enter
|
|
1639
|
+
|
|
1640
|
+
\`focus()\` on a control moves focus to the element a reader would reach with
|
|
1641
|
+
Tab, and pressing a \`<label>\` that names the control does the same. In a group,
|
|
1642
|
+
that is the chosen radio, or the first one when nothing is chosen.
|
|
1643
|
+
|
|
1644
|
+
Pressing Enter in a single-line field submits its form, as Enter in a native
|
|
1645
|
+
text field does. These fields do it:
|
|
1646
|
+
|
|
1647
|
+
- \`Input\`, \`NumberInput\`, and \`PinInput\`
|
|
1648
|
+
- \`DateInput\`, \`TimeInput\`, and \`ColorInput\`
|
|
1649
|
+
- \`Combobox\`, while its list is closed
|
|
1650
|
+
|
|
1651
|
+
The form's first submit button is pressed, and a \`helix-button type="submit"\`
|
|
1652
|
+
counts as one, for a native field too. A form with no submit button is
|
|
1653
|
+
submitted when it has only one text field.
|
|
1654
|
+
|
|
1530
1655
|
\`Radio.Group\` and \`Toggle.Group\` take part in the form for their members. Each
|
|
1531
1656
|
group owns the \`name\`, the \`value\`, and the validity. A single radio is an
|
|
1532
1657
|
answer, and the group is the control it answers. \`Checkbox.Group\` works the
|
|
@@ -1620,7 +1745,7 @@ Add the frame, with an element inside it for the renderer to draw in:
|
|
|
1620
1745
|
Give the frame its notes and links, make the renderer, and connect the two:
|
|
1621
1746
|
|
|
1622
1747
|
\`\`\`js
|
|
1623
|
-
import '@fusion.dev/helix'
|
|
1748
|
+
import '@fusion.dev/helix/graph'
|
|
1624
1749
|
import { connectGraph } from '@fusion.dev/helix-graph'
|
|
1625
1750
|
import { sigmaDriver } from '@fusion.dev/helix-graph/sigma'
|
|
1626
1751
|
import Graph from 'graphology'
|
|
@@ -1775,7 +1900,10 @@ is a button that shows or hides the group's notes, in the drawing and in the
|
|
|
1775
1900
|
list:
|
|
1776
1901
|
|
|
1777
1902
|
\`\`\`html
|
|
1778
|
-
<helix-graph
|
|
1903
|
+
<helix-graph
|
|
1904
|
+
label="Company notes"
|
|
1905
|
+
legend
|
|
1906
|
+
>
|
|
1779
1907
|
<div></div>
|
|
1780
1908
|
</helix-graph>
|
|
1781
1909
|
\`\`\`
|
|
@@ -1823,7 +1951,10 @@ and the frame brings it into view with its neighbors. Start with one selected
|
|
|
1823
1951
|
with \`default-active\`:
|
|
1824
1952
|
|
|
1825
1953
|
\`\`\`html
|
|
1826
|
-
<helix-graph
|
|
1954
|
+
<helix-graph
|
|
1955
|
+
default-active="roadmap"
|
|
1956
|
+
label="Research notes"
|
|
1957
|
+
>
|
|
1827
1958
|
<div></div>
|
|
1828
1959
|
</helix-graph>
|
|
1829
1960
|
\`\`\`
|
|
@@ -1835,7 +1966,11 @@ Set \`depth\` to show only the notes within that many links of the selected one,
|
|
|
1835
1966
|
for a graph too large to read at once:
|
|
1836
1967
|
|
|
1837
1968
|
\`\`\`html
|
|
1838
|
-
<helix-graph
|
|
1969
|
+
<helix-graph
|
|
1970
|
+
default-active="roadmap"
|
|
1971
|
+
depth="2"
|
|
1972
|
+
label="Research notes"
|
|
1973
|
+
>
|
|
1839
1974
|
<div></div>
|
|
1840
1975
|
</helix-graph>
|
|
1841
1976
|
\`\`\`
|
|
@@ -1908,7 +2043,10 @@ finger moves it. A graph embedded in a page takes the wheel from a reader who
|
|
|
1908
2043
|
is scrolling past it. Set \`gestures\` on the frame to share them:
|
|
1909
2044
|
|
|
1910
2045
|
\`\`\`html
|
|
1911
|
-
<helix-graph
|
|
2046
|
+
<helix-graph
|
|
2047
|
+
gestures="cooperative"
|
|
2048
|
+
label="Research notes"
|
|
2049
|
+
>
|
|
1912
2050
|
<div></div>
|
|
1913
2051
|
</helix-graph>
|
|
1914
2052
|
\`\`\`
|
|
@@ -1929,7 +2067,11 @@ drawing takes all of it, as at the top of a page. A Notes button among the
|
|
|
1929
2067
|
controls opens them over the drawing:
|
|
1930
2068
|
|
|
1931
2069
|
\`\`\`html
|
|
1932
|
-
<helix-graph
|
|
2070
|
+
<helix-graph
|
|
2071
|
+
gestures="cooperative"
|
|
2072
|
+
label="Research notes"
|
|
2073
|
+
no-panel
|
|
2074
|
+
>
|
|
1933
2075
|
<div></div>
|
|
1934
2076
|
</helix-graph>
|
|
1935
2077
|
\`\`\`
|
|
@@ -1998,7 +2140,8 @@ leaves removing it to your framework.
|
|
|
1998
2140
|
minus keys zoom it. Set \`controls="pan zoom fullscreen"\` to add buttons that
|
|
1999
2141
|
move it.
|
|
2000
2142
|
- The list is a listbox, named by \`notes-label\`. Arrow keys, Home, End, Page
|
|
2001
|
-
Up, and Page Down move through it,
|
|
2143
|
+
Up, and Page Down move through it, typing a letter moves to the next note
|
|
2144
|
+
whose name starts with it, and Enter or Space selects a note.
|
|
2002
2145
|
- In the search field, Down moves into the list, and Escape empties the search.
|
|
2003
2146
|
With \`no-panel\`, Escape on an empty search closes the list.
|
|
2004
2147
|
- Screen readers read the selected note first, then how each other note links
|
|
@@ -2254,15 +2397,15 @@ Each file has its own export. If you bring your own reset or your own ramp,
|
|
|
2254
2397
|
import the two files you want and skip \`helix.css\`.
|
|
2255
2398
|
|
|
2256
2399
|
- **\`primitives.css\`** holds the raw ramp that the semantic layer is derived
|
|
2257
|
-
from. The
|
|
2258
|
-
|
|
2259
|
-
\`tokens.css\` refers to
|
|
2260
|
-
every semantic token resolves to nothing. We measured a page without it:
|
|
2400
|
+
from. The \`--helix-seed-*\` properties are read here. Your own code should
|
|
2401
|
+
not name a primitive, and leaving the file out does not enforce that.
|
|
2402
|
+
\`tokens.css\` refers to the primitives throughout, so without
|
|
2403
|
+
\`primitives.css\` every semantic token resolves to nothing. We measured a page without it:
|
|
2261
2404
|
\`--helix-color-background\` computes to \`rgba(0, 0, 0, 0)\`, and so does every
|
|
2262
2405
|
other color. [Theming](theming.mdx) also depends on this file, because without
|
|
2263
2406
|
it, setting \`--helix-seed-brand\` changes nothing.
|
|
2264
|
-
- **\`tokens.css\`** declares the semantic layer
|
|
2265
|
-
|
|
2407
|
+
- **\`tokens.css\`** declares the semantic layer, the custom properties grouped
|
|
2408
|
+
by category, plus \`color-scheme: light dark\` on \`:root\`. The files below read
|
|
2266
2409
|
from it, and it reads from \`primitives.css\`.
|
|
2267
2410
|
- **\`base.css\`** holds the element reset, the type scale on bare \`h1\` through
|
|
2268
2411
|
\`h6\`, and the recipes for markup that Helix does not render. It reads tokens.
|
|
@@ -2277,25 +2420,23 @@ components. The order then stays visible in one place.
|
|
|
2277
2420
|
|
|
2278
2421
|
## Register the elements
|
|
2279
2422
|
|
|
2280
|
-
|
|
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:
|
|
2423
|
+
Import each family you use from its subpath:
|
|
2290
2424
|
|
|
2291
2425
|
\`\`\`ts
|
|
2292
2426
|
import '@fusion.dev/helix/button'
|
|
2293
2427
|
import '@fusion.dev/helix/dialog'
|
|
2294
2428
|
\`\`\`
|
|
2295
2429
|
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2430
|
+
Each import has a side effect: it calls \`customElements.define\` for the
|
|
2431
|
+
elements of that family, and for the families they render. You can run it more
|
|
2432
|
+
than once. A second \`define\` for the same tag throws an error and stops the rest
|
|
2433
|
+
of the module, so the helper behind the import checks the registry first.
|
|
2434
|
+
|
|
2435
|
+
The package has side effects by design, so a bundler keeps everything you
|
|
2436
|
+
import. \`import '@fusion.dev/helix'\` registers every element in the library,
|
|
2437
|
+
which is the whole library in your bundle. Use it for a prototype, and use
|
|
2438
|
+
subpaths in an app. [Metrics](./metrics) lists the size of each family and of
|
|
2439
|
+
the whole package.
|
|
2299
2440
|
|
|
2300
2441
|
## Check the installation
|
|
2301
2442
|
|
|
@@ -2502,12 +2643,12 @@ reason.
|
|
|
2502
2643
|
bun add @fusion.dev/helix @fusion.dev/helix-styles
|
|
2503
2644
|
\`\`\`
|
|
2504
2645
|
|
|
2505
|
-
|
|
2506
|
-
anywhere:
|
|
2646
|
+
Import the stylesheet at your app root, then each family you use. Then you can
|
|
2647
|
+
use those elements anywhere:
|
|
2507
2648
|
|
|
2508
2649
|
\`\`\`ts
|
|
2509
2650
|
import '@fusion.dev/helix-styles/helix.css'
|
|
2510
|
-
import '@fusion.dev/helix'
|
|
2651
|
+
import '@fusion.dev/helix/accordion'
|
|
2511
2652
|
\`\`\`
|
|
2512
2653
|
|
|
2513
2654
|
\`\`\`html
|
|
@@ -2635,8 +2776,8 @@ Six families format numbers or dates and take a \`locale\`:
|
|
|
2635
2776
|
|
|
2636
2777
|
| | |
|
|
2637
2778
|
|---|---|
|
|
2638
|
-
| \`Date Input\`, \`Date Picker\` | Date formats and first day of week |
|
|
2639
|
-
| \`Time Input\`, \`Time Picker\` | 12 or 24 hour, and
|
|
2779
|
+
| \`Date Input\`, \`Date Picker\` | Date formats, and the first day of the week where \`first-day-of-week\` is not set |
|
|
2780
|
+
| \`Time Input\`, \`Time Picker\` | 12 or 24 hour, separators, and the AM and PM on the wheels |
|
|
2640
2781
|
| \`Pagination\` | Grouped thousands in page numbers |
|
|
2641
2782
|
| \`File Input\` | File sizes |
|
|
2642
2783
|
|
|
@@ -2651,6 +2792,15 @@ If you do not set \`locale\`, these controls use the browser's locale, which is
|
|
|
2651
2792
|
usually correct. Set \`locale\` when your users choose your application's
|
|
2652
2793
|
language separately from the language of their operating system.
|
|
2653
2794
|
|
|
2795
|
+
The first day of the week comes from \`Intl.Locale\`'s week information, which
|
|
2796
|
+
Firefox does not provide. There, and where you set no \`locale\`, the week starts
|
|
2797
|
+
on Sunday. Set \`first-day-of-week\` to choose the day yourself.
|
|
2798
|
+
|
|
2799
|
+
\`locale\` formats dates, times, and numbers. It does not translate the words a
|
|
2800
|
+
control speaks, such as "Previous month" on a calendar or "Hour" on a time
|
|
2801
|
+
wheel. Set those through their properties, such as \`previous-label\` and
|
|
2802
|
+
\`next-label\` on Date Picker and Date Input, and \`hour-label\` on Time Picker.
|
|
2803
|
+
|
|
2654
2804
|
Formatting uses \`Intl\`, so Helix bundles no locale data, and you have nothing to
|
|
2655
2805
|
keep up to date.
|
|
2656
2806
|
|
|
@@ -2680,8 +2830,13 @@ it reports:
|
|
|
2680
2830
|
- \`bad-input-message\`
|
|
2681
2831
|
- \`range-underflow-message\`
|
|
2682
2832
|
- \`range-overflow-message\`
|
|
2833
|
+
- \`step-mismatch-message\`
|
|
2683
2834
|
- \`too-short-message\`
|
|
2684
2835
|
|
|
2836
|
+
Date Picker, Date Input, Time Picker, and Time Input also take
|
|
2837
|
+
\`unavailable-message\`, for a date or time that \`disable-dates\`, \`disable-days\`,
|
|
2838
|
+
or \`disable-times\` rules out.
|
|
2839
|
+
|
|
2685
2840
|
A message appears in the browser's own validation bubble and on the line under
|
|
2686
2841
|
the field. \`feedback\` does not reach the bubble. If you do not set a message, a
|
|
2687
2842
|
text field shows the browser's own message, which is already in your user's
|
|
@@ -2695,6 +2850,18 @@ language. Every other control shows its English sentence.
|
|
|
2695
2850
|
></helix-number-input>
|
|
2696
2851
|
\`\`\`
|
|
2697
2852
|
|
|
2853
|
+
Color Picker and Color Input say a color's name to a screen reader, such as
|
|
2854
|
+
"vibrant red". Set \`color-words\` to a JSON table of the words a name is made
|
|
2855
|
+
of. The keys are the English words, and they match the strings that React
|
|
2856
|
+
Aria's \`@react-stately/color\` translates, so you can reuse that table.
|
|
2857
|
+
|
|
2858
|
+
\`\`\`html
|
|
2859
|
+
<helix-color-picker
|
|
2860
|
+
color-words='{"red": "rot", "vibrant": "kräftiges", "colorName": "{lightness} {chroma} {hue}"}'
|
|
2861
|
+
lang="de"
|
|
2862
|
+
></helix-color-picker>
|
|
2863
|
+
\`\`\`
|
|
2864
|
+
|
|
2698
2865
|
**Pass these strings from your own translation system.** Helix ships English
|
|
2699
2866
|
defaults and no translation tools. If Helix had its own string catalog, you
|
|
2700
2867
|
would have to keep two catalogs in step.
|
|
@@ -2774,7 +2941,7 @@ Add the map frame, an element for MapLibre to draw in, and your places:
|
|
|
2774
2941
|
Create the map with a style from your theme, then connect it to the frame:
|
|
2775
2942
|
|
|
2776
2943
|
\`\`\`js
|
|
2777
|
-
import '@fusion.dev/helix'
|
|
2944
|
+
import '@fusion.dev/helix/map'
|
|
2778
2945
|
import 'maplibre-gl/dist/maplibre-gl.css'
|
|
2779
2946
|
import { colorsReady, connectMap } from '@fusion.dev/helix-map'
|
|
2780
2947
|
import { followTheme, mapLibreDriver, mapLibreStyle } from '@fusion.dev/helix-map/maplibre'
|
|
@@ -2899,7 +3066,11 @@ is the map's. Give the container a position, such as \`position: relative\`:
|
|
|
2899
3066
|
|
|
2900
3067
|
\`\`\`html
|
|
2901
3068
|
<section class="hero">
|
|
2902
|
-
<helix-map
|
|
3069
|
+
<helix-map
|
|
3070
|
+
credit-placement="bottom-end"
|
|
3071
|
+
fill
|
|
3072
|
+
label="Downtown Austin"
|
|
3073
|
+
>
|
|
2903
3074
|
<div id="map"></div>
|
|
2904
3075
|
</helix-map>
|
|
2905
3076
|
<div class="hero-words">
|
|
@@ -2973,7 +3144,10 @@ A map embedded in a page, such as a hero, takes the wheel from a reader who is
|
|
|
2973
3144
|
scrolling past it. Set \`gestures\` on the frame to share them:
|
|
2974
3145
|
|
|
2975
3146
|
\`\`\`html
|
|
2976
|
-
<helix-map
|
|
3147
|
+
<helix-map
|
|
3148
|
+
gestures="cooperative"
|
|
3149
|
+
label="Downtown Austin"
|
|
3150
|
+
>
|
|
2977
3151
|
<div id="map"></div>
|
|
2978
3152
|
</helix-map>
|
|
2979
3153
|
\`\`\`
|
|
@@ -3225,7 +3399,10 @@ is a map type, which the frame's \`map-type\` attribute chooses:
|
|
|
3225
3399
|
- \`satellite\`: the imagery alone, without the roads and names.
|
|
3226
3400
|
|
|
3227
3401
|
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.
|
|
3402
|
+
each map type, showing a picture of the map in it. Choosing a card sends
|
|
3403
|
+
\`helix-before-change\` with the type's name, \`standard\`, \`hybrid\`, or
|
|
3404
|
+
\`satellite\`, and \`change\` once \`map-type\` holds it. Cancel the first to keep the
|
|
3405
|
+
current type, or listen for the second to store the choice. Set \`max-zoom\` to the deepest
|
|
3229
3406
|
zoom your provider has tiles for, and the map enlarges those tiles when a user
|
|
3230
3407
|
zooms in further.
|
|
3231
3408
|
|
|
@@ -3298,6 +3475,10 @@ tile is lit while its layer is shown. Pressing a tile sets its layer's \`hidden\
|
|
|
3298
3475
|
attribute, and \`connectMap\` does not draw a hidden layer. Write \`hidden\` on a
|
|
3299
3476
|
layer to start it turned off.
|
|
3300
3477
|
|
|
3478
|
+
Before it sets \`hidden\`, a tile sends \`helix-before-toggle\` from the layer, with
|
|
3479
|
+
\`checked\` true when the layer is to be shown. Store the choice from it, or
|
|
3480
|
+
cancel it to keep the layer as it is.
|
|
3481
|
+
|
|
3301
3482
|
Give layers the same \`group\` to show them as one tile, such as a route and the
|
|
3302
3483
|
dotted legs at its ends. The tile takes the name of the first layer in the
|
|
3303
3484
|
group, and shows or hides every layer in it. Keep labels short, such as
|
|
@@ -3405,7 +3586,7 @@ on its own.
|
|
|
3405
3586
|
|
|
3406
3587
|
| | Raw | Gzip | Brotli |
|
|
3407
3588
|
|---|---|---|---|
|
|
3408
|
-
| Lit and \`@fusion.dev/helix-core\` |
|
|
3589
|
+
| Lit and \`@fusion.dev/helix-core\` | 182,087 | 57,026 | 49,129 |
|
|
3409
3590
|
|
|
3410
3591
|
## Whole packages
|
|
3411
3592
|
|
|
@@ -3416,12 +3597,12 @@ either barrel. The per-component tables show what your page pays.
|
|
|
3416
3597
|
|
|
3417
3598
|
| Package | Raw | Gzip | Brotli | |
|
|
3418
3599
|
|---|---|---|---|---|
|
|
3419
|
-
| \`@fusion.dev/helix-core\` |
|
|
3420
|
-
| \`@fusion.dev/helix-headless\` |
|
|
3421
|
-
| \`@fusion.dev/helix-icons\` | 55,
|
|
3600
|
+
| \`@fusion.dev/helix-core\` | 181,641 | 56,641 | 48,897 | The element base class, mixins, decorators, and floating positioning. |
|
|
3601
|
+
| \`@fusion.dev/helix-headless\` | 929,891 | 247,016 | 188,830 | Every headless family. The barrel entry includes all of them. |
|
|
3602
|
+
| \`@fusion.dev/helix-icons\` | 55,738 | 17,784 | 15,143 | The whole glyph set. |
|
|
3422
3603
|
| \`@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
3604
|
| \`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,
|
|
3605
|
+
| \`@fusion.dev/helix\` | 1,471,844 | 349,349 | 250,882 | Every styled family. |
|
|
3425
3606
|
| \`lit\` | 15,394 | 6,118 | 5,460 | Lit itself, listed so you can subtract it from every row above. |
|
|
3426
3607
|
|
|
3427
3608
|
## Stylesheets
|
|
@@ -3435,68 +3616,70 @@ shows the whole cost of using the base layer on its own.
|
|
|
3435
3616
|
| File | Raw | Gzip | Brotli | |
|
|
3436
3617
|
|---|---|---|---|---|
|
|
3437
3618
|
| \`base.css\` | 30,786 | 4,465 | 3,884 | The base layer. It styles markup Helix does not render, and it works with no JavaScript. |
|
|
3438
|
-
| \`elements.css\` | 8,
|
|
3619
|
+
| \`elements.css\` | 8,862 | 1,492 | 1,318 | Hides each element until its definition loads. It is generated from the tags in \`@fusion.dev/helix\`. |
|
|
3439
3620
|
| \`helix.css\` | 207 | 148 | 118 | The other four stylesheets in one import, in the order they must load. |
|
|
3440
3621
|
| \`primitives.css\` | 7,510 | 1,402 | 1,201 | The primitive layer. It is private, and it ships because \`tokens.css\` refers to it. |
|
|
3441
3622
|
| \`tokens.css\` | 22,349 | 2,664 | 2,247 | The 193 semantic tokens. Every styled component needs them. |
|
|
3442
3623
|
|
|
3443
3624
|
## What the numbers say
|
|
3444
3625
|
|
|
3445
|
-
**Most of your first component is the shared runtime.** The median styled family is
|
|
3626
|
+
**Most of your first component is the shared runtime.** The median styled family is 17,001 bytes gzipped alone, and it adds 2,926 to a page that already has Helix. The shared runtime is 83 percent of the first component, and the component itself is 17 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
3627
|
|
|
3447
|
-
Across the 104 styled components, the smallest is \`code\` at 10,
|
|
3628
|
+
Across the 104 styled components, the smallest is \`code\` at 10,676 bytes gzipped alone, and the largest is \`data-table\` at 56,196. Every family together is 349,349.
|
|
3448
3629
|
|
|
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
|
|
3630
|
+
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 247,016 bytes gzipped, whatever else the page imports. That is 15 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
3631
|
|
|
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
|
|
3632
|
+
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 16,148 bytes gzipped alone.
|
|
3452
3633
|
|
|
3453
3634
|
## Compared with other systems
|
|
3454
3635
|
|
|
3455
|
-
We compare Helix with
|
|
3636
|
+
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
3637
|
|
|
3457
3638
|
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
3639
|
|
|
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
|
|
3640
|
+
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
3641
|
|
|
3461
3642
|
| Component | System | Raw | Gzip | Brotli |
|
|
3462
3643
|
|---|---|---|---|---|
|
|
3463
|
-
| \`button\` | **Helix** |
|
|
3644
|
+
| \`button\` | **Helix** | 56,398 | 16,247 | 14,165 |
|
|
3464
3645
|
| | Carbon | 133,058 | 20,959 | 17,685 |
|
|
3465
3646
|
| | Material Web | 47,060 | 14,173 | 12,591 |
|
|
3466
3647
|
| | Shoelace | 62,628 | 18,287 | 15,805 |
|
|
3467
3648
|
| | Spectrum | 98,792 | 22,045 | 18,674 |
|
|
3468
|
-
| \`checkbox\` | **Helix** |
|
|
3649
|
+
| \`checkbox\` | **Helix** | 60,002 | 16,960 | 14,858 |
|
|
3469
3650
|
| | Carbon | 60,255 | 15,609 | 13,550 |
|
|
3470
3651
|
| | Material Web | 43,785 | 13,556 | 12,015 |
|
|
3471
3652
|
| | Shoelace | 47,614 | 15,177 | 13,301 |
|
|
3472
3653
|
| | Spectrum | 62,492 | 15,437 | 13,481 |
|
|
3473
|
-
| \`dialog\` | **Helix** |
|
|
3654
|
+
| \`dialog\` | **Helix** | 54,741 | 16,320 | 14,276 |
|
|
3474
3655
|
| | Carbon | 510,866 | 67,390 | 39,189 |
|
|
3475
3656
|
| | Material Web | 34,238 | 11,510 | 10,229 |
|
|
3476
3657
|
| | Shoelace | 52,754 | 17,698 | 15,554 |
|
|
3477
3658
|
| | Spectrum | 155,708 | 31,899 | 26,262 |
|
|
3478
|
-
| \`radio\` | **Helix** |
|
|
3659
|
+
| \`radio\` | **Helix** | 64,144 | 17,850 | 15,648 |
|
|
3479
3660
|
| | Carbon | 63,055 | 16,887 | 14,605 |
|
|
3480
3661
|
| | Material Web | 41,044 | 13,234 | 11,757 |
|
|
3481
3662
|
| | Shoelace | 34,865 | 12,027 | 10,559 |
|
|
3482
3663
|
| | Spectrum | 38,685 | 10,660 | 9,370 |
|
|
3483
|
-
| \`switch\` | **Helix** |
|
|
3664
|
+
| \`switch\` | **Helix** | 57,461 | 16,577 | 14,545 |
|
|
3484
3665
|
| | Carbon | 69,423 | 17,127 | 14,764 |
|
|
3485
3666
|
| | Material Web | 50,155 | 14,577 | 12,935 |
|
|
3486
3667
|
| | Shoelace | 37,833 | 11,814 | 10,568 |
|
|
3487
3668
|
| | Spectrum | 62,322 | 15,059 | 13,321 |
|
|
3488
|
-
| \`tabs\` | **Helix** |
|
|
3669
|
+
| \`tabs\` | **Helix** | 55,917 | 16,074 | 14,020 |
|
|
3489
3670
|
| | Carbon | 578,766 | 73,537 | 43,235 |
|
|
3490
3671
|
| | Material Web | 38,883 | 12,820 | 11,368 |
|
|
3491
3672
|
| | Shoelace | 54,573 | 17,140 | 15,068 |
|
|
3492
3673
|
| | Spectrum | 64,875 | 18,298 | 16,283 |
|
|
3493
|
-
| \`tooltip\` | **Helix** |
|
|
3674
|
+
| \`tooltip\` | **Helix** | 74,148 | 23,682 | 20,846 |
|
|
3494
3675
|
| | Carbon | 189,382 | 30,354 | 22,273 |
|
|
3495
3676
|
| | Material Web | | not shipped | |
|
|
3496
3677
|
| | Shoelace | 57,412 | 20,220 | 17,933 |
|
|
3497
3678
|
| | Spectrum | 136,599 | 40,552 | 35,286 |
|
|
3498
3679
|
|
|
3499
|
-
At least one system is smaller than Helix on \`checkbox\`, \`dialog\`, \`radio\`, \`switch\`, \`tabs\`, \`tooltip\`. The largest gap is radio against Spectrum, at
|
|
3680
|
+
At least one system is smaller than Helix on \`button\`, \`checkbox\`, \`dialog\`, \`radio\`, \`switch\`, \`tabs\`, \`tooltip\`. The largest gap is radio against Spectrum, at 7,190 bytes gzipped. 15 of 27 peer measurements are smaller than the Helix row.
|
|
3681
|
+
|
|
3682
|
+
Helix's \`radio\` family includes Radio Group, so its row carries an element that some peer rows measure without.
|
|
3500
3683
|
|
|
3501
3684
|
- **Carbon** \`@carbon/web-components@2.61.0\`. Its dialog is Modal, its radio is Radio Button, and its switch is Toggle.
|
|
3502
3685
|
- **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 +3723,104 @@ Structure, accessibility, state, and form participation. It has no presentation
|
|
|
3540
3723
|
|
|
3541
3724
|
| Family | Alone raw | Alone gzip | Alone brotli | Added raw | Added gzip | Added brotli |
|
|
3542
3725
|
|---|---|---|---|---|---|---|
|
|
3543
|
-
| \`accordion\` |
|
|
3544
|
-
| \`announcement\` |
|
|
3545
|
-
| \`app-header\` |
|
|
3546
|
-
| \`area-chart\` |
|
|
3547
|
-
| \`avatar\` |
|
|
3548
|
-
| \`badge\` |
|
|
3549
|
-
| \`bar-chart\` |
|
|
3550
|
-
| \`blockquote\` |
|
|
3551
|
-
| \`breadcrumbs\` |
|
|
3552
|
-
| \`button\` |
|
|
3553
|
-
| \`button-group\` |
|
|
3554
|
-
| \`callout\` |
|
|
3555
|
-
| \`canvas\` |
|
|
3556
|
-
| \`card\` |
|
|
3557
|
-
| \`carousel\` |
|
|
3558
|
-
| \`chat\` |
|
|
3559
|
-
| \`checkbox\` |
|
|
3560
|
-
| \`checkbox-group\` |
|
|
3561
|
-
| \`code\` |
|
|
3562
|
-
| \`code-block\` |
|
|
3563
|
-
| \`color-input\` |
|
|
3564
|
-
| \`color-picker\` |
|
|
3565
|
-
| \`combobox\` |
|
|
3566
|
-
| \`command\` |
|
|
3567
|
-
| \`copy-button\` |
|
|
3568
|
-
| \`data-table\` |
|
|
3569
|
-
| \`date-input\` |
|
|
3570
|
-
| \`date-picker\` |
|
|
3571
|
-
| \`description-list\` |
|
|
3572
|
-
| \`dialog\` |
|
|
3573
|
-
| \`divider\` |
|
|
3574
|
-
| \`donut-chart\` |
|
|
3575
|
-
| \`drawer\` |
|
|
3576
|
-
| \`drilldown\` |
|
|
3577
|
-
| \`empty\` |
|
|
3578
|
-
| \`file-input\` |
|
|
3579
|
-
| \`filter-input\` |
|
|
3580
|
-
| \`format-date\` |
|
|
3581
|
-
| \`graph\` |
|
|
3582
|
-
| \`heatmap\` |
|
|
3583
|
-
| \`icon\` |
|
|
3584
|
-
| \`icon-button\` |
|
|
3585
|
-
| \`image\` |
|
|
3586
|
-
| \`input\` |
|
|
3587
|
-
| \`kbd\` |
|
|
3588
|
-
| \`legend\` |
|
|
3589
|
-
| \`lightbox\` |
|
|
3590
|
-
| \`line-chart\` |
|
|
3591
|
-
| \`list\` |
|
|
3592
|
-
| \`listbox\` |
|
|
3593
|
-
| \`loader\` |
|
|
3594
|
-
| \`map\` |
|
|
3595
|
-
| \`megamenu\` |
|
|
3596
|
-
| \`menu\` |
|
|
3597
|
-
| \`meter\` |
|
|
3598
|
-
| \`navigation\` |
|
|
3599
|
-
| \`notifications\` |
|
|
3600
|
-
| \`number-input\` |
|
|
3601
|
-
| \`object-inspector\` |
|
|
3602
|
-
| \`option\` |
|
|
3603
|
-
| \`outline\` |
|
|
3604
|
-
| \`pagination\` |
|
|
3605
|
-
| \`pin-input\` |
|
|
3606
|
-
| \`popover\` |
|
|
3607
|
-
| \`progress\` |
|
|
3608
|
-
| \`qr-code\` |
|
|
3609
|
-
| \`quote\` |
|
|
3610
|
-
| \`radio\` |
|
|
3611
|
-
| \`rating\` |
|
|
3612
|
-
| \`scatter-chart\` |
|
|
3613
|
-
| \`scroll-area\` |
|
|
3614
|
-
| \`select\` |
|
|
3615
|
-
| \`skeleton\` |
|
|
3616
|
-
| \`skip-link\` |
|
|
3617
|
-
| \`slider\` |
|
|
3618
|
-
| \`sparkline\` |
|
|
3619
|
-
| \`speed-dial\` |
|
|
3620
|
-
| \`splitter\` |
|
|
3621
|
-
| \`stat\` |
|
|
3622
|
-
| \`steps\` |
|
|
3623
|
-
| \`switch\` |
|
|
3624
|
-
| \`table\` |
|
|
3625
|
-
| \`tabs\` |
|
|
3626
|
-
| \`tag\` |
|
|
3627
|
-
| \`textarea\` |
|
|
3628
|
-
| \`time-input\` |
|
|
3629
|
-
| \`time-picker\` |
|
|
3630
|
-
| \`timeline\` |
|
|
3631
|
-
| \`toast\` |
|
|
3632
|
-
| \`toggle\` |
|
|
3633
|
-
| \`toolbar\` |
|
|
3634
|
-
| \`tooltip\` |
|
|
3635
|
-
| \`tour\` |
|
|
3636
|
-
| \`tree\` |
|
|
3637
|
-
| \`trend\` |
|
|
3638
|
-
| \`video\` |
|
|
3639
|
-
| \`video-playlist\` |
|
|
3640
|
-
| \`virtual-list\` |
|
|
3726
|
+
| \`accordion\` | 44,701 | 13,626 | 11,933 | 4,240 | 1,216 | 879 |
|
|
3727
|
+
| \`announcement\` | 40,721 | 12,427 | 10,877 | 1,422 | 470 | 220 |
|
|
3728
|
+
| \`app-header\` | 37,314 | 11,161 | 9,828 | 1,800 | 610 | 304 |
|
|
3729
|
+
| \`area-chart\` | 90,369 | 29,258 | 25,668 | 13,495 | 4,140 | 3,231 |
|
|
3730
|
+
| \`avatar\` | 40,474 | 12,079 | 10,630 | 4,317 | 1,319 | 916 |
|
|
3731
|
+
| \`badge\` | 36,128 | 10,891 | 9,562 | 1,149 | 436 | 150 |
|
|
3732
|
+
| \`bar-chart\` | 92,950 | 29,977 | 26,287 | 15,690 | 4,734 | 3,684 |
|
|
3733
|
+
| \`blockquote\` | 36,294 | 10,964 | 9,606 | 912 | 368 | 166 |
|
|
3734
|
+
| \`breadcrumbs\` | 38,511 | 11,586 | 10,180 | 2,248 | 662 | 420 |
|
|
3735
|
+
| \`button\` | 49,106 | 14,753 | 12,864 | 4,710 | 1,442 | 966 |
|
|
3736
|
+
| \`button-group\` | 36,012 | 10,792 | 9,472 | 661 | 278 | 17 |
|
|
3737
|
+
| \`callout\` | 41,362 | 12,662 | 11,077 | 1,329 | 509 | 341 |
|
|
3738
|
+
| \`canvas\` | 97,945 | 28,734 | 25,129 | 50,699 | 15,269 | 12,665 |
|
|
3739
|
+
| \`card\` | 37,123 | 11,127 | 9,754 | 1,604 | 507 | 199 |
|
|
3740
|
+
| \`carousel\` | 49,032 | 14,602 | 12,873 | 12,343 | 3,380 | 2,522 |
|
|
3741
|
+
| \`chat\` | 63,883 | 19,478 | 17,158 | 18,377 | 5,465 | 4,344 |
|
|
3742
|
+
| \`checkbox\` | 53,376 | 15,507 | 13,630 | 2,958 | 958 | 510 |
|
|
3743
|
+
| \`checkbox-group\` | 58,828 | 16,890 | 14,812 | 7,836 | 2,158 | 1,422 |
|
|
3744
|
+
| \`code\` | 34,631 | 10,379 | 9,095 | 451 | 217 | 5 |
|
|
3745
|
+
| \`code-block\` | 97,970 | 30,627 | 26,843 | 23,818 | 6,378 | 5,060 |
|
|
3746
|
+
| \`color-input\` | 126,667 | 38,020 | 33,193 | 37,761 | 9,575 | 7,587 |
|
|
3747
|
+
| \`color-picker\` | 89,459 | 26,331 | 23,074 | 30,390 | 8,129 | 6,339 |
|
|
3748
|
+
| \`combobox\` | 124,918 | 36,824 | 32,129 | 35,736 | 8,855 | 6,997 |
|
|
3749
|
+
| \`command\` | 86,526 | 24,600 | 21,456 | 26,825 | 7,073 | 5,455 |
|
|
3750
|
+
| \`copy-button\` | 91,383 | 28,739 | 25,185 | 17,224 | 4,559 | 3,426 |
|
|
3751
|
+
| \`data-table\` | 166,647 | 48,062 | 41,467 | 76,823 | 19,901 | 15,778 |
|
|
3752
|
+
| \`date-input\` | 135,874 | 39,621 | 34,569 | 34,269 | 8,259 | 6,505 |
|
|
3753
|
+
| \`date-picker\` | 62,134 | 18,124 | 16,067 | 16,799 | 4,429 | 3,354 |
|
|
3754
|
+
| \`description-list\` | 36,115 | 10,751 | 9,429 | 1,132 | 329 | 52 |
|
|
3755
|
+
| \`dialog\` | 49,122 | 15,045 | 13,119 | 4,950 | 1,588 | 1,070 |
|
|
3756
|
+
| \`divider\` | 36,362 | 10,991 | 9,663 | 981 | 387 | 140 |
|
|
3757
|
+
| \`donut-chart\` | 88,589 | 28,406 | 24,960 | 13,145 | 3,946 | 3,122 |
|
|
3758
|
+
| \`drawer\` | 49,857 | 15,264 | 13,305 | 4,473 | 1,494 | 972 |
|
|
3759
|
+
| \`drilldown\` | 52,271 | 15,920 | 13,912 | 6,372 | 1,788 | 1,225 |
|
|
3760
|
+
| \`empty\` | 36,800 | 11,098 | 9,726 | 956 | 375 | 156 |
|
|
3761
|
+
| \`file-input\` | 70,157 | 21,089 | 18,462 | 13,699 | 4,113 | 3,073 |
|
|
3762
|
+
| \`filter-input\` | 122,233 | 36,317 | 31,769 | 32,194 | 8,036 | 6,293 |
|
|
3763
|
+
| \`format-date\` | 41,800 | 12,579 | 11,116 | 4,302 | 1,231 | 822 |
|
|
3764
|
+
| \`graph\` | 68,878 | 20,642 | 18,131 | 14,811 | 4,762 | 3,746 |
|
|
3765
|
+
| \`heatmap\` | 93,526 | 29,776 | 26,031 | 13,605 | 3,880 | 2,960 |
|
|
3766
|
+
| \`icon\` | 93,519 | 29,356 | 25,023 | 55,716 | 19,410 | 15,184 |
|
|
3767
|
+
| \`icon-button\` | 49,502 | 14,787 | 12,881 | 5,109 | 1,488 | 931 |
|
|
3768
|
+
| \`image\` | 39,391 | 11,664 | 10,247 | 3,695 | 1,088 | 699 |
|
|
3769
|
+
| \`input\` | 58,901 | 17,599 | 15,313 | 7,196 | 2,442 | 1,597 |
|
|
3770
|
+
| \`kbd\` | 39,704 | 12,134 | 10,658 | 3,432 | 1,172 | 699 |
|
|
3771
|
+
| \`legend\` | 42,474 | 12,907 | 11,291 | 2,304 | 797 | 399 |
|
|
3772
|
+
| \`lightbox\` | 52,296 | 15,432 | 13,574 | 7,865 | 2,197 | 1,462 |
|
|
3773
|
+
| \`line-chart\` | 90,719 | 29,240 | 25,692 | 13,695 | 4,083 | 3,203 |
|
|
3774
|
+
| \`list\` | 37,108 | 10,989 | 9,641 | 1,766 | 503 | 212 |
|
|
3775
|
+
| \`listbox\` | 72,278 | 21,086 | 18,482 | 16,468 | 4,603 | 3,470 |
|
|
3776
|
+
| \`loader\` | 38,134 | 11,443 | 10,061 | 1,966 | 701 | 428 |
|
|
3777
|
+
| \`map\` | 88,866 | 24,638 | 21,318 | 37,993 | 9,921 | 7,589 |
|
|
3778
|
+
| \`megamenu\` | 67,545 | 21,979 | 19,301 | 5,166 | 1,504 | 950 |
|
|
3779
|
+
| \`menu\` | 84,482 | 27,139 | 23,697 | 10,758 | 2,901 | 2,034 |
|
|
3780
|
+
| \`meter\` | 39,935 | 11,963 | 10,523 | 4,407 | 1,321 | 936 |
|
|
3781
|
+
| \`navigation\` | 42,076 | 12,846 | 11,125 | 1,587 | 531 | 233 |
|
|
3782
|
+
| \`notifications\` | 60,428 | 17,470 | 15,447 | 15,559 | 4,000 | 3,056 |
|
|
3783
|
+
| \`number-input\` | 62,711 | 18,414 | 16,200 | 9,936 | 2,710 | 1,914 |
|
|
3784
|
+
| \`object-inspector\` | 107,211 | 33,688 | 29,397 | 26,855 | 7,376 | 5,779 |
|
|
3785
|
+
| \`option\` | 39,192 | 11,592 | 10,200 | 3,485 | 905 | 564 |
|
|
3786
|
+
| \`outline\` | 41,446 | 12,643 | 11,102 | 4,703 | 1,485 | 1,025 |
|
|
3787
|
+
| \`pagination\` | 121,340 | 36,006 | 31,403 | 38,967 | 9,843 | 7,657 |
|
|
3788
|
+
| \`pin-input\` | 56,225 | 16,427 | 14,415 | 6,212 | 1,940 | 1,209 |
|
|
3789
|
+
| \`popover\` | 72,247 | 23,560 | 20,556 | 3,678 | 1,122 | 667 |
|
|
3790
|
+
| \`progress\` | 37,937 | 11,449 | 10,052 | 2,409 | 803 | 484 |
|
|
3791
|
+
| \`qr-code\` | 50,196 | 16,089 | 14,139 | 14,937 | 5,517 | 4,541 |
|
|
3792
|
+
| \`quote\` | 35,535 | 10,672 | 9,341 | 552 | 293 | 133 |
|
|
3793
|
+
| \`radio\` | 55,852 | 16,358 | 14,260 | 3,954 | 1,196 | 751 |
|
|
3794
|
+
| \`rating\` | 60,609 | 18,068 | 15,805 | 7,789 | 2,398 | 1,708 |
|
|
3795
|
+
| \`scatter-chart\` | 90,002 | 28,914 | 25,377 | 13,985 | 4,210 | 3,261 |
|
|
3796
|
+
| \`scroll-area\` | 37,778 | 11,354 | 9,950 | 2,743 | 897 | 591 |
|
|
3797
|
+
| \`select\` | 106,032 | 32,233 | 28,217 | 23,738 | 6,133 | 4,792 |
|
|
3798
|
+
| \`skeleton\` | 36,541 | 10,963 | 9,654 | 1,190 | 453 | 126 |
|
|
3799
|
+
| \`skip-link\` | 36,698 | 11,106 | 9,705 | 1,562 | 631 | 311 |
|
|
3800
|
+
| \`slider\` | 57,787 | 16,802 | 14,802 | 7,357 | 2,094 | 1,438 |
|
|
3801
|
+
| \`sparkline\` | 43,547 | 13,471 | 11,798 | 2,387 | 913 | 631 |
|
|
3802
|
+
| \`speed-dial\` | 70,466 | 23,179 | 20,368 | 4,218 | 1,216 | 728 |
|
|
3803
|
+
| \`splitter\` | 50,411 | 14,864 | 13,103 | 10,977 | 2,906 | 2,217 |
|
|
3804
|
+
| \`stat\` | 36,863 | 10,988 | 9,645 | 1,511 | 493 | 222 |
|
|
3805
|
+
| \`steps\` | 55,412 | 16,440 | 14,377 | 8,459 | 2,323 | 1,635 |
|
|
3806
|
+
| \`switch\` | 52,608 | 15,403 | 13,513 | 1,790 | 676 | 308 |
|
|
3807
|
+
| \`table\` | 57,260 | 17,241 | 15,170 | 14,844 | 4,328 | 3,413 |
|
|
3808
|
+
| \`tabs\` | 49,298 | 14,722 | 12,809 | 4,025 | 1,047 | 747 |
|
|
3809
|
+
| \`tag\` | 47,772 | 14,598 | 12,861 | 5,626 | 1,674 | 1,136 |
|
|
3810
|
+
| \`textarea\` | 55,171 | 16,121 | 14,138 | 4,676 | 1,440 | 983 |
|
|
3811
|
+
| \`time-input\` | 148,716 | 43,305 | 37,532 | 43,009 | 10,737 | 8,330 |
|
|
3812
|
+
| \`time-picker\` | 85,174 | 24,617 | 21,538 | 27,375 | 7,292 | 5,587 |
|
|
3813
|
+
| \`timeline\` | 38,507 | 11,551 | 10,144 | 2,239 | 643 | 438 |
|
|
3814
|
+
| \`toast\` | 53,129 | 16,174 | 14,275 | 8,468 | 2,532 | 1,874 |
|
|
3815
|
+
| \`toggle\` | 59,077 | 17,265 | 15,114 | 5,356 | 1,515 | 1,001 |
|
|
3816
|
+
| \`toolbar\` | 43,517 | 13,332 | 11,648 | 4,134 | 1,427 | 851 |
|
|
3817
|
+
| \`tooltip\` | 71,070 | 22,939 | 20,172 | 8,345 | 2,401 | 1,737 |
|
|
3818
|
+
| \`tour\` | 87,778 | 27,527 | 24,134 | 15,948 | 4,335 | 3,270 |
|
|
3819
|
+
| \`tree\` | 54,810 | 16,530 | 14,410 | 8,344 | 2,414 | 1,763 |
|
|
3820
|
+
| \`trend\` | 38,098 | 11,560 | 10,156 | 2,213 | 709 | 384 |
|
|
3821
|
+
| \`video\` | 119,411 | 36,126 | 31,356 | 41,045 | 10,622 | 8,364 |
|
|
3822
|
+
| \`video-playlist\` | 92,641 | 28,852 | 25,227 | 17,519 | 4,309 | 3,217 |
|
|
3823
|
+
| \`virtual-list\` | 47,934 | 14,791 | 12,860 | 3,995 | 1,384 | 997 |
|
|
3641
3824
|
|
|
3642
3825
|
### Styled tier
|
|
3643
3826
|
|
|
@@ -3645,110 +3828,110 @@ The headless tier plus presentation. \`bun add @fusion.dev/helix\` installs this
|
|
|
3645
3828
|
|
|
3646
3829
|
| Family | Alone raw | Alone gzip | Alone brotli | Added raw | Added gzip | Added brotli |
|
|
3647
3830
|
|---|---|---|---|---|---|---|
|
|
3648
|
-
| \`accordion\` |
|
|
3649
|
-
| \`announcement\` |
|
|
3650
|
-
| \`app-header\` |
|
|
3651
|
-
| \`area-chart\` |
|
|
3652
|
-
| \`aura\` |
|
|
3653
|
-
| \`avatar\` |
|
|
3654
|
-
| \`badge\` |
|
|
3655
|
-
| \`bar-chart\` |
|
|
3656
|
-
| \`blockquote\` |
|
|
3657
|
-
| \`breadcrumbs\` |
|
|
3658
|
-
| \`button\` |
|
|
3659
|
-
| \`button-group\` |
|
|
3660
|
-
| \`callout\` |
|
|
3661
|
-
| \`canvas\` |
|
|
3662
|
-
| \`card\` |
|
|
3663
|
-
| \`carousel\` |
|
|
3664
|
-
| \`chat\` |
|
|
3665
|
-
| \`checkbox\` |
|
|
3666
|
-
| \`checkbox-group\` |
|
|
3667
|
-
| \`code\` |
|
|
3668
|
-
| \`code-block\` |
|
|
3669
|
-
| \`color-input\` |
|
|
3670
|
-
| \`color-picker\` |
|
|
3671
|
-
| \`combobox\` |
|
|
3672
|
-
| \`command\` |
|
|
3673
|
-
| \`copy-button\` |
|
|
3674
|
-
| \`data-table\` |
|
|
3675
|
-
| \`date-input\` |
|
|
3676
|
-
| \`date-picker\` |
|
|
3677
|
-
| \`description-list\` |
|
|
3678
|
-
| \`dialog\` |
|
|
3679
|
-
| \`divider\` |
|
|
3680
|
-
| \`donut-chart\` |
|
|
3681
|
-
| \`drawer\` |
|
|
3682
|
-
| \`drilldown\` |
|
|
3683
|
-
| \`empty\` |
|
|
3684
|
-
| \`file-input\` |
|
|
3685
|
-
| \`filter-input\` |
|
|
3686
|
-
| \`flex\` |
|
|
3687
|
-
| \`format-date\` |
|
|
3688
|
-
| \`graph\` |
|
|
3689
|
-
| \`grid\` |
|
|
3690
|
-
| \`heatmap\` |
|
|
3691
|
-
| \`icon\` |
|
|
3692
|
-
| \`icon-button\` |
|
|
3693
|
-
| \`image\` |
|
|
3694
|
-
| \`input\` |
|
|
3695
|
-
| \`kbd\` |
|
|
3696
|
-
| \`legend\` |
|
|
3697
|
-
| \`lightbox\` |
|
|
3698
|
-
| \`line-chart\` |
|
|
3699
|
-
| \`list\` |
|
|
3700
|
-
| \`listbox\` |
|
|
3701
|
-
| \`loader\` |
|
|
3702
|
-
| \`map\` |
|
|
3703
|
-
| \`megamenu\` |
|
|
3704
|
-
| \`menu\` |
|
|
3705
|
-
| \`meter\` |
|
|
3706
|
-
| \`navigation\` |
|
|
3707
|
-
| \`notifications\` |
|
|
3708
|
-
| \`number-input\` |
|
|
3709
|
-
| \`object-inspector\` |
|
|
3710
|
-
| \`option\` |
|
|
3711
|
-
| \`orb\` |
|
|
3712
|
-
| \`outline\` |
|
|
3713
|
-
| \`pagination\` |
|
|
3714
|
-
| \`pin-input\` |
|
|
3715
|
-
| \`popover\` |
|
|
3716
|
-
| \`progress\` |
|
|
3717
|
-
| \`qr-code\` |
|
|
3718
|
-
| \`quote\` |
|
|
3719
|
-
| \`radio\` |
|
|
3720
|
-
| \`rating\` |
|
|
3721
|
-
| \`sandbox\` |
|
|
3722
|
-
| \`scatter-chart\` |
|
|
3723
|
-
| \`scroll-area\` |
|
|
3724
|
-
| \`select\` |
|
|
3725
|
-
| \`skeleton\` |
|
|
3726
|
-
| \`skip-link\` |
|
|
3727
|
-
| \`slider\` |
|
|
3728
|
-
| \`sparkline\` |
|
|
3729
|
-
| \`speed-dial\` |
|
|
3730
|
-
| \`splitter\` |
|
|
3731
|
-
| \`stat\` |
|
|
3732
|
-
| \`steps\` |
|
|
3733
|
-
| \`switch\` |
|
|
3734
|
-
| \`table\` |
|
|
3735
|
-
| \`tabs\` |
|
|
3736
|
-
| \`tag\` |
|
|
3737
|
-
| \`text\` |
|
|
3738
|
-
| \`textarea\` |
|
|
3739
|
-
| \`time-input\` |
|
|
3740
|
-
| \`time-picker\` |
|
|
3741
|
-
| \`timeline\` |
|
|
3742
|
-
| \`toast\` |
|
|
3743
|
-
| \`toggle\` |
|
|
3744
|
-
| \`toolbar\` |
|
|
3745
|
-
| \`tooltip\` |
|
|
3746
|
-
| \`tour\` |
|
|
3747
|
-
| \`tree\` |
|
|
3748
|
-
| \`trend\` |
|
|
3749
|
-
| \`video\` |
|
|
3750
|
-
| \`video-playlist\` |
|
|
3751
|
-
| \`virtual-list\` |
|
|
3831
|
+
| \`accordion\` | 48,121 | 14,422 | 12,688 | 7,647 | 2,065 | 1,560 |
|
|
3832
|
+
| \`announcement\` | 45,485 | 13,478 | 11,811 | 6,169 | 1,548 | 1,222 |
|
|
3833
|
+
| \`app-header\` | 41,202 | 12,052 | 10,574 | 5,673 | 1,515 | 1,108 |
|
|
3834
|
+
| \`area-chart\` | 98,228 | 30,935 | 27,181 | 21,331 | 5,831 | 4,582 |
|
|
3835
|
+
| \`aura\` | 64,892 | 19,687 | 17,298 | 26,743 | 8,324 | 7,050 |
|
|
3836
|
+
| \`avatar\` | 44,061 | 12,836 | 11,293 | 7,891 | 2,116 | 1,661 |
|
|
3837
|
+
| \`badge\` | 40,439 | 11,760 | 10,311 | 5,445 | 1,325 | 1,001 |
|
|
3838
|
+
| \`bar-chart\` | 106,399 | 32,622 | 28,595 | 29,117 | 7,395 | 5,972 |
|
|
3839
|
+
| \`blockquote\` | 37,656 | 11,278 | 9,895 | 2,258 | 693 | 401 |
|
|
3840
|
+
| \`breadcrumbs\` | 42,077 | 12,357 | 10,859 | 5,799 | 1,446 | 1,054 |
|
|
3841
|
+
| \`button\` | 56,398 | 16,247 | 14,165 | 11,984 | 2,955 | 2,197 |
|
|
3842
|
+
| \`button-group\` | 37,688 | 11,167 | 9,792 | 2,320 | 688 | 446 |
|
|
3843
|
+
| \`callout\` | 45,299 | 13,583 | 11,889 | 5,248 | 1,441 | 1,084 |
|
|
3844
|
+
| \`canvas\` | 118,250 | 32,469 | 28,310 | 70,994 | 18,981 | 15,657 |
|
|
3845
|
+
| \`card\` | 40,909 | 12,065 | 10,599 | 5,378 | 1,439 | 1,060 |
|
|
3846
|
+
| \`carousel\` | 59,973 | 16,383 | 14,508 | 23,273 | 5,225 | 4,198 |
|
|
3847
|
+
| \`chat\` | 78,040 | 21,966 | 19,379 | 32,525 | 7,983 | 6,436 |
|
|
3848
|
+
| \`checkbox\` | 60,002 | 16,960 | 14,858 | 9,568 | 2,436 | 1,804 |
|
|
3849
|
+
| \`checkbox-group\` | 66,556 | 18,479 | 16,166 | 15,554 | 3,827 | 2,840 |
|
|
3850
|
+
| \`code\` | 35,708 | 10,676 | 9,358 | 1,511 | 510 | 280 |
|
|
3851
|
+
| \`code-block\` | 117,062 | 33,746 | 29,661 | 42,896 | 9,601 | 7,751 |
|
|
3852
|
+
| \`color-input\` | 161,920 | 43,479 | 38,020 | 72,998 | 15,074 | 12,421 |
|
|
3853
|
+
| \`color-picker\` | 119,011 | 31,025 | 27,241 | 59,934 | 12,942 | 10,570 |
|
|
3854
|
+
| \`combobox\` | 141,827 | 39,737 | 34,754 | 52,627 | 11,802 | 9,495 |
|
|
3855
|
+
| \`command\` | 98,519 | 26,850 | 23,518 | 38,807 | 9,390 | 7,486 |
|
|
3856
|
+
| \`copy-button\` | 103,331 | 30,817 | 26,998 | 29,157 | 6,650 | 5,227 |
|
|
3857
|
+
| \`data-table\` | 208,210 | 56,196 | 47,474 | 118,121 | 28,030 | 21,633 |
|
|
3858
|
+
| \`date-input\` | 157,188 | 43,280 | 37,801 | 55,567 | 11,971 | 9,704 |
|
|
3859
|
+
| \`date-picker\` | 69,815 | 19,452 | 17,281 | 24,462 | 5,777 | 4,561 |
|
|
3860
|
+
| \`description-list\` | 38,493 | 11,308 | 9,902 | 3,500 | 914 | 586 |
|
|
3861
|
+
| \`dialog\` | 54,741 | 16,320 | 14,276 | 10,551 | 2,885 | 2,204 |
|
|
3862
|
+
| \`divider\` | 38,940 | 11,591 | 10,168 | 3,542 | 990 | 652 |
|
|
3863
|
+
| \`donut-chart\` | 98,342 | 30,409 | 26,765 | 22,874 | 5,995 | 4,800 |
|
|
3864
|
+
| \`drawer\` | 55,007 | 16,412 | 14,381 | 9,604 | 2,677 | 2,095 |
|
|
3865
|
+
| \`drilldown\` | 56,968 | 16,933 | 14,788 | 11,056 | 2,834 | 2,148 |
|
|
3866
|
+
| \`empty\` | 38,473 | 11,578 | 10,099 | 2,613 | 857 | 561 |
|
|
3867
|
+
| \`file-input\` | 81,761 | 23,313 | 20,426 | 25,298 | 6,337 | 5,024 |
|
|
3868
|
+
| \`filter-input\` | 150,189 | 40,993 | 35,691 | 59,777 | 12,607 | 10,072 |
|
|
3869
|
+
| \`flex\` | 37,069 | 11,029 | 9,663 | 2,078 | 606 | 316 |
|
|
3870
|
+
| \`format-date\` | 42,448 | 12,721 | 11,225 | 4,932 | 1,384 | 975 |
|
|
3871
|
+
| \`graph\` | 83,721 | 23,127 | 20,248 | 29,634 | 7,367 | 5,805 |
|
|
3872
|
+
| \`grid\` | 38,524 | 11,590 | 10,202 | 3,533 | 1,152 | 854 |
|
|
3873
|
+
| \`heatmap\` | 100,985 | 31,285 | 27,393 | 21,043 | 5,417 | 4,248 |
|
|
3874
|
+
| \`icon\` | 94,226 | 29,533 | 25,208 | 56,405 | 19,564 | 15,360 |
|
|
3875
|
+
| \`icon-button\` | 57,339 | 16,168 | 14,140 | 12,926 | 2,896 | 2,176 |
|
|
3876
|
+
| \`image\` | 41,085 | 12,122 | 10,641 | 5,371 | 1,566 | 1,173 |
|
|
3877
|
+
| \`input\` | 63,649 | 18,692 | 16,286 | 11,927 | 3,565 | 2,565 |
|
|
3878
|
+
| \`kbd\` | 41,118 | 12,584 | 11,043 | 4,829 | 1,629 | 1,121 |
|
|
3879
|
+
| \`legend\` | 47,965 | 14,166 | 12,383 | 7,671 | 2,046 | 1,442 |
|
|
3880
|
+
| \`lightbox\` | 57,296 | 16,525 | 14,566 | 12,850 | 3,300 | 2,482 |
|
|
3881
|
+
| \`line-chart\` | 101,137 | 31,376 | 27,585 | 24,094 | 6,226 | 5,072 |
|
|
3882
|
+
| \`list\` | 41,331 | 11,967 | 10,518 | 5,976 | 1,490 | 1,177 |
|
|
3883
|
+
| \`listbox\` | 76,796 | 22,106 | 19,326 | 20,975 | 5,632 | 4,354 |
|
|
3884
|
+
| \`loader\` | 41,425 | 12,238 | 10,760 | 5,242 | 1,484 | 1,079 |
|
|
3885
|
+
| \`map\` | 125,915 | 30,054 | 26,073 | 75,034 | 15,543 | 12,270 |
|
|
3886
|
+
| \`megamenu\` | 72,426 | 23,061 | 20,296 | 10,031 | 2,594 | 1,911 |
|
|
3887
|
+
| \`menu\` | 92,016 | 28,697 | 25,105 | 18,272 | 4,491 | 3,413 |
|
|
3888
|
+
| \`meter\` | 46,018 | 13,184 | 11,630 | 10,472 | 2,578 | 2,052 |
|
|
3889
|
+
| \`navigation\` | 43,728 | 13,312 | 11,528 | 3,221 | 1,022 | 622 |
|
|
3890
|
+
| \`notifications\` | 73,708 | 19,871 | 17,586 | 28,831 | 6,427 | 5,267 |
|
|
3891
|
+
| \`number-input\` | 67,684 | 19,551 | 17,221 | 14,890 | 3,876 | 2,953 |
|
|
3892
|
+
| \`object-inspector\` | 122,792 | 36,326 | 31,725 | 42,419 | 10,058 | 8,043 |
|
|
3893
|
+
| \`option\` | 42,446 | 12,501 | 11,019 | 6,725 | 1,813 | 1,295 |
|
|
3894
|
+
| \`orb\` | 46,363 | 14,669 | 12,905 | 8,724 | 3,373 | 2,779 |
|
|
3895
|
+
| \`outline\` | 45,186 | 13,419 | 11,785 | 8,426 | 2,301 | 1,717 |
|
|
3896
|
+
| \`pagination\` | 139,323 | 39,095 | 34,021 | 56,933 | 12,979 | 10,410 |
|
|
3897
|
+
| \`pin-input\` | 59,673 | 17,283 | 15,193 | 9,643 | 2,818 | 2,023 |
|
|
3898
|
+
| \`popover\` | 75,869 | 24,333 | 21,264 | 7,282 | 1,936 | 1,356 |
|
|
3899
|
+
| \`progress\` | 43,533 | 12,712 | 11,219 | 7,987 | 2,083 | 1,600 |
|
|
3900
|
+
| \`qr-code\` | 51,860 | 16,518 | 14,502 | 16,585 | 5,954 | 4,865 |
|
|
3901
|
+
| \`quote\` | 36,215 | 10,843 | 9,481 | 1,216 | 460 | 197 |
|
|
3902
|
+
| \`radio\` | 64,144 | 17,850 | 15,648 | 12,236 | 2,730 | 2,072 |
|
|
3903
|
+
| \`rating\` | 64,926 | 19,300 | 16,928 | 12,084 | 3,628 | 2,814 |
|
|
3904
|
+
| \`sandbox\` | 77,010 | 20,452 | 17,994 | 37,272 | 8,465 | 6,969 |
|
|
3905
|
+
| \`scatter-chart\` | 98,869 | 30,809 | 27,023 | 22,828 | 6,117 | 4,881 |
|
|
3906
|
+
| \`scroll-area\` | 40,926 | 11,999 | 10,508 | 5,874 | 1,556 | 1,077 |
|
|
3907
|
+
| \`select\` | 118,886 | 34,630 | 30,262 | 36,578 | 8,554 | 6,822 |
|
|
3908
|
+
| \`skeleton\` | 39,347 | 11,644 | 10,257 | 3,981 | 1,150 | 791 |
|
|
3909
|
+
| \`skip-link\` | 38,161 | 11,506 | 10,081 | 3,008 | 1,022 | 664 |
|
|
3910
|
+
| \`slider\` | 68,867 | 18,804 | 16,589 | 18,420 | 4,147 | 3,205 |
|
|
3911
|
+
| \`sparkline\` | 47,474 | 14,421 | 12,684 | 6,294 | 1,882 | 1,503 |
|
|
3912
|
+
| \`speed-dial\` | 134,519 | 43,564 | 36,886 | 66,341 | 21,581 | 17,007 |
|
|
3913
|
+
| \`splitter\` | 56,483 | 15,850 | 13,987 | 17,031 | 3,967 | 3,124 |
|
|
3914
|
+
| \`stat\` | 40,443 | 11,709 | 10,282 | 5,081 | 1,229 | 889 |
|
|
3915
|
+
| \`steps\` | 70,250 | 19,157 | 16,771 | 23,289 | 5,099 | 4,082 |
|
|
3916
|
+
| \`switch\` | 57,461 | 16,577 | 14,545 | 6,627 | 1,858 | 1,342 |
|
|
3917
|
+
| \`table\` | 63,029 | 18,409 | 16,244 | 20,603 | 5,526 | 4,454 |
|
|
3918
|
+
| \`tabs\` | 55,917 | 16,074 | 14,020 | 10,629 | 2,426 | 1,812 |
|
|
3919
|
+
| \`tag\` | 52,749 | 15,717 | 13,896 | 10,588 | 2,807 | 2,044 |
|
|
3920
|
+
| \`text\` | 40,992 | 11,800 | 10,350 | 6,004 | 1,453 | 998 |
|
|
3921
|
+
| \`textarea\` | 58,889 | 17,042 | 14,926 | 8,378 | 2,391 | 1,704 |
|
|
3922
|
+
| \`time-input\` | 172,753 | 47,297 | 40,980 | 67,030 | 14,784 | 11,821 |
|
|
3923
|
+
| \`time-picker\` | 96,904 | 26,815 | 23,494 | 39,096 | 9,543 | 7,544 |
|
|
3924
|
+
| \`timeline\` | 41,820 | 12,294 | 10,765 | 5,538 | 1,397 | 1,058 |
|
|
3925
|
+
| \`toast\` | 61,343 | 17,944 | 15,845 | 16,665 | 4,368 | 3,382 |
|
|
3926
|
+
| \`toggle\` | 64,719 | 18,533 | 16,240 | 10,987 | 2,817 | 2,127 |
|
|
3927
|
+
| \`toolbar\` | 44,810 | 13,631 | 11,889 | 5,409 | 1,735 | 1,212 |
|
|
3928
|
+
| \`tooltip\` | 74,148 | 23,682 | 20,846 | 11,405 | 3,162 | 2,426 |
|
|
3929
|
+
| \`tour\` | 99,455 | 29,632 | 26,015 | 27,607 | 6,491 | 5,087 |
|
|
3930
|
+
| \`tree\` | 60,660 | 17,892 | 15,658 | 14,183 | 3,823 | 2,941 |
|
|
3931
|
+
| \`trend\` | 39,907 | 12,024 | 10,551 | 4,003 | 1,179 | 874 |
|
|
3932
|
+
| \`video\` | 137,129 | 39,344 | 34,264 | 58,747 | 13,884 | 11,183 |
|
|
3933
|
+
| \`video-playlist\` | 105,059 | 31,036 | 27,158 | 29,919 | 6,565 | 5,145 |
|
|
3934
|
+
| \`virtual-list\` | 48,726 | 15,007 | 13,061 | 4,770 | 1,587 | 1,099 |
|
|
3752
3935
|
|
|
3753
3936
|
## What an install adds to \`node_modules\`
|
|
3754
3937
|
|
|
@@ -3760,18 +3943,18 @@ stripped column shows the bytes we removed.
|
|
|
3760
3943
|
|
|
3761
3944
|
| Package | Unpacked | Files | Source maps stripped | Runtime dependencies |
|
|
3762
3945
|
|---|---|---|---|---|
|
|
3763
|
-
| \`@fusion.dev/helix-core\` | 1,
|
|
3764
|
-
| \`@fusion.dev/helix-headless\` |
|
|
3765
|
-
| \`@fusion.dev/helix-icons\` |
|
|
3766
|
-
| \`@fusion.dev/helix-styles\` | 106,
|
|
3946
|
+
| \`@fusion.dev/helix-core\` | 1,637,132 | 231 | 417,937 | \`@floating-ui/dom\`, \`@fusion.dev/helix-icons\` |
|
|
3947
|
+
| \`@fusion.dev/helix-headless\` | 15,882,414 | 561 | 1,363,913 | \`@fusion.dev/helix-core\`, \`@fusion.dev/helix-icons\`, \`uqr\` |
|
|
3948
|
+
| \`@fusion.dev/helix-icons\` | 149,615 | 21 | 47,843 | \`svgo\` |
|
|
3949
|
+
| \`@fusion.dev/helix-styles\` | 106,152 | 6 | 0 | none |
|
|
3767
3950
|
| \`@fusion.dev/helix-theme\` | 528,598 | 8 | 5,393 | none |
|
|
3768
|
-
| \`@fusion.dev/helix\` |
|
|
3951
|
+
| \`@fusion.dev/helix\` | 16,571,414 | 885 | 383,770 | \`@fusion.dev/helix-core\`, \`@fusion.dev/helix-headless\`, \`@fusion.dev/helix-styles\` |
|
|
3769
3952
|
|
|
3770
3953
|
## Not measured yet
|
|
3771
3954
|
|
|
3772
3955
|
We list these gaps so you know what the numbers above leave out.
|
|
3773
3956
|
|
|
3774
|
-
- **No whole-library comparison, and
|
|
3957
|
+
- **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
3958
|
- **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
3959
|
- **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
3960
|
- **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 +4126,11 @@ it.
|
|
|
3943
4126
|
## Register the elements
|
|
3944
4127
|
|
|
3945
4128
|
\`\`\`ts
|
|
3946
|
-
import '@fusion.dev/helix'
|
|
4129
|
+
import '@fusion.dev/helix/button'
|
|
4130
|
+
import '@fusion.dev/helix/dialog'
|
|
3947
4131
|
\`\`\`
|
|
3948
4132
|
|
|
3949
|
-
Import
|
|
4133
|
+
Import each family you use once, anywhere that runs in the browser. The stylesheets are the same
|
|
3950
4134
|
in every framework, and they are the part most often left out. See
|
|
3951
4135
|
[Installation](./installation) for the stylesheets.
|
|
3952
4136
|
`,
|
|
@@ -4022,17 +4206,44 @@ checks focus by walking through the shadow roots.
|
|
|
4022
4206
|
Nested overlays work because lifecycle events do not bubble.
|
|
4023
4207
|
\`helix-before-open\` and \`helix-before-close\` do not bubble and are not composed,
|
|
4024
4208
|
so a menu that closes inside a dialog does not close the dialog. \`Escape\` closes
|
|
4025
|
-
the innermost overlay and leaves the others open.
|
|
4209
|
+
the innermost overlay and leaves the others open. The overlay that closes
|
|
4210
|
+
cancels the key press, so a \`Dialog\` or \`Drawer\` around it stays open until you
|
|
4211
|
+
press \`Escape\` again.
|
|
4026
4212
|
|
|
4027
4213
|
## Where focus goes
|
|
4028
4214
|
|
|
4029
4215
|
A modal overlay keeps \`Tab\` inside itself while it is open, and it returns focus
|
|
4030
|
-
to the element that opened it. \`Dialog\`
|
|
4031
|
-
|
|
4216
|
+
to the element that opened it. \`Dialog\` does this, and so does \`Drawer\` unless
|
|
4217
|
+
you set \`modal="false"\`. The page behind a modal \`Dialog\` or \`Drawer\` does not
|
|
4218
|
+
scroll while it is open.
|
|
4219
|
+
|
|
4220
|
+
Opening a \`Popover\` moves focus to the first control in its panel, or to the
|
|
4221
|
+
panel where it holds none, and closing it from inside gives focus back to the
|
|
4222
|
+
trigger. It does not trap focus unless you set \`modal\`, which keeps \`Tab\` in the
|
|
4223
|
+
panel until it closes. When focus moves out of its trigger and its panel, the
|
|
4224
|
+
popover closes.
|
|
4225
|
+
|
|
4226
|
+
Press F8 to move focus to the \`Toast\` stack, and press it again to go back.
|
|
4227
|
+
Set \`hotkey\` on the stack to use another key. The stack's name says which key
|
|
4228
|
+
it is.
|
|
4229
|
+
|
|
4230
|
+
The fields with a panel behave the same way:
|
|
4231
|
+
|
|
4232
|
+
- \`Select\` and \`Combobox\` close their list when \`Tab\` moves focus out.
|
|
4233
|
+
- \`Date Input\`, \`Time Input\`, and \`Color Input\` close their panel when focus
|
|
4234
|
+
leaves the field, and \`Escape\` returns focus to the field.
|
|
4235
|
+
- Opening one of those panels from its trigger, or with \`ArrowDown\`, moves
|
|
4236
|
+
focus into the panel.
|
|
4032
4237
|
|
|
4033
4238
|
**A tooltip never takes focus.** A tooltip only describes a control, so it
|
|
4034
4239
|
cannot contain a button. For something with a button in it, use a \`Popover\`.
|
|
4035
4240
|
|
|
4241
|
+
A tooltip describes its trigger by itself, whether it wraps the trigger or
|
|
4242
|
+
names it with \`for\`. A Helix trigger is described as soon as it has rendered.
|
|
4243
|
+
A plain element in your markup is described the first time a reader points at
|
|
4244
|
+
it or focuses it, so the link is never written into markup your server sent.
|
|
4245
|
+
Write \`aria-describedby\` yourself to have the link in the server's markup.
|
|
4246
|
+
|
|
4036
4247
|
## Keep an overlay open
|
|
4037
4248
|
|
|
4038
4249
|
An overlay sends \`helix-before-close\` before it closes. Cancel the event to keep
|
|
@@ -4056,6 +4267,20 @@ on the \`overlay\` and \`display\` properties, which allows an exit animation on
|
|
|
4056
4267
|
element the browser is about to remove from the top layer. Every overlay
|
|
4057
4268
|
responds to \`prefers-reduced-motion\`.
|
|
4058
4269
|
|
|
4270
|
+
\`Dialog\` and \`Drawer\` also say where they are in the journey:
|
|
4271
|
+
\`:state(entering)\` holds from the moment they open until their entrance has
|
|
4272
|
+
finished, and \`:state(exiting)\` from the moment they close until their exit has
|
|
4273
|
+
finished. Select on them to draw an entrance or an exit of your own.
|
|
4274
|
+
|
|
4275
|
+
## Swiping an overlay away
|
|
4276
|
+
|
|
4277
|
+
A touch or a pen swipes a \`Drawer\` toward the edge it came from, and a \`Toast\`
|
|
4278
|
+
message toward the end of the line. A swipe past halfway, or a quick one, closes
|
|
4279
|
+
it through the same cancelable request as its close control. A \`Drawer\` with
|
|
4280
|
+
\`snap-points\` comes to rest at the nearest point, such as half open. In a
|
|
4281
|
+
\`Lightbox\`, a swipe across the viewer shows the next or the previous item. A
|
|
4282
|
+
mouse never swipes, because dragging with a mouse selects text.
|
|
4283
|
+
|
|
4059
4284
|
## Choose an overlay
|
|
4060
4285
|
|
|
4061
4286
|
| Component | Use it for |
|
|
@@ -4379,7 +4604,9 @@ See [State and control](./state-and-control) for the full model.
|
|
|
4379
4604
|
|
|
4380
4605
|
\`\`\`tsx
|
|
4381
4606
|
'use client'
|
|
4382
|
-
|
|
4607
|
+
// One line per family you use.
|
|
4608
|
+
import '@fusion.dev/helix/button'
|
|
4609
|
+
import '@fusion.dev/helix/dialog'
|
|
4383
4610
|
|
|
4384
4611
|
export const HelixElements = () => null
|
|
4385
4612
|
\`\`\`
|
|
@@ -4852,20 +5079,84 @@ without tracking which element sent each event. A pane named \`html\` sets the
|
|
|
4852
5079
|
preview's markup, and a pane named \`css\` sets its stylesheet. The sandbox
|
|
4853
5080
|
ignores a pane with any other name, so that pane only displays its contents.
|
|
4854
5081
|
|
|
5082
|
+
A pane's text goes in its \`value\`. The pane renders no children. The sandbox
|
|
5083
|
+
also hands each pane's \`value\` to the preview when it starts, so you write the
|
|
5084
|
+
text once, in the pane. A preview given its own \`source\` keeps it until the
|
|
5085
|
+
first edit.
|
|
5086
|
+
|
|
4855
5087
|
\`\`\`html
|
|
4856
5088
|
<helix-sandbox>
|
|
4857
5089
|
<helix-sandbox-source
|
|
4858
5090
|
name="html"
|
|
4859
5091
|
slot="source"
|
|
4860
|
-
|
|
5092
|
+
value="<p>Hello</p>"
|
|
5093
|
+
></helix-sandbox-source>
|
|
4861
5094
|
<helix-sandbox-source
|
|
4862
5095
|
name="css"
|
|
4863
5096
|
slot="source"
|
|
4864
|
-
|
|
4865
|
-
|
|
5097
|
+
value="p { color: teal }"
|
|
5098
|
+
></helix-sandbox-source>
|
|
5099
|
+
<helix-sandbox-preview
|
|
5100
|
+
slot="preview"
|
|
5101
|
+
src="/frame.html"
|
|
5102
|
+
></helix-sandbox-preview>
|
|
4866
5103
|
</helix-sandbox>
|
|
4867
5104
|
\`\`\`
|
|
4868
5105
|
|
|
5106
|
+
Cancel \`helix-before-edit\` to refuse an edit. The pane keeps its text, and the
|
|
5107
|
+
preview does not receive the refused one.
|
|
5108
|
+
|
|
5109
|
+
In a source pane, Tab inserts two spaces. Shift+Tab moves focus back, and
|
|
5110
|
+
Escape then Tab moves it forward. The field's description says this to a
|
|
5111
|
+
screen reader.
|
|
5112
|
+
|
|
5113
|
+
## The frame document
|
|
5114
|
+
|
|
5115
|
+
\`helix-sandbox-preview\` loads \`src\` into a sandboxed frame. You provide that
|
|
5116
|
+
document. It loads the styles and the elements your examples use, and it talks
|
|
5117
|
+
to the preview through \`postMessage\`:
|
|
5118
|
+
|
|
5119
|
+
| Message | Sent by | What it carries |
|
|
5120
|
+
|---|---|---|
|
|
5121
|
+
| \`helix-preview-console\` | The frame | One console call: \`level\` (\`log\`, \`info\`, \`warn\` or \`error\`) and \`text\` |
|
|
5122
|
+
| \`helix-preview-press\` | The frame | Nothing. Send it on \`pointerdown\`, so menus outside the frame close |
|
|
5123
|
+
| \`helix-preview-ready\` | The frame | Nothing. Send it once the listener for renders is in place |
|
|
5124
|
+
| \`helix-preview-render\` | The preview | \`source\`, \`styles\`, \`layout\`, \`direction\` and an optional \`colorMode\` |
|
|
5125
|
+
| \`helix-preview-size\` | The frame | \`size\`, the height of the content in CSS pixels |
|
|
5126
|
+
|
|
5127
|
+
Each message is an object with a \`type\` naming it. The preview sends
|
|
5128
|
+
\`helix-preview-render\` once the frame posts \`helix-preview-ready\` or fires
|
|
5129
|
+
\`load\`, and again after each edit settles. The frame writes \`source\` into its
|
|
5130
|
+
body and \`styles\` into a stylesheet. The preview accepts a message only from
|
|
5131
|
+
its own frame, and only from an opaque origin, so the frame keeps the sandbox
|
|
5132
|
+
it was given. The types are exported from \`@fusion.dev/helix/sandbox\` as
|
|
5133
|
+
\`PreviewMessage\` and its members.
|
|
5134
|
+
|
|
5135
|
+
A minimal frame follows. \`/helix.css\` is the stylesheet from
|
|
5136
|
+
\`@fusion.dev/helix-styles\`, and \`/elements.js\` is a classic script that
|
|
5137
|
+
registers your elements, for the reason under "How the preview is isolated".
|
|
5138
|
+
|
|
5139
|
+
\`\`\`html
|
|
5140
|
+
<!doctype html>
|
|
5141
|
+
<link
|
|
5142
|
+
href="/helix.css"
|
|
5143
|
+
rel="stylesheet"
|
|
5144
|
+
>
|
|
5145
|
+
<script
|
|
5146
|
+
defer
|
|
5147
|
+
src="/elements.js"
|
|
5148
|
+
></script>
|
|
5149
|
+
<style id="example-styles"></style>
|
|
5150
|
+
<script defer>
|
|
5151
|
+
addEventListener('message', ({ data }) => {
|
|
5152
|
+
if (data?.type !== 'helix-preview-render') return
|
|
5153
|
+
document.getElementById('example-styles').textContent = data.styles
|
|
5154
|
+
document.body.innerHTML = data.source
|
|
5155
|
+
})
|
|
5156
|
+
parent.postMessage({ type: 'helix-preview-ready' }, '*')
|
|
5157
|
+
</script>
|
|
5158
|
+
\`\`\`
|
|
5159
|
+
|
|
4869
5160
|
## Console output from the example
|
|
4870
5161
|
|
|
4871
5162
|
Logs from the example appear in the console panel. Logs from the page around it
|
|
@@ -4940,7 +5231,7 @@ browser. Load Lit's hydration support before the components:
|
|
|
4940
5231
|
|
|
4941
5232
|
\`\`\`ts
|
|
4942
5233
|
import '@lit-labs/ssr-client/lit-element-hydrate-support.js'
|
|
4943
|
-
import '@fusion.dev/helix'
|
|
5234
|
+
import '@fusion.dev/helix/button'
|
|
4944
5235
|
\`\`\`
|
|
4945
5236
|
|
|
4946
5237
|
Hydration assumes the markup already matches the client's first render. If a
|
|
@@ -5454,6 +5745,12 @@ current value. The pair comes from the platform. A native input reflects its
|
|
|
5454
5745
|
\`value\` *content attribute* to \`defaultValue\`, and it keeps a dirty flag. Once a
|
|
5455
5746
|
user has typed, the flag stops the attribute from changing the value.
|
|
5456
5747
|
|
|
5748
|
+
**A form reset clears a \`value\` or \`checked\` you wrote in markup.** A native
|
|
5749
|
+
\`<input value="Ada">\` resets to \`Ada\`, and \`<helix-input value="Ada">\` resets to
|
|
5750
|
+
empty, because a Helix control resets to \`default-value\` and \`default-checked\`.
|
|
5751
|
+
Write the starting value of a form control as \`default-value\`, or
|
|
5752
|
+
\`default-checked\` for a checkbox or a switch.
|
|
5753
|
+
|
|
5457
5754
|
## State is published as a custom state
|
|
5458
5755
|
|
|
5459
5756
|
\`\`\`css
|
|
@@ -5468,7 +5765,8 @@ A reflected \`value\` would carry the password past every session-replay masker
|
|
|
5468
5765
|
that masks \`.value\` and \`input[value]\`.
|
|
5469
5766
|
|
|
5470
5767
|
Helix publishes the resolved boolean as a custom state, and the attribute keeps
|
|
5471
|
-
the value you wrote.
|
|
5768
|
+
the value you wrote. These are the most common, and each component's reference
|
|
5769
|
+
page lists the states it publishes:
|
|
5472
5770
|
|
|
5473
5771
|
- \`:state(open)\`
|
|
5474
5772
|
- \`:state(checked)\`
|
|
@@ -5625,7 +5923,7 @@ and you do not need a compiler flag.
|
|
|
5625
5923
|
Svelte passes objects and arrays as properties on its own:
|
|
5626
5924
|
|
|
5627
5925
|
\`\`\`svelte
|
|
5628
|
-
<helix-
|
|
5926
|
+
<helix-data-table label="People" rows={people} />
|
|
5629
5927
|
\`\`\`
|
|
5630
5928
|
|
|
5631
5929
|
Svelte's own attributes are typed on every Helix tag as well, so \`onclick\`,
|
|
@@ -5928,7 +6226,11 @@ Mark the section so the stylesheet derives its own colors there from the
|
|
|
5928
6226
|
section's seeds, in the section's mode, and paint it with its page color:
|
|
5929
6227
|
|
|
5930
6228
|
\`\`\`html
|
|
5931
|
-
<section
|
|
6229
|
+
<section
|
|
6230
|
+
data-band
|
|
6231
|
+
data-color-mode="dark"
|
|
6232
|
+
data-helix-theme
|
|
6233
|
+
>…</section>
|
|
5932
6234
|
\`\`\`
|
|
5933
6235
|
|
|
5934
6236
|
\`\`\`css
|
|
@@ -6504,7 +6806,7 @@ looks enabled while it does not accept input.
|
|
|
6504
6806
|
|
|
6505
6807
|
\`\`\`ts
|
|
6506
6808
|
import '@fusion.dev/helix-styles/helix.css'
|
|
6507
|
-
import '@fusion.dev/helix'
|
|
6809
|
+
import '@fusion.dev/helix/button'
|
|
6508
6810
|
\`\`\`
|
|
6509
6811
|
|
|
6510
6812
|
\`helix.css\` combines four files in the order they must load:
|
|
@@ -6741,10 +7043,12 @@ button.
|
|
|
6741
7043
|
## Import \`elements.css\` beside the base layer
|
|
6742
7044
|
|
|
6743
7045
|
\`\`\`ts
|
|
6744
|
-
import '@fusion.dev/helix-styles/base.css'
|
|
6745
7046
|
import '@fusion.dev/helix-styles/helix.css'
|
|
6746
7047
|
\`\`\`
|
|
6747
7048
|
|
|
7049
|
+
\`helix.css\` imports \`elements.css\` after the primitives, the tokens, and the
|
|
7050
|
+
base layer. If you import the layers one at a time, import \`elements.css\` last.
|
|
7051
|
+
|
|
6748
7052
|
\`elements.css\` hides each tag with \`:not(:defined)\` until the element upgrades.
|
|
6749
7053
|
It uses \`visibility\`, so the page does not reflow. Without it, a card appears as
|
|
6750
7054
|
unstyled text and then jumps into its card layout.
|
|
@@ -6763,6 +7067,24 @@ import '@fusion.dev/helix' // ❌ the barrel
|
|
|
6763
7067
|
Import one component family per module, so you do not ship the whole library to
|
|
6764
7068
|
use a button.
|
|
6765
7069
|
|
|
7070
|
+
## Turn off an attribute that is on by default
|
|
7071
|
+
|
|
7072
|
+
A boolean attribute is off until you write it, with four exceptions. These are
|
|
7073
|
+
on until you write the string \`"false"\`:
|
|
7074
|
+
|
|
7075
|
+
- \`modal\` on Drawer
|
|
7076
|
+
- \`playsinline\` on Video
|
|
7077
|
+
- \`default-pinned\` on Chat
|
|
7078
|
+
- \`tab-indents\` on Sandbox Source
|
|
7079
|
+
|
|
7080
|
+
\`\`\`html
|
|
7081
|
+
<helix-drawer modal="false"></helix-drawer>
|
|
7082
|
+
\`\`\`
|
|
7083
|
+
|
|
7084
|
+
In JSX, \`modal={false}\` sets the property and does the same. Other features
|
|
7085
|
+
that are on by default turn off with an attribute named \`no-\`, such as
|
|
7086
|
+
\`no-copy\`.
|
|
7087
|
+
|
|
6766
7088
|
## Declarative shadow DOM is opt-in
|
|
6767
7089
|
|
|
6768
7090
|
The site ships no declarative shadow DOM (DSD). The shadow styles load with the
|
|
@@ -7205,7 +7527,8 @@ That works for every Helix element. A string goes through either path, and an
|
|
|
7205
7527
|
array or an object goes through the property.
|
|
7206
7528
|
|
|
7207
7529
|
\`\`\`vue
|
|
7208
|
-
<helix-
|
|
7530
|
+
<helix-data-table label="People" :rows="people" />
|
|
7531
|
+
<helix-tabs @helix-before-activate="onActivate" />
|
|
7209
7532
|
\`\`\`
|
|
7210
7533
|
|
|
7211
7534
|
\`@helix-before-activate\` binds with \`addEventListener\`, so use the event's own
|