@fusion.dev/helix-docs 0.0.0-dev → 0.0.2
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/browser-support.mdx +2 -2
- package/content/charting.mdx +4 -8
- package/content/coding-agents.mdx +14 -22
- package/content/color-modes.mdx +4 -4
- package/content/color.mdx +2 -2
- package/content/elevation-and-material.mdx +2 -2
- package/content/events.mdx +1 -1
- package/content/forms.mdx +5 -7
- package/content/iconography.mdx +15 -12
- package/content/installation.mdx +4 -6
- package/content/introduction.mdx +1 -1
- package/content/metrics.mdx +214 -214
- package/content/other-frameworks.mdx +6 -5
- package/content/overriding-a-component.mdx +11 -15
- package/content/routing.mdx +4 -4
- package/content/server-rendering.mdx +1 -1
- package/content/shape-and-borders.mdx +19 -8
- package/content/space-and-size.mdx +1 -1
- package/content/state-and-control.mdx +5 -5
- package/content/svelte.mdx +3 -3
- package/content/theme-builder.mdx +1 -1
- package/content/theming.mdx +1 -1
- package/content/tiers.mdx +2 -2
- package/content/tokens.mdx +4 -4
- package/content/using-helix-with-an-agent.mdx +30 -27
- package/content/using-the-elements.mdx +0 -2
- package/content/visual-axes.mdx +5 -7
- package/content/without-a-bundler.mdx +4 -5
- package/dist/catalog.d.ts +19 -29
- package/dist/catalog.js +27 -49
- package/dist/naming.js +1 -1
- package/dist/pages.generated.d.ts +1 -1
- package/dist/pages.generated.js +1 -1
- package/dist/reference.js +1 -1
- package/dist/registry.d.ts +3 -3
- package/dist/registry.js +3 -3
- package/dist/sections.d.ts +3 -7
- package/dist/sections.js +3 -7
- package/dist/sources.generated.d.ts +2 -2
- package/dist/sources.generated.js +367 -374
- package/package.json +6 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Every page's MDX, inlined by `
|
|
3
|
-
* `content/` are the source, and `
|
|
2
|
+
* Every page's MDX, inlined by `turbo run docs`. Do not edit: the files in
|
|
3
|
+
* `content/` are the source, and `turbo run docs -- --check` fails when this module
|
|
4
4
|
* and they disagree.
|
|
5
5
|
*/
|
|
6
6
|
export const docSources = {
|
|
@@ -213,11 +213,11 @@ report we want, and it is not one we would have caught.
|
|
|
213
213
|
| Custom elements and shadow DOM | Everything |
|
|
214
214
|
| \`ElementInternals\` | Form participation, and ARIA that has to cross a shadow boundary |
|
|
215
215
|
| Popover API | Every overlay: menu, tooltip, select, combobox, dialog |
|
|
216
|
-
| \`light-dark()\` |
|
|
216
|
+
| \`light-dark()\` | 156 declarations in the shipped stylesheets, 71 of them in the token layer |
|
|
217
217
|
| \`oklch()\` | Every color in the system |
|
|
218
218
|
| \`:has()\` | 11 rules, mostly relational styling of slotted content |
|
|
219
219
|
| \`@starting-style\` | Entry transitions on overlays |
|
|
220
|
-
| \`:state()\` | Every boolean state the library publishes: \`open\`, \`checked\`, \`selected\`, \`invalid\`, \`read\`, \`has-label\`, \`settled\`, \`empty\` |
|
|
220
|
+
| \`:state()\` | Every boolean state the library publishes: \`open\`, \`checked\`, \`selected\`, \`invalid\`, \`read\`, \`has-label\`, \`settled\`, \`empty\`, \`controls\` |
|
|
221
221
|
| \`CSS.highlights\` | Filter-match highlighting, in \`Command\` and \`Combobox\` |
|
|
222
222
|
|
|
223
223
|
Positioning is \`@floating-ui/dom\` rather than CSS anchor positioning, which is a
|
|
@@ -465,18 +465,14 @@ Hide the table visually if it should not be seen, and the data is still there:
|
|
|
465
465
|
The caption becomes the chart's accessible name unless you set \`label\`, which is
|
|
466
466
|
usually the right words and is already written.
|
|
467
467
|
|
|
468
|
-
## Series
|
|
468
|
+
## Series colors
|
|
469
469
|
|
|
470
470
|
Twenty-four \`--helix-color-series-*\` tokens, in order. A chart with three series
|
|
471
471
|
uses the first three. They are ordered to stay distinguishable in that order
|
|
472
472
|
rather than to look good as a full set of twenty-four.
|
|
473
473
|
|
|
474
|
-
The palette wraps, and where it wraps is one number in one place
|
|
475
|
-
|
|
476
|
-
fifth, so when the palette went from eight to twenty-four one of them was missed
|
|
477
|
-
and drew every ninth series in the first color while the legend beside it named
|
|
478
|
-
the ninth correctly. A number two files have to agree on is a number that will
|
|
479
|
-
stop agreeing.
|
|
474
|
+
The palette wraps, and where it wraps is one number in one place, so a chart and
|
|
475
|
+
the legend beside it can never disagree about which color a series is.
|
|
480
476
|
|
|
481
477
|
**A chart's mark carries its own series color as a custom property**, because a
|
|
482
478
|
chart knows which series a bar belongs to and CSS cannot count it. That is what
|
|
@@ -489,7 +485,7 @@ lets you restyle a series from outside without knowing the drawing order.
|
|
|
489
485
|
<helix-bar-chart for="revenue"></helix-bar-chart>
|
|
490
486
|
\`\`\`
|
|
491
487
|
|
|
492
|
-
The legend reads the same table, so the names and the
|
|
488
|
+
The legend reads the same table, so the names and the colors cannot disagree
|
|
493
489
|
with the chart's. Pointing them at two different tables is the only way to make
|
|
494
490
|
them disagree, and it is not something to do by accident.
|
|
495
491
|
|
|
@@ -525,13 +521,9 @@ https://fusion.dev/helix/custom-elements.json
|
|
|
525
521
|
@fusion.dev/helix/custom-elements.json
|
|
526
522
|
\`\`\`
|
|
527
523
|
|
|
528
|
-
A URL and a package path, the same file either way. **
|
|
529
|
-
|
|
530
|
-
\`llms.txt\` has this site and no checkout
|
|
531
|
-
\`node_modules\` and from nowhere else. It was only the specifier until 24 Aug 2026,
|
|
532
|
-
and the specifier did not resolve either: \`exports\` carried a \`./*\` pattern
|
|
533
|
-
pointing at \`./dist/*/index.js\`, so the path two pages recommended was one
|
|
534
|
-
\`require.resolve\` refused.
|
|
524
|
+
A URL and a package path, the same file either way. **Both exist because a
|
|
525
|
+
specifier is reachable from a \`node_modules\` and from nowhere else**, and an
|
|
526
|
+
agent that found the library through \`llms.txt\` has this site and no checkout.
|
|
535
527
|
|
|
536
528
|
Every element, every property with its literal type union, every event with its
|
|
537
529
|
class, every slot, every part, every custom property. It is what the framework
|
|
@@ -569,13 +561,13 @@ These are the difference between code that looks right and code that passes:
|
|
|
569
561
|
|
|
570
562
|
| Rule | Check |
|
|
571
563
|
|---|---|
|
|
572
|
-
| A dispatched event must be declared | \`
|
|
573
|
-
| A documented part must be rendered | \`
|
|
574
|
-
| A documented CSS hook must be read | \`
|
|
575
|
-
| A visual property draws from its axis | \`
|
|
576
|
-
| A form control styles with \`:disabled\` | \`
|
|
577
|
-
| A component that animates answers reduced motion | \`
|
|
578
|
-
| No component reads a primitive token | \`
|
|
564
|
+
| A dispatched event must be declared | \`helix component --only events\` |
|
|
565
|
+
| A documented part must be rendered | \`helix component\`'s \`parts\` |
|
|
566
|
+
| A documented CSS hook must be read | \`helix component --only hooks\` |
|
|
567
|
+
| A visual property draws from its axis | \`helix component\`'s \`axes\` |
|
|
568
|
+
| A form control styles with \`:disabled\` | \`helix component --only disabled\` |
|
|
569
|
+
| A component that animates answers reduced motion | \`helix component --only motion\` |
|
|
570
|
+
| No component reads a primitive token | \`helix component\`'s \`tokens\` |
|
|
579
571
|
|
|
580
572
|
If you are generating Helix code, the first two are the ones that produce
|
|
581
573
|
working-looking output that is wrong.
|
|
@@ -593,8 +585,7 @@ existing.
|
|
|
593
585
|
|
|
594
586
|
Start there rather than crawling: one request, and it names every page on the
|
|
595
587
|
site plus the two machine-readable surfaces above. No count here, because a
|
|
596
|
-
number typed into prose is a number that goes stale
|
|
597
|
-
on 24 Aug 2026 found five of.
|
|
588
|
+
number typed into prose is a number that goes stale.
|
|
598
589
|
|
|
599
590
|
## From a component's page
|
|
600
591
|
|
|
@@ -634,12 +625,9 @@ of a binary you installed, talking to a client you chose, with no network in it.
|
|
|
634
625
|
page into one file is out of date the moment anything changes, where the links
|
|
635
626
|
in \`llms.txt\` are individually cacheable and individually current.
|
|
636
627
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
this site and no checkout. What it was for is covered better by the two surfaces
|
|
641
|
-
already here. \`llms.txt\` is the index, one request, and each family's \`.md\` is
|
|
642
|
-
the document. Fetch the families you are using.
|
|
628
|
+
What such a file would be for is covered better by the two surfaces already
|
|
629
|
+
here. \`llms.txt\` is the index, one request, and each family's \`.md\` is the
|
|
630
|
+
document. Fetch the families you are using.
|
|
643
631
|
|
|
644
632
|
**A search index.** The site has one for humans; there is nothing an agent can
|
|
645
633
|
query yet, and \`llms.txt\` plus the documents it names is a smaller thing to read
|
|
@@ -653,7 +641,7 @@ title: Color
|
|
|
653
641
|
|
|
654
642
|
# Color
|
|
655
643
|
|
|
656
|
-
Seventy-four of the library's
|
|
644
|
+
Seventy-four of the library's 185 tokens are color, which is most of what a
|
|
657
645
|
theme is. They are roles rather than values: nothing in Helix is named after
|
|
658
646
|
what it looks like, because a name like \`--brand-blue-500\` stops being true the
|
|
659
647
|
moment anybody rethemes.
|
|
@@ -728,7 +716,7 @@ pairing a reader has to be able to read.
|
|
|
728
716
|
/* Yours to read. */
|
|
729
717
|
color: var(--helix-color-foreground-muted);
|
|
730
718
|
|
|
731
|
-
/* Not yours to read, and \`
|
|
719
|
+
/* Not yours to read, and the \`tokens\` rule fails the build on it. */
|
|
732
720
|
color: var(--_helix-neutral-500);
|
|
733
721
|
\`\`\`
|
|
734
722
|
|
|
@@ -760,9 +748,9 @@ stylesheet, no \`.dark\` class to toggle, and nothing to remember to update twic
|
|
|
760
748
|
|
|
761
749
|
Every token is written once, with both halves in a \`light-dark()\`. Which half
|
|
762
750
|
resolves is decided by \`color-scheme\` and nothing else, so the mode is a single
|
|
763
|
-
inherited property and no token is restated to honor it. That is
|
|
764
|
-
declarations across the
|
|
765
|
-
modes without a second copy of anything.
|
|
751
|
+
inherited property and no token is restated to honor it. That is 156
|
|
752
|
+
declarations across the shipped stylesheets, 71 of them in the token layer,
|
|
753
|
+
expressing two modes without a second copy of anything.
|
|
766
754
|
|
|
767
755
|
## Setting the mode
|
|
768
756
|
|
|
@@ -812,7 +800,7 @@ told.
|
|
|
812
800
|
|
|
813
801
|
## What this means for your own CSS
|
|
814
802
|
|
|
815
|
-
Write \`light-dark()\` for your own
|
|
803
|
+
Write \`light-dark()\` for your own colors and set nothing else:
|
|
816
804
|
|
|
817
805
|
\`\`\`css
|
|
818
806
|
.callout {
|
|
@@ -1070,8 +1058,8 @@ Eight tokens describing translucency rather than color:
|
|
|
1070
1058
|
| \`--helix-material-blur-sm\` | \`8px\` | The lightest backdrop blur. |
|
|
1071
1059
|
| \`--helix-material-blur-md\` | \`16px\` | The backdrop blur a modal takes. |
|
|
1072
1060
|
| \`--helix-material-blur-lg\` | \`32px\` | The heaviest backdrop blur. |
|
|
1073
|
-
| \`--helix-material-translucent\` | \`color-mix(in oklab, light-dark(oklch(1 0 0), oklch(0.
|
|
1074
|
-
| \`--helix-material-translucent-strong\` | \`color-mix(in oklab, light-dark(oklch(1 0 0), oklch(0.
|
|
1061
|
+
| \`--helix-material-translucent\` | \`color-mix(in oklab, light-dark(oklch(1 0 0), oklch(0.182 var(--helix-seed-neutral-chroma, 0) var(--helix-seed-neutral-hue, 258))) 30%, transparent)\` | The translucent ground, for a surface that admits what is behind it. |
|
|
1062
|
+
| \`--helix-material-translucent-strong\` | \`color-mix(in oklab, light-dark(oklch(1 0 0), oklch(0.182 var(--helix-seed-neutral-chroma, 0) var(--helix-seed-neutral-hue, 258))) 88%, transparent)\` | The heavier translucent ground, for one that admits less. |
|
|
1075
1063
|
| \`--helix-material-border\` | \`light-dark(color-mix(in oklab, oklch(0.15 var(--helix-seed-neutral-chroma, 0) var(--helix-seed-neutral-hue, 258)) 14%, transparent), color-mix(in oklab, oklch(1 0 0) 12%, transparent))\` | The edge a translucent surface needs to have any at all. |
|
|
1076
1064
|
|
|
1077
1065
|
[//]: # (/tokens)
|
|
@@ -1197,7 +1185,7 @@ dispatch, so an event you can listen for is an event that is documented.
|
|
|
1197
1185
|
| \`helix-navigate\` | A component is about to navigate |
|
|
1198
1186
|
| \`helix-copy\` | Something was copied |
|
|
1199
1187
|
| \`helix-caret\` | The cursor moved in a text control |
|
|
1200
|
-
| \`helix-
|
|
1188
|
+
| \`helix-complete\` | A control that fills up has filled |
|
|
1201
1189
|
| \`helix-create\` | A new item was made from a query |
|
|
1202
1190
|
| \`helix-console\` | The sandbox relaying a log |
|
|
1203
1191
|
| \`helix-tour-ask\`, \`helix-sample-start\`, \`helix-sample-end\` | Tour and color sampling |
|
|
@@ -1314,7 +1302,7 @@ Submitting an empty form blocks and points at the control. \`checkValidity()\`,
|
|
|
1314
1302
|
\`reportValidity()\` and \`:invalid\` behave.
|
|
1315
1303
|
|
|
1316
1304
|
**\`feedback\` overrides the message.** Left empty, the browser's own is shown,
|
|
1317
|
-
which is
|
|
1305
|
+
which is localized and familiar; set, it says what you want in the words your
|
|
1318
1306
|
product uses:
|
|
1319
1307
|
|
|
1320
1308
|
\`\`\`html
|
|
@@ -1343,12 +1331,10 @@ deliberately reports no value of its own.
|
|
|
1343
1331
|
</fieldset>
|
|
1344
1332
|
\`\`\`
|
|
1345
1333
|
|
|
1346
|
-
That works
|
|
1347
|
-
through \`formDisabledCallback\`,
|
|
1348
|
-
disabled fieldset
|
|
1349
|
-
|
|
1350
|
-
and carried no \`aria-disabled\`, while the form's entry list correctly left it
|
|
1351
|
-
out. Interactive and unsubmittable is the worst of both.
|
|
1334
|
+
That works. The platform tells a form-associated element it has been disabled by
|
|
1335
|
+
an ancestor through \`formDisabledCallback\`, and every Helix control implements
|
|
1336
|
+
it, so a control inside a disabled fieldset refuses input and announces itself
|
|
1337
|
+
as off rather than staying typeable and unsubmittable.
|
|
1352
1338
|
|
|
1353
1339
|
**For your own CSS this means one rule.** Style disabled controls with
|
|
1354
1340
|
\`:disabled\`, never \`[disabled]\`:
|
|
@@ -1390,7 +1376,7 @@ returns to, which is usually what a seed in a form means:
|
|
|
1390
1376
|
See [State and control](./state-and-control).
|
|
1391
1377
|
`,
|
|
1392
1378
|
iconography: `---
|
|
1393
|
-
description:
|
|
1379
|
+
description: 105 glyphs, one geometry, and how to draw one that is not in the set.
|
|
1394
1380
|
section: Foundations
|
|
1395
1381
|
title: Iconography
|
|
1396
1382
|
---
|
|
@@ -1401,10 +1387,12 @@ title: Iconography
|
|
|
1401
1387
|
<helix-icon name="trash"></helix-icon>
|
|
1402
1388
|
\`\`\`
|
|
1403
1389
|
|
|
1404
|
-
|
|
1390
|
+
105 glyphs, from Phosphor, drawn on a 256 box at Phosphor's bold weight. That is
|
|
1405
1391
|
Phosphor's own geometry and it is kept rather than rescaled: normalizing to a 24
|
|
1406
1392
|
box would change the optical weight of every glyph and stop the set matching
|
|
1407
|
-
anything upstream.
|
|
1393
|
+
anything upstream. Bold rather than regular, because Phosphor's regular is a
|
|
1394
|
+
hairline beside the medium weight this library sets its text in, and an icon
|
|
1395
|
+
that reads lighter than the words next to it is the opposite of a mark.
|
|
1408
1396
|
|
|
1409
1397
|
## Size and color come from the context
|
|
1410
1398
|
|
|
@@ -1454,21 +1442,22 @@ failure rather than an empty box.
|
|
|
1454
1442
|
|
|
1455
1443
|
## Adding one
|
|
1456
1444
|
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
hand-transcribing a path into a TypeScript object.
|
|
1445
|
+
Add the name to \`helix/icons/icons.txt\` and run \`turbo run icons\`. Phosphor names
|
|
1446
|
+
resolve from \`@phosphor-icons/core\` at build time, so adding a glyph is adding a
|
|
1447
|
+
line rather than hand-transcribing a path into a TypeScript object.
|
|
1460
1448
|
|
|
1461
|
-
|
|
1462
|
-
|
|
1449
|
+
A mark Phosphor does not draw goes into \`helix/icons/raw\` as an SVG under the
|
|
1450
|
+
same name, and is read from there when the package has no match. Keep it to the
|
|
1451
|
+
same geometry, a 256 box at the bold weight: a glyph drawn at a different weight
|
|
1452
|
+
is visible immediately when it sits beside one that was not.
|
|
1463
1453
|
|
|
1464
1454
|
## Icons this set does not have
|
|
1465
1455
|
|
|
1466
1456
|
Product marks. Helix and Cortex have marks and they live in the icon package,
|
|
1467
1457
|
but a mark is not an icon: it identifies a product and does not mean an action.
|
|
1468
|
-
|
|
1469
|
-
metaphor
|
|
1470
|
-
|
|
1471
|
-
If you are reaching for the icon set to draw a logo, that is the wrong drawer.
|
|
1458
|
+
**A mark is one rounded body with material removed**, never a pictogram of a
|
|
1459
|
+
metaphor, because the parent it stands beside is a geometric monogram. If you
|
|
1460
|
+
are reaching for the icon set to draw a logo, that is the wrong drawer.
|
|
1472
1461
|
`,
|
|
1473
1462
|
installation: `---
|
|
1474
1463
|
description: What to install, the order the stylesheets go in, and how to check it worked.
|
|
@@ -1496,8 +1485,7 @@ import '@fusion.dev/helix/helix.css'
|
|
|
1496
1485
|
|
|
1497
1486
|
One import, and it is four files in the order they have to be in:
|
|
1498
1487
|
\`primitives.css\`, \`tokens.css\`, \`base.css\`, \`elements.css\`. The order is
|
|
1499
|
-
load-bearing and the failure is silent,
|
|
1500
|
-
for longer than anyone would like, so it is stated once inside the package
|
|
1488
|
+
load-bearing and the failure is silent, so it is stated once inside the package
|
|
1501
1489
|
rather than by every consumer.
|
|
1502
1490
|
|
|
1503
1491
|
It resolves \`@fusion.dev/helix-styles\` through this package's own dependency, so
|
|
@@ -1513,13 +1501,12 @@ own ramp imports the two they want and skips the bundle.
|
|
|
1513
1501
|
- **\`primitives.css\`** is the raw ramp the semantic layer is derived from, and
|
|
1514
1502
|
it is where the seven \`--helix-seed-*\` knobs are read. Nothing in your own
|
|
1515
1503
|
code should name a primitive, and leaving the file out is not a way to
|
|
1516
|
-
enforce that: \`tokens.css\` refers to one
|
|
1504
|
+
enforce that: \`tokens.css\` refers to one 297 times, so without it every
|
|
1517
1505
|
semantic token resolves to nothing at all. Measured on a page missing it,
|
|
1518
1506
|
\`--helix-color-background\` computes to \`rgba(0, 0, 0, 0)\`, and so does every
|
|
1519
1507
|
other color. It is also the file [theming](theming.mdx) depends on, since a
|
|
1520
|
-
\`--helix-seed-brand\` nobody reads moves nothing.
|
|
1521
|
-
|
|
1522
|
-
- **\`tokens.css\`** declares the semantic layer, 177 custom properties in 15
|
|
1508
|
+
\`--helix-seed-brand\` nobody reads moves nothing.
|
|
1509
|
+
- **\`tokens.css\`** declares the semantic layer, 185 custom properties in 15
|
|
1523
1510
|
categories, plus \`color-scheme: light dark\` on \`:root\`. Everything below reads
|
|
1524
1511
|
from it, and it reads primitives.
|
|
1525
1512
|
- **\`base.css\`** is the element reset, the type scale on bare \`h1\` through
|
|
@@ -1736,7 +1723,7 @@ analysis time rather than left to review.
|
|
|
1736
1723
|
bun add @fusion.dev/helix @fusion.dev/helix-styles
|
|
1737
1724
|
\`\`\`
|
|
1738
1725
|
|
|
1739
|
-
|
|
1726
|
+
Two imports at your app root, in this order, then the elements are usable
|
|
1740
1727
|
anywhere:
|
|
1741
1728
|
|
|
1742
1729
|
\`\`\`ts
|
|
@@ -1879,7 +1866,7 @@ title: Metrics
|
|
|
1879
1866
|
|
|
1880
1867
|
# Metrics
|
|
1881
1868
|
|
|
1882
|
-
*Generated by \`bun run metrics\` from the built packages. Do not edit: every
|
|
1869
|
+
*Generated by \`bun run gen:metrics\` from the built packages. Do not edit: every
|
|
1883
1870
|
number here is measured, and an edited one is a number nothing produced.*
|
|
1884
1871
|
|
|
1885
1872
|
Bundle size, and what a component costs in time. The two are kept apart on
|
|
@@ -1919,7 +1906,7 @@ nobody ever downloads this floor on its own.
|
|
|
1919
1906
|
|
|
1920
1907
|
| | Raw | Gzip | Brotli |
|
|
1921
1908
|
|---|---|---|---|
|
|
1922
|
-
| Lit and \`@fusion.dev/helix-core\` |
|
|
1909
|
+
| Lit and \`@fusion.dev/helix-core\` | 134,972 | 44,683 | 38,067 |
|
|
1923
1910
|
|
|
1924
1911
|
## Whole packages
|
|
1925
1912
|
|
|
@@ -1930,11 +1917,11 @@ repository does that. The per-component tables are what a page pays.
|
|
|
1930
1917
|
|
|
1931
1918
|
| Package | Raw | Gzip | Brotli | |
|
|
1932
1919
|
|---|---|---|---|---|
|
|
1933
|
-
| \`@fusion.dev/helix-core\` |
|
|
1934
|
-
| \`@fusion.dev/helix-headless\` |
|
|
1935
|
-
| \`@fusion.dev/helix-icons\` |
|
|
1936
|
-
| \`@fusion.dev/helix-theme\` | 3,288 | 1,
|
|
1937
|
-
| \`@fusion.dev/helix\` |
|
|
1920
|
+
| \`@fusion.dev/helix-core\` | 134,526 | 44,221 | 37,891 | Element base class, mixins, decorators, floating positioning. |
|
|
1921
|
+
| \`@fusion.dev/helix-headless\` | 519,032 | 131,647 | 103,098 | Every headless family, which is what the barrel means. |
|
|
1922
|
+
| \`@fusion.dev/helix-icons\` | 47,484 | 14,907 | 12,553 | The whole glyph set. |
|
|
1923
|
+
| \`@fusion.dev/helix-theme\` | 3,288 | 1,571 | 1,355 | The derivation engine. Build time for most consumers, runtime for a theme switcher. |
|
|
1924
|
+
| \`@fusion.dev/helix\` | 956,589 | 216,783 | 158,845 | Every styled family. |
|
|
1938
1925
|
| \`lit\` | 15,394 | 6,118 | 5,460 | Not ours. Here so it can be subtracted from every row above it. |
|
|
1939
1926
|
|
|
1940
1927
|
## The stylesheets
|
|
@@ -1947,25 +1934,25 @@ is the whole cost of adopting the base layer on its own.
|
|
|
1947
1934
|
|
|
1948
1935
|
| File | Raw | Gzip | Brotli | |
|
|
1949
1936
|
|---|---|---|---|---|
|
|
1950
|
-
| \`base.css\` | 23,
|
|
1951
|
-
| \`elements.css\` | 8,
|
|
1937
|
+
| \`base.css\` | 23,145 | 3,556 | 3,065 | The base layer. Recipes for markup Helix does not render, usable with no JavaScript at all. |
|
|
1938
|
+
| \`elements.css\` | 8,290 | 1,875 | 1,600 | The components' own layer, generated from every family's stylesheet. |
|
|
1952
1939
|
| \`all.css\` | 179 | 142 | 110 | The three above in one import, in the order they have to be in. |
|
|
1953
|
-
| \`primitives.css\` | 6,
|
|
1954
|
-
| \`tokens.css\` | 19,989 | 2,
|
|
1940
|
+
| \`primitives.css\` | 6,275 | 1,234 | 1,062 | The primitive layer. Private, shipped because \`tokens.css\` resolves into it. |
|
|
1941
|
+
| \`tokens.css\` | 19,989 | 2,467 | 2,073 | The 185 semantic tokens. Nothing paints without this. |
|
|
1955
1942
|
|
|
1956
1943
|
## What the numbers say
|
|
1957
1944
|
|
|
1958
|
-
**Most of a first component is the runtime under it.** The median styled family is 13,
|
|
1945
|
+
**Most of a first component is the runtime under it.** The median styled family is 13,974 bytes gzipped alone and adds 2,414 to a page that already has Helix on it, so 83 percent of the first one is shared and 17 percent is the component. Ten typical components are one plus nine additions rather than ten of the first number, and the pair of columns below is what lets that be worked out rather than guessed.
|
|
1959
1946
|
|
|
1960
|
-
Across the tier: the cheapest is \`code\` at 9,
|
|
1947
|
+
Across the tier: the cheapest is \`code\` at 9,065 gzipped alone, the dearest \`data-table\` at 49,868, over 93 components. Every family at once is 216,783.
|
|
1961
1948
|
|
|
1962
|
-
**No family imports a barrel, and \`
|
|
1949
|
+
**No family imports a barrel, and the \`barrels\` rule in \`fusion workspace\` is what keeps it that way.** \`@fusion.dev/helix-headless\` is \`sideEffects\` over every module in \`dist\`, which is true of a file that calls \`customElements.define\` and which means a bundler may drop none of it: one \`import { HelixHeadlessButton } from '@fusion.dev/helix-headless'\` costs 131,647 bytes gzipped whatever else the page does, which is 9 times the median family measured above. The styled tier imports the family it extends instead, all 93 of them, and the check refuses the shape rather than the package name, so the rule follows \`sideEffects\` wherever it goes.
|
|
1963
1950
|
|
|
1964
|
-
The headless tier never had the problem, and it is the control: \`@fusion.dev/helix-core\` is \`sideEffects: false\`, and a headless family is a median of 16,
|
|
1951
|
+
The headless tier never had the problem, and it is the control: \`@fusion.dev/helix-core\` is \`sideEffects: false\`, and a headless family is a median of 16,187 bytes gzipped alone.
|
|
1965
1952
|
|
|
1966
1953
|
## Against other systems
|
|
1967
1954
|
|
|
1968
|
-
Four other libraries of custom elements, pinned and measured on 2026-08-24 by \`
|
|
1955
|
+
Four other libraries of custom elements, pinned and measured on 2026-08-24 by \`turbo run peers\`, which installs them into \`.local\` and bundles them through the harness that produced everything above. **Helix's own rows are measured on every run of \`bun run gen:metrics\`**, so the column that could go stale against this repository is the one that cannot.
|
|
1969
1956
|
|
|
1970
1957
|
**Every system here is built on Lit**, so the runtime under the comparison is the same library in every column and what is left is the components. A React component library is not in the table, because comparing a custom element with a React component measures the framework.
|
|
1971
1958
|
|
|
@@ -1973,43 +1960,43 @@ Four other libraries of custom elements, pinned and measured on 2026-08-24 by \`
|
|
|
1973
1960
|
|
|
1974
1961
|
| Component | System | Raw | Gzip | Brotli |
|
|
1975
1962
|
|---|---|---|---|---|
|
|
1976
|
-
| \`button\` | **Helix** | 37,
|
|
1963
|
+
| \`button\` | **Helix** | 37,399 | 11,545 | 10,187 |
|
|
1977
1964
|
| | Carbon | 133,058 | 20,959 | 17,685 |
|
|
1978
1965
|
| | Material Web | 47,060 | 14,173 | 12,591 |
|
|
1979
1966
|
| | Shoelace | 62,628 | 18,287 | 15,805 |
|
|
1980
1967
|
| | Spectrum | 98,792 | 22,045 | 18,674 |
|
|
1981
|
-
| \`checkbox\` | **Helix** | 40,
|
|
1968
|
+
| \`checkbox\` | **Helix** | 40,821 | 12,584 | 11,091 |
|
|
1982
1969
|
| | Carbon | 60,255 | 15,609 | 13,550 |
|
|
1983
1970
|
| | Material Web | 43,785 | 13,556 | 12,015 |
|
|
1984
1971
|
| | Shoelace | 47,614 | 15,177 | 13,301 |
|
|
1985
1972
|
| | Spectrum | 62,492 | 15,437 | 13,481 |
|
|
1986
|
-
| \`dialog\` | **Helix** | 34,
|
|
1973
|
+
| \`dialog\` | **Helix** | 34,819 | 11,243 | 9,909 |
|
|
1987
1974
|
| | Carbon | 510,866 | 67,390 | 39,189 |
|
|
1988
1975
|
| | Material Web | 34,238 | 11,510 | 10,229 |
|
|
1989
1976
|
| | Shoelace | 52,754 | 17,698 | 15,554 |
|
|
1990
1977
|
| | Spectrum | 155,708 | 31,899 | 26,262 |
|
|
1991
|
-
| \`radio\` | **Helix** | 43,
|
|
1978
|
+
| \`radio\` | **Helix** | 43,516 | 12,844 | 11,308 |
|
|
1992
1979
|
| | Carbon | 63,055 | 16,887 | 14,605 |
|
|
1993
1980
|
| | Material Web | 41,044 | 13,234 | 11,757 |
|
|
1994
1981
|
| | Shoelace | 34,865 | 12,027 | 10,559 |
|
|
1995
1982
|
| | Spectrum | 38,685 | 10,660 | 9,370 |
|
|
1996
|
-
| \`switch\` | **Helix** | 38,
|
|
1983
|
+
| \`switch\` | **Helix** | 38,603 | 12,160 | 10,668 |
|
|
1997
1984
|
| | Carbon | 69,423 | 17,127 | 14,764 |
|
|
1998
1985
|
| | Material Web | 50,155 | 14,577 | 12,935 |
|
|
1999
1986
|
| | Shoelace | 37,833 | 11,814 | 10,568 |
|
|
2000
1987
|
| | Spectrum | 62,322 | 15,059 | 13,321 |
|
|
2001
|
-
| \`tabs\` | **Helix** | 40,
|
|
1988
|
+
| \`tabs\` | **Helix** | 40,196 | 12,332 | 10,861 |
|
|
2002
1989
|
| | Carbon | 578,766 | 73,537 | 43,235 |
|
|
2003
1990
|
| | Material Web | 38,883 | 12,820 | 11,368 |
|
|
2004
1991
|
| | Shoelace | 54,573 | 17,140 | 15,068 |
|
|
2005
1992
|
| | Spectrum | 64,875 | 18,298 | 16,283 |
|
|
2006
|
-
| \`tooltip\` | **Helix** |
|
|
1993
|
+
| \`tooltip\` | **Helix** | 60,498 | 20,576 | 18,184 |
|
|
2007
1994
|
| | Carbon | 189,382 | 30,354 | 22,273 |
|
|
2008
1995
|
| | Material Web | | not shipped | |
|
|
2009
1996
|
| | Shoelace | 57,412 | 20,220 | 17,933 |
|
|
2010
1997
|
| | Spectrum | 136,599 | 40,552 | 35,286 |
|
|
2011
1998
|
|
|
2012
|
-
**Where Helix loses**, which is the half of a comparison table worth reading: \`radio\`, \`switch\`, \`tooltip\`. The largest gap is radio against Spectrum, by 2,
|
|
1999
|
+
**Where Helix loses**, which is the half of a comparison table worth reading: \`radio\`, \`switch\`, \`tooltip\`. The largest gap is radio against Spectrum, by 2,184 bytes gzipped. 4 of 28 peer measurements come in under ours.
|
|
2013
2000
|
|
|
2014
2001
|
- **Carbon** \`@carbon/web-components@2.61.0\`. Its dialog is Modal, its radio is Radio Button, and its switch is Toggle.
|
|
2015
2002
|
- **Material Web** \`@material/web@2.5.0\`. Ships no tooltip. Its button is measured as the filled one, there being no single button element.
|
|
@@ -2020,7 +2007,7 @@ Every specifier measured is in [\`peers.json\`](https://github.com/project-fusio
|
|
|
2020
2007
|
|
|
2021
2008
|
## What it costs in time
|
|
2022
2009
|
|
|
2023
|
-
Measured on 2026-08-26 by \`
|
|
2010
|
+
Measured on 2026-08-26 by \`turbo run timings\`, which drives a real browser against the built packages. The median of 9 runs each, on one machine.
|
|
2024
2011
|
|
|
2025
2012
|
**These never join the comparison above, and that is not a hedge.** Bytes are a fact about a package and can be held against anybody else's. A timing is a fact about a page, a machine and a day, so a column of somebody else's milliseconds would be comparing two laptops rather than two libraries.
|
|
2026
2013
|
|
|
@@ -2054,94 +2041,94 @@ Structure, accessibility, state and form participation. No presentation, and no
|
|
|
2054
2041
|
|
|
2055
2042
|
| Family | Alone raw | Alone gzip | Alone brotli | Added raw | Added gzip | Added brotli |
|
|
2056
2043
|
|---|---|---|---|---|---|---|
|
|
2057
|
-
| \`accordion\` |
|
|
2058
|
-
| \`announcement\` |
|
|
2059
|
-
| \`app-header\` | 27,
|
|
2060
|
-
| \`avatar\` | 28,859 | 9,794 | 8,
|
|
2061
|
-
| \`badge\` | 26,919 | 9,246 | 8,
|
|
2062
|
-
| \`bar-chart\` |
|
|
2063
|
-
| \`blockquote\` | 26,839 | 9,232 | 8,140 | 917 |
|
|
2064
|
-
| \`breadcrumbs\` |
|
|
2065
|
-
| \`button\` | 31,
|
|
2066
|
-
| \`button-group\` | 26,832 | 9,170 | 8,068 | 661 |
|
|
2067
|
-
| \`callout\` |
|
|
2068
|
-
| \`card\` | 26,866 | 9,186 | 8,102 | 694 |
|
|
2069
|
-
| \`carousel\` |
|
|
2070
|
-
| \`chat\` |
|
|
2071
|
-
| \`checkbox\` | 34,
|
|
2072
|
-
| \`checkbox-group\` | 37,
|
|
2073
|
-
| \`code\` | 25,451 | 8,754 | 7,715 | 451 |
|
|
2074
|
-
| \`code-block\` |
|
|
2075
|
-
| \`color-input\` |
|
|
2076
|
-
| \`color-picker\` |
|
|
2077
|
-
| \`combobox\` |
|
|
2078
|
-
| \`command\` |
|
|
2079
|
-
| \`copy-button\` |
|
|
2080
|
-
| \`data-table\` |
|
|
2081
|
-
| \`date-input\` |
|
|
2082
|
-
| \`date-picker\` |
|
|
2083
|
-
| \`dialog\` | 30,
|
|
2084
|
-
| \`divider\` | 27,036 | 9,
|
|
2085
|
-
| \`donut-chart\` |
|
|
2086
|
-
| \`drawer\` | 29,268 | 9,
|
|
2087
|
-
| \`drilldown\` |
|
|
2088
|
-
| \`empty\` | 26,988 | 9,226 | 8,147 | 816 |
|
|
2089
|
-
| \`file-input\` |
|
|
2090
|
-
| \`format-date\` | 30,257 | 10,284 | 9,103 | 2,805 |
|
|
2091
|
-
| \`heatmap\` |
|
|
2092
|
-
| \`icon\` |
|
|
2093
|
-
| \`icon-button\` | 31,
|
|
2094
|
-
| \`image\` | 28,816 | 9,
|
|
2095
|
-
| \`input\` |
|
|
2096
|
-
| \`kbd\` | 28,
|
|
2097
|
-
| \`legend\` | 29,187 | 10,066 | 8,845 | 1,097 |
|
|
2098
|
-
| \`line-chart\` |
|
|
2099
|
-
| \`list\` | 27,887 | 9,
|
|
2100
|
-
| \`listbox\` |
|
|
2101
|
-
| \`loader\` | 27,072 | 9,293 | 8,182 | 900 |
|
|
2102
|
-
| \`megamenu\` | 55,
|
|
2103
|
-
| \`menu\` |
|
|
2104
|
-
| \`meter\` | 29,964 | 10,
|
|
2105
|
-
| \`navigation\` | 28,831 | 9,815 | 8,680 | 1,582 |
|
|
2106
|
-
| \`notifications\` |
|
|
2107
|
-
| \`number-input\` |
|
|
2108
|
-
| \`option\` | 28,849 | 9,
|
|
2109
|
-
| \`outline\` | 31,837 | 10,
|
|
2110
|
-
| \`pagination\` |
|
|
2111
|
-
| \`pin-input\` | 37,
|
|
2112
|
-
| \`popover\` |
|
|
2113
|
-
| \`progress\` | 28,113 | 9,
|
|
2114
|
-
| \`qr-code\` | 38,587 | 13,
|
|
2115
|
-
| \`quote\` | 26,355 | 9,041 | 7,964 | 552 |
|
|
2116
|
-
| \`radio\` | 35,977 | 11,448 | 10,
|
|
2117
|
-
| \`rating\` | 38,033 | 12,
|
|
2118
|
-
| \`scroll-area\` | 28,
|
|
2119
|
-
| \`select\` |
|
|
2120
|
-
| \`skeleton\` | 25,544 | 8,786 | 7,725 | 544 |
|
|
2121
|
-
| \`slider\` | 37,
|
|
2122
|
-
| \`sparkline\` | 31,645 | 11,
|
|
2123
|
-
| \`speed-dial\` |
|
|
2124
|
-
| \`splitter\` | 36,329 | 11,
|
|
2125
|
-
| \`stat\` | 27,320 | 9,222 | 8,136 | 1,150 |
|
|
2126
|
-
| \`steps\` |
|
|
2127
|
-
| \`switch\` | 34,
|
|
2128
|
-
| \`table\` | 31,
|
|
2129
|
-
| \`tabs\` | 33,935 | 11,
|
|
2130
|
-
| \`tag\` |
|
|
2131
|
-
| \`textarea\` |
|
|
2132
|
-
| \`time-input\` |
|
|
2133
|
-
| \`time-picker\` |
|
|
2134
|
-
| \`timeline\` |
|
|
2135
|
-
| \`toast\` |
|
|
2136
|
-
| \`toggle\` | 38,209 | 12,
|
|
2137
|
-
| \`toolbar\` | 28,734 | 9,827 | 8,655 | 2,932 | 1,
|
|
2138
|
-
| \`tooltip\` |
|
|
2139
|
-
| \`tour\` | 61,
|
|
2140
|
-
| \`tree\` |
|
|
2141
|
-
| \`trend\` |
|
|
2142
|
-
| \`video\` |
|
|
2143
|
-
| \`video-playlist\` |
|
|
2144
|
-
| \`virtual-list\` | 29,714 | 10,244 | 9,021 | 2,089 |
|
|
2044
|
+
| \`accordion\` | 77,373 | 25,790 | 21,229 | 3,227 | 1,191 | 689 |
|
|
2045
|
+
| \`announcement\` | 75,404 | 25,148 | 20,701 | 1,374 | 658 | 330 |
|
|
2046
|
+
| \`app-header\` | 27,425 | 9,322 | 8,205 | 1,248 | 581 | 264 |
|
|
2047
|
+
| \`avatar\` | 28,859 | 9,794 | 8,642 | 2,644 | 1,039 | 606 |
|
|
2048
|
+
| \`badge\` | 26,919 | 9,246 | 8,163 | 1,120 | 547 | 298 |
|
|
2049
|
+
| \`bar-chart\` | 71,762 | 24,550 | 21,745 | 12,487 | 4,215 | 3,012 |
|
|
2050
|
+
| \`blockquote\` | 26,839 | 9,232 | 8,140 | 917 | 486 | 238 |
|
|
2051
|
+
| \`breadcrumbs\` | 75,025 | 24,814 | 20,607 | 1,955 | 703 | 408 |
|
|
2052
|
+
| \`button\` | 31,312 | 10,445 | 9,216 | 3,167 | 1,103 | 679 |
|
|
2053
|
+
| \`button-group\` | 26,832 | 9,170 | 8,068 | 661 | 386 | 96 |
|
|
2054
|
+
| \`callout\` | 74,155 | 24,675 | 20,454 | 912 | 499 | 245 |
|
|
2055
|
+
| \`card\` | 26,866 | 9,186 | 8,102 | 694 | 393 | 100 |
|
|
2056
|
+
| \`carousel\` | 80,904 | 26,737 | 22,141 | 7,686 | 2,419 | 1,636 |
|
|
2057
|
+
| \`chat\` | 84,863 | 27,980 | 23,052 | 9,449 | 2,818 | 1,981 |
|
|
2058
|
+
| \`checkbox\` | 34,646 | 11,172 | 9,831 | 2,252 | 977 | 459 |
|
|
2059
|
+
| \`checkbox-group\` | 37,546 | 11,793 | 10,407 | 4,655 | 1,615 | 961 |
|
|
2060
|
+
| \`code\` | 25,451 | 8,754 | 7,715 | 451 | 280 | 126 |
|
|
2061
|
+
| \`code-block\` | 113,692 | 37,922 | 32,016 | 12,788 | 3,653 | 2,656 |
|
|
2062
|
+
| \`color-input\` | 131,269 | 42,548 | 35,825 | 26,066 | 7,146 | 5,816 |
|
|
2063
|
+
| \`color-picker\` | 100,398 | 32,385 | 26,772 | 19,492 | 5,706 | 4,527 |
|
|
2064
|
+
| \`combobox\` | 127,329 | 41,037 | 34,567 | 20,327 | 5,495 | 4,250 |
|
|
2065
|
+
| \`command\` | 100,670 | 32,023 | 26,366 | 17,317 | 4,912 | 3,765 |
|
|
2066
|
+
| \`copy-button\` | 112,372 | 37,654 | 31,723 | 11,469 | 3,400 | 2,482 |
|
|
2067
|
+
| \`data-table\` | 143,864 | 45,643 | 38,407 | 37,364 | 9,893 | 7,960 |
|
|
2068
|
+
| \`date-input\` | 124,144 | 40,441 | 34,068 | 19,388 | 5,371 | 4,207 |
|
|
2069
|
+
| \`date-picker\` | 85,626 | 28,231 | 23,302 | 9,805 | 3,138 | 2,316 |
|
|
2070
|
+
| \`dialog\` | 30,484 | 10,235 | 9,019 | 2,717 | 1,112 | 734 |
|
|
2071
|
+
| \`divider\` | 27,036 | 9,307 | 8,174 | 1,115 | 567 | 227 |
|
|
2072
|
+
| \`donut-chart\` | 67,672 | 23,131 | 20,446 | 9,747 | 3,379 | 2,367 |
|
|
2073
|
+
| \`drawer\` | 29,268 | 9,874 | 8,685 | 1,792 | 774 | 440 |
|
|
2074
|
+
| \`drilldown\` | 80,657 | 26,804 | 22,019 | 5,059 | 1,740 | 1,144 |
|
|
2075
|
+
| \`empty\` | 26,988 | 9,226 | 8,147 | 816 | 448 | 183 |
|
|
2076
|
+
| \`file-input\` | 85,388 | 28,229 | 23,148 | 6,217 | 2,172 | 1,468 |
|
|
2077
|
+
| \`format-date\` | 30,257 | 10,284 | 9,103 | 2,805 | 940 | 531 |
|
|
2078
|
+
| \`heatmap\` | 69,136 | 23,403 | 20,696 | 11,040 | 3,623 | 2,602 |
|
|
2079
|
+
| \`icon\` | 73,561 | 24,431 | 20,290 | 850 | 450 | 184 |
|
|
2080
|
+
| \`icon-button\` | 31,711 | 10,475 | 9,230 | 3,566 | 1,129 | 709 |
|
|
2081
|
+
| \`image\` | 28,816 | 9,691 | 8,518 | 2,969 | 1,030 | 655 |
|
|
2082
|
+
| \`input\` | 84,757 | 27,868 | 22,877 | 4,797 | 1,672 | 1,142 |
|
|
2083
|
+
| \`kbd\` | 28,706 | 9,926 | 8,748 | 2,897 | 1,293 | 870 |
|
|
2084
|
+
| \`legend\` | 29,187 | 10,066 | 8,845 | 1,097 | 577 | 235 |
|
|
2085
|
+
| \`line-chart\` | 69,788 | 23,947 | 21,209 | 10,514 | 3,619 | 2,633 |
|
|
2086
|
+
| \`list\` | 27,887 | 9,360 | 8,245 | 1,727 | 579 | 292 |
|
|
2087
|
+
| \`listbox\` | 92,543 | 30,186 | 24,704 | 10,677 | 3,391 | 2,393 |
|
|
2088
|
+
| \`loader\` | 27,072 | 9,293 | 8,182 | 900 | 475 | 143 |
|
|
2089
|
+
| \`megamenu\` | 55,893 | 19,552 | 17,265 | 4,934 | 1,728 | 1,178 |
|
|
2090
|
+
| \`menu\` | 110,293 | 37,007 | 31,290 | 8,105 | 2,374 | 1,645 |
|
|
2091
|
+
| \`meter\` | 29,964 | 10,079 | 8,879 | 3,800 | 1,234 | 880 |
|
|
2092
|
+
| \`navigation\` | 28,831 | 9,815 | 8,680 | 1,582 | 685 | 347 |
|
|
2093
|
+
| \`notifications\` | 84,856 | 28,045 | 23,078 | 8,640 | 2,567 | 1,892 |
|
|
2094
|
+
| \`number-input\` | 86,974 | 28,468 | 23,363 | 7,100 | 2,293 | 1,618 |
|
|
2095
|
+
| \`option\` | 28,849 | 9,639 | 8,506 | 2,680 | 872 | 552 |
|
|
2096
|
+
| \`outline\` | 31,837 | 10,811 | 9,517 | 4,539 | 1,759 | 1,115 |
|
|
2097
|
+
| \`pagination\` | 132,398 | 42,069 | 35,542 | 26,097 | 6,582 | 5,162 |
|
|
2098
|
+
| \`pin-input\` | 37,535 | 12,009 | 10,627 | 5,135 | 1,841 | 1,219 |
|
|
2099
|
+
| \`popover\` | 53,190 | 18,820 | 16,606 | 1,985 | 825 | 427 |
|
|
2100
|
+
| \`progress\` | 28,113 | 9,566 | 8,450 | 1,949 | 759 | 507 |
|
|
2101
|
+
| \`qr-code\` | 38,587 | 13,554 | 11,997 | 12,807 | 4,944 | 4,132 |
|
|
2102
|
+
| \`quote\` | 26,355 | 9,041 | 7,964 | 552 | 371 | 135 |
|
|
2103
|
+
| \`radio\` | 35,977 | 11,448 | 10,088 | 3,138 | 1,130 | 692 |
|
|
2104
|
+
| \`rating\` | 38,033 | 12,238 | 10,784 | 5,617 | 2,008 | 1,288 |
|
|
2105
|
+
| \`scroll-area\` | 28,465 | 9,748 | 8,556 | 2,612 | 1,073 | 632 |
|
|
2106
|
+
| \`select\` | 121,561 | 39,765 | 33,471 | 15,389 | 4,421 | 3,267 |
|
|
2107
|
+
| \`skeleton\` | 25,544 | 8,786 | 7,725 | 544 | 330 | 72 |
|
|
2108
|
+
| \`slider\` | 37,896 | 12,065 | 10,659 | 5,250 | 1,807 | 1,286 |
|
|
2109
|
+
| \`sparkline\` | 31,645 | 11,088 | 9,794 | 2,530 | 1,054 | 773 |
|
|
2110
|
+
| \`speed-dial\` | 102,854 | 35,015 | 29,681 | 3,821 | 1,260 | 786 |
|
|
2111
|
+
| \`splitter\` | 36,329 | 11,667 | 10,338 | 10,165 | 2,907 | 2,207 |
|
|
2112
|
+
| \`stat\` | 27,320 | 9,222 | 8,136 | 1,150 | 437 | 205 |
|
|
2113
|
+
| \`steps\` | 82,900 | 27,205 | 22,347 | 6,303 | 1,836 | 1,248 |
|
|
2114
|
+
| \`switch\` | 34,314 | 11,106 | 9,826 | 1,798 | 839 | 376 |
|
|
2115
|
+
| \`table\` | 31,861 | 10,274 | 9,086 | 4,373 | 1,285 | 854 |
|
|
2116
|
+
| \`tabs\` | 33,935 | 11,035 | 9,722 | 4,469 | 1,273 | 781 |
|
|
2117
|
+
| \`tag\` | 74,439 | 24,760 | 20,435 | 897 | 472 | 253 |
|
|
2118
|
+
| \`textarea\` | 37,001 | 11,743 | 10,362 | 4,115 | 1,412 | 892 |
|
|
2119
|
+
| \`time-input\` | 136,201 | 43,547 | 36,687 | 28,643 | 7,660 | 6,042 |
|
|
2120
|
+
| \`time-picker\` | 100,564 | 32,606 | 26,818 | 18,154 | 5,497 | 4,221 |
|
|
2121
|
+
| \`timeline\` | 74,971 | 24,767 | 20,563 | 1,896 | 666 | 359 |
|
|
2122
|
+
| \`toast\` | 78,169 | 25,872 | 21,292 | 4,007 | 1,246 | 750 |
|
|
2123
|
+
| \`toggle\` | 38,209 | 12,101 | 10,670 | 3,928 | 1,315 | 828 |
|
|
2124
|
+
| \`toolbar\` | 28,734 | 9,827 | 8,655 | 2,932 | 1,238 | 676 |
|
|
2125
|
+
| \`tooltip\` | 56,933 | 19,770 | 17,504 | 6,216 | 2,147 | 1,428 |
|
|
2126
|
+
| \`tour\` | 61,953 | 20,875 | 18,482 | 10,277 | 2,940 | 2,122 |
|
|
2127
|
+
| \`tree\` | 84,423 | 27,823 | 22,815 | 7,054 | 2,342 | 1,593 |
|
|
2128
|
+
| \`trend\` | 73,764 | 24,534 | 20,358 | 1,056 | 535 | 320 |
|
|
2129
|
+
| \`video\` | 133,542 | 42,701 | 36,225 | 31,103 | 7,713 | 6,441 |
|
|
2130
|
+
| \`video-playlist\` | 117,742 | 38,672 | 32,725 | 14,151 | 3,686 | 2,752 |
|
|
2131
|
+
| \`virtual-list\` | 29,714 | 10,244 | 9,021 | 2,089 | 937 | 604 |
|
|
2145
2132
|
|
|
2146
2133
|
### Styled tier
|
|
2147
2134
|
|
|
@@ -2149,99 +2136,99 @@ The headless tier plus presentation. This is what \`bun add @fusion.dev/helix\`
|
|
|
2149
2136
|
|
|
2150
2137
|
| Family | Alone raw | Alone gzip | Alone brotli | Added raw | Added gzip | Added brotli |
|
|
2151
2138
|
|---|---|---|---|---|---|---|
|
|
2152
|
-
| \`accordion\` |
|
|
2153
|
-
| \`announcement\` |
|
|
2154
|
-
| \`app-header\` | 30,
|
|
2155
|
-
| \`aura\` |
|
|
2156
|
-
| \`avatar\` | 32,433 | 10,538 | 9,
|
|
2157
|
-
| \`badge\` | 29,
|
|
2158
|
-
| \`bar-chart\` |
|
|
2159
|
-
| \`blockquote\` | 28,015 | 9,529 | 8,383 | 2,077 |
|
|
2160
|
-
| \`breadcrumbs\` |
|
|
2161
|
-
| \`button\` | 37,
|
|
2162
|
-
| \`button-group\` | 28,508 | 9,543 | 8,424 | 2,320 |
|
|
2163
|
-
| \`callout\` |
|
|
2164
|
-
| \`card\` | 30,
|
|
2165
|
-
| \`carousel\` |
|
|
2166
|
-
| \`chat\` |
|
|
2167
|
-
| \`checkbox\` | 40,
|
|
2168
|
-
| \`checkbox-group\` | 39,
|
|
2169
|
-
| \`code\` | 26,
|
|
2170
|
-
| \`code-block\` |
|
|
2171
|
-
| \`color-input\` |
|
|
2172
|
-
| \`color-picker\` |
|
|
2173
|
-
| \`combobox\` |
|
|
2174
|
-
| \`command\` |
|
|
2175
|
-
| \`copy-button\` |
|
|
2176
|
-
| \`data-table\` |
|
|
2177
|
-
| \`date-input\` |
|
|
2178
|
-
| \`date-picker\` |
|
|
2179
|
-
| \`dialog\` | 34,
|
|
2180
|
-
| \`divider\` | 29,181 | 9,
|
|
2181
|
-
| \`donut-chart\` |
|
|
2182
|
-
| \`drawer\` | 33,
|
|
2183
|
-
| \`drilldown\` |
|
|
2184
|
-
| \`empty\` | 28,295 | 9,601 | 8,463 | 2,107 |
|
|
2185
|
-
| \`file-input\` |
|
|
2186
|
-
| \`flex\` | 27,799 | 9,
|
|
2187
|
-
| \`format-date\` | 30,905 | 10,420 | 9,233 | 3,435 | 1,
|
|
2188
|
-
| \`grid\` | 28,326 | 9,
|
|
2189
|
-
| \`heatmap\` |
|
|
2190
|
-
| \`icon\` |
|
|
2191
|
-
| \`icon-button\` | 37,
|
|
2192
|
-
| \`image\` | 30,
|
|
2193
|
-
| \`input\` |
|
|
2194
|
-
| \`kbd\` |
|
|
2195
|
-
| \`legend\` | 34,022 | 11,
|
|
2196
|
-
| \`line-chart\` |
|
|
2197
|
-
| \`list\` | 31,940 | 10,
|
|
2198
|
-
| \`listbox\` |
|
|
2199
|
-
| \`loader\` | 30,078 | 10,033 | 8,
|
|
2200
|
-
| \`megamenu\` |
|
|
2201
|
-
| \`menu\` |
|
|
2202
|
-
| \`meter\` | 35,
|
|
2203
|
-
| \`navigation\` | 30,
|
|
2204
|
-
| \`notifications\` |
|
|
2205
|
-
| \`number-input\` |
|
|
2206
|
-
| \`option\` | 32,116 | 10,
|
|
2207
|
-
| \`outline\` | 35,
|
|
2208
|
-
| \`pagination\` |
|
|
2209
|
-
| \`pin-input\` | 40,
|
|
2210
|
-
| \`popover\` | 55,
|
|
2211
|
-
| \`progress\` | 33,
|
|
2212
|
-
| \`qr-code\` | 40,238 | 13,
|
|
2213
|
-
| \`quote\` | 27,030 | 9,207 | 8,088 | 1,211 |
|
|
2214
|
-
| \`radio\` | 43,
|
|
2215
|
-
| \`rating\` | 41,008 | 13,
|
|
2216
|
-
| \`sandbox\` |
|
|
2217
|
-
| \`scroll-area\` | 31,
|
|
2218
|
-
| \`select\` |
|
|
2219
|
-
| \`skeleton\` | 28,062 | 9,544 | 8,416 | 2,242 |
|
|
2220
|
-
| \`slider\` | 47,
|
|
2221
|
-
| \`sparkline\` | 35,412 | 12,
|
|
2222
|
-
| \`speed-dial\` |
|
|
2223
|
-
| \`splitter\` | 42,
|
|
2224
|
-
| \`stat\` | 29,954 | 9,789 | 8,646 | 3,774 | 1,
|
|
2225
|
-
| \`steps\` |
|
|
2226
|
-
| \`switch\` | 38,
|
|
2227
|
-
| \`table\` |
|
|
2228
|
-
| \`tabs\` | 40,
|
|
2229
|
-
| \`tag\` |
|
|
2230
|
-
| \`text\` | 29,734 | 9,670 | 8,508 | 3,922 |
|
|
2231
|
-
| \`textarea\` | 40,
|
|
2232
|
-
| \`time-input\` |
|
|
2233
|
-
| \`time-picker\` |
|
|
2234
|
-
| \`timeline\` |
|
|
2235
|
-
| \`toast\` |
|
|
2236
|
-
| \`toggle\` | 43,
|
|
2237
|
-
| \`toolbar\` | 29,632 | 10,054 | 8,841 | 3,813 | 1,
|
|
2238
|
-
| \`tooltip\` |
|
|
2239
|
-
| \`tour\` | 71,
|
|
2240
|
-
| \`tree\` |
|
|
2241
|
-
| \`trend\` |
|
|
2242
|
-
| \`video\` |
|
|
2243
|
-
| \`video-playlist\` |
|
|
2244
|
-
| \`virtual-list\` | 30,546 | 10,470 | 9,192 | 2,904 | 1,
|
|
2139
|
+
| \`accordion\` | 80,416 | 26,550 | 21,816 | 6,258 | 1,975 | 1,399 |
|
|
2140
|
+
| \`announcement\` | 79,088 | 26,034 | 21,464 | 5,042 | 1,489 | 1,099 |
|
|
2141
|
+
| \`app-header\` | 30,683 | 10,087 | 8,885 | 4,489 | 1,317 | 888 |
|
|
2142
|
+
| \`aura\` | 87,842 | 30,863 | 26,680 | 60,879 | 21,466 | 18,593 |
|
|
2143
|
+
| \`avatar\` | 32,433 | 10,538 | 9,281 | 6,205 | 1,781 | 1,278 |
|
|
2144
|
+
| \`badge\` | 29,366 | 9,907 | 8,704 | 3,550 | 1,144 | 814 |
|
|
2145
|
+
| \`bar-chart\` | 87,353 | 27,299 | 24,047 | 28,058 | 7,012 | 5,413 |
|
|
2146
|
+
| \`blockquote\` | 28,015 | 9,529 | 8,383 | 2,077 | 767 | 433 |
|
|
2147
|
+
| \`breadcrumbs\` | 78,416 | 25,590 | 21,198 | 5,334 | 1,454 | 1,153 |
|
|
2148
|
+
| \`button\` | 37,399 | 11,545 | 10,187 | 9,236 | 2,232 | 1,639 |
|
|
2149
|
+
| \`button-group\` | 28,508 | 9,543 | 8,424 | 2,320 | 754 | 446 |
|
|
2150
|
+
| \`callout\` | 76,173 | 25,235 | 20,977 | 2,914 | 1,011 | 742 |
|
|
2151
|
+
| \`card\` | 30,101 | 10,012 | 8,842 | 3,917 | 1,172 | 843 |
|
|
2152
|
+
| \`carousel\` | 89,716 | 28,257 | 23,609 | 16,487 | 3,950 | 3,041 |
|
|
2153
|
+
| \`chat\` | 96,458 | 30,119 | 24,932 | 21,033 | 4,920 | 3,833 |
|
|
2154
|
+
| \`checkbox\` | 40,821 | 12,584 | 11,091 | 8,411 | 2,390 | 1,743 |
|
|
2155
|
+
| \`checkbox-group\` | 39,793 | 12,366 | 10,895 | 6,888 | 2,197 | 1,425 |
|
|
2156
|
+
| \`code\` | 26,546 | 9,065 | 7,981 | 1,529 | 585 | 353 |
|
|
2157
|
+
| \`code-block\` | 126,793 | 40,099 | 33,817 | 25,870 | 5,745 | 4,508 |
|
|
2158
|
+
| \`color-input\` | 162,845 | 47,380 | 40,111 | 57,622 | 11,935 | 10,051 |
|
|
2159
|
+
| \`color-picker\` | 126,684 | 36,608 | 30,439 | 45,772 | 9,885 | 8,284 |
|
|
2160
|
+
| \`combobox\` | 140,948 | 43,524 | 36,682 | 33,925 | 7,923 | 6,293 |
|
|
2161
|
+
| \`command\` | 110,979 | 34,028 | 28,065 | 27,611 | 6,895 | 5,493 |
|
|
2162
|
+
| \`copy-button\` | 122,915 | 39,507 | 33,361 | 21,994 | 5,157 | 3,968 |
|
|
2163
|
+
| \`data-table\` | 171,800 | 49,868 | 42,094 | 65,280 | 14,167 | 11,566 |
|
|
2164
|
+
| \`date-input\` | 138,993 | 43,266 | 36,617 | 34,215 | 8,160 | 6,694 |
|
|
2165
|
+
| \`date-picker\` | 91,241 | 29,416 | 24,327 | 15,402 | 4,304 | 3,406 |
|
|
2166
|
+
| \`dialog\` | 34,819 | 11,243 | 9,909 | 7,037 | 2,150 | 1,594 |
|
|
2167
|
+
| \`divider\` | 29,181 | 9,820 | 8,610 | 3,243 | 1,049 | 722 |
|
|
2168
|
+
| \`donut-chart\` | 79,399 | 25,131 | 22,173 | 21,457 | 5,448 | 4,033 |
|
|
2169
|
+
| \`drawer\` | 33,085 | 10,746 | 9,460 | 5,591 | 1,651 | 1,258 |
|
|
2170
|
+
| \`drilldown\` | 85,015 | 27,777 | 22,820 | 9,404 | 2,708 | 2,034 |
|
|
2171
|
+
| \`empty\` | 28,295 | 9,601 | 8,463 | 2,107 | 798 | 588 |
|
|
2172
|
+
| \`file-input\` | 96,132 | 30,394 | 25,004 | 16,954 | 4,318 | 3,346 |
|
|
2173
|
+
| \`flex\` | 27,799 | 9,392 | 8,240 | 1,986 | 673 | 463 |
|
|
2174
|
+
| \`format-date\` | 30,905 | 10,420 | 9,233 | 3,435 | 1,102 | 726 |
|
|
2175
|
+
| \`grid\` | 28,326 | 9,564 | 8,449 | 2,511 | 843 | 595 |
|
|
2176
|
+
| \`heatmap\` | 72,928 | 24,255 | 21,435 | 14,814 | 4,498 | 3,331 |
|
|
2177
|
+
| \`icon\` | 74,256 | 24,607 | 20,394 | 1,528 | 613 | 284 |
|
|
2178
|
+
| \`icon-button\` | 37,727 | 11,481 | 10,120 | 9,568 | 2,163 | 1,587 |
|
|
2179
|
+
| \`image\` | 30,564 | 10,174 | 8,943 | 4,699 | 1,516 | 1,088 |
|
|
2180
|
+
| \`input\` | 90,860 | 29,217 | 23,927 | 10,895 | 2,997 | 2,248 |
|
|
2181
|
+
| \`kbd\` | 30,118 | 10,382 | 9,139 | 4,294 | 1,762 | 1,231 |
|
|
2182
|
+
| \`legend\` | 34,022 | 11,148 | 9,812 | 5,924 | 1,710 | 1,182 |
|
|
2183
|
+
| \`line-chart\` | 82,192 | 26,074 | 23,014 | 22,899 | 5,824 | 4,292 |
|
|
2184
|
+
| \`list\` | 31,940 | 10,292 | 9,050 | 5,770 | 1,512 | 1,226 |
|
|
2185
|
+
| \`listbox\` | 96,658 | 31,152 | 25,519 | 14,779 | 4,354 | 3,220 |
|
|
2186
|
+
| \`loader\` | 30,078 | 10,033 | 8,830 | 3,891 | 1,161 | 878 |
|
|
2187
|
+
| \`megamenu\` | 60,316 | 20,594 | 18,232 | 9,342 | 2,771 | 2,053 |
|
|
2188
|
+
| \`menu\` | 116,491 | 38,410 | 32,480 | 14,285 | 3,708 | 2,802 |
|
|
2189
|
+
| \`meter\` | 35,367 | 11,232 | 9,921 | 9,185 | 2,414 | 1,935 |
|
|
2190
|
+
| \`navigation\` | 30,214 | 10,212 | 8,987 | 2,949 | 1,064 | 655 |
|
|
2191
|
+
| \`notifications\` | 92,415 | 29,580 | 24,433 | 16,186 | 4,091 | 3,171 |
|
|
2192
|
+
| \`number-input\` | 91,816 | 29,585 | 24,291 | 11,928 | 3,385 | 2,491 |
|
|
2193
|
+
| \`option\` | 32,116 | 10,548 | 9,315 | 5,935 | 1,760 | 1,226 |
|
|
2194
|
+
| \`outline\` | 35,566 | 11,583 | 10,246 | 8,251 | 2,550 | 1,778 |
|
|
2195
|
+
| \`pagination\` | 149,985 | 45,089 | 38,045 | 43,666 | 9,526 | 7,717 |
|
|
2196
|
+
| \`pin-input\` | 40,676 | 12,803 | 11,279 | 8,259 | 2,654 | 2,002 |
|
|
2197
|
+
| \`popover\` | 55,826 | 19,462 | 17,235 | 4,603 | 1,489 | 1,046 |
|
|
2198
|
+
| \`progress\` | 33,160 | 10,749 | 9,508 | 6,978 | 1,946 | 1,517 |
|
|
2199
|
+
| \`qr-code\` | 40,238 | 13,974 | 12,313 | 14,441 | 5,376 | 4,396 |
|
|
2200
|
+
| \`quote\` | 27,030 | 9,207 | 8,088 | 1,211 | 543 | 230 |
|
|
2201
|
+
| \`radio\` | 43,516 | 12,844 | 11,308 | 10,669 | 2,572 | 1,892 |
|
|
2202
|
+
| \`rating\` | 41,008 | 13,169 | 11,612 | 8,574 | 2,932 | 2,109 |
|
|
2203
|
+
| \`sandbox\` | 60,999 | 16,779 | 14,889 | 34,537 | 8,005 | 6,566 |
|
|
2204
|
+
| \`scroll-area\` | 31,431 | 10,376 | 9,102 | 5,561 | 1,744 | 1,128 |
|
|
2205
|
+
| \`select\` | 133,744 | 42,058 | 35,488 | 27,551 | 6,632 | 5,215 |
|
|
2206
|
+
| \`skeleton\` | 28,062 | 9,544 | 8,416 | 2,242 | 832 | 568 |
|
|
2207
|
+
| \`slider\` | 47,778 | 13,857 | 12,277 | 15,115 | 3,569 | 2,799 |
|
|
2208
|
+
| \`sparkline\` | 35,412 | 12,015 | 10,603 | 6,285 | 2,003 | 1,558 |
|
|
2209
|
+
| \`speed-dial\` | 110,306 | 36,504 | 30,886 | 11,251 | 2,716 | 1,971 |
|
|
2210
|
+
| \`splitter\` | 42,441 | 12,678 | 11,269 | 16,259 | 3,939 | 3,134 |
|
|
2211
|
+
| \`stat\` | 29,954 | 9,789 | 8,646 | 3,774 | 1,011 | 725 |
|
|
2212
|
+
| \`steps\` | 96,252 | 29,575 | 24,410 | 19,643 | 4,204 | 3,348 |
|
|
2213
|
+
| \`switch\` | 38,603 | 12,160 | 10,668 | 6,072 | 1,895 | 1,306 |
|
|
2214
|
+
| \`table\` | 35,190 | 10,865 | 9,580 | 7,692 | 1,917 | 1,426 |
|
|
2215
|
+
| \`tabs\` | 40,196 | 12,332 | 10,861 | 10,719 | 2,594 | 1,939 |
|
|
2216
|
+
| \`tag\` | 77,633 | 25,634 | 21,148 | 4,076 | 1,244 | 880 |
|
|
2217
|
+
| \`text\` | 29,734 | 9,670 | 8,508 | 3,922 | 967 | 650 |
|
|
2218
|
+
| \`textarea\` | 40,350 | 12,544 | 11,034 | 7,447 | 2,228 | 1,644 |
|
|
2219
|
+
| \`time-input\` | 156,103 | 46,933 | 39,629 | 48,526 | 11,002 | 8,949 |
|
|
2220
|
+
| \`time-picker\` | 111,867 | 34,716 | 28,718 | 29,452 | 7,605 | 6,027 |
|
|
2221
|
+
| \`timeline\` | 78,237 | 25,530 | 21,180 | 5,151 | 1,366 | 981 |
|
|
2222
|
+
| \`toast\` | 85,449 | 27,484 | 22,691 | 11,274 | 2,870 | 2,137 |
|
|
2223
|
+
| \`toggle\` | 43,243 | 13,254 | 11,675 | 8,954 | 2,503 | 1,844 |
|
|
2224
|
+
| \`toolbar\` | 29,632 | 10,054 | 8,841 | 3,813 | 1,475 | 913 |
|
|
2225
|
+
| \`tooltip\` | 60,498 | 20,576 | 18,184 | 9,763 | 2,945 | 2,103 |
|
|
2226
|
+
| \`tour\` | 71,822 | 22,543 | 19,985 | 20,127 | 4,599 | 3,480 |
|
|
2227
|
+
| \`tree\` | 89,446 | 29,019 | 23,862 | 12,065 | 3,544 | 2,650 |
|
|
2228
|
+
| \`trend\` | 76,798 | 25,221 | 20,884 | 4,083 | 1,172 | 831 |
|
|
2229
|
+
| \`video\` | 150,914 | 45,855 | 38,950 | 48,454 | 10,824 | 9,072 |
|
|
2230
|
+
| \`video-playlist\` | 130,351 | 40,960 | 34,695 | 26,741 | 5,898 | 4,740 |
|
|
2231
|
+
| \`virtual-list\` | 30,546 | 10,470 | 9,192 | 2,904 | 1,153 | 858 |
|
|
2245
2232
|
|
|
2246
2233
|
## What lands in \`node_modules\`
|
|
2247
2234
|
|
|
@@ -2253,12 +2240,12 @@ column is what was removed rather than part of what remains.
|
|
|
2253
2240
|
|
|
2254
2241
|
| Package | Unpacked | Files | Source maps stripped | Runtime dependencies |
|
|
2255
2242
|
|---|---|---|---|---|
|
|
2256
|
-
| \`@fusion.dev/helix-core\` |
|
|
2257
|
-
| \`@fusion.dev/helix-headless\` |
|
|
2258
|
-
| \`@fusion.dev/helix-icons\` |
|
|
2259
|
-
| \`@fusion.dev/helix-styles\` | 83,
|
|
2260
|
-
| \`@fusion.dev/helix-theme\` |
|
|
2261
|
-
| \`@fusion.dev/helix\` |
|
|
2243
|
+
| \`@fusion.dev/helix-core\` | 875,831 | 113 | 161,883 | \`@floating-ui/dom\`, \`@fusion.dev/helix-icons\` |
|
|
2244
|
+
| \`@fusion.dev/helix-headless\` | 9,741,797 | 422 | 738,193 | \`@fusion.dev/helix-core\`, \`@fusion.dev/helix-icons\`, \`uqr\` |
|
|
2245
|
+
| \`@fusion.dev/helix-icons\` | 66,379 | 11 | 20,959 | none |
|
|
2246
|
+
| \`@fusion.dev/helix-styles\` | 83,277 | 5 | 0 | none |
|
|
2247
|
+
| \`@fusion.dev/helix-theme\` | 463,476 | 8 | 4,764 | none |
|
|
2248
|
+
| \`@fusion.dev/helix\` | 9,714,436 | 718 | 287,181 | \`@fusion.dev/helix-core\`, \`@fusion.dev/helix-headless\`, \`@fusion.dev/helix-styles\` |
|
|
2262
2249
|
|
|
2263
2250
|
## Not measured yet
|
|
2264
2251
|
|
|
@@ -2266,8 +2253,8 @@ Named rather than left out, because a metrics page is read for what it does
|
|
|
2266
2253
|
not say as much as for what it does.
|
|
2267
2254
|
|
|
2268
2255
|
- **No whole-library comparison, and no fifth component.** The comparison above is five components against four systems. Widening it means naming the equivalent element in each system by hand, which is where a comparison table starts arguing, so each addition is a deliberate one rather than a sweep.
|
|
2269
|
-
- **The peer numbers are pinned, so they age.** They are dated in the section above and refreshed by running \`
|
|
2270
|
-
- **No
|
|
2256
|
+
- **The peer numbers are pinned, so they age.** They are dated in the section above and refreshed by running \`turbo run peers\`. Nothing fails when they are old, because nothing in this repository changes when somebody else releases, and a check that fired on the calendar would be noise.
|
|
2257
|
+
- **No first paint.** The timings above are facts about a component: time to upgrade, first render, hydration. First paint is a fact about a whole page, so it belongs to whatever renders one rather than to the library it renders.
|
|
2271
2258
|
- **No per-component stylesheet bytes.** There are none to report: a family's CSS is compiled into its JavaScript, so it is already inside every number above. \`elements.css\` is the light-DOM layer and is in the stylesheet table.
|
|
2272
2259
|
`,
|
|
2273
2260
|
motion: `---
|
|
@@ -2396,17 +2383,18 @@ should end up passing that string through.
|
|
|
2396
2383
|
element.addEventListener('helix-before-change', (event) => console.log(event.detail))
|
|
2397
2384
|
\`\`\`
|
|
2398
2385
|
|
|
2399
|
-
**A declared \`value\`, \`open\`, \`checked\` or \`active\` is a
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2386
|
+
**A declared \`value\`, \`open\`, \`checked\` or \`active\` is a seed.** The element
|
|
2387
|
+
starts there and goes on managing itself, exactly as \`<input value="Ada">\` does.
|
|
2388
|
+
To take one decision, listen for the matching \`helix-before-*\` event and call
|
|
2389
|
+
\`preventDefault()\`; to own the state outright, refuse and assign your own.
|
|
2390
|
+
\`default-value\`, \`default-open\` and their siblings are what a reset returns to.
|
|
2403
2391
|
[State and control](./state-and-control) is the page about it.
|
|
2404
2392
|
|
|
2405
2393
|
## What each one needs
|
|
2406
2394
|
|
|
2407
2395
|
| Framework | Notes |
|
|
2408
2396
|
|---|---|
|
|
2409
|
-
| Solid | Sets properties on custom elements by default. Use \`prop:\` to force one and \`attr:\` to force the other. \`on:helix-change\` binds the literal name |
|
|
2397
|
+
| Solid | Sets properties on custom elements by default. Use \`prop:\` to force one and \`attr:\` to force the other. \`on:helix-before-change\` binds the literal name |
|
|
2410
2398
|
| Qwik | Works as JSX. Bind with \`document:on…\` or a ref, since a plain \`on*\` prop is normalized |
|
|
2411
2399
|
| Lit | \`.prop=\`, \`?bool=\` and \`@helix-before-change=\` are already the right three channels |
|
|
2412
2400
|
| Ember | Angle-bracket invocation passes attributes only, so set properties from a modifier |
|
|
@@ -2555,12 +2543,14 @@ Three doors are open, and they are in the order you should try them.
|
|
|
2555
2543
|
|
|
2556
2544
|
\`\`\`css
|
|
2557
2545
|
:root {
|
|
2558
|
-
--helix-radii
|
|
2546
|
+
--helix-seed-radii: 2px;
|
|
2559
2547
|
}
|
|
2560
2548
|
\`\`\`
|
|
2561
2549
|
|
|
2562
2550
|
If every card, dialog and button should be squarer, that is a token change and
|
|
2563
|
-
you are done.
|
|
2551
|
+
you are done. The seed rather than \`--helix-radii-md\`, because the four rungs
|
|
2552
|
+
are derived from it: \`md\` on its own is one step of four, and the buttons and
|
|
2553
|
+
dialogs are on a different one. See [Shape and borders](./shape-and-borders). Tokens cross shadow boundaries on their own, because custom
|
|
2564
2554
|
properties inherit, so one declaration reaches every component at once.
|
|
2565
2555
|
|
|
2566
2556
|
Reach for this first. Most requests that arrive as "can I restyle the button"
|
|
@@ -2589,10 +2579,7 @@ changes that component and nothing else.
|
|
|
2589
2579
|
after the component (\`--card-padding\`, \`--drawer-radius\`) and a token is named
|
|
2590
2580
|
\`--helix-*\`. Every documented hook is held to a rule that actually reads it, in
|
|
2591
2581
|
both directions: declared and never read is a promise with nothing behind it,
|
|
2592
|
-
and read and never declared is a working feature nobody is told about.
|
|
2593
|
-
\`Button\`'s four hooks were inert for a refactor's worth of time while the
|
|
2594
|
-
reference went on listing them, which is how that check came
|
|
2595
|
-
to exist.
|
|
2582
|
+
and read and never declared is a working feature nobody is told about.
|
|
2596
2583
|
|
|
2597
2584
|
Each component's page lists its hooks under Custom properties.
|
|
2598
2585
|
|
|
@@ -2615,10 +2602,8 @@ internal structure.
|
|
|
2615
2602
|
|
|
2616
2603
|
**A published part is a promise**, held both ways:
|
|
2617
2604
|
a documented part that nothing renders, and a rendered part nobody was told
|
|
2618
|
-
about. The
|
|
2619
|
-
nothing is valid CSS that matches nothing and reports nothing.
|
|
2620
|
-
published a \`nav\` part the family does not render; \`Checkbox\` renders the
|
|
2621
|
-
\`field\` part the whole styled appearance is built on and never declared it.
|
|
2605
|
+
about. The first is the worse of the two for you, because a \`::part()\` that
|
|
2606
|
+
resolves to nothing is valid CSS that matches nothing and reports nothing.
|
|
2622
2607
|
|
|
2623
2608
|
Each component's page lists its parts.
|
|
2624
2609
|
|
|
@@ -2643,12 +2628,11 @@ its arrow is \`tooltip-arrow\`.
|
|
|
2643
2628
|
\`Command\` forwarded the listbox's \`search-field\` under a name it also rendered
|
|
2644
2629
|
itself, so \`::part(search-field)\` matched two elements at once.
|
|
2645
2630
|
|
|
2646
|
-
This is checked in both directions. \`
|
|
2647
|
-
rendered one to each other, and \`
|
|
2631
|
+
This is checked in both directions. \`helix component\`'s \`parts\` holds a published part and a
|
|
2632
|
+
rendered one to each other, and \`helix component\`'s \`exportparts\` holds a composition to
|
|
2648
2633
|
forwarding everything its child publishes, under one prefix, colliding with
|
|
2649
|
-
nothing.
|
|
2650
|
-
|
|
2651
|
-
date picker's from inside a date input.
|
|
2634
|
+
nothing. So every part the color picker publishes is reachable from inside a
|
|
2635
|
+
color input, and every part the date picker publishes from inside a date input.
|
|
2652
2636
|
|
|
2653
2637
|
If you still find a part you cannot reach, that is worth reporting rather than
|
|
2654
2638
|
working around: the missing part is the bug.
|
|
@@ -3010,9 +2994,9 @@ amount of JavaScript reproduces:
|
|
|
3010
2994
|
- right-click offers Copy Link Address
|
|
3011
2995
|
- a crawler follows it
|
|
3012
2996
|
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
2997
|
+
A \`<Link>\` inside each row buys none of it. In the docs sidebar the anchor was
|
|
2998
|
+
57px of a 240px row, so five sixths of every row did nothing, and Enter did
|
|
2999
|
+
nothing at all: the tree announced a selection and no anchor heard it.
|
|
3016
3000
|
|
|
3017
3001
|
## \`href\` and a framework's \`<Link>\`
|
|
3018
3002
|
|
|
@@ -3171,7 +3155,7 @@ host is the only element the listbox can point at.
|
|
|
3171
3155
|
same browser, the accessibility tree for \`<div role="option"><a href>Open
|
|
3172
3156
|
settings</a></div>\` inside a listbox is an option with *no accessible name*, and
|
|
3173
3157
|
the link exposed as a child of it. The sibling option with plain text is named
|
|
3174
|
-
correctly. So the
|
|
3158
|
+
correctly. So the maneuver that works for \`treeitem\` and \`menuitem\`, moving the
|
|
3175
3159
|
role onto the anchor, is exactly the one thing that cannot be done here.
|
|
3176
3160
|
|
|
3177
3161
|
Two constraints pointing opposite ways, and no arrangement satisfies both.
|
|
@@ -3301,7 +3285,7 @@ has a tree.
|
|
|
3301
3285
|
**Anything that inspects the tree runs in \`firstUpdated\` or later**, and is
|
|
3302
3286
|
therefore a client-side enhancement by definition.
|
|
3303
3287
|
|
|
3304
|
-
## Never
|
|
3288
|
+
## Never initialize state in \`connectedCallback\`
|
|
3305
3289
|
|
|
3306
3290
|
SSR does not call it. Derive from properties, or seed in \`willUpdate\`, which SSR
|
|
3307
3291
|
does call.
|
|
@@ -3391,18 +3375,30 @@ square: a percentage radius on a wide element gives an ellipse, and a pill is
|
|
|
3391
3375
|
what you wanted.
|
|
3392
3376
|
|
|
3393
3377
|
Rounding is the fastest single change to how a system feels, and it is one
|
|
3394
|
-
token:
|
|
3378
|
+
token, but it is the **seed** rather than one of the four above:
|
|
3395
3379
|
|
|
3396
3380
|
\`\`\`css
|
|
3397
3381
|
:root {
|
|
3398
|
-
--helix-radii
|
|
3382
|
+
--helix-seed-radii: 2px;
|
|
3399
3383
|
}
|
|
3400
3384
|
\`\`\`
|
|
3401
3385
|
|
|
3402
|
-
That makes every card, dialog, input and button squarer at once
|
|
3386
|
+
That makes every card, dialog, input and button squarer at once, because \`sm\`,
|
|
3387
|
+
\`md\` and \`lg\` are all derived from it: they become 1px, 2px and 3px. The theme
|
|
3403
3388
|
engine takes a \`radius\` intent input for exactly this reason. See [Deriving a
|
|
3404
3389
|
theme](./theming).
|
|
3405
3390
|
|
|
3391
|
+
**Setting \`--helix-radii-md\` instead moves only what reads \`md\`**, which is
|
|
3392
|
+
neither the buttons, the inputs and the dialogs (\`sm\`) nor the cards (\`lg\`).
|
|
3393
|
+
The four rungs are siblings derived from the seed, not a chain, so overriding
|
|
3394
|
+
one is how you change a single step on purpose rather than how you reshape a
|
|
3395
|
+
system.
|
|
3396
|
+
|
|
3397
|
+
**Every floating panel takes \`sm\`.** A dialog, a drawer, a menu, a popover, a
|
|
3398
|
+
tooltip, a toast, and the panel any field opens under itself: all the same
|
|
3399
|
+
corner, whatever the panel's size. A radius is read against the corner beside it
|
|
3400
|
+
rather than against the area behind it.
|
|
3401
|
+
|
|
3406
3402
|
**A shape that is round rather than softened does not use these.** An avatar, a
|
|
3407
3403
|
loader and a radio are circles because of what they are, so they say \`50%\`
|
|
3408
3404
|
directly and are unaffected by a theme that squares everything else off.
|
|
@@ -3425,11 +3421,10 @@ belong to [Surfaces and separation](./surfaces-and-separation): they are what a
|
|
|
3425
3421
|
theme sets to zero to go shadow-first, or to a width to go border-first.
|
|
3426
3422
|
|
|
3427
3423
|
This distinction is why a component's border width sits behind a per-component
|
|
3428
|
-
hook rather than being written inline.
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
could never be added either.
|
|
3424
|
+
hook rather than being written inline. A width written inline can be recolored
|
|
3425
|
+
by a theme and never removed, and a hardcoded \`border: none\` can never have one
|
|
3426
|
+
added back, so a surface themes perfectly in one direction and not at all in the
|
|
3427
|
+
other.
|
|
3433
3428
|
|
|
3434
3429
|
## Corner radius on a group
|
|
3435
3430
|
|
|
@@ -3583,7 +3578,7 @@ Use them for gap, padding and margin:
|
|
|
3583
3578
|
|
|
3584
3579
|
## Size
|
|
3585
3580
|
|
|
3586
|
-
|
|
3581
|
+
Forty-one tokens, and almost all of them name a specific thing:
|
|
3587
3582
|
\`--helix-size-control\`, \`--helix-size-checkbox\`, \`--helix-size-switch\`,
|
|
3588
3583
|
\`--helix-size-avatar\`, \`--helix-size-icon\`, \`--helix-size-tag\`,
|
|
3589
3584
|
\`--helix-size-header\`, \`--helix-size-progress\`, \`--helix-size-meter\`.
|
|
@@ -3645,11 +3640,11 @@ That works. Type in it and the value moves. Assign to it later and the value
|
|
|
3645
3640
|
moves to what you assigned. There is no mode to be in and nothing to wire before
|
|
3646
3641
|
the control responds.
|
|
3647
3642
|
|
|
3648
|
-
*This page said the opposite until 26 Aug 2026
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3643
|
+
*This page said the opposite until 26 Aug 2026: writing a property was a claim
|
|
3644
|
+
of ownership, so the element announced its changes and applied none of them
|
|
3645
|
+
until it was told. The mode is deleted. If you were refusing a change by
|
|
3646
|
+
withholding a state update rather than by calling \`preventDefault()\`, that is
|
|
3647
|
+
the one thing that has to be rewritten.*
|
|
3653
3648
|
|
|
3654
3649
|
## Taking a decision
|
|
3655
3650
|
|
|
@@ -3896,9 +3891,9 @@ because Svelte was already right about custom elements.
|
|
|
3896
3891
|
\`bind:\` does not work on a Helix control, because there is no two-way binding
|
|
3897
3892
|
convention a custom element can opt into. Read the value off the event.
|
|
3898
3893
|
|
|
3899
|
-
And a declared \`value\`, \`open\`, \`checked\` or \`active\` is a
|
|
3900
|
-
|
|
3901
|
-
\`
|
|
3894
|
+
And a declared \`value\`, \`open\`, \`checked\` or \`active\` is a seed: the element
|
|
3895
|
+
starts there and goes on applying its own changes. To refuse one, cancel the
|
|
3896
|
+
matching \`helix-before-*\` event; withholding a state update refuses nothing.
|
|
3902
3897
|
See [State and control](./state-and-control).
|
|
3903
3898
|
`,
|
|
3904
3899
|
'theme-builder': `---
|
|
@@ -3958,7 +3953,7 @@ export const theme = { brand: '#2563eb', chroma: { ceiling: 0.1 }, radius: 2 }
|
|
|
3958
3953
|
|
|
3959
3954
|
**Keep the intent, not the tokens.** The tokens are the output of a solver, and
|
|
3960
3955
|
the solver improves: a theme stored as its inputs picks up a better derivation,
|
|
3961
|
-
and a theme stored as
|
|
3956
|
+
and a theme stored as literal values is frozen at the version that produced
|
|
3962
3957
|
it. The tokens are for pasting into a system that cannot run the engine.
|
|
3963
3958
|
|
|
3964
3959
|
## What it does not do
|
|
@@ -4033,7 +4028,7 @@ console.log(toCss(theme))
|
|
|
4033
4028
|
\`\`\`
|
|
4034
4029
|
|
|
4035
4030
|
The emitted block carries the seeds as well as the tokens, so the halves the
|
|
4036
|
-
engine does not compute, the twenty-four series
|
|
4031
|
+
engine does not compute, the twenty-four series colors a chart reads, the
|
|
4037
4032
|
spacing scale and the corner radii, re-derive from the same values the solver
|
|
4038
4033
|
used. That is what stops the two paths disagreeing on the same page.
|
|
4039
4034
|
|
|
@@ -4097,7 +4092,7 @@ direction never reverses.
|
|
|
4097
4092
|
| \`@fusion.dev/helix-styles\` | Tokens and the base layer. Pure CSS | nothing |
|
|
4098
4093
|
| \`@fusion.dev/helix-core\` | Element base class, mixins, decorators | Lit |
|
|
4099
4094
|
| \`@fusion.dev/helix-headless\` | Structure, accessibility, state, form participation | \`core\` |
|
|
4100
|
-
| \`@fusion.dev/helix\` | Presentation: tokens, parts, and the visual axes | \`headless\`, \`styles\` |
|
|
4095
|
+
| \`@fusion.dev/helix\` | Presentation: tokens, parts, and the visual axes | \`headless\`, \`turbo run styles\` |
|
|
4101
4096
|
|
|
4102
4097
|
\`@fusion.dev/helix-theme\` and \`@fusion.dev/helix-icons\` ship beside the stack rather than in it:
|
|
4103
4098
|
neither is a tier, and neither is needed to render a component. **There is no
|
|
@@ -4107,7 +4102,7 @@ the bridge that repairs React's hydration of custom events is in
|
|
|
4107
4102
|
|
|
4108
4103
|
## Why the split
|
|
4109
4104
|
|
|
4110
|
-
**\`headless\` must never depend on \`styles\`.**
|
|
4105
|
+
**\`headless\` must never depend on \`turbo run styles\`.**
|
|
4111
4106
|
|
|
4112
4107
|
That single constraint is what makes the headless tier independently
|
|
4113
4108
|
consumable. Consume it and bring your own
|
|
@@ -4284,10 +4279,10 @@ be lifted into: a raised surface goes *down* the ramp, not up.
|
|
|
4284
4279
|
groove.
|
|
4285
4280
|
|
|
4286
4281
|
**\`raised\` and \`overlay\` are the pair worth learning.** They land on the same
|
|
4287
|
-
step in dark mode,
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4282
|
+
step in dark mode, so one token looks like it would do both jobs. In light they
|
|
4283
|
+
want opposite fills: a hovered row must be darker than a white page, and a thumb
|
|
4284
|
+
must be lighter than the groove it sits in. If something looks almost right in
|
|
4285
|
+
dark and wrong in light, this is usually why.
|
|
4291
4286
|
|
|
4292
4287
|
## Per-component hooks
|
|
4293
4288
|
|
|
@@ -4497,37 +4492,37 @@ request and names every document plus these two surfaces.
|
|
|
4497
4492
|
|
|
4498
4493
|
These are in order of how often they look like a library bug and are not.
|
|
4499
4494
|
|
|
4500
|
-
### 1.
|
|
4501
|
-
|
|
4502
|
-
\`\`\`text
|
|
4503
|
-
<!-- Ignores every keystroke. Nothing is logged. Nothing looks wrong. -->
|
|
4504
|
-
<helix-input label="Name" value="Ada"></helix-input>
|
|
4505
|
-
\`\`\`
|
|
4495
|
+
### 1. Refusing a change by not answering
|
|
4506
4496
|
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
order to name it.
|
|
4511
|
-
|
|
4512
|
-
**Writing \`value\`, \`open\`, \`checked\` or \`active\` is a claim of ownership.** From
|
|
4513
|
-
then on the element announces changes and applies none of them, waiting to be
|
|
4514
|
-
told. Which mode it is in is read once, at its first update.
|
|
4515
|
-
|
|
4516
|
-
Seed with the \`default-\` twin, or answer the event:
|
|
4497
|
+
**Writing \`value\`, \`open\`, \`checked\` or \`active\` is a seed and a correction.**
|
|
4498
|
+
The element starts there and goes on applying its own changes, exactly as
|
|
4499
|
+
\`<input value="Ada">\` does, so this works and needs no handler beside it:
|
|
4517
4500
|
|
|
4518
4501
|
\`\`\`html
|
|
4519
4502
|
<helix-input
|
|
4520
|
-
default-value="Ada"
|
|
4521
4503
|
label="Name"
|
|
4504
|
+
value="Ada"
|
|
4522
4505
|
></helix-input>
|
|
4523
4506
|
\`\`\`
|
|
4524
4507
|
|
|
4508
|
+
The trap is on the other side. React force-restores a native \`<input>\` whose
|
|
4509
|
+
state did not move and does not do this for a custom element, so a handler that
|
|
4510
|
+
declines to call \`setState\` leaves the element holding the new value. Refusal is
|
|
4511
|
+
\`preventDefault()\` on the matching \`helix-before-*\` event:
|
|
4512
|
+
|
|
4525
4513
|
\`\`\`tsx
|
|
4526
|
-
<helix-input
|
|
4514
|
+
<helix-input
|
|
4515
|
+
label="Name"
|
|
4516
|
+
onhelix-before-change={(event) => {
|
|
4517
|
+
event.preventDefault()
|
|
4518
|
+
setName(clean(event.detail.value))
|
|
4519
|
+
}}
|
|
4520
|
+
value={name}
|
|
4521
|
+
/>
|
|
4527
4522
|
\`\`\`
|
|
4528
4523
|
|
|
4529
|
-
|
|
4530
|
-
|
|
4524
|
+
\`default-value\` and its twins are what a reset returns to. See
|
|
4525
|
+
[State and control](./state-and-control).
|
|
4531
4526
|
|
|
4532
4527
|
### 2. The event name is the event's own
|
|
4533
4528
|
|
|
@@ -4569,10 +4564,11 @@ The tell for a missing layer is which. A flash before hydration is
|
|
|
4569
4564
|
\`elements.css\`; bare headings are \`base.css\`. **No color anywhere means the
|
|
4570
4565
|
ramp or the semantic layer, and the two are told apart by what is in the
|
|
4571
4566
|
stylesheet rather than by what is on screen**: without \`tokens.css\` nothing
|
|
4572
|
-
declares \`--helix-color-*\` at all, while without \`primitives.css\` all
|
|
4573
|
-
declared and every
|
|
4574
|
-
to a primitive
|
|
4575
|
-
like a working install, and it is the reason
|
|
4567
|
+
declares \`--helix-color-*\` at all, while without \`primitives.css\` all 185
|
|
4568
|
+
semantic tokens are declared and every color resolves to \`rgba(0, 0, 0, 0)\`,
|
|
4569
|
+
since \`tokens.css\` refers to a primitive 297 times and to nothing else. The
|
|
4570
|
+
second is the one that looks like a working install, and it is the reason
|
|
4571
|
+
\`all.css\` exists.
|
|
4576
4572
|
|
|
4577
4573
|
## Choosing a family
|
|
4578
4574
|
|
|
@@ -4594,9 +4590,11 @@ Two distinctions worth knowing before searching:
|
|
|
4594
4590
|
|
|
4595
4591
|
Three doors, in the order to try them.
|
|
4596
4592
|
|
|
4597
|
-
1. **A token.** \`--helix-radii
|
|
4593
|
+
1. **A token.** \`--helix-seed-radii: 2px\` at \`:root\` reaches every component,
|
|
4598
4594
|
because custom properties inherit. Most "can I restyle the button" is really
|
|
4599
|
-
"our brand has less rounding".
|
|
4595
|
+
"our brand has less rounding". The seed and not \`--helix-radii-md\`: the four
|
|
4596
|
+
radii are siblings derived from it, so \`md\` alone moves neither the buttons
|
|
4597
|
+
nor the cards.
|
|
4600
4598
|
2. **A per-component hook.** \`--card-padding\` on \`helix-card\`. Named after the
|
|
4601
4599
|
component, documented on its page, defaults to a semantic token.
|
|
4602
4600
|
3. **A part.** \`helix-select::part(trigger)\`. The most powerful and the one that
|
|
@@ -4638,7 +4636,7 @@ for the API.
|
|
|
4638
4636
|
|
|
4639
4637
|
| Tool | Where it goes |
|
|
4640
4638
|
|---|---|
|
|
4641
|
-
| Claude Code | \`CLAUDE.md\`, or a skill in \`.claude/skills/\` |
|
|
4639
|
+
| Claude Code | \`AGENTS.md\` or \`CLAUDE.md\`, or a skill in \`.claude/skills/\` |
|
|
4642
4640
|
| Cursor | \`.cursor/rules/\` |
|
|
4643
4641
|
| GitHub Copilot | \`.github/copilot-instructions.md\` |
|
|
4644
4642
|
| Anything else | Whatever it reads. The line is the same |
|
|
@@ -4744,8 +4742,6 @@ inspecting it.
|
|
|
4744
4742
|
- \`onHelixOpen\` binds an event called \`HelixOpen\`, which nobody dispatches. ❌
|
|
4745
4743
|
|
|
4746
4744
|
The number of hyphens does not matter, measured in Chrome against React 19.2.8.
|
|
4747
|
-
An earlier version of this page said two were a hard stop; that was the
|
|
4748
|
-
hydration bug above, read as a fact about names.
|
|
4749
4745
|
|
|
4750
4746
|
## Register once, in a client component
|
|
4751
4747
|
|
|
@@ -4909,8 +4905,7 @@ vocabularies. You cannot invent a value, and a component may take a subset.
|
|
|
4909
4905
|
## Why two axes
|
|
4910
4906
|
|
|
4911
4907
|
**The library had four axes and one word for all of them.** Counted across both
|
|
4912
|
-
tiers, \`appearance\`
|
|
4913
|
-
questions: where a surface ends (\`outlined\` against \`plain\` on a Card), how much
|
|
4908
|
+
tiers, \`appearance\` described at least four different questions: where a surface ends (\`outlined\` against \`plain\` on a Card), how much
|
|
4914
4909
|
ink a control claims (\`ghost\` against \`solid\` on a Button), which widget gets
|
|
4915
4910
|
rendered (\`segmented\` against \`underlined\` on Tabs), and in one case a plain
|
|
4916
4911
|
misfiled tone.
|
|
@@ -4925,10 +4920,9 @@ and a component reintroducing it fails the build.
|
|
|
4925
4920
|
|
|
4926
4921
|
## Two axes, not one
|
|
4927
4922
|
|
|
4928
|
-
This is the test
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
be glass *and* outlined. Two axes.
|
|
4923
|
+
This is the test. \`Megamenu\` is the worked example: a consumer can make the panel
|
|
4924
|
+
glass, which is not an appearance, because \`full\` already occupies that axis with
|
|
4925
|
+
a layout. A panel can be glass *and* outlined. Two axes.
|
|
4932
4926
|
|
|
4933
4927
|
If you are adding a property and cannot decide which axis it belongs to, that is
|
|
4934
4928
|
usually the answer: it is two properties.
|
|
@@ -4946,7 +4940,7 @@ choice between two widgets, which is structural wherever it is made, so it lives
|
|
|
4946
4940
|
on either tier.
|
|
4947
4941
|
|
|
4948
4942
|
**What it may not be is a place to put something that is on an axis.** That is
|
|
4949
|
-
the failure mode \`appearance\` demonstrated
|
|
4943
|
+
the failure mode \`appearance\` demonstrated.
|
|
4950
4944
|
|
|
4951
4945
|
## \`tone\` is the one axis both tiers carry
|
|
4952
4946
|
|
|
@@ -5144,11 +5138,10 @@ against the stylesheet's own URL with no bundler involved. Copy the whole
|
|
|
5144
5138
|
four requests and both layers resolve.
|
|
5145
5139
|
|
|
5146
5140
|
*This page listed \`tokens.css\` and \`base.css\` and no \`primitives.css\` until 24
|
|
5147
|
-
Aug 2026
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
cannot be got wrong again.*
|
|
5141
|
+
Aug 2026. \`tokens.css\` refers to a primitive 297 times and imports nothing, so a
|
|
5142
|
+
reader who followed that got all 185 semantic tokens declared and every color
|
|
5143
|
+
resolving to \`rgba(0, 0, 0, 0)\`. If your page looks unstyled in exactly that
|
|
5144
|
+
way, link \`all.css\` instead.*
|
|
5152
5145
|
|
|
5153
5146
|
\`elements.css\` stays its own link, being \`@fusion.dev/helix\`'s rather than this
|
|
5154
5147
|
package's, and it matters more here than anywhere: with no bundler the module
|