@fusion.dev/helix-theme 0.0.0-dev → 0.0.3
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/dist/index.d.ts +3 -3
- package/dist/types.d.ts +23 -48
- package/dist/types.js +5 -9
- package/package.json +7 -2
- package/wasm/fusion_helix_theme.d.ts +4 -8
- package/wasm/fusion_helix_theme.js +4 -8
- package/wasm/fusion_helix_theme_bg.wasm +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ export interface ThemeEngine {
|
|
|
14
14
|
/**
|
|
15
15
|
* Reads a hex color into its OKLCH components.
|
|
16
16
|
*
|
|
17
|
-
* @throws when the string is not a hex color.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* @throws when the string is not a hex color. Returning a `NaN` triple
|
|
18
|
+
* instead is worse: every comparison against it is false, so a color that
|
|
19
|
+
* could not be read travels onward looking like one.
|
|
20
20
|
*/
|
|
21
21
|
hexToOklch(hex: string): Oklch;
|
|
22
22
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The shapes a consumer writes and the shapes they get back.
|
|
3
3
|
*
|
|
4
|
-
* **Declarations only
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* only about a *field name*, which is what `check:wasm` compares.
|
|
10
|
-
*
|
|
11
|
-
* The prose is kept whole from the files it came from. It is the argument for
|
|
12
|
-
* why each field exists, and it was never about how any of them was computed.
|
|
4
|
+
* **Declarations only.** The derivation is Rust, reached through WebAssembly, so
|
|
5
|
+
* what a JavaScript consumer needs from this package is the vocabulary rather
|
|
6
|
+
* than the solver. A type is erased at build time, so nothing here is a second
|
|
7
|
+
* implementation of anything: it cannot drift into disagreeing with the engine
|
|
8
|
+
* about an *answer*, only about a *field name*, which is what is compared.
|
|
13
9
|
*/
|
|
14
10
|
/** A color in OKLCH. Lightness 0 to 1, chroma from 0, hue in degrees. */
|
|
15
11
|
export interface Oklch {
|
|
@@ -24,7 +20,7 @@ export type Color = Oklch | string;
|
|
|
24
20
|
*
|
|
25
21
|
* Written as a relationship rather than a second color because a literal
|
|
26
22
|
* drifts out of relation the moment anybody rethemes, which is the failure of
|
|
27
|
-
* every palette with two hardcoded
|
|
23
|
+
* every palette with two hardcoded colors in it.
|
|
28
24
|
*/
|
|
29
25
|
export interface Relation {
|
|
30
26
|
/**
|
|
@@ -126,10 +122,6 @@ export interface ThemeIntent {
|
|
|
126
122
|
* **The one material choice that can invalidate the guarantee.** Contrast is
|
|
127
123
|
* measured against a known ground and a translucent surface does not have
|
|
128
124
|
* one, so a pair over it comes back `unverifiable` rather than measured.
|
|
129
|
-
*
|
|
130
|
-
* The audit found this half nearly done already: six declarations across two
|
|
131
|
-
* families, both already behind hooks, so material needed a policy token to
|
|
132
|
-
* default to and nothing else.
|
|
133
125
|
*/
|
|
134
126
|
material?: {
|
|
135
127
|
blur?: number;
|
|
@@ -138,12 +130,8 @@ export interface ThemeIntent {
|
|
|
138
130
|
/**
|
|
139
131
|
* The faces the theme is set in.
|
|
140
132
|
*
|
|
141
|
-
* **
|
|
142
|
-
*
|
|
143
|
-
* unreachable from intent while every color in the palette was one field
|
|
144
|
-
* away. Families are the half a consumer actually chooses; the size scale,
|
|
145
|
-
* the weights and the spacing are the half that is a system, and they are
|
|
146
|
-
* still fixed.
|
|
133
|
+
* **Families are the half a consumer chooses**; the size scale, the weights
|
|
134
|
+
* and the spacing are the half that is a system, and they stay fixed.
|
|
147
135
|
*
|
|
148
136
|
* `display` falls back to `body`, which is what the stylesheet already does:
|
|
149
137
|
* a theme with one face is the common case and should not have to say so
|
|
@@ -190,12 +178,7 @@ export interface ThemeIntent {
|
|
|
190
178
|
*/
|
|
191
179
|
namespace?: string;
|
|
192
180
|
/**
|
|
193
|
-
* How the theme's motion feels.
|
|
194
|
-
*
|
|
195
|
-
* **The other axis with no input at all**, alongside the half of type that is
|
|
196
|
-
* a system: nine tokens, four durations and five curves, and a brand with a
|
|
197
|
-
* snappy voice and one with a gentle one reached them the same way, which is
|
|
198
|
-
* to say not at all.
|
|
181
|
+
* How the theme's motion feels: nine tokens, four durations and five curves.
|
|
199
182
|
*
|
|
200
183
|
* `character` sets the curve every component reaches for by default and
|
|
201
184
|
* carries a duration multiplier with it, because the two are one decision: a
|
|
@@ -204,8 +187,7 @@ export interface ThemeIntent {
|
|
|
204
187
|
*
|
|
205
188
|
* `instant` is not scaled. It is 0 and means "do not animate", which is a
|
|
206
189
|
* statement rather than a duration, and it emits no curves at all: three
|
|
207
|
-
* easings for transitions of zero length is a contradiction
|
|
208
|
-
* allow through `scale: 0`.
|
|
190
|
+
* easings for transitions of zero length is a contradiction.
|
|
209
191
|
*
|
|
210
192
|
* `precise` is the one character that is not physical. The other three
|
|
211
193
|
* accelerate, settle or overshoot; linear reads as moved by a mechanism, and
|
|
@@ -222,8 +204,7 @@ export interface ThemeIntent {
|
|
|
222
204
|
* Chroma 0 is a dead gray and is the default, matching `primitives.css`,
|
|
223
205
|
* which records why: a fixed chroma is a rising *saturation* as a surface
|
|
224
206
|
* darkens, so a trace that looks right on a light page reads navy across a
|
|
225
|
-
* dark one.
|
|
226
|
-
* stylesheet had already rejected for that reason.
|
|
207
|
+
* dark one.
|
|
227
208
|
*/
|
|
228
209
|
neutral?: {
|
|
229
210
|
chroma?: number;
|
|
@@ -245,9 +226,8 @@ export interface ThemeIntent {
|
|
|
245
226
|
* rather than a comment asking nicely.
|
|
246
227
|
*
|
|
247
228
|
* `fill` and `space` produce the same edge and lift, which is none of
|
|
248
|
-
* either: the difference between them lives in the surface
|
|
249
|
-
* `density`, not here.
|
|
250
|
-
* looks like a bug until it is explained.
|
|
229
|
+
* either: the difference between them lives in the surface colors and in
|
|
230
|
+
* `density`, not here. Two values with one output reads as a bug and is not.
|
|
251
231
|
*/
|
|
252
232
|
separation?: {
|
|
253
233
|
floating?: 'border' | 'fill' | 'shadow';
|
|
@@ -352,10 +332,10 @@ export interface Pairing {
|
|
|
352
332
|
* measured and passed. Folding the two together is how a guarantee decays
|
|
353
333
|
* into a claim about the pairs that happened to be easy.
|
|
354
334
|
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
335
|
+
* Two producers: a pairing naming a token this theme does not emit, which a
|
|
336
|
+
* caller supplying their own `pairings` will legitimately do, and a ground
|
|
337
|
+
* the model marks unbounded, where what sits behind the surface is whatever
|
|
338
|
+
* the reader scrolled under it.
|
|
359
339
|
*/
|
|
360
340
|
status: 'fail' | 'pass' | 'unverifiable';
|
|
361
341
|
/**
|
|
@@ -369,13 +349,9 @@ export interface Pairing {
|
|
|
369
349
|
/**
|
|
370
350
|
* What a derivation produced.
|
|
371
351
|
*
|
|
372
|
-
* **No `intent
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
* by the oracle, and therefore never checked. Serialising it across the boundary
|
|
376
|
-
* means a `Serialize` on every shape in the vocabulary including three unions
|
|
377
|
-
* with hand-written readers, which is a day of work for a field with no caller.
|
|
378
|
-
* It goes back the moment one appears.
|
|
352
|
+
* **No resolved `intent` field.** Carrying one across the WebAssembly boundary
|
|
353
|
+
* means a `Serialize` on every shape in the vocabulary, three hand-read unions
|
|
354
|
+
* included, and no consumer has asked for it. It goes back when one does.
|
|
379
355
|
*/
|
|
380
356
|
export interface DerivedTheme {
|
|
381
357
|
/**
|
|
@@ -406,20 +382,19 @@ export interface DerivedTheme {
|
|
|
406
382
|
pairings: Pairing[];
|
|
407
383
|
/**
|
|
408
384
|
* The seed values a consumer must write for `helix/styles` to re-derive the
|
|
409
|
-
* halves this engine does not compute: the twenty-four series
|
|
385
|
+
* halves this engine does not compute: the twenty-four series colors, the
|
|
410
386
|
* spacing scale and the corner radii.
|
|
411
387
|
*
|
|
412
388
|
* **Data rather than only a line of CSS**, because the two consumers apply it
|
|
413
389
|
* differently. `toCss` renders a block; a page theming one panel writes the
|
|
414
390
|
* properties onto that element. Both read this, so neither can hold a
|
|
415
|
-
* different opinion about what the seed is
|
|
416
|
-
* marketing site's hand-written bridge had become.
|
|
391
|
+
* different opinion about what the seed is.
|
|
417
392
|
*/
|
|
418
393
|
seeds: Record<string, string>;
|
|
419
394
|
tokens: DerivedToken[];
|
|
420
395
|
/**
|
|
421
396
|
* Pairings that failed their contrast target, pinned values included.
|
|
422
|
-
* Rendered from `pairings
|
|
397
|
+
* Rendered from `pairings`.
|
|
423
398
|
*/
|
|
424
399
|
violations: string[];
|
|
425
400
|
}
|
package/dist/types.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The shapes a consumer writes and the shapes they get back.
|
|
3
3
|
*
|
|
4
|
-
* **Declarations only
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* only about a *field name*, which is what `check:wasm` compares.
|
|
10
|
-
*
|
|
11
|
-
* The prose is kept whole from the files it came from. It is the argument for
|
|
12
|
-
* why each field exists, and it was never about how any of them was computed.
|
|
4
|
+
* **Declarations only.** The derivation is Rust, reached through WebAssembly, so
|
|
5
|
+
* what a JavaScript consumer needs from this package is the vocabulary rather
|
|
6
|
+
* than the solver. A type is erased at build time, so nothing here is a second
|
|
7
|
+
* implementation of anything: it cannot drift into disagreeing with the engine
|
|
8
|
+
* about an *answer*, only about a *field name*, which is what is compared.
|
|
13
9
|
*/
|
|
14
10
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-theme",
|
|
3
3
|
"description": "Theme derivation engine. Computes a complete, contrast-guaranteed token set from intent inputs.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -26,9 +26,14 @@
|
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "tsc -p tsconfig.json",
|
|
28
28
|
"test": "cargo test -p fusion-helix-theme --manifest-path ../../Cargo.toml",
|
|
29
|
-
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
29
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
30
|
+
"wasm": "node scripts/build-wasm.mjs",
|
|
31
|
+
"wasm-check": "bun scripts/check-wasm.mjs"
|
|
30
32
|
},
|
|
31
33
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@fusion.dev/scripts": "0.0.0-dev"
|
|
36
|
+
},
|
|
32
37
|
"homepage": "https://fusion.dev",
|
|
33
38
|
"keywords": [
|
|
34
39
|
"theming",
|
|
@@ -11,9 +11,6 @@
|
|
|
11
11
|
* intent-in-CSS-out function would have it deriving twice for one keystroke.
|
|
12
12
|
* The result carries `css` keyed by selector, empty when none were asked for.
|
|
13
13
|
*
|
|
14
|
-
* For reference, the TypeScript engine this replaces took 39ms for the
|
|
15
|
-
* derivation alone, so the builder does less work than it did rather than more.
|
|
16
|
-
*
|
|
17
14
|
* `selectors` is a JSON array, keeping the boundary uniformly JSON in and JSON
|
|
18
15
|
* out rather than mixing in a bound array type for one argument.
|
|
19
16
|
*
|
|
@@ -27,11 +24,10 @@ export function derive(intent: string, selectors: string): string;
|
|
|
27
24
|
/**
|
|
28
25
|
* Reads a hex color into its OKLCH components, as JSON.
|
|
29
26
|
*
|
|
30
|
-
* **Throws
|
|
31
|
-
*
|
|
32
|
-
* that
|
|
33
|
-
*
|
|
34
|
-
* caller passing the value of a color input never sees this.
|
|
27
|
+
* **Throws rather than returning a `NaN` triple**, which is the decision
|
|
28
|
+
* `resolve` makes for a brand: every comparison against `NaN` is false, so a
|
|
29
|
+
* color that could not be read travels onward looking like a color. A caller
|
|
30
|
+
* passing the value of a color input never sees this.
|
|
35
31
|
*
|
|
36
32
|
* # Errors
|
|
37
33
|
*
|
|
@@ -10,9 +10,6 @@
|
|
|
10
10
|
* intent-in-CSS-out function would have it deriving twice for one keystroke.
|
|
11
11
|
* The result carries `css` keyed by selector, empty when none were asked for.
|
|
12
12
|
*
|
|
13
|
-
* For reference, the TypeScript engine this replaces took 39ms for the
|
|
14
|
-
* derivation alone, so the builder does less work than it did rather than more.
|
|
15
|
-
*
|
|
16
13
|
* `selectors` is a JSON array, keeping the boundary uniformly JSON in and JSON
|
|
17
14
|
* out rather than mixing in a bound array type for one argument.
|
|
18
15
|
*
|
|
@@ -50,11 +47,10 @@ export function derive(intent, selectors) {
|
|
|
50
47
|
/**
|
|
51
48
|
* Reads a hex color into its OKLCH components, as JSON.
|
|
52
49
|
*
|
|
53
|
-
* **Throws
|
|
54
|
-
*
|
|
55
|
-
* that
|
|
56
|
-
*
|
|
57
|
-
* caller passing the value of a color input never sees this.
|
|
50
|
+
* **Throws rather than returning a `NaN` triple**, which is the decision
|
|
51
|
+
* `resolve` makes for a brand: every comparison against `NaN` is false, so a
|
|
52
|
+
* color that could not be read travels onward looking like a color. A caller
|
|
53
|
+
* passing the value of a color input never sees this.
|
|
58
54
|
*
|
|
59
55
|
* # Errors
|
|
60
56
|
*
|
|
Binary file
|