@fusion.dev/helix-docs 0.104.1 → 0.106.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.
Files changed (48) hide show
  1. package/content/accessibility.mdx +92 -71
  2. package/content/angular.mdx +26 -24
  3. package/content/browser-support.mdx +61 -58
  4. package/content/building-on-the-headless-tier.mdx +100 -74
  5. package/content/charting.mdx +98 -79
  6. package/content/coding-agents.mdx +87 -69
  7. package/content/color-modes.mdx +40 -37
  8. package/content/color.mdx +67 -54
  9. package/content/composition.mdx +85 -83
  10. package/content/elevation-and-material.mdx +32 -29
  11. package/content/events.mdx +77 -65
  12. package/content/forms.mdx +69 -58
  13. package/content/iconography.mdx +75 -71
  14. package/content/installation.mdx +77 -68
  15. package/content/intent-reference.mdx +59 -54
  16. package/content/introduction.mdx +25 -23
  17. package/content/localization.mdx +122 -82
  18. package/content/maps.mdx +431 -0
  19. package/content/metrics.mdx +296 -299
  20. package/content/motion.mdx +44 -36
  21. package/content/other-frameworks.mdx +33 -31
  22. package/content/overlays.mdx +72 -54
  23. package/content/overriding-a-component.mdx +85 -74
  24. package/content/react.mdx +72 -64
  25. package/content/recipes.mdx +64 -47
  26. package/content/routing.mdx +100 -93
  27. package/content/sandbox.mdx +39 -39
  28. package/content/server-rendering.mdx +95 -84
  29. package/content/shape-and-borders.mdx +44 -37
  30. package/content/size-and-density.mdx +51 -46
  31. package/content/space-and-size.mdx +41 -34
  32. package/content/state-and-control.mdx +63 -51
  33. package/content/surfaces-and-separation.mdx +55 -53
  34. package/content/svelte.mdx +20 -19
  35. package/content/theme-builder.mdx +42 -31
  36. package/content/theming.mdx +58 -51
  37. package/content/tiers.mdx +69 -61
  38. package/content/tokens.mdx +72 -53
  39. package/content/typography.mdx +47 -47
  40. package/content/using-helix-with-an-agent.mdx +147 -115
  41. package/content/using-the-elements.mdx +55 -50
  42. package/content/versioning.mdx +42 -35
  43. package/content/visual-axes.mdx +168 -146
  44. package/content/vue.mdx +24 -24
  45. package/content/without-a-bundler.mdx +40 -23
  46. package/dist/pages.generated.js +49 -43
  47. package/dist/sources.generated.js +3548 -2682
  48. package/package.json +3 -3
@@ -1,13 +1,14 @@
1
1
  ---
2
- description: Registered words with fixed vocabularies, one escape hatch, and the word that is refused.
2
+ description: The attributes that set how a component looks, the values each one accepts, and what each value draws.
3
3
  section: Theming
4
4
  title: Visual axes
5
5
  ---
6
6
 
7
7
  # Visual axes
8
8
 
9
- A component's visual choices come from a registry of axes with fixed
10
- vocabularies. You cannot invent a value, and a component may take a subset.
9
+ A component's visual options come from a registry of axes. Each axis has a
10
+ fixed set of values. You cannot add a value of your own, and a component can
11
+ accept a subset of an axis's values.
11
12
 
12
13
  | Axis | Values |
13
14
  |---|---|
@@ -16,7 +17,7 @@ vocabularies. You cannot invent a value, and a component may take a subset.
16
17
  | `nesting` | `heading`, `peer`, `subordinate` |
17
18
  | `orientation` | `auto`, `horizontal`, `vertical` |
18
19
  | `separation` | `elevated`, `filled`, `outlined`, `plain` |
19
- | `shape` | `arc`, `circle`, `diamond`, `dots`, `pill`, `ring`, `rounded`, `square`, `text` |
20
+ | `shape` | `arc`, `circle`, `diamond`, `dots`, `pill`, `pin`, `ring`, `rounded`, `square`, `text` |
20
21
  | `size` | `sm`, `md`, `lg`, `full` |
21
22
  | `tone` | The status and intent words: `primary`, `accent`, `neutral`, `danger`, and so on |
22
23
  | `width` | `auto`, `full` |
@@ -30,113 +31,123 @@ vocabularies. You cannot invent a value, and a component may take a subset.
30
31
  <helix-megamenu material="glass">…</helix-megamenu>
31
32
  ```
32
33
 
33
- ## Why two axes
34
+ ## Why there is no `appearance` attribute
34
35
 
35
- **The library had four axes and one word for all of them.** Counted across both
36
- tiers, `appearance` described at least four different questions: where a surface ends (`outlined` against `plain` on a Card), how much
37
- ink a control claims (`ghost` against `solid` on a Button), which widget gets
38
- rendered (`segmented` against `underlined` on Tabs), and in one case a plain
39
- misfiled tone.
36
+ Helix once used one attribute, `appearance`, for at least four different
37
+ settings across both tiers:
40
38
 
41
- The tell is that `outlined` appeared in two of those groups meaning different
42
- things. On a Card it says where the surface ends. On a Button it says how much
43
- ink. Same word, two questions, and no way to ask one without answering the
39
+ - where a surface ends, such as `outlined` or `plain` on a Card
40
+ - how much ink a control uses, such as `ghost` or `solid` on a Button
41
+ - which widget is rendered, such as `segmented` or `underlined` on Tabs
42
+ - in one case, a tone filed in the wrong place
43
+
44
+ `outlined` appeared in two of those groups with different meanings. On a Card,
45
+ it set where the surface ends. On a Button, it set how much ink the button uses.
46
+ With one attribute for both, you could not set one without also setting the
44
47
  other.
45
48
 
46
- **`appearance` is refused outright now.** It is not a word this library uses,
47
- and a component reintroducing it fails the build.
49
+ **Helix does not accept `appearance`.** A component that adds it back fails the
50
+ build.
48
51
 
49
- ## Two axes, not one
52
+ ## When a property needs two axes
50
53
 
51
- This is the test. `Megamenu` is the worked example: a consumer can make the panel
52
- glass, which is not an appearance, because `band` already occupies that axis
53
- with a layout. A panel can be glass *and* outlined. Two axes.
54
+ **If two values can apply at the same time, they belong on two axes.**
55
+ `Megamenu` is the example. `variant="band"` sets the layout of its panel, and
56
+ glass is a `material`. A panel can be a band and glass at once, so the two
57
+ values sit on two axes. A panel can also be glass and outlined at once.
54
58
 
55
- If you are adding a property and cannot decide which axis it belongs to, that is
56
- usually the answer: it is two properties.
59
+ If you are adding a property and cannot decide which axis it belongs on, it is
60
+ usually two properties.
57
61
 
58
- ## `variant` is the escape hatch
62
+ ## Use `variant` for a choice between widgets
59
63
 
60
64
  ```html
61
65
  <helix-tabs variant="segmented">…</helix-tabs>
62
66
  <helix-time-picker variant="wheels">…</helix-time-picker>
63
67
  ```
64
68
 
65
- `variant` takes no registry, being component-specific by definition: `segmented`
66
- against `underlined`, `list` against `wheels`, `grip` against `line`. It is a
67
- choice between two widgets, which is structural wherever it is made, so it lives
68
- on either tier.
69
+ `variant` has no registry, because its values belong to one component. For
70
+ example:
71
+
72
+ - `segmented` or `underlined`
73
+ - `list` or `wheels`
74
+ - `grip` or `line`
75
+
76
+ A variant is a choice between two widgets. That choice changes structure
77
+ wherever it is made, so `variant` can appear on either tier.
69
78
 
70
- **What it may not be is a place to put something that is on an axis.** That is
71
- the failure mode `appearance` demonstrated.
79
+ **Do not use `variant` for anything an axis already covers.** That is the
80
+ problem `appearance` had.
72
81
 
73
- ## Some axes are carried by both tiers
82
+ ## Axes on both tiers
74
83
 
75
- A styled axis never appears on the headless tier, which has nothing to paint and
76
- no box to size. The exceptions are the axes that are not about paint. `tone` says
77
- what a thing *means*, and meaning survives having no stylesheet. `shape` says
78
- what gets *rendered*: a meter at `ring` emits an arc rather than a bar, so the
79
- markup differs before any rule is written. `nesting` says what depth *is*: a
80
- tree at `subordinate` ranks its rows, a tree at `heading` makes each branch the
81
- name of the list under it, a file explorer does neither, and that is true of a
82
- tree nobody has styled. `orientation` is `shape`'s reason again: `aria-orientation`
83
- is markup, and the toolbar, the splitter, the divider and the table column all
84
- write it with nothing painted.
84
+ Styled axes do not appear on the headless tier, because the headless tier has
85
+ nothing to paint and no box to size. The exceptions are the axes that are not
86
+ about paint:
85
87
 
86
- `size` is the axis that goes the other way. It is asked of pictures and regions
87
- and never of controls, which take their height from the region they sit in
88
- through `data-density`, so it lives only where something is painted.
88
+ - `tone` sets what a thing means, and that meaning holds without a stylesheet.
89
+ - `shape` sets what is rendered. A meter at `ring` renders an arc where it would
90
+ otherwise render a bar, so the markup differs before any CSS rule is written.
91
+ - `nesting` sets what depth means. A tree at `subordinate` ranks its rows. A
92
+ tree at `heading` makes each branch the name of the list under it. A file
93
+ explorer does neither. All of this holds for a tree with no styles.
94
+ - `orientation` is on both tiers for the same reason as `shape`.
95
+ `aria-orientation` is markup, and the toolbar, the splitter, the divider, and
96
+ the table column all write it with nothing painted.
97
+
98
+ `size` is the opposite case. Pictures and regions take a `size`. Controls do
99
+ not, because they take their height from their region through `data-density`.
100
+ So `size` appears only where something is painted.
89
101
 
90
102
  ## When a family takes `neutral`
91
103
 
92
- `tone` is the one axis whose vocabulary the table above leaves open, and
93
- `neutral` is the value families have kept deciding about one at a time. Three
94
- have argued it at their own declarations and arrived at the same rule, so it
95
- belongs here once instead.
104
+ `tone` is the one axis whose values the table above does not list in full.
105
+ Families have decided one at a time whether to accept `neutral`. Three of them
106
+ reached the same rule in their own declarations, so the rule is stated here.
96
107
 
97
- **A family that reports a status takes the status words and stops.** `Callout`
98
- and `Toast` say it in nearly the same sentence: a callout reports a status and
99
- never a brand role, so it takes four of the seven. There is no neutral status,
100
- and a value that could not be drawn is worse than a value that cannot be named.
108
+ **A family that reports a status accepts only the status values.** `Callout` and
109
+ `Toast` both state this. A callout reports a status and never a brand role, so
110
+ it accepts four of the seven tones. There is no neutral status. Accepting a
111
+ value the family cannot draw is worse than leaving the value out.
101
112
 
102
- **A family whose resting state is already untoned does not need it.** `Text`
103
- gives that reason against its own missing `default`: a value matching no rule
104
- would fall through to the inherited ink and read as working while saying
105
- nothing. The absent attribute is the resting case and says it better.
113
+ **A family whose resting state has no tone does not need `neutral`.** `Text`
114
+ gives this reason for having no `default` value. A value that matches no rule
115
+ would fall back to the inherited ink. It would look like it works and change
116
+ nothing. Leaving the attribute off already gives the resting state.
106
117
 
107
- **`neutral` is for a thing that carries a tone without reporting one**: a gray
108
- tag beside six colored ones, a button that is a button rather than the primary
109
- action. `Announcement` spells its own out rather than leaving the attribute off,
110
- which is what makes the tone sayable rather than only reachable, and that is the
111
- whole of when this value is worth taking.
118
+ **Use `neutral` for something that has a tone but reports no status.** Examples
119
+ are a gray tag beside six colored ones, or a button that is not the primary
120
+ action. `Announcement` accepts `neutral` as a value you write, so you can set
121
+ the untoned look by name. Leaving the attribute off would give the same look
122
+ without a name. That is the only reason to accept this value.
112
123
 
113
- ## What each shape is
124
+ ## What each shape draws
114
125
 
115
- `shape` is the axis whose values are geometries that look alike in a table and
116
- not on a page, so it is worth saying what each one draws.
126
+ Several `shape` values sound alike and draw different geometries:
117
127
 
118
128
  | Value | What it draws |
119
129
  |---|---|
120
130
  | `arc` | An open curve, a gauge that stops short of a full turn |
121
- | `circle` | A full round, the whole edge at `radii-full` |
122
- | `diamond` | A square turned on its point, its corners at the middles of the box's sides, which is where a flowchart's decision sits |
123
- | `dots` | Separate marks rather than one joined figure |
131
+ | `circle` | A full circle, with the whole edge at `radii-full` |
132
+ | `diamond` | A square turned on its point, with its corners at the middles of the box's sides, like a flowchart's decision step |
133
+ | `dots` | Separate marks, with nothing joining them |
124
134
  | `pill` | A rectangle whose short ends are half-circles, the round of `radii-full` on a box wider than it is tall |
135
+ | `pin` | A teardrop that marks a place with its tip, such as where a journey ends on a map |
125
136
  | `ring` | A closed curve, the whole turn drawn as a band |
126
137
  | `rounded` | Corners cut to `radii-md`, still a rectangle |
127
- | `square` | Sharp corners, the pole `rounded` departs from |
128
- | `text` | A line of type's shape, as wide as a line and as tall |
138
+ | `square` | Sharp corners, the shape `rounded` softens |
139
+ | `text` | The shape of a line of text, as wide and as tall as one line |
129
140
 
130
- **`square` is not `rounded`.** They were one word for a while: an avatar drawing
131
- `radii-md` called it `square` while a QR code drawing sharp modules called it
132
- `square` too, in the same registered axis. Membership is what a check can see,
133
- so nothing could have caught that, and a table is what stops it happening again.
141
+ **`square` has sharp corners, and `rounded` has corners cut to `radii-md`.**
142
+ They were once one word. An avatar drawing `radii-md` called its shape `square`,
143
+ and a QR code drawing sharp modules also called its shape `square`, on the same
144
+ registered axis. A check can confirm only that a value is in the registry, so no
145
+ check could catch this. The table above keeps it from happening again.
134
146
 
135
147
  ## What each separation draws
136
148
 
137
- `separation` says where a box ends, and `elevated` is the value nearly every
138
- family leaves out, so it is worth saying what each one draws and what that
139
- omission is about.
149
+ `separation` sets where a box ends. Nearly every family leaves out `elevated`,
150
+ and this section explains why.
140
151
 
141
152
  | Value | What it draws |
142
153
  |---|---|
@@ -145,35 +156,42 @@ omission is about.
145
156
  | `outlined` | An edge over the ground it already has |
146
157
  | `plain` | Neither, so the box ends where its content does |
147
158
 
148
- **Leaving `elevated` out is a fact about the value rather than about the family
149
- that skips it.** A shadow says the box floats above the page, which is true of a
150
- card picked up off a grid and of an announcement laid over the content, and
151
- false of a row in a feed, a groove a thumb sits in, a checkbox, or a bar across
152
- a video. A family taking the other three and stopping is following the value,
153
- not departing from the axis, and owes no argument for it. A family that *does*
154
- take it is the one saying something, and `Card` and `Announcement` both do.
159
+ **Most families leave out `elevated` because of what the value means.** A shadow
160
+ shows that the box floats above the page. That is true of a card picked up off a
161
+ grid and of an announcement laid over the content. It is false of:
162
+
163
+ - a row in a feed
164
+ - a groove a thumb sits in
165
+ - a checkbox
166
+ - a bar across a video
155
167
 
156
- ## What a step inward means
168
+ A family that accepts only the other three values needs no reason for it. A
169
+ family that accepts `elevated` has made a choice, and `Card` and `Announcement`
170
+ both accept it.
157
171
 
158
- `nesting` is the one axis whose values are three readings of the same fact, so
159
- it is worth saying which tree each is for.
172
+ ## What each nesting value does
173
+
174
+ The three `nesting` values are three ways to show the same depth in a tree.
175
+ Each suits a different kind of tree.
160
176
 
161
177
  | Value | The tree it suits | What moves |
162
178
  |---|---|---|
163
179
  | `heading` | A documentation sidebar, where a branch names the list it holds and is not a page | The branch, which takes the rail heading. Its children keep the row they had |
164
- | `peer` | A file explorer, where every row is the same kind of thing | Nothing. The indent is the whole of what depth says |
180
+ | `peer` | A file explorer, where every row is the same kind of thing | Nothing. Only the indent shows depth |
165
181
  | `subordinate` | Side navigation, a categorization, a facet list | The nested row, one step down the type scale and no further |
166
182
 
167
- `heading` and `subordinate` are not one answer said twice. `subordinate` keys on
168
- depth and quiets the child; `heading` keys on holding children and relabels the
169
- parent, which is why a branch at any depth is a heading while the step below
170
- stops after one, and why a top-level leaf sitting beside a branch is left alone
171
- by both for opposite reasons.
183
+ `heading` and `subordinate` work differently. `subordinate` depends on depth and
184
+ makes the child quieter. `heading` depends on whether a row has children and
185
+ turns the parent into a heading. As a result:
186
+
187
+ - Under `heading`, a branch at any depth is a heading.
188
+ - Under `subordinate`, the step down stops after one level.
189
+ - Both leave a top-level leaf beside a branch alone, for opposite reasons.
172
190
 
173
- ## What each emphasis claims
191
+ ## What each emphasis draws
174
192
 
175
- `emphasis` is how loud a control is, and its values are one ladder with a rung
176
- that changes meaning halfway along, so it is worth saying what each draws.
193
+ `emphasis` sets how prominent a control is. Its values form one ladder, and one
194
+ value changes meaning partway along.
177
195
 
178
196
  | Value | What it draws |
179
197
  |---|---|
@@ -183,21 +201,23 @@ that changes meaning halfway along, so it is worth saying what each draws.
183
201
  | `ghost` | Nothing at rest, the tone carried by the ink alone |
184
202
  | `muted` | Quieter ink, where there is no surface to quiet |
185
203
 
186
- **`outlined` is the rung that changes.** On a control the edge arrives and the
187
- fill leaves, which is what makes it quieter than `solid`. On a chart mark the
188
- fill stays under the edge, because there the area encodes a value and dropping
189
- it would drop the reading. Both are the same question, how much ink this claims,
190
- answered by what the thing has to spend it on.
204
+ **`outlined` is the value that changes meaning.** On a control, it adds an edge
205
+ and removes the fill, which makes it quieter than `solid`. On a chart mark, the
206
+ fill stays under the edge, because the area shows a value and removing the fill
207
+ would hide that value. In both cases, `outlined` sets how much ink the element
208
+ uses, based on what the element needs the ink for.
191
209
 
192
- **`muted` is for a thing whose only ink is its letterform.** Text carries it and
193
- nothing else does, because everything else has a surface to quiet first. That is
194
- a fact about the value, not a gap.
210
+ **`muted` is for something whose only ink is its letterforms.** Only text takes
211
+ it, because everything else has a surface to make quieter first. Leaving it off
212
+ other families is intentional.
195
213
 
196
- ## What each material is made of
214
+ ## What each material draws
197
215
 
198
- `material` is one pair of declarations at three strengths, and the pair is the
199
- point: a translucent ground without a backdrop filter is a smear, and a filter
200
- behind an opaque ground is invisible. Absent is opaque.
216
+ Each `material` value sets two declarations together: a translucent ground and a
217
+ backdrop filter. The three values set that pair at different strengths. They
218
+ work only as a pair. A translucent ground without a backdrop filter looks
219
+ smeared, and a filter behind an opaque ground cannot be seen. With no
220
+ `material`, a surface is opaque.
201
221
 
202
222
  | Value | What it draws |
203
223
  |---|---|
@@ -205,51 +225,53 @@ behind an opaque ground is invisible. Absent is opaque.
205
225
  | `frosted` | The same pair turned up, a heavier ground under a heavier blur |
206
226
  | `transparent` | Neither, so the page shows through structure and spacing |
207
227
 
208
- `frosted` is for a surface that has to stay readable over a busy page. It is not
209
- "more glass than `glass`" in a theme's sense: a theme owns how strong the pair
210
- is, and these three are which pair.
228
+ Use `frosted` for a surface that has to stay readable over a busy page. A theme
229
+ sets how strong each pair is. The three values choose which pair a surface uses.
230
+
231
+ ## What each orientation does
232
+
233
+ A component reads `orientation` as a value, because it changes more than paint.
234
+ It turns:
211
235
 
212
- ## What each orientation turns
236
+ - the drag axis
237
+ - the arrow keys
238
+ - `aria-orientation`
213
239
 
214
- `orientation` is not paint, which is why it is a value a component reads rather
215
- than a rule a stylesheet applies: the drag axis, the arrow keys and
216
- `aria-orientation` all turn with it, and a CSS-only version would look stacked
217
- while behaving side by side, with the keyboard moving the wrong way.
240
+ A version done only in CSS would look stacked while behaving side by side, and
241
+ the arrow keys would move the wrong way.
218
242
 
219
243
  | Value | What it does |
220
244
  |---|---|
221
- | `horizontal` | Lays along the inline axis and says so in `aria-orientation` |
222
- | `vertical` | Along the block axis, and says that |
223
- | `auto` | Lets the component decide from the room it has, and turn again when that changes |
245
+ | `horizontal` | Lays out along the inline axis and sets `aria-orientation` to match |
246
+ | `vertical` | Lays out along the block axis and sets `aria-orientation` to match |
247
+ | `auto` | Picks a direction from the room the component has, and turns again when that changes |
224
248
 
225
- **`auto` asks the component's own width and never the viewport.** A splitter in a
226
- 300px panel of a 1400px window has no room for two panes side by side, and a
227
- media query would hand it the desktop branch, so a `ResizeObserver` on the host
228
- asks the only question with an honest answer.
249
+ **`auto` uses the component's own width, never the viewport's.** A splitter in a
250
+ 300px panel of a 1400px window has no room for two panes side by side. A media
251
+ query would give it the desktop layout. A `ResizeObserver` on the host measures
252
+ the width the splitter actually has.
229
253
 
230
- ## What each size step is
254
+ ## What each size draws
231
255
 
232
- `size` is asked of pictures and regions and never of controls, which is the
233
- domain and not a list of who carries it. The table is worth having because one
234
- of the four is not a rung of the same kind.
256
+ `size` applies to pictures and regions, and never to controls. That rule sets
257
+ the scope of the axis. One of the four values is a different kind of step.
235
258
 
236
259
  | Value | What it draws |
237
260
  |---|---|
238
- | `sm` | The small rung |
239
- | `md` | The middle one, and the resting case where a family has one |
240
- | `lg` | The large one |
241
- | `full` | The region less the same inset every rung already stops short by |
261
+ | `sm` | The small step |
262
+ | `md` | The middle step, and the resting state for a family that has one |
263
+ | `lg` | The large step |
264
+ | `full` | The whole region, less the same inset every other step already leaves |
242
265
 
243
- **`full` is one more rung and not a second property.** A takeover dialog is the
244
- same question answered further along, so it belongs on this axis rather than in
245
- a `fullscreen` boolean beside it, which would be a private spelling of a
246
- registry question.
266
+ **`full` is one more step on the `size` axis.** A takeover dialog is the same
267
+ setting taken further, so it belongs on this axis. A separate `fullscreen`
268
+ boolean would be one component's own way to set a value the registry already
269
+ covers.
247
270
 
248
271
  ## What each tone means
249
272
 
250
- `tone` is the one axis whose cell in the table above is prose rather than a
251
- list, because a page naming four of the seven reads better than a page reciting
252
- all of them. The seven are still fixed, and this is where they are said.
273
+ The table at the top describes `tone` in words and names four of its values.
274
+ `tone` has seven fixed values:
253
275
 
254
276
  | Value | What it means |
255
277
  |---|---|
@@ -261,20 +283,20 @@ all of them. The seven are still fixed, and this is where they are said.
261
283
  | `warning` | May go wrong, or needs attention before it does |
262
284
  | `danger` | Destructive, or already wrong |
263
285
 
264
- The first three are intent and the last four are status, which is the split a
265
- family is really choosing between when it takes a subset. See above for when
266
- `neutral` is worth taking.
286
+ The first three are intents, and the last four are statuses. A family that
287
+ accepts a subset is choosing between these two groups. The section on `neutral`
288
+ above says when to accept it.
267
289
 
268
- ## What each width policy is
290
+ ## What each width value does
269
291
 
270
- `width` here is a policy, not a measurement: two buttons sitting together may
271
- legitimately differ, which is the test that keeps this off `size`.
292
+ `width` sets a policy. Two buttons placed together can have different widths.
293
+ By the same test that keeps height off each control, width belongs on each
294
+ component, separate from `size`.
272
295
 
273
296
  | Value | What it draws |
274
297
  |---|---|
275
- | `auto` | As wide as its content, the resting behavior said out loud |
276
- | `full` | The whole of the inline space its parent offers |
298
+ | `auto` | As wide as its content. This is the resting behavior, written out |
299
+ | `full` | All the inline space its parent gives it |
277
300
 
278
- **A `width` taking a number is a different property wearing the same name.** A
279
- canvas and a table column are measured rather than given a policy, so they take
280
- a length and are not on this axis. The name is shared and the question is not.
301
+ **A `width` that takes a number is a different property with the same name.** A
302
+ canvas and a table column take a length, so they are not on this axis.
package/content/vue.mdx CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: The one compiler setting Vue needs, and why props and events already work.
2
+ description: The compiler setting Vue needs, and how Vue passes props and binds events.
3
3
  parent: installation
4
4
  section: Getting started
5
5
  title: Vue
@@ -11,15 +11,15 @@ title: Vue
11
11
  import '@fusion.dev/helix/vue'
12
12
  ```
13
13
 
14
- A types-only import, once. It augments Vue's `GlobalComponents` so every Helix
15
- tag is typed in an SFC template, with its real props and its real events. The
16
- generated file declares the augmentation under both `vue` and
17
- `@vue/runtime-core`, because tooling disagrees about which one to read.
14
+ Add this types-only import once. It augments Vue's `GlobalComponents`, so every
15
+ Helix tag in an SFC template has typed props and events. The generated file
16
+ declares the augmentation under both `vue` and `@vue/runtime-core`, because
17
+ different tools read different ones.
18
18
 
19
- ## Tell the compiler the tags are deliberate
19
+ ## Mark Helix tags as custom elements
20
20
 
21
- Without this, Vue resolves `<helix-button>` as a component it cannot find and
22
- warns on every render.
21
+ Without this setting, Vue treats `<helix-button>` as a component it cannot find
22
+ and logs a warning on every render.
23
23
 
24
24
  ```ts
25
25
  // vite.config.ts
@@ -32,37 +32,37 @@ export default defineConfig({
32
32
  })
33
33
  ```
34
34
 
35
- The prefix test is the whole rule. Every element in the library is `helix-`
36
- something, in both tiers, and nothing else is.
35
+ The prefix test is enough. Every Helix element name starts with `helix-`, in
36
+ both tiers, and no other name in the library does.
37
37
 
38
- ## Props and events need no ceremony
38
+ ## Pass props and bind events
39
39
 
40
- Vue sets a property when the element has one and falls back to an attribute
41
- otherwise, which is exactly right for these: a string goes through either path
42
- and an array or an object goes through the property.
40
+ Vue sets a property when the element has one, and sets an attribute otherwise.
41
+ That works for every Helix element. A string goes through either path, and an
42
+ array or an object goes through the property.
43
43
 
44
44
  ```vue
45
45
  <helix-tabs :items="items" @helix-before-activate="onActivate" />
46
46
  ```
47
47
 
48
- `@helix-before-activate` binds with `addEventListener`, so the name is the event's own.
49
- Vue is the framework this works most quietly in, which is why this page is
50
- short: there is no bridge and no wrapper, only the compiler setting above.
48
+ `@helix-before-activate` binds with `addEventListener`, so use the event's own
49
+ name. Vue needs no bridge and no wrapper. The compiler setting above is the only
50
+ setup.
51
51
 
52
- **Force the property with `.prop` if you ever need to**, for instance where a
53
- string would be ambiguous:
52
+ To force a property, use `.prop`. You may need it where a string would be
53
+ ambiguous:
54
54
 
55
55
  ```vue
56
56
  <helix-input :value.prop="'42'" />
57
57
  ```
58
58
 
59
- Rarely necessary, and it exists so you do not go looking for it.
59
+ You will rarely need `.prop`.
60
60
 
61
- ## Seeding, mirroring and refusing
61
+ ## Seed, mirror, or refuse a value
62
62
 
63
- `value`, `open`, `checked` and `active` are seeds. The element applies its own
64
- changes from there, so all three of these work. See [State and
65
- control](./state-and-control).
63
+ `value`, `open`, `checked`, and `active` are seeds. The element starts with the
64
+ value you set and then applies its own changes, so all three of these patterns
65
+ work. See [State and control](./state-and-control).
66
66
 
67
67
  ```vue
68
68
  <!-- Seeded: the element owns it from there. -->
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: A page that uses Helix with no build step, and what that costs.
2
+ description: Use the Helix styles on a page with no build step, and why the elements need a bundler for now.
3
3
  parent: installation
4
4
  section: Getting started
5
5
  title: Without a bundler
@@ -8,10 +8,10 @@ trailing: true
8
8
 
9
9
  # Without a bundler
10
10
 
11
- Helix ships standard ES modules and plain CSS files, so a page can use it with
12
- no build step at all. Two ways, and they suit different things.
11
+ Helix ships standard ES modules and plain CSS files. On a page with no build
12
+ step, you can use the Helix styles. The elements need a bundler for now.
13
13
 
14
- ## Styles alone
14
+ ## Use the styles alone
15
15
 
16
16
  ```html
17
17
  <link
@@ -20,22 +20,39 @@ no build step at all. Two ways, and they suit different things.
20
20
  />
21
21
  ```
22
22
 
23
- `helix.css` carries `primitives.css`, `tokens.css`, `base.css` and
24
- `elements.css` in the order they have to be in, and its `@import`s are relative,
25
- so a browser resolves them against the stylesheet's own URL with no bundler
26
- involved. Copy the whole `dist` folder and link the one file. Verified in
27
- Chromium: one `<link>` produces five requests and every layer resolves.
28
-
29
- *This page listed `tokens.css` and `base.css` and no `primitives.css` until 24
30
- Aug 2026. `tokens.css` refers to a primitive 297 times and imports nothing, so a
31
- reader who followed that got all 185 semantic tokens declared and every color
32
- resolving to `rgba(0, 0, 0, 0)`. If your page looks unstyled in exactly that
33
- way, link `helix.css` instead.*
34
-
35
- **`elements.css` matters more here than anywhere**, and it is the fourth layer
36
- `helix.css` pulls in: with no bundler the module graph arrives over the network,
37
- so the interval where the markup exists and the definitions do not is longer
38
- than it is in a built app. It was a second link until it moved into this package,
39
- which is what let the import become relative. A bare specifier in an `@import`
40
- is resolved by a bundler and never by a browser, so on this page of all pages it
41
- could not have been one.
23
+ `helix.css` imports four files in the order they must load:
24
+
25
+ 1. `primitives.css`
26
+ 2. `tokens.css`
27
+ 3. `base.css`
28
+ 4. `elements.css`
29
+
30
+ Its `@import`s are relative, so a browser resolves them against the stylesheet's
31
+ own URL. Copy the whole `dist` folder and link `helix.css`. We checked this in
32
+ Chromium: one `<link>` makes five requests, and every layer resolves.
33
+
34
+ *Until August 24, 2026, this page listed `tokens.css` and `base.css` without
35
+ `primitives.css`. `tokens.css` refers to a primitive 297 times and imports
36
+ nothing. If you followed the old instructions, all 185 semantic tokens are
37
+ declared and every color resolves to `rgba(0, 0, 0, 0)`. If your page looks
38
+ unstyled in that way, link `helix.css`.*
39
+
40
+ `elements.css` matters most on a page with no bundler. Without a bundler, the
41
+ module graph loads over the network, so the markup is on the page longer before
42
+ the element definitions arrive. `elements.css` is the fourth layer that
43
+ `helix.css` imports. It used to be a second link, and moving it into the same
44
+ package made its import relative. Only a bundler resolves a bare specifier in an
45
+ `@import`, so a bare specifier would not work on a page with no bundler.
46
+
47
+ ## The elements need a bundler
48
+
49
+ `@fusion.dev/helix` imports its dependencies by bare specifiers, such as
50
+ `@fusion.dev/helix-core` and `lit`. A browser resolves a bare specifier only
51
+ through an import map, and the elements import 97 separate subpaths of
52
+ `@fusion.dev/helix-headless`. An import map would need an entry for each one,
53
+ and for each subpath of `lit`.
54
+
55
+ To use the elements, load them through a bundler, as
56
+ [Installation](./installation) shows. A CDN that rewrites bare specifiers into
57
+ URLs can serve the elements to a page with no build step, once the packages are
58
+ public on npm.