@fusion.dev/helix-templates 0.138.0 → 0.140.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/README.md +18 -6
- package/dist/index.js +24 -0
- package/package.json +1 -1
- package/templates/angular/angular.json +57 -0
- package/templates/angular/package.json +28 -0
- package/templates/angular/src/app/app.config.ts +8 -0
- package/templates/angular/src/app/app.html +19 -0
- package/templates/angular/src/app/app.ts +29 -0
- package/templates/angular/src/app/data.ts +81 -0
- package/templates/angular/src/app/docs.ts +29 -0
- package/templates/angular/src/app/landing.html +77 -0
- package/templates/angular/src/app/landing.ts +29 -0
- package/templates/angular/src/app/overview.html +49 -0
- package/templates/angular/src/app/overview.ts +25 -0
- package/templates/angular/src/app/pathname.ts +24 -0
- package/templates/angular/src/app/signup-form.html +90 -0
- package/templates/angular/src/app/signup-form.ts +65 -0
- package/templates/angular/src/app/site-footer.html +10 -0
- package/templates/angular/src/app/site-footer.ts +22 -0
- package/templates/angular/src/app/site-header.html +30 -0
- package/templates/angular/src/app/site-header.ts +57 -0
- package/templates/angular/src/app.css +355 -0
- package/templates/angular/src/diagnostics.ts +24 -0
- package/templates/angular/src/index.html +12 -0
- package/templates/angular/src/main.ts +21 -0
- package/templates/angular/tsconfig.app.json +9 -0
- package/templates/angular/tsconfig.json +34 -0
- package/templates/react-nextjs/app/app.css +144 -152
- package/templates/react-nextjs/app/data.ts +17 -17
- package/templates/react-nextjs/app/diagnostics.ts +19 -0
- package/templates/react-nextjs/app/docs.ts +9 -9
- package/templates/react-nextjs/app/landing.tsx +63 -121
- package/templates/react-nextjs/app/overview.tsx +25 -27
- package/templates/react-nextjs/app/signup-form.tsx +36 -39
- package/templates/react-nextjs/app/site-footer.tsx +7 -10
- package/templates/react-nextjs/app/site-header.tsx +17 -21
- package/templates/react-nextjs/helix-jsx.d.ts +5 -7
- package/templates/react-nextjs/instrumentation-client.ts +6 -0
- package/templates/react-nextjs/package.json +1 -0
- package/templates/react-nextjs/tsconfig.json +1 -0
- package/templates/react-vite/helix-jsx.d.ts +5 -7
- package/templates/react-vite/package.json +1 -0
- package/templates/react-vite/src/app.css +144 -152
- package/templates/react-vite/src/data.ts +17 -17
- package/templates/react-vite/src/diagnostics.ts +24 -0
- package/templates/react-vite/src/docs.ts +9 -9
- package/templates/react-vite/src/landing.tsx +63 -121
- package/templates/react-vite/src/main.tsx +6 -0
- package/templates/react-vite/src/overview.tsx +24 -26
- package/templates/react-vite/src/routes.tsx +11 -13
- package/templates/react-vite/src/signup-form.tsx +36 -39
- package/templates/react-vite/src/site-footer.tsx +7 -10
- package/templates/react-vite/src/site-header.tsx +15 -19
- package/templates/react-vite/tsconfig.json +1 -0
- package/templates/solid-vite/helix-solid.d.ts +14 -0
- package/templates/solid-vite/index.html +12 -0
- package/templates/solid-vite/package.json +22 -0
- package/templates/solid-vite/src/App.tsx +35 -0
- package/templates/solid-vite/src/app.css +355 -0
- package/templates/solid-vite/src/data.ts +81 -0
- package/templates/solid-vite/src/diagnostics.ts +24 -0
- package/templates/solid-vite/src/docs.ts +29 -0
- package/templates/solid-vite/src/landing.tsx +130 -0
- package/templates/solid-vite/src/main.tsx +23 -0
- package/templates/solid-vite/src/overview.tsx +78 -0
- package/templates/solid-vite/src/routes.ts +22 -0
- package/templates/solid-vite/src/signup-form.tsx +151 -0
- package/templates/solid-vite/src/site-footer.tsx +34 -0
- package/templates/solid-vite/src/site-header.tsx +76 -0
- package/templates/solid-vite/tsconfig.json +27 -0
- package/templates/solid-vite/vite.config.ts +7 -0
- package/templates/svelte-vite/helix-svelte.d.ts +9 -0
- package/templates/svelte-vite/index.html +12 -0
- package/templates/svelte-vite/package.json +23 -0
- package/templates/svelte-vite/src/App.svelte +35 -0
- package/templates/svelte-vite/src/Landing.svelte +100 -0
- package/templates/svelte-vite/src/Overview.svelte +67 -0
- package/templates/svelte-vite/src/SignupForm.svelte +147 -0
- package/templates/svelte-vite/src/SiteFooter.svelte +26 -0
- package/templates/svelte-vite/src/SiteHeader.svelte +71 -0
- package/templates/svelte-vite/src/app.css +355 -0
- package/templates/svelte-vite/src/data.ts +81 -0
- package/templates/svelte-vite/src/diagnostics.ts +24 -0
- package/templates/svelte-vite/src/docs.ts +29 -0
- package/templates/svelte-vite/src/main.ts +23 -0
- package/templates/svelte-vite/src/routes.svelte.ts +19 -0
- package/templates/svelte-vite/tsconfig.json +28 -0
- package/templates/svelte-vite/vite.config.ts +7 -0
- package/templates/vue-vite/helix-vue.d.ts +8 -0
- package/templates/vue-vite/index.html +12 -0
- package/templates/vue-vite/package.json +23 -0
- package/templates/vue-vite/src/App.vue +39 -0
- package/templates/vue-vite/src/LandingPage.vue +102 -0
- package/templates/vue-vite/src/OverviewPage.vue +69 -0
- package/templates/vue-vite/src/SignupForm.vue +149 -0
- package/templates/vue-vite/src/SiteFooter.vue +28 -0
- package/templates/vue-vite/src/SiteHeader.vue +71 -0
- package/templates/vue-vite/src/app.css +355 -0
- package/templates/vue-vite/src/data.ts +81 -0
- package/templates/vue-vite/src/diagnostics.ts +24 -0
- package/templates/vue-vite/src/docs.ts +29 -0
- package/templates/vue-vite/src/main.ts +23 -0
- package/templates/vue-vite/src/routes.ts +26 -0
- package/templates/vue-vite/tsconfig.json +26 -0
- package/templates/vue-vite/vite.config.ts +13 -0
- package/templates.json +41 -0
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* The page around the components.
|
|
3
3
|
*
|
|
4
|
-
* Helix draws
|
|
5
|
-
* measure, the rhythm between blocks, and the few
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* of anything.
|
|
4
|
+
* Helix draws the inside of each component, so an app stylesheet holds the
|
|
5
|
+
* measure, the rhythm between blocks, and the few decisions a component leaves
|
|
6
|
+
* open. Everything below is a Helix token or a documented hook, so a theme
|
|
7
|
+
* changes it, and both color modes follow from one copy.
|
|
9
8
|
*
|
|
10
|
-
* **Color appears
|
|
11
|
-
* `--helix-color-brand-mark`,
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* **Color appears in two places, and both are named.** The wordmark takes
|
|
10
|
+
* `--helix-color-brand-mark`, the token for the brand as a graphic, and a
|
|
11
|
+
* chosen row takes `--helix-color-primary-subtle` through the parts the table
|
|
12
|
+
* publishes. Everywhere else the page is ink on the background, and the
|
|
13
|
+
* components carry their own color.
|
|
15
14
|
*/
|
|
16
15
|
|
|
17
16
|
/*
|
|
18
|
-
* **The shell
|
|
19
|
-
* a header, a table and a caption, which on a 1280 by 900
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* end of it puts a floor under every route.
|
|
17
|
+
* **The shell: a column the height of the window, with the footer at its end.**
|
|
18
|
+
* The overview is a header, a table, and a caption, which on a 1280 by 900
|
|
19
|
+
* window left about four hundred empty pixels under it. The column puts a floor
|
|
20
|
+
* under every route.
|
|
23
21
|
*
|
|
24
|
-
* **
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
22
|
+
* **A flex column, because the bar is sticky.** A grid item's containing block
|
|
23
|
+
* is its own grid area, one row as tall as the bar, so a sticky header in a
|
|
24
|
+
* grid row has nowhere to stick. A flex item's containing block is the flex
|
|
25
|
+
* container, which here is the whole document.
|
|
28
26
|
*/
|
|
29
27
|
.shell {
|
|
30
28
|
display: flex;
|
|
@@ -33,14 +31,13 @@
|
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
/*
|
|
36
|
-
* **56rem,
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* wordmark sits over the first column of the page rather than near it.
|
|
34
|
+
* **56rem, the width the widest block reads well at.** The widest block here is
|
|
35
|
+
* a four-column table: given the whole of a 1280 window, its first column came
|
|
36
|
+
* out 448 pixels across to hold a name, which reads as a stretched table. The
|
|
37
|
+
* bar and the footer are centered in the same width, so the wordmark sits over
|
|
38
|
+
* the first column of the page.
|
|
42
39
|
*
|
|
43
|
-
* `flex-grow`
|
|
40
|
+
* `flex-grow` gives the spare height to the page, and the footer keeps its own.
|
|
44
41
|
*/
|
|
45
42
|
.page {
|
|
46
43
|
flex-grow: 1;
|
|
@@ -51,23 +48,21 @@
|
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
/*
|
|
54
|
-
* Two documented hooks,
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* color, so it follows the theme.
|
|
51
|
+
* Two documented hooks, both to match the page. The bar centers its row in the
|
|
52
|
+
* page's measure, so the wordmark sits over the first column. And the bar draws
|
|
53
|
+
* no line under itself by default, since a header over a page with its own
|
|
54
|
+
* surface needs none: this page has no such surface, so it sets one. The line
|
|
55
|
+
* is a token, so it follows the theme.
|
|
60
56
|
*/
|
|
61
57
|
helix-app-header {
|
|
62
58
|
--app-header-border-color: var(--helix-color-border);
|
|
63
59
|
--app-header-max-inline-size: 56rem;
|
|
64
60
|
}
|
|
65
61
|
|
|
66
|
-
/* The mark beside the project's name,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
replace the whole element with your own logo. */
|
|
62
|
+
/* The mark beside the project's name, the one graphic on the page and the
|
|
63
|
+
reason `--helix-color-brand-mark` exists. WCAG asks 3:1 of a graphic and 4.5:1
|
|
64
|
+
of text, so a mark can sit closer to a theme's brand color than any text
|
|
65
|
+
color can. Swap the glyph, or replace the whole element with your own logo. */
|
|
71
66
|
.wordmark {
|
|
72
67
|
align-items: center;
|
|
73
68
|
display: inline-flex;
|
|
@@ -79,72 +74,102 @@ helix-app-header {
|
|
|
79
74
|
}
|
|
80
75
|
|
|
81
76
|
/*
|
|
82
|
-
* One rhythm between the blocks of a page, so no page
|
|
77
|
+
* One rhythm between the blocks of a page, so no page sets its own.
|
|
83
78
|
*
|
|
84
|
-
* **`minmax(0, 1fr)`
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* the
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* to. Zero as the minimum hands the overflow back to whoever is equipped for it.
|
|
79
|
+
* **`minmax(0, 1fr)` for every column, the guard every grid here needs.** An
|
|
80
|
+
* implicit track is `auto`, and an `auto` track's minimum is its content's
|
|
81
|
+
* min-content size, so a child that scrolls itself widens the track and takes
|
|
82
|
+
* the page with it. Measured at 320: the table's columns floor at 344, the
|
|
83
|
+
* column it sits in should have been 288, and `documentElement.scrollWidth`
|
|
84
|
+
* came back 360 against a 320 viewport, so the whole page scrolled sideways. A
|
|
85
|
+
* minimum of zero leaves the overflow to the table, which scrolls its own box.
|
|
92
86
|
*/
|
|
93
87
|
.stack,
|
|
94
88
|
.section,
|
|
95
89
|
.hero,
|
|
96
90
|
.first-screen,
|
|
97
|
-
.
|
|
98
|
-
.facts,
|
|
91
|
+
.features,
|
|
99
92
|
.notes,
|
|
100
93
|
.split {
|
|
101
94
|
grid-template-columns: minmax(0, 1fr);
|
|
102
95
|
}
|
|
103
96
|
|
|
104
97
|
/* One step between the blocks of a page and a smaller one inside them, which is
|
|
105
|
-
the whole of the rhythm: `3xl` here
|
|
106
|
-
|
|
107
|
-
evenly spaced things. */
|
|
98
|
+
the whole of the rhythm: `3xl` here, and the `md` a section puts between its
|
|
99
|
+
heading and its block. */
|
|
108
100
|
.stack {
|
|
109
101
|
display: grid;
|
|
110
102
|
gap: var(--helix-space-3xl);
|
|
111
103
|
}
|
|
112
104
|
|
|
113
105
|
/*
|
|
114
|
-
* **The first screen
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* reading, so they become one and the panel reads as the thing the words were
|
|
118
|
-
* about.
|
|
106
|
+
* **The first screen: one lit panel, with what the starter is on the left and
|
|
107
|
+
* the library at work on the right.** Below 60rem two readable columns do not
|
|
108
|
+
* fit, so they become one, and the glass card follows the words.
|
|
119
109
|
*
|
|
120
|
-
* `
|
|
121
|
-
*
|
|
122
|
-
*
|
|
110
|
+
* `isolation` makes the panel its own stacking context, so the light behind it
|
|
111
|
+
* sits under the content and above the page, and `overflow: clip` keeps the
|
|
112
|
+
* light inside the rounded corners.
|
|
123
113
|
*/
|
|
124
114
|
.first-screen {
|
|
125
|
-
align-items:
|
|
115
|
+
align-items: center;
|
|
116
|
+
border: var(--helix-border-thin) solid var(--helix-color-border);
|
|
117
|
+
border-radius: var(--helix-radii-lg);
|
|
126
118
|
display: grid;
|
|
127
|
-
gap: var(--helix-space-
|
|
119
|
+
gap: var(--helix-space-2xl);
|
|
120
|
+
isolation: isolate;
|
|
121
|
+
overflow: clip;
|
|
122
|
+
padding: var(--helix-space-3xl) var(--helix-space-2xl);
|
|
123
|
+
position: relative;
|
|
128
124
|
}
|
|
129
125
|
|
|
130
126
|
@media (width >= 60rem) {
|
|
131
127
|
.first-screen {
|
|
132
|
-
grid-template-columns: minmax(0, 1fr) minmax(0,
|
|
128
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 18rem);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* The light, under everything in the panel and out of the way of the pointer,
|
|
133
|
+
and faded out behind the words so they keep their contrast: it is at full
|
|
134
|
+
strength only behind the card, which is below the words in one column and
|
|
135
|
+
beside them in two. */
|
|
136
|
+
.first-light {
|
|
137
|
+
block-size: auto;
|
|
138
|
+
inset: 0;
|
|
139
|
+
mask-image: linear-gradient(to bottom, transparent 40%, black 80%);
|
|
140
|
+
pointer-events: none;
|
|
141
|
+
position: absolute;
|
|
142
|
+
z-index: var(--helix-layer-beneath);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@media (width >= 60rem) {
|
|
146
|
+
.first-light {
|
|
147
|
+
mask-image: linear-gradient(to right, transparent 35%, black 70%);
|
|
133
148
|
}
|
|
134
149
|
}
|
|
135
150
|
|
|
136
|
-
/* A heading and the lines around it are one block,
|
|
137
|
-
|
|
151
|
+
/* A heading and the lines around it are one block, with a smaller gap than the
|
|
152
|
+
one between blocks. Every route opens with one. */
|
|
138
153
|
.hero {
|
|
139
154
|
display: grid;
|
|
140
155
|
gap: var(--helix-space-xs);
|
|
141
156
|
justify-items: start;
|
|
142
157
|
}
|
|
143
158
|
|
|
144
|
-
/*
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
159
|
+
/* The first screen's heading takes more room around it than a route's, and
|
|
160
|
+
its lede a step more size, wrapped to even lines. */
|
|
161
|
+
.first-screen .hero {
|
|
162
|
+
gap: var(--helix-space-md);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.first-screen .lede {
|
|
166
|
+
font-size: var(--helix-text-lg);
|
|
167
|
+
text-wrap: balance;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* **A measure for the lede, narrower than the page's.** A line of prose across
|
|
171
|
+
56rem is around 110 characters, and the readable range tops out near 75. The
|
|
172
|
+
heading above it keeps the page's measure, since a heading is scanned. */
|
|
148
173
|
.lede {
|
|
149
174
|
max-inline-size: 42rem;
|
|
150
175
|
}
|
|
@@ -157,12 +182,11 @@ helix-app-header {
|
|
|
157
182
|
}
|
|
158
183
|
|
|
159
184
|
/*
|
|
160
|
-
* **The panel is the library
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* number in.
|
|
185
|
+
* **The panel is the library at work**, so all it needs from here is room. Two
|
|
186
|
+
* documented hooks: the figures come down a step from the display size, which
|
|
187
|
+
* suits one figure on its own and is too loud for three in an 18rem column, and
|
|
188
|
+
* the gap around the rule between them comes in from `2xl`, which `divided`
|
|
189
|
+
* doubles, leaving no room for a number.
|
|
166
190
|
*/
|
|
167
191
|
.specimen {
|
|
168
192
|
--stat-group-gap: var(--helix-space-md);
|
|
@@ -176,71 +200,37 @@ helix-app-header {
|
|
|
176
200
|
gap: var(--helix-space-md);
|
|
177
201
|
}
|
|
178
202
|
|
|
179
|
-
/*
|
|
180
|
-
|
|
181
|
-
* identical outlined boxes is the shape a generated page takes, and it is also a
|
|
182
|
-
* claim: a box says each of these is its own object, when they are three
|
|
183
|
-
* paragraphs about the same installed thing. A rule over each column groups them
|
|
184
|
-
* at a fraction of the weight, and leaves the cards below to mean something,
|
|
185
|
-
* which is that they go somewhere.
|
|
186
|
-
*
|
|
187
|
-
* `border-thick` in the foreground rather than a hairline in the border color:
|
|
188
|
-
* this is a heading device rather than a container edge, and it is the one place
|
|
189
|
-
* the page draws in ink.
|
|
190
|
-
*/
|
|
191
|
-
.facts {
|
|
203
|
+
/* Three tiles, side by side where there is room for three. */
|
|
204
|
+
.features {
|
|
192
205
|
display: grid;
|
|
193
206
|
gap: var(--helix-space-lg);
|
|
194
207
|
}
|
|
195
208
|
|
|
196
209
|
@media (width >= 48rem) {
|
|
197
|
-
.
|
|
210
|
+
.features {
|
|
198
211
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
199
212
|
}
|
|
200
213
|
}
|
|
201
214
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
border-block-start: var(--helix-border-thick) solid var(--helix-color-foreground);
|
|
205
|
-
display: grid;
|
|
206
|
-
gap: var(--helix-space-xs);
|
|
207
|
-
justify-items: start;
|
|
208
|
-
padding-block-start: var(--helix-space-sm);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/*
|
|
212
|
-
* **The one departure the grids state.** `helix-grid` takes a fixed count as
|
|
213
|
-
* plain CSS, which is what keeps a server-rendered row of cards correct before
|
|
214
|
-
* any JavaScript arrives. Below this width there is only ever room for one
|
|
215
|
-
* column, and `--grid-columns` is the documented way to say so from outside the
|
|
216
|
-
* shadow root.
|
|
217
|
-
*/
|
|
218
|
-
@media (width < 48rem) {
|
|
219
|
-
helix-grid {
|
|
220
|
-
--grid-columns: minmax(0, 1fr);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/*
|
|
225
|
-
* **The cards keep `start`, which is `--card-align`'s resting value, and the
|
|
226
|
-
* alternative is worth naming because it looks right and is not.**
|
|
227
|
-
* `space-between` puts the last line of each card on its bottom edge, so a row
|
|
228
|
-
* of cards ends in a straight line. It gets there by sharing the slack out
|
|
229
|
-
* between every region, and the first thing that moves is the body: three cards
|
|
230
|
-
* of six, five and seven lines had their opening lines 50 pixels apart under
|
|
231
|
-
* headings that were level. A reader scans the first line of each, so that is
|
|
232
|
-
* the alignment worth keeping.
|
|
233
|
-
*/
|
|
234
|
-
|
|
235
|
-
/* The card fills the link that wraps it, so a row of destinations ends level:
|
|
236
|
-
the anchor is the grid item and stretches, and the card inside it does not.
|
|
237
|
-
The regions stay packed at the top, per `--card-align` above. */
|
|
215
|
+
/* The card fills the link that wraps it, so the row of tiles ends level: the
|
|
216
|
+
anchor is the grid item, which stretches, and the card takes its full height. */
|
|
238
217
|
[data-card] > helix-card {
|
|
239
218
|
block-size: 100%;
|
|
240
219
|
}
|
|
241
220
|
|
|
242
|
-
/*
|
|
243
|
-
|
|
221
|
+
/* Each tile's icon, on a tint of the brand. */
|
|
222
|
+
.feature-mark {
|
|
223
|
+
--icon-size: 1.25rem;
|
|
224
|
+
background-color: var(--helix-color-primary-subtle);
|
|
225
|
+
border-radius: var(--helix-radii-md);
|
|
226
|
+
color: var(--helix-color-primary);
|
|
227
|
+
display: inline-flex;
|
|
228
|
+
inline-size: fit-content;
|
|
229
|
+
padding: var(--helix-space-xs);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* A form is read straight down, and a field wider than about 28rem is hard to
|
|
233
|
+
scan, however much room the window has. */
|
|
244
234
|
.form {
|
|
245
235
|
align-content: start;
|
|
246
236
|
display: grid;
|
|
@@ -255,11 +245,10 @@ helix-app-header {
|
|
|
255
245
|
}
|
|
256
246
|
|
|
257
247
|
/*
|
|
258
|
-
* **The form takes a column and the notes take the rest.** A 28rem form
|
|
259
|
-
* 1280 window
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
* postscript, which is the order they are written in.
|
|
248
|
+
* **The form takes a column and the notes take the rest.** A 28rem form alone
|
|
249
|
+
* on a 1280 window fills a third of the page and leaves two thirds empty: the
|
|
250
|
+
* form has a right width, and the page keeps its own. Narrow, the two stack,
|
|
251
|
+
* and the notes read as a postscript, the order they are written in.
|
|
263
252
|
*/
|
|
264
253
|
.split {
|
|
265
254
|
display: grid;
|
|
@@ -291,10 +280,10 @@ helix-app-header {
|
|
|
291
280
|
}
|
|
292
281
|
|
|
293
282
|
/*
|
|
294
|
-
* **The counterpart to the bar,
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
283
|
+
* **The counterpart to the bar, which gives every route an end.** The rule runs
|
|
284
|
+
* the width of the window while its contents keep the page's measure, as a
|
|
285
|
+
* footer under a centered page does. The shell above holds it to the bottom of a
|
|
286
|
+
* window a route does not fill.
|
|
298
287
|
*/
|
|
299
288
|
.site-footer {
|
|
300
289
|
border-block-start: var(--helix-border-thin) solid var(--helix-color-border);
|
|
@@ -318,12 +307,16 @@ helix-app-header {
|
|
|
318
307
|
}
|
|
319
308
|
|
|
320
309
|
/*
|
|
321
|
-
* **Narrow, the gutter gives
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
310
|
+
* **Narrow, the gutter gives first.** 24 pixels either side of a 390 window
|
|
311
|
+
* spend 48 of 390 on margin, and the table needs 355 of what is left. At `md` it
|
|
312
|
+
* has 358 and fits; at `lg` it was 13 pixels short, and the last column sat
|
|
313
|
+
* outside the box until you scrolled the table sideways.
|
|
325
314
|
*/
|
|
326
315
|
@media (width < 40rem) {
|
|
316
|
+
.first-screen {
|
|
317
|
+
padding: var(--helix-space-2xl) var(--helix-space-lg);
|
|
318
|
+
}
|
|
319
|
+
|
|
327
320
|
.page {
|
|
328
321
|
padding-block: var(--helix-space-xl) var(--helix-space-2xl);
|
|
329
322
|
padding-inline: var(--helix-space-md);
|
|
@@ -336,22 +329,21 @@ helix-app-header {
|
|
|
336
329
|
|
|
337
330
|
/*
|
|
338
331
|
* **The escape hatch, and the reason a component names its parts.** The table
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* however specific that one is.
|
|
332
|
+
* tints a chosen row at the strength `Tag` rests at, and this page wants a
|
|
333
|
+
* ticked row easy to find from across the screen, a step past any token.
|
|
334
|
+
* `::part` reaches the boxes the component drew, with no fork, and a rule
|
|
335
|
+
* written out here beats the component's own, however specific that one is.
|
|
344
336
|
*
|
|
345
|
-
* **Two parts
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
337
|
+
* **Two parts, because a row has no box.** The row is `display: contents`, so
|
|
338
|
+
* one grid can align every column across every row, and the cells are what a
|
|
339
|
+
* selection is painted on. The table names both: the data cells and the cell
|
|
340
|
+
* holding the checkbox. Naming only the first leaves a pale stripe down the
|
|
341
|
+
* left of every chosen row.
|
|
350
342
|
*
|
|
351
343
|
* The values are still the library's, so a theme carries them like everything
|
|
352
|
-
* else. `primary-subtle
|
|
353
|
-
*
|
|
354
|
-
*
|
|
344
|
+
* else. `primary-subtle`, because `primary-surface` is the solid accent a
|
|
345
|
+
* button stands on, made for white text, so a row painted with it would put the
|
|
346
|
+
* table's own ink on a saturated fill.
|
|
355
347
|
*/
|
|
356
348
|
helix-data-table::part(cell-selected),
|
|
357
349
|
helix-data-table::part(select-selected) {
|
|
@@ -2,39 +2,40 @@
|
|
|
2
2
|
* The rows the overview draws.
|
|
3
3
|
*
|
|
4
4
|
* A local module and no network, so the starter runs with nothing behind it.
|
|
5
|
-
* Point `rows` at whatever you fetch and the table
|
|
6
|
-
* whole result and does the sorting, the filtering and the paging itself. Past
|
|
7
|
-
* the size a browser can hold, `mode="server"`
|
|
8
|
-
*
|
|
5
|
+
* Point `rows` at whatever you fetch and the table stays the same: it takes the
|
|
6
|
+
* whole result and does the sorting, the filtering, and the paging itself. Past
|
|
7
|
+
* the size a browser can hold, `mode="server"` hands the paging to you, one page
|
|
8
|
+
* at a time.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* One person on the roster.
|
|
13
13
|
*
|
|
14
|
-
* **A type alias
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* **A type alias, which TypeScript makes load-bearing here.** `rows` takes
|
|
15
|
+
* `Readonly<Record<string, unknown>>`, and an interface has no implicit index
|
|
16
|
+
* signature, so an interface of exactly these fields is not assignable to it.
|
|
17
|
+
* The error names the index signature, so it reads as though the data were
|
|
18
|
+
* wrong.
|
|
19
19
|
*/
|
|
20
20
|
export type Member = {
|
|
21
21
|
/**
|
|
22
22
|
* A stable identity, which is what `row-key` names.
|
|
23
23
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* With one, a sort moves each row's element whole, so focus and anything
|
|
25
|
+
* attached to a row go with it. Without one, a sort rewrites the cells in
|
|
26
|
+
* place and loses both.
|
|
26
27
|
*/
|
|
27
28
|
readonly id: string
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
+
* The name a row is found by.
|
|
30
31
|
*/
|
|
31
32
|
readonly name: string
|
|
32
33
|
/**
|
|
33
|
-
* A number
|
|
34
|
+
* A number, so the column sorts by size.
|
|
34
35
|
*
|
|
35
36
|
* A cell showing `2.4k` sorts as text unless the column's `compare` says what
|
|
36
|
-
* the value underneath is, which is
|
|
37
|
-
*
|
|
37
|
+
* the value underneath is, which is cheap to get right now and expensive to
|
|
38
|
+
* add later.
|
|
38
39
|
*/
|
|
39
40
|
readonly reviews: number
|
|
40
41
|
/**
|
|
@@ -68,8 +69,7 @@ export const teams: readonly string[] = [...new Set(members.map((one) => one.tea
|
|
|
68
69
|
/**
|
|
69
70
|
* The same roster as three figures, for the panel on the first screen.
|
|
70
71
|
*
|
|
71
|
-
* Derived
|
|
72
|
-
* does not show.
|
|
72
|
+
* Derived from the rows, so the panel and the table always agree.
|
|
73
73
|
*/
|
|
74
74
|
export const roster = {
|
|
75
75
|
/** How many rows the data view has. */
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helix diagnostics, which `instrumentation-client.ts` loads in development only.
|
|
3
|
+
*
|
|
4
|
+
* It finds the Helix mistakes that are valid CSS and therefore silent, such as
|
|
5
|
+
* a `::part()` naming a part nothing publishes, and an attribute value outside
|
|
6
|
+
* the set a component takes. Each finding prints once in DevTools, and a badge
|
|
7
|
+
* in the corner of the page lists them while there are any.
|
|
8
|
+
*
|
|
9
|
+
* **Checked against the Helix you installed**, from the lint data it ships, so
|
|
10
|
+
* nothing is loaded from the network.
|
|
11
|
+
*
|
|
12
|
+
* To print the findings in your terminal as well, run `npx helix diagnostics`
|
|
13
|
+
* from `@fusion.dev/helix-cli` beside the dev server, and add
|
|
14
|
+
* `sinks: { relay: true }` below.
|
|
15
|
+
*/
|
|
16
|
+
import { initDiagnostics } from '@fusion.dev/helix-diagnostics'
|
|
17
|
+
import lint from '@fusion.dev/helix/lint.json'
|
|
18
|
+
|
|
19
|
+
initDiagnostics({ environment: 'development', tiers: [{ lint }] })
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The documentation
|
|
2
|
+
* The documentation the starter links to.
|
|
3
3
|
*
|
|
4
|
-
* **One module, because
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* **One module, because links are what rots first in a starter.** A page that
|
|
5
|
+
* composes its own URLs ships a plausible-looking 404 to every project
|
|
6
|
+
* scaffolded from it, and it shows only when the link is followed. Here they
|
|
7
|
+
* are in one list you can open and check, and pointing the starter at a mirror
|
|
8
|
+
* or an internal copy is one edit.
|
|
9
9
|
*
|
|
10
|
-
* Checked
|
|
10
|
+
* Checked October 4, 2026: every entry answers 200.
|
|
11
11
|
*/
|
|
12
12
|
export const DOCS = {
|
|
13
13
|
/** How the elements are registered and written, which is the first page to read. */
|
|
14
14
|
elements: 'https://fusion.dev/helix/docs/using-the-elements',
|
|
15
15
|
/** What a `<form>` does with these controls, and what it cannot do. */
|
|
16
16
|
forms: 'https://fusion.dev/helix/docs/forms',
|
|
17
|
-
/** Every component, with its API, its parts and its examples. */
|
|
17
|
+
/** Every component, with its API, its parts, and its examples. */
|
|
18
18
|
gallery: 'https://fusion.dev/helix/components',
|
|
19
|
-
/** The light and dark pair, and the attribute that
|
|
19
|
+
/** The light and dark pair, and the attribute that sets which one shows. */
|
|
20
20
|
modes: 'https://fusion.dev/helix/docs/color-modes',
|
|
21
21
|
/** Reaching a component's parts from a page, which `app.css` does once. */
|
|
22
22
|
parts: 'https://fusion.dev/helix/docs/overriding-a-component',
|