@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.
- package/content/accessibility.mdx +92 -71
- package/content/angular.mdx +26 -24
- package/content/browser-support.mdx +61 -58
- package/content/building-on-the-headless-tier.mdx +100 -74
- package/content/charting.mdx +98 -79
- package/content/coding-agents.mdx +87 -69
- package/content/color-modes.mdx +40 -37
- package/content/color.mdx +67 -54
- package/content/composition.mdx +85 -83
- package/content/elevation-and-material.mdx +32 -29
- package/content/events.mdx +77 -65
- package/content/forms.mdx +69 -58
- package/content/iconography.mdx +75 -71
- package/content/installation.mdx +77 -68
- package/content/intent-reference.mdx +59 -54
- package/content/introduction.mdx +25 -23
- package/content/localization.mdx +122 -82
- package/content/maps.mdx +431 -0
- package/content/metrics.mdx +296 -299
- package/content/motion.mdx +44 -36
- package/content/other-frameworks.mdx +33 -31
- package/content/overlays.mdx +72 -54
- package/content/overriding-a-component.mdx +85 -74
- package/content/react.mdx +72 -64
- package/content/recipes.mdx +64 -47
- package/content/routing.mdx +100 -93
- package/content/sandbox.mdx +39 -39
- package/content/server-rendering.mdx +95 -84
- package/content/shape-and-borders.mdx +44 -37
- package/content/size-and-density.mdx +51 -46
- package/content/space-and-size.mdx +41 -34
- package/content/state-and-control.mdx +63 -51
- package/content/surfaces-and-separation.mdx +55 -53
- package/content/svelte.mdx +20 -19
- package/content/theme-builder.mdx +42 -31
- package/content/theming.mdx +58 -51
- package/content/tiers.mdx +69 -61
- package/content/tokens.mdx +72 -53
- package/content/typography.mdx +47 -47
- package/content/using-helix-with-an-agent.mdx +147 -115
- package/content/using-the-elements.mdx +55 -50
- package/content/versioning.mdx +42 -35
- package/content/visual-axes.mdx +168 -146
- package/content/vue.mdx +24 -24
- package/content/without-a-bundler.mdx +40 -23
- package/dist/pages.generated.js +49 -43
- package/dist/sources.generated.js +3548 -2682
- package/package.json +3 -3
package/content/typography.mdx
CHANGED
|
@@ -1,48 +1,49 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: The font families, the type scale, and how Helix styles headings and prose.
|
|
3
3
|
section: Foundations
|
|
4
4
|
title: Typography
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Typography
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Font families
|
|
10
10
|
|
|
11
11
|
[//]: # (tokens:font)
|
|
12
12
|
|
|
13
13
|
| Token | Value | For |
|
|
14
14
|
| --- | --- | --- |
|
|
15
|
-
| `--helix-font-sans` | `ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif` |
|
|
16
|
-
| `--helix-font-mono` | `ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace` | Code, and
|
|
17
|
-
| `--helix-font-display` | `ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif` |
|
|
15
|
+
| `--helix-font-sans` | `ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif` | All text except code and display headings. |
|
|
16
|
+
| `--helix-font-mono` | `ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace` | Code, and text that needs to line up in columns. |
|
|
17
|
+
| `--helix-font-display` | `ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif` | Large display headings. Falls back to the sans face. |
|
|
18
18
|
|
|
19
19
|
[//]: # (/tokens)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
families than a product
|
|
21
|
+
Helix has three font families and no scale of weights and widths. A design
|
|
22
|
+
system with more families than a product uses ends up with two that mean the
|
|
23
|
+
same thing.
|
|
23
24
|
|
|
24
|
-
## The scale
|
|
25
|
+
## The type scale
|
|
25
26
|
|
|
26
|
-
`--helix-text-xs`
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
The type scale runs from `--helix-text-xs` to `--helix-text-3xl`.
|
|
28
|
+
`--helix-text-control` sets the size of a control's own text. It follows the
|
|
29
|
+
region's density and is separate from the type scale.
|
|
29
30
|
|
|
30
|
-
**The
|
|
31
|
+
**The base layer applies the scale to heading elements.**
|
|
31
32
|
|
|
32
33
|
```css
|
|
33
34
|
:where([data-prose] h1) { font-size: var(--helix-text-3xl); }
|
|
34
35
|
:where([data-prose] h2) { font-size: var(--helix-text-2xl); }
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
`[data-prose]
|
|
38
|
+
Because the styles target the elements, a heading's markup and its appearance
|
|
39
|
+
match by default. The styles also reach prose that Helix does not render.
|
|
40
|
+
Content from a CMS, a Markdown file, or a rich-text field is styled correctly
|
|
41
|
+
inside `[data-prose]`, with no changes to the content.
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
section's second heading
|
|
44
|
-
outline
|
|
45
|
-
|
|
43
|
+
Use `Text` when a heading's element and its appearance need to differ. A
|
|
44
|
+
section's second heading may need to look smaller and keep its place in the
|
|
45
|
+
outline. A `<p>` may need to look like a caption. `as` chooses the element, and
|
|
46
|
+
`variant` chooses the ramp:
|
|
46
47
|
|
|
47
48
|
```html
|
|
48
49
|
<helix-text
|
|
@@ -51,14 +52,14 @@ element and `variant` chooses the ramp:
|
|
|
51
52
|
>Reads as body, outlines as a heading</helix-text>
|
|
52
53
|
```
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
the
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
right. There is no separate `Heading` component, because that
|
|
55
|
+
By default the two match, so most headings need only `as="h2"`. CSS resolves
|
|
56
|
+
the match. `Text` does not write an attribute onto the host element, because
|
|
57
|
+
that would cause a hydration mismatch in every React app. Size, weight, and
|
|
58
|
+
leading are not properties. Each ramp already sets them, and setting them one
|
|
59
|
+
by one would allow a few hundred combinations, of which only a handful are
|
|
60
|
+
right. There is no separate `Heading` component, because `as` does that job.
|
|
60
61
|
|
|
61
|
-
##
|
|
62
|
+
## Style your own text
|
|
62
63
|
|
|
63
64
|
```html
|
|
64
65
|
<article data-prose>
|
|
@@ -67,25 +68,25 @@ right. There is no separate `Heading` component, because that is `as`.
|
|
|
67
68
|
</article>
|
|
68
69
|
```
|
|
69
70
|
|
|
70
|
-
`[data-prose]`
|
|
71
|
-
|
|
71
|
+
Put `[data-prose]` on the element that contains your text. Inside it, the token
|
|
72
|
+
layer styles headings, paragraphs, lists, links, and code.
|
|
72
73
|
|
|
73
|
-
For one-off text outside prose, `[data-text]`
|
|
74
|
+
For one-off text outside prose, use `[data-text]` to set the ramp:
|
|
74
75
|
|
|
75
76
|
```html
|
|
76
77
|
<span data-text="sm">Fine print</span>
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
##
|
|
80
|
+
## Line height, letter spacing, and weight
|
|
80
81
|
|
|
81
82
|
[//]: # (tokens:leading)
|
|
82
83
|
|
|
83
84
|
| Token | Value | For |
|
|
84
85
|
| --- | --- | --- |
|
|
85
|
-
| `--helix-leading-tight` | `1.2` | Body text set close, for
|
|
86
|
-
| `--helix-leading-normal` | `1.5` | Body text
|
|
87
|
-
| `--helix-leading-loose` | `1.7` | Body text set open, for
|
|
88
|
-
| `--helix-leading-heading` | `calc(0.99em + 0.5rem)` | Headings, which
|
|
86
|
+
| `--helix-leading-tight` | `1.2` | Body text set close, for short lines. |
|
|
87
|
+
| `--helix-leading-normal` | `1.5` | Body text. The default line height for a paragraph. |
|
|
88
|
+
| `--helix-leading-loose` | `1.7` | Body text set open, for long lines or small sizes. |
|
|
89
|
+
| `--helix-leading-heading` | `calc(0.99em + 0.5rem)` | Headings, which need less line height than a paragraph. It is a length plus an em, so it tightens as the type grows. |
|
|
89
90
|
|
|
90
91
|
[//]: # (/tokens)
|
|
91
92
|
|
|
@@ -93,10 +94,10 @@ For one-off text outside prose, `[data-text]` carries the ramp:
|
|
|
93
94
|
|
|
94
95
|
| Token | Value | For |
|
|
95
96
|
| --- | --- | --- |
|
|
96
|
-
| `--helix-tracking-tight` | `-0.01em` | Large type, which needs
|
|
97
|
-
| `--helix-tracking-normal` | `0` | Body text
|
|
98
|
-
| `--helix-tracking-wide` | `0.02em` |
|
|
99
|
-
| `--helix-tracking-wider` | `0.12em` |
|
|
97
|
+
| `--helix-tracking-tight` | `-0.01em` | Large type, which needs tighter letter spacing than a paragraph. |
|
|
98
|
+
| `--helix-tracking-normal` | `0` | Body text. The default letter spacing. |
|
|
99
|
+
| `--helix-tracking-wide` | `0.02em` | Labels and small capitals, which need extra letter spacing. |
|
|
100
|
+
| `--helix-tracking-wider` | `0.12em` | Uppercase eyebrows, which need more letter spacing than a label. |
|
|
100
101
|
|
|
101
102
|
[//]: # (/tokens)
|
|
102
103
|
|
|
@@ -104,14 +105,13 @@ For one-off text outside prose, `[data-text]` carries the ramp:
|
|
|
104
105
|
|
|
105
106
|
| Token | Value | For |
|
|
106
107
|
| --- | --- | --- |
|
|
107
|
-
| `--helix-weight-regular` | `400` | Body text
|
|
108
|
-
| `--helix-weight-medium` | `500` |
|
|
109
|
-
| `--helix-weight-semibold` | `600` |
|
|
108
|
+
| `--helix-weight-regular` | `400` | Body text. Most of a page uses this weight. |
|
|
109
|
+
| `--helix-weight-medium` | `500` | Labels, and quieter headings. |
|
|
110
|
+
| `--helix-weight-semibold` | `600` | Headings. The heaviest weight in Helix. |
|
|
110
111
|
|
|
111
112
|
[//]: # (/tokens)
|
|
112
113
|
|
|
113
|
-
**Headings have their own leading token
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
every heading level.
|
|
114
|
+
**Headings have their own leading token.** At a paragraph's line height, a
|
|
115
|
+
heading looks loose at every size. The fix is not proportional, because larger
|
|
116
|
+
type needs less leading. `--helix-leading-heading` expresses that once, so no
|
|
117
|
+
heading level needs its own multiplier.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: Four mistakes that look like Helix bugs, and the files an agent should read.
|
|
3
3
|
parent: coding-agents
|
|
4
4
|
section: Getting started
|
|
5
5
|
title: Using Helix with an agent
|
|
@@ -8,16 +8,21 @@ title: Using Helix with an agent
|
|
|
8
8
|
|
|
9
9
|
# Using Helix with an agent
|
|
10
10
|
|
|
11
|
-
**
|
|
12
|
-
`.claude/skills/using-helix/SKILL.md`,
|
|
13
|
-
repository
|
|
14
|
-
Copilot reads `.github/copilot-instructions.md`, and a consumer of the published
|
|
15
|
-
packages has none of them because they have this site and no checkout.
|
|
11
|
+
**We publish this guide as a web page so that every tool can read it.** It began
|
|
12
|
+
as `.claude/skills/using-helix/SKILL.md`, a file format that one vendor reads in
|
|
13
|
+
a repository. Every other vendor reads its own file:
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
- Cursor reads `.cursor/rules`.
|
|
16
|
+
- Copilot reads `.github/copilot-instructions.md`.
|
|
17
|
+
|
|
18
|
+
If you install the published packages, you have none of these files. You have
|
|
19
|
+
this site and no checkout of our repository.
|
|
20
|
+
|
|
21
|
+
So the guide lives in one place, here, at a URL that
|
|
22
|
+
[llms.txt](https://fusion.dev/llms.txt) indexes and that each of those files can
|
|
23
|
+
link to. Paste the link into the file your tool reads. [The MCP
|
|
24
|
+
server](./coding-agents) works with any vendor and runs code, and Claude,
|
|
25
|
+
Cursor, Windsurf, and Zed all support it.
|
|
21
26
|
|
|
22
27
|
## Read the manifest before writing a tag
|
|
23
28
|
|
|
@@ -26,33 +31,39 @@ https://fusion.dev/helix/custom-elements.json
|
|
|
26
31
|
@fusion.dev/helix/custom-elements.json
|
|
27
32
|
```
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
The manifest lists:
|
|
35
|
+
|
|
36
|
+
- every tag
|
|
37
|
+
- every property, with its literal union
|
|
38
|
+
- every event, with its class
|
|
39
|
+
- every slot, part, and custom property
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
**If a tag is not in the manifest, it does not exist.** A property value outside
|
|
42
|
+
a declared union is invalid. Property types are literal unions for this reason.
|
|
43
|
+
`'ghost' | 'outlined' | 'solid' | 'subtle'` shows you the values, and a named
|
|
44
|
+
type such as `ButtonEmphasis` sends you somewhere else to find them.
|
|
45
|
+
|
|
46
|
+
When you need one family, fetch it as data:
|
|
37
47
|
|
|
38
48
|
```
|
|
39
49
|
https://fusion.dev/helix/components/<family>.json
|
|
40
50
|
https://fusion.dev/helix/components/<family>.md
|
|
41
51
|
```
|
|
42
52
|
|
|
43
|
-
The `.md`
|
|
44
|
-
|
|
45
|
-
request
|
|
53
|
+
The `.md` file has the API tables and the examples. The HTML page leaves the
|
|
54
|
+
examples out on purpose. Start from `https://fusion.dev/llms.txt`. In one
|
|
55
|
+
request, it names every document and these two sources.
|
|
46
56
|
|
|
47
|
-
##
|
|
57
|
+
## Four mistakes that look like Helix bugs
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
Each of these looks like a bug in Helix. They are listed from the most common to
|
|
60
|
+
the least common.
|
|
50
61
|
|
|
51
|
-
### 1.
|
|
62
|
+
### 1. Blocking a change without `preventDefault()`
|
|
52
63
|
|
|
53
|
-
**
|
|
54
|
-
|
|
55
|
-
`<input value="Ada"
|
|
64
|
+
**Setting `value`, `open`, `checked`, or `active` sets the starting state and
|
|
65
|
+
corrects the current state.** The element starts in that state and then applies
|
|
66
|
+
its own changes, the same as `<input value="Ada">`. This works with no handler:
|
|
56
67
|
|
|
57
68
|
```html
|
|
58
69
|
<helix-input
|
|
@@ -61,10 +72,10 @@ The element starts there and goes on applying its own changes, exactly as
|
|
|
61
72
|
></helix-input>
|
|
62
73
|
```
|
|
63
74
|
|
|
64
|
-
The
|
|
65
|
-
state did not
|
|
66
|
-
|
|
67
|
-
`preventDefault()` on the matching `helix-before-*` event:
|
|
75
|
+
The mistake happens when you block a change. React restores a native `<input>`
|
|
76
|
+
whose state did not change. React does not do this for a custom element, so a
|
|
77
|
+
handler that does not call `setState` leaves the element with the new value. To
|
|
78
|
+
block a change, call `preventDefault()` on the matching `helix-before-*` event:
|
|
68
79
|
|
|
69
80
|
```tsx
|
|
70
81
|
<helix-input
|
|
@@ -77,92 +88,109 @@ declines to call `setState` leaves the element holding the new value. Refusal is
|
|
|
77
88
|
/>
|
|
78
89
|
```
|
|
79
90
|
|
|
80
|
-
`default-value` and
|
|
81
|
-
[State and control](./state-and-control).
|
|
91
|
+
A form reset returns the element to `default-value` and the matching attributes
|
|
92
|
+
for the other states. See [State and control](./state-and-control).
|
|
82
93
|
|
|
83
|
-
### 2.
|
|
94
|
+
### 2. Using the exact event name
|
|
84
95
|
|
|
85
|
-
`onhelix-before-open
|
|
86
|
-
prop and listens for exactly
|
|
87
|
-
|
|
96
|
+
In React, write `onhelix-before-open`. `onHelixOpen` and `onOpen` do not work.
|
|
97
|
+
React removes `on` from the prop name and listens for exactly the rest, so the
|
|
98
|
+
casing must match. Outside React, use
|
|
99
|
+
`addEventListener('helix-before-open', …)`.
|
|
88
100
|
|
|
89
|
-
**Lifecycle
|
|
90
|
-
`helix-before-close` reach the element and stop,
|
|
91
|
-
not the dialog
|
|
92
|
-
|
|
93
|
-
|
|
101
|
+
**Lifecycle events do not bubble. Coordination events do.**
|
|
102
|
+
`helix-before-open` and `helix-before-close` reach the element and stop there,
|
|
103
|
+
so a menu closing inside a dialog does not close the dialog. `helix-select`,
|
|
104
|
+
`helix-before-change`, and `helix-dismiss` cross shadow boundaries, so you can
|
|
105
|
+
listen for them on a container. If a listener on a wrapper receives nothing, the
|
|
106
|
+
event is a lifecycle event. Put the listener on the element.
|
|
94
107
|
|
|
95
|
-
### 3.
|
|
108
|
+
### 3. Styling a disabled control with `:disabled`
|
|
96
109
|
|
|
97
110
|
```css
|
|
98
111
|
helix-input:disabled { … } /* right: matches a disabled fieldset too */
|
|
99
112
|
helix-input[disabled] { … } /* wrong: a fieldset sets no attribute */
|
|
100
113
|
```
|
|
101
114
|
|
|
102
|
-
|
|
103
|
-
attribute
|
|
115
|
+
The browser disables a control inside `<fieldset disabled>` without adding an
|
|
116
|
+
attribute to it. The `[disabled]` selector does not match it, so the control
|
|
117
|
+
looks enabled while it does not accept input.
|
|
104
118
|
|
|
105
|
-
### 4.
|
|
119
|
+
### 4. Loading every style layer before the elements
|
|
106
120
|
|
|
107
121
|
```ts
|
|
108
122
|
import '@fusion.dev/helix-styles/helix.css'
|
|
109
123
|
import '@fusion.dev/helix'
|
|
110
124
|
```
|
|
111
125
|
|
|
112
|
-
`helix.css`
|
|
113
|
-
|
|
126
|
+
`helix.css` combines four files in the order they must load:
|
|
127
|
+
|
|
128
|
+
1. `primitives.css`
|
|
129
|
+
2. `tokens.css`
|
|
130
|
+
3. `base.css`
|
|
131
|
+
4. `elements.css`
|
|
132
|
+
|
|
133
|
+
Import them one by one only when you need to replace one of them.
|
|
114
134
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
styles of its own, so the markup
|
|
135
|
+
People most often leave out `elements.css`. Everything works without it until
|
|
136
|
+
you render the page on the server. An element that has not upgraded has no
|
|
137
|
+
styles of its own, so the markup appears unstyled and then jumps into place.
|
|
118
138
|
|
|
119
|
-
|
|
120
|
-
`elements.css`; bare headings are `base.css`. **No color anywhere means the
|
|
121
|
-
ramp or the semantic layer, and the two are told apart by what is in the
|
|
122
|
-
stylesheet rather than by what is on screen**: without `tokens.css` nothing
|
|
123
|
-
declares `--helix-color-*` at all, while without `primitives.css` all 185
|
|
124
|
-
semantic tokens are declared and every color resolves to `rgba(0, 0, 0, 0)`,
|
|
125
|
-
since `tokens.css` refers to a primitive 297 times and to nothing else. The
|
|
126
|
-
second is the one that looks like a working install, and it is the reason
|
|
127
|
-
`helix.css` exists.
|
|
139
|
+
Each missing layer has its own symptom:
|
|
128
140
|
|
|
129
|
-
|
|
141
|
+
- An unstyled flash before hydration means `elements.css` is missing.
|
|
142
|
+
- Unstyled headings mean `base.css` is missing.
|
|
143
|
+
- No color anywhere means `primitives.css` or `tokens.css` is missing.
|
|
130
144
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
145
|
+
To tell the last two apart, look at the stylesheet. The screen looks the same.
|
|
146
|
+
Without `tokens.css`, nothing declares `--helix-color-*`. Without
|
|
147
|
+
`primitives.css`, all 185 semantic tokens are declared and every color resolves
|
|
148
|
+
to `rgba(0, 0, 0, 0)`, because `tokens.css` refers to a primitive 297 times and
|
|
149
|
+
to nothing else. A missing `primitives.css` looks like a working install, and
|
|
150
|
+
`helix.css` exists to prevent it.
|
|
134
151
|
|
|
135
|
-
|
|
152
|
+
## Choosing a component family
|
|
136
153
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
`Button Group` are families whose members submit themselves.
|
|
140
|
-
- **A control has no `size`.** Height comes from `data-density` on the region,
|
|
141
|
-
`sm` / `md` / `lg`, which crosses shadow boundaries through custom properties.
|
|
142
|
-
If two controls in a row must differ in height, the layout is wrong rather than
|
|
143
|
-
the API.
|
|
154
|
+
Look up the family in the manifest. Each family's `helix.aliases` lists its
|
|
155
|
+
other names, and a request often uses one of them:
|
|
144
156
|
|
|
145
|
-
|
|
157
|
+
- `Segment` and `NavItem` are `Toggle`.
|
|
158
|
+
- `Key` is `Legend`.
|
|
159
|
+
- `Hint` is `Tooltip`.
|
|
146
160
|
|
|
147
|
-
|
|
161
|
+
Know two rules before you search:
|
|
162
|
+
|
|
163
|
+
- **A group that reports a form value is a part.** A group that does not is its
|
|
164
|
+
own family. `Radio.Group` and `Toggle.Group` are parts. `Checkbox Group` and
|
|
165
|
+
`Button Group` are families whose members each submit their own value.
|
|
166
|
+
- **A control has no `size`.** Its height comes from `data-density` on the
|
|
167
|
+
region, `sm` / `md` / `lg`, which crosses shadow boundaries through custom
|
|
168
|
+
properties. If two controls in a row need different heights, change the
|
|
169
|
+
layout.
|
|
170
|
+
|
|
171
|
+
## Styling components from outside
|
|
172
|
+
|
|
173
|
+
You can style a component in three ways. Try them in this order:
|
|
148
174
|
|
|
149
175
|
1. **A token.** `--helix-seed-radii: 2px` at `:root` reaches every component,
|
|
150
|
-
because custom properties inherit. Most
|
|
151
|
-
|
|
152
|
-
radii are
|
|
153
|
-
nor the cards.
|
|
154
|
-
2. **A per-component hook.** `--card-padding` on `helix-card`.
|
|
155
|
-
component, documented on
|
|
156
|
-
|
|
157
|
-
|
|
176
|
+
because custom properties inherit. Most requests to restyle the button are
|
|
177
|
+
really requests for less rounding across the brand. Set the seed. The four
|
|
178
|
+
radii, including `--helix-radii-md`, are computed from it, so changing `md`
|
|
179
|
+
alone changes neither the buttons nor the cards.
|
|
180
|
+
2. **A per-component hook.** For example, `--card-padding` on `helix-card`. Each
|
|
181
|
+
hook is named after its component, documented on the component's page, and
|
|
182
|
+
defaults to a semantic token.
|
|
183
|
+
3. **A part.** For example, `helix-select::part(trigger)`. A part gives you the
|
|
184
|
+
most control, and it ties your styles to the component's internal structure.
|
|
158
185
|
|
|
159
|
-
**Never read a primitive.** `--_helix-neutral-500` and
|
|
160
|
-
`@fusion.dev/helix-styles
|
|
186
|
+
**Never read a primitive.** `--_helix-neutral-500` and the other primitives
|
|
187
|
+
belong to `@fusion.dev/helix-styles`. The underscore marks them as internal.
|
|
188
|
+
Read the semantic tokens that refer to them.
|
|
161
189
|
|
|
162
|
-
##
|
|
190
|
+
## Styling HTML without custom elements
|
|
163
191
|
|
|
164
|
-
`@fusion.dev/helix-styles` is plain CSS with no JavaScript
|
|
165
|
-
markup Helix does not render:
|
|
192
|
+
`@fusion.dev/helix-styles` is plain CSS with no JavaScript. It includes recipes
|
|
193
|
+
for markup that Helix does not render:
|
|
166
194
|
|
|
167
195
|
```html
|
|
168
196
|
<button
|
|
@@ -173,16 +201,21 @@ markup Helix does not render:
|
|
|
173
201
|
<div data-density="sm">…</div>
|
|
174
202
|
```
|
|
175
203
|
|
|
176
|
-
A recipe
|
|
177
|
-
|
|
178
|
-
|
|
204
|
+
A recipe sets appearance only. It has none of these:
|
|
205
|
+
|
|
206
|
+
- state
|
|
207
|
+
- form participation
|
|
208
|
+
- focus trapping
|
|
209
|
+
- keyboard handling
|
|
210
|
+
|
|
211
|
+
If you are adding a script to a recipe, use the component.
|
|
179
212
|
|
|
180
|
-
##
|
|
213
|
+
## Link your tool to this guide
|
|
181
214
|
|
|
182
|
-
**
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
215
|
+
**Link to this page from your instructions file, and do not copy it.** Each tool
|
|
216
|
+
that reads project instructions reads a file in your repository, and each tool
|
|
217
|
+
reads a different one. A copy starts to go stale as soon as you paste it, and
|
|
218
|
+
this page changes with the library.
|
|
186
219
|
|
|
187
220
|
```md
|
|
188
221
|
Helix: read https://fusion.dev/helix/docs/using-helix-with-an-agent
|
|
@@ -197,13 +230,12 @@ for the API.
|
|
|
197
230
|
| GitHub Copilot | `.github/copilot-instructions.md` |
|
|
198
231
|
| Anything else | Whatever it reads. The line is the same |
|
|
199
232
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
paste and yours to delete.
|
|
233
|
+
We do not write those files for you, and we chose this on purpose. You would
|
|
234
|
+
have to maintain a file we generated in your repository against our changes. A
|
|
235
|
+
tool that rewrote it on install would be a dependency you did not ask for, in a
|
|
236
|
+
directory you own. You paste the line above, and you can delete it.
|
|
205
237
|
|
|
206
|
-
##
|
|
238
|
+
## Install the Helix MCP server
|
|
207
239
|
|
|
208
240
|
```json
|
|
209
241
|
{
|
|
@@ -213,22 +245,22 @@ paste and yours to delete.
|
|
|
213
245
|
}
|
|
214
246
|
```
|
|
215
247
|
|
|
216
|
-
`helix mcp` is a subcommand of the CLI
|
|
217
|
-
Cursor, Windsurf and Zed all read. It
|
|
218
|
-
which
|
|
219
|
-
|
|
248
|
+
`helix mcp` is a subcommand of the CLI. It serves MCP over stdio, which Claude,
|
|
249
|
+
Cursor, Windsurf, and Zed all read. It computes the theme a given brand color
|
|
250
|
+
produces, which no document can list. It runs on your machine, talks to a client
|
|
251
|
+
you chose, and makes no network requests.
|
|
220
252
|
|
|
221
|
-
## What this
|
|
253
|
+
## What this guide does not cover
|
|
222
254
|
|
|
223
|
-
**Anything the manifest
|
|
224
|
-
|
|
225
|
-
of them here would be a second copy
|
|
255
|
+
**Anything in the manifest.** Property names, unions, part names, event names,
|
|
256
|
+
and hooks change with the library, and they are in a file you can fetch. A list
|
|
257
|
+
of them here would be a second copy that goes stale. Fetch the family.
|
|
226
258
|
|
|
227
|
-
**
|
|
228
|
-
|
|
229
|
-
`
|
|
230
|
-
|
|
259
|
+
**The theme a brand color produces.** Helix computes it, so use `helix mcp`, an
|
|
260
|
+
MCP server over stdio with `helix_audit_theme` and `helix_derive_theme`. Both
|
|
261
|
+
take the same JSON that a `helix.theme.json` file holds. It runs on your
|
|
262
|
+
machine, and we do not host it.
|
|
231
263
|
|
|
232
|
-
**Whether a component
|
|
233
|
-
|
|
234
|
-
`https://fusion.dev/helix/sandbox?e=<family>.<slug>` opens one
|
|
264
|
+
**Whether a component fits your case.** Read the examples to decide. Every
|
|
265
|
+
family's `.md` file includes them as text, and
|
|
266
|
+
`https://fusion.dev/helix/sandbox?e=<family>.<slug>` opens one for editing.
|