@oxyhq/bloom 0.7.7 → 0.8.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/lib/commonjs/normalize-colors.d.js +2 -0
- package/lib/commonjs/normalize-colors.d.js.map +1 -0
- package/lib/commonjs/theme/apply-dark-class.js +8 -24
- package/lib/commonjs/theme/apply-dark-class.js.map +1 -1
- package/lib/commonjs/theme/build-theme.js +39 -61
- package/lib/commonjs/theme/build-theme.js.map +1 -1
- package/lib/commonjs/theme/color-presets.js +9 -9
- package/lib/commonjs/theme/color-scope/index.web.js +7 -14
- package/lib/commonjs/theme/color-scope/index.web.js.map +1 -1
- package/lib/commonjs/theme/color-scope/style-builder.js +7 -6
- package/lib/commonjs/theme/color-scope/style-builder.js.map +1 -1
- package/lib/commonjs/theme/color-space.js +76 -0
- package/lib/commonjs/theme/color-space.js.map +1 -0
- package/lib/commonjs/theme/index.js +0 -6
- package/lib/commonjs/theme/index.js.map +1 -1
- package/lib/commonjs/theme/native-root-vars.native.js +28 -18
- package/lib/commonjs/theme/native-root-vars.native.js.map +1 -1
- package/lib/commonjs/theme/preset-vars.js +20 -152
- package/lib/commonjs/theme/preset-vars.js.map +1 -1
- package/lib/commonjs/theme/token-registry.js +123 -0
- package/lib/commonjs/theme/token-registry.js.map +1 -0
- package/lib/module/normalize-colors.d.js +2 -0
- package/lib/module/normalize-colors.d.js.map +1 -0
- package/lib/module/theme/apply-dark-class.js +8 -19
- package/lib/module/theme/apply-dark-class.js.map +1 -1
- package/lib/module/theme/build-theme.js +39 -61
- package/lib/module/theme/build-theme.js.map +1 -1
- package/lib/module/theme/color-presets.js +9 -9
- package/lib/module/theme/color-scope/index.web.js +7 -14
- package/lib/module/theme/color-scope/index.web.js.map +1 -1
- package/lib/module/theme/color-scope/style-builder.js +7 -6
- package/lib/module/theme/color-scope/style-builder.js.map +1 -1
- package/lib/module/theme/color-space.js +69 -0
- package/lib/module/theme/color-space.js.map +1 -0
- package/lib/module/theme/index.js +1 -1
- package/lib/module/theme/index.js.map +1 -1
- package/lib/module/theme/native-root-vars.native.js +29 -18
- package/lib/module/theme/native-root-vars.native.js.map +1 -1
- package/lib/module/theme/preset-vars.js +19 -150
- package/lib/module/theme/preset-vars.js.map +1 -1
- package/lib/module/theme/token-registry.js +113 -0
- package/lib/module/theme/token-registry.js.map +1 -0
- package/lib/typescript/commonjs/theme/apply-dark-class.d.ts +5 -10
- package/lib/typescript/commonjs/theme/apply-dark-class.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/build-theme.d.ts +1 -1
- package/lib/typescript/commonjs/theme/build-theme.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-presets.d.ts +9 -9
- package/lib/typescript/commonjs/theme/color-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-scope/style-builder.d.ts +5 -2
- package/lib/typescript/commonjs/theme/color-scope/style-builder.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-space.d.ts +28 -0
- package/lib/typescript/commonjs/theme/color-space.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/index.d.ts +1 -2
- package/lib/typescript/commonjs/theme/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/native-root-vars.native.d.ts +25 -15
- package/lib/typescript/commonjs/theme/native-root-vars.native.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/preset-vars.d.ts +11 -74
- package/lib/typescript/commonjs/theme/preset-vars.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/token-registry.d.ts +53 -0
- package/lib/typescript/commonjs/theme/token-registry.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/types.d.ts +3 -0
- package/lib/typescript/commonjs/theme/types.d.ts.map +1 -1
- package/lib/typescript/module/theme/apply-dark-class.d.ts +5 -10
- package/lib/typescript/module/theme/apply-dark-class.d.ts.map +1 -1
- package/lib/typescript/module/theme/build-theme.d.ts +1 -1
- package/lib/typescript/module/theme/build-theme.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-presets.d.ts +9 -9
- package/lib/typescript/module/theme/color-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-scope/style-builder.d.ts +5 -2
- package/lib/typescript/module/theme/color-scope/style-builder.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-space.d.ts +28 -0
- package/lib/typescript/module/theme/color-space.d.ts.map +1 -0
- package/lib/typescript/module/theme/index.d.ts +1 -2
- package/lib/typescript/module/theme/index.d.ts.map +1 -1
- package/lib/typescript/module/theme/native-root-vars.native.d.ts +25 -15
- package/lib/typescript/module/theme/native-root-vars.native.d.ts.map +1 -1
- package/lib/typescript/module/theme/preset-vars.d.ts +11 -74
- package/lib/typescript/module/theme/preset-vars.d.ts.map +1 -1
- package/lib/typescript/module/theme/token-registry.d.ts +53 -0
- package/lib/typescript/module/theme/token-registry.d.ts.map +1 -0
- package/lib/typescript/module/theme/types.d.ts +3 -0
- package/lib/typescript/module/theme/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/BloomColorScope.test.tsx +5 -5
- package/src/__tests__/BloomThemeProvider.test.tsx +4 -3
- package/src/__tests__/apply-dark-class.test.ts +26 -21
- package/src/__tests__/native-root-vars.test.ts +8 -7
- package/src/__tests__/preset-vars.test.ts +31 -77
- package/src/__tests__/theme.test.ts +6 -6
- package/src/normalize-colors.d.ts +22 -0
- package/src/react-native-css.d.ts +3 -3
- package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +574 -0
- package/src/theme/__tests__/__snapshots__/visual-gallery.test.tsx.snap +838 -0
- package/src/theme/__tests__/color-space.test.ts +28 -0
- package/src/theme/__tests__/golden-tokens.test.ts +33 -0
- package/src/theme/__tests__/runtime-contract.test.ts +49 -0
- package/src/theme/__tests__/token-registry.test.ts +30 -0
- package/src/theme/__tests__/visual-gallery.test.tsx +10 -0
- package/src/theme/apply-dark-class.ts +8 -17
- package/src/theme/build-theme.ts +39 -67
- package/src/theme/color-presets.ts +9 -9
- package/src/theme/color-scope/index.web.tsx +7 -14
- package/src/theme/color-scope/style-builder.ts +7 -4
- package/src/theme/color-space.ts +56 -0
- package/src/theme/index.ts +1 -6
- package/src/theme/native-root-vars.native.ts +28 -18
- package/src/theme/preset-vars.ts +17 -178
- package/src/theme/token-registry.ts +159 -0
- package/src/theme/types.ts +3 -0
|
@@ -5,10 +5,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.applyPresetVarsToDocument = applyPresetVarsToDocument;
|
|
7
7
|
exports.getPresetVars = getPresetVars;
|
|
8
|
-
exports.hslTripletToRgb = hslTripletToRgb;
|
|
9
|
-
exports.toWebColorValue = toWebColorValue;
|
|
10
8
|
var _reactNative = require("react-native");
|
|
11
9
|
var _colorPresets = require("./color-presets.js");
|
|
10
|
+
var _tokenRegistry = require("./token-registry.js");
|
|
11
|
+
// Circular at the module graph level (`token-registry` imports `getPresetVars`
|
|
12
|
+
// from here), but safe: `getResolvedTokens` is only referenced inside the
|
|
13
|
+
// `applyPresetVarsToDocument` function body — i.e. at call time, after both
|
|
14
|
+
// modules have finished evaluating — never during module initialization.
|
|
15
|
+
|
|
12
16
|
function extractHue(hslVar) {
|
|
13
17
|
return parseInt(hslVar.split(' ')[0] ?? '0', 10);
|
|
14
18
|
}
|
|
@@ -16,139 +20,6 @@ function extractSat(hslVar) {
|
|
|
16
20
|
return parseInt(hslVar.split(' ')[1] ?? '0', 10);
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
/**
|
|
20
|
-
* Convert a shadcn-style HSL triple (`'H S% L%'`, optionally with an alpha tail
|
|
21
|
-
* `'H S% L% / A'`) into an sRGB `rgb(...)` string.
|
|
22
|
-
*
|
|
23
|
-
* Why rgb and not hsl (the native alpha-utility bug this fixes)
|
|
24
|
-
* -------------------------------------------------------------
|
|
25
|
-
* Tailwind v4 compiles an alpha-on-theme-color utility (`bg-primary/10`) into a
|
|
26
|
-
* `color-mix(... var(--color-primary) 10%, transparent)` declaration. On native,
|
|
27
|
-
* react-native-css resolves that `color-mix` at runtime via `colorjs.io/fn`, but
|
|
28
|
-
* its `color-mix` implementation registers ONLY the `sRGB`, `P3`, and `OKLab`
|
|
29
|
-
* color spaces — never `HSL`. So if `--color-primary` resolves to an `hsl(...)`
|
|
30
|
-
* string, `parse('hsl(...)')` throws, the mix is swallowed, and the utility
|
|
31
|
-
* silently produces no color. Emitting the resolved var as `rgb(...)` (a space
|
|
32
|
-
* colorjs.io always has registered) makes the alpha utilities resolve on native,
|
|
33
|
-
* matching web. Full (non-alpha) utilities already worked because React Native's
|
|
34
|
-
* native color parser handles `hsl()` directly; only `color-mix` was affected.
|
|
35
|
-
*
|
|
36
|
-
* Output is space-separated channels (`rgb(31 153 239)`), the modern CSS syntax
|
|
37
|
-
* parsed by both `colorjs.io/fn` (with only sRGB/P3/OKLab registered) and
|
|
38
|
-
* react-native-web / browsers. An alpha tail emits `rgb(r g b / a)`, likewise
|
|
39
|
-
* parsed by both.
|
|
40
|
-
*
|
|
41
|
-
* Pure function — standard HSL→sRGB conversion, channels rounded to integers.
|
|
42
|
-
* Tolerates a `deg` suffix on the hue and `%` suffixes on saturation/lightness.
|
|
43
|
-
*/
|
|
44
|
-
function hslTripletToRgb(triplet) {
|
|
45
|
-
const [colorPart, alphaPart] = triplet.split('/').map(part => part.trim());
|
|
46
|
-
const channels = (colorPart ?? '').split(/\s+/).filter(Boolean);
|
|
47
|
-
const hue = parseFloat((channels[0] ?? '0').replace(/deg$/i, ''));
|
|
48
|
-
const sat = parseFloat((channels[1] ?? '0').replace('%', '')) / 100;
|
|
49
|
-
const light = parseFloat((channels[2] ?? '0').replace('%', '')) / 100;
|
|
50
|
-
const h = Number.isFinite(hue) ? hue : 0;
|
|
51
|
-
const s = Number.isFinite(sat) ? sat : 0;
|
|
52
|
-
const l = Number.isFinite(light) ? light : 0;
|
|
53
|
-
const chroma = (1 - Math.abs(2 * l - 1)) * s;
|
|
54
|
-
const huePrime = (h % 360 + 360) % 360 / 60;
|
|
55
|
-
const second = chroma * (1 - Math.abs(huePrime % 2 - 1));
|
|
56
|
-
let r = 0;
|
|
57
|
-
let g = 0;
|
|
58
|
-
let b = 0;
|
|
59
|
-
if (huePrime < 1) {
|
|
60
|
-
[r, g, b] = [chroma, second, 0];
|
|
61
|
-
} else if (huePrime < 2) {
|
|
62
|
-
[r, g, b] = [second, chroma, 0];
|
|
63
|
-
} else if (huePrime < 3) {
|
|
64
|
-
[r, g, b] = [0, chroma, second];
|
|
65
|
-
} else if (huePrime < 4) {
|
|
66
|
-
[r, g, b] = [0, second, chroma];
|
|
67
|
-
} else if (huePrime < 5) {
|
|
68
|
-
[r, g, b] = [second, 0, chroma];
|
|
69
|
-
} else {
|
|
70
|
-
[r, g, b] = [chroma, 0, second];
|
|
71
|
-
}
|
|
72
|
-
const match = l - chroma / 2;
|
|
73
|
-
const red = Math.round((r + match) * 255);
|
|
74
|
-
const green = Math.round((g + match) * 255);
|
|
75
|
-
const blue = Math.round((b + match) * 255);
|
|
76
|
-
if (alphaPart !== undefined && alphaPart !== '') {
|
|
77
|
-
const alpha = alphaPart.endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart);
|
|
78
|
-
const safeAlpha = Number.isFinite(alpha) ? alpha : 1;
|
|
79
|
-
return `rgb(${red} ${green} ${blue} / ${safeAlpha})`;
|
|
80
|
-
}
|
|
81
|
-
return `rgb(${red} ${green} ${blue})`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Prefix that marks a Tailwind v4 resolved color var (`--color-primary`). These
|
|
86
|
-
* are already emitted as full `rgb(...)` colors by `getPresetVars` and must be
|
|
87
|
-
* written to web verbatim — wrapping them would corrupt the value.
|
|
88
|
-
*/
|
|
89
|
-
const RESOLVED_COLOR_VAR_PREFIX = '--color-';
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Matches a shadcn-style raw HSL triple — `H S% L%`, optionally with an alpha
|
|
93
|
-
* tail `H S% L% / A`. The value starts with a digit (or a leading `-`) and
|
|
94
|
-
* carries at least one `%` (the saturation/lightness units), which together
|
|
95
|
-
* distinguish a bare triple from an already-resolved CSS color (`rgb(...)`,
|
|
96
|
-
* `hsl(...)`, `#fff`, named colors) or a unitless/length token (`--radius`).
|
|
97
|
-
* Mirrors the triple shape parsed by `hslTripletToRgb`.
|
|
98
|
-
*/
|
|
99
|
-
const RAW_HSL_TRIPLE = /^-?\d[\d.]*\s+[\d.]+%/;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Transform a single preset var into the value to write to a WEB element
|
|
103
|
-
* (`document.documentElement` or a `BloomColorScope` subtree element).
|
|
104
|
-
*
|
|
105
|
-
* The web apps (Vite + Tailwind v4 + shadcn) compile their `@theme inline`
|
|
106
|
-
* block so the color utilities reference the BASE token directly — e.g.
|
|
107
|
-
* `.bg-background { background-color: var(--background) }`. So on web the base
|
|
108
|
-
* `--x` tokens MUST resolve to a COMPLETE CSS color; a bare HSL triple
|
|
109
|
-
* (`185 50% 5%`) is invalid as a `background-color` value and renders
|
|
110
|
-
* transparent (the production incident this fixes). We therefore wrap raw
|
|
111
|
-
* triples in `hsl(...)`, preserving the exact preset color math (and any `/ A`
|
|
112
|
-
* alpha tail, valid in modern `hsl(H S% L% / A)` syntax) with zero rounding
|
|
113
|
-
* drift.
|
|
114
|
-
*
|
|
115
|
-
* Values that are already full colors pass through unchanged:
|
|
116
|
-
* - `--color-*` resolved vars (already `rgb(...)` from `getPresetVars`),
|
|
117
|
-
* - any value not shaped like a raw HSL triple (`--radius: 0.5rem`,
|
|
118
|
-
* pre-resolved `rgb(...)`/`hsl(...)`, etc.).
|
|
119
|
-
*
|
|
120
|
-
* NATIVE never calls this — `getPresetVars` returns raw triples verbatim and
|
|
121
|
-
* `native-root-vars.native.ts` writes them through bloom's `hsl(var(--x))`
|
|
122
|
-
* native `global.css` indirection. Pure function — no side effects — so it is
|
|
123
|
-
* unit-testable in isolation.
|
|
124
|
-
*/
|
|
125
|
-
function toWebColorValue(key, value) {
|
|
126
|
-
if (key.startsWith(RESOLVED_COLOR_VAR_PREFIX)) return value;
|
|
127
|
-
if (!RAW_HSL_TRIPLE.test(value)) return value;
|
|
128
|
-
return `hsl(${value})`;
|
|
129
|
-
}
|
|
130
|
-
const RESOLVED_COLOR_MAP = {
|
|
131
|
-
'--background': '--color-background',
|
|
132
|
-
'--foreground': '--color-foreground',
|
|
133
|
-
'--primary': '--color-primary',
|
|
134
|
-
'--primary-foreground': '--color-primary-foreground',
|
|
135
|
-
'--secondary': '--color-secondary',
|
|
136
|
-
'--secondary-foreground': '--color-secondary-foreground',
|
|
137
|
-
'--muted': '--color-muted',
|
|
138
|
-
'--muted-foreground': '--color-muted-foreground',
|
|
139
|
-
'--accent': '--color-accent',
|
|
140
|
-
'--accent-foreground': '--color-accent-foreground',
|
|
141
|
-
'--destructive': '--color-destructive',
|
|
142
|
-
'--border': '--color-border',
|
|
143
|
-
'--input': '--color-input',
|
|
144
|
-
'--ring': '--color-ring',
|
|
145
|
-
'--popover': '--color-popover',
|
|
146
|
-
'--popover-foreground': '--color-popover-foreground',
|
|
147
|
-
'--surface': '--color-surface',
|
|
148
|
-
'--surface-foreground': '--color-surface-foreground',
|
|
149
|
-
'--card': '--color-card',
|
|
150
|
-
'--card-foreground': '--color-card-foreground'
|
|
151
|
-
};
|
|
152
23
|
/**
|
|
153
24
|
* Bloom's base preset tokens extended with the surface/card/chart/sidebar
|
|
154
25
|
* tokens that apps layer on top of the core shadcn palette. Synthesized from
|
|
@@ -156,8 +27,13 @@ const RESOLVED_COLOR_MAP = {
|
|
|
156
27
|
*
|
|
157
28
|
* This is the single source of truth for extended theming vars — consumer apps
|
|
158
29
|
* must not redefine these per-app.
|
|
30
|
+
*
|
|
31
|
+
* Values are platform-agnostic **raw HSL triples** (`'185 100% 20%'`, optionally
|
|
32
|
+
* with a `/ A` alpha tail). The single canonical resolver `getResolvedTokens`
|
|
33
|
+
* (in `token-registry.ts`) converts these to sRGB `rgb(...)` for BOTH web and
|
|
34
|
+
* native runtime writes — this function only produces the raw triple map.
|
|
159
35
|
*/
|
|
160
|
-
function getPresetVars(colorName, mode
|
|
36
|
+
function getPresetVars(colorName, mode) {
|
|
161
37
|
const preset = _colorPresets.APP_COLOR_PRESETS[colorName];
|
|
162
38
|
const base = mode === 'light' ? preset.light : preset.dark;
|
|
163
39
|
const get = key => base[key] ?? '0 0% 0%';
|
|
@@ -187,15 +63,7 @@ function getPresetVars(colorName, mode, options = {}) {
|
|
|
187
63
|
'--sidebar-border': get('--border'),
|
|
188
64
|
'--sidebar-ring': get('--ring')
|
|
189
65
|
};
|
|
190
|
-
|
|
191
|
-
const resolved = {
|
|
192
|
-
...extended
|
|
193
|
-
};
|
|
194
|
-
for (const [rawKey, colorKey] of Object.entries(RESOLVED_COLOR_MAP)) {
|
|
195
|
-
const value = extended[rawKey];
|
|
196
|
-
if (value) resolved[colorKey] = hslTripletToRgb(value);
|
|
197
|
-
}
|
|
198
|
-
return resolved;
|
|
66
|
+
return extended;
|
|
199
67
|
}
|
|
200
68
|
|
|
201
69
|
/**
|
|
@@ -204,17 +72,17 @@ function getPresetVars(colorName, mode, options = {}) {
|
|
|
204
72
|
* call this only when an app needs the extended (card/chart/sidebar) tokens on
|
|
205
73
|
* the document root.
|
|
206
74
|
*
|
|
207
|
-
*
|
|
208
|
-
* `
|
|
209
|
-
*
|
|
210
|
-
*
|
|
75
|
+
* Tokens are resolved to sRGB `rgb(...)` via the single canonical
|
|
76
|
+
* `getResolvedTokens` pipeline, so `var(--x)` — the form Tailwind v4
|
|
77
|
+
* `@theme inline` compiles its color utilities to — resolves directly to a
|
|
78
|
+
* valid color on web.
|
|
211
79
|
*/
|
|
212
|
-
function applyPresetVarsToDocument(colorName, mode
|
|
80
|
+
function applyPresetVarsToDocument(colorName, mode) {
|
|
213
81
|
if (_reactNative.Platform.OS !== 'web' || typeof document === 'undefined') return;
|
|
214
|
-
const vars =
|
|
82
|
+
const vars = (0, _tokenRegistry.getResolvedTokens)(colorName, mode);
|
|
215
83
|
const root = document.documentElement.style;
|
|
216
84
|
for (const [key, value] of Object.entries(vars)) {
|
|
217
|
-
root.setProperty(key,
|
|
85
|
+
root.setProperty(key, value);
|
|
218
86
|
}
|
|
219
87
|
}
|
|
220
88
|
//# sourceMappingURL=preset-vars.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_colorPresets","extractHue","hslVar","parseInt","split","extractSat","
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_colorPresets","_tokenRegistry","extractHue","hslVar","parseInt","split","extractSat","getPresetVars","colorName","mode","preset","APP_COLOR_PRESETS","base","light","dark","get","key","primary","foreground","hue","sat","Math","min","isDark","extended","applyPresetVarsToDocument","Platform","OS","document","vars","getResolvedTokens","root","documentElement","style","value","Object","entries","setProperty"],"sourceRoot":"../../../src","sources":["theme/preset-vars.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "APP_COLOR_NAMES", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _colorPresets.APP_COLOR_NAMES;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.CANONICAL_TOKENS = void 0;
|
|
13
|
+
exports.getResolvedTokens = getResolvedTokens;
|
|
14
|
+
exports.hslToSrgb = hslToSrgb;
|
|
15
|
+
var _colorPresets = require("./color-presets.js");
|
|
16
|
+
var _presetVars = require("./preset-vars.js");
|
|
17
|
+
/**
|
|
18
|
+
* The canonical set of Bloom theme token names — WITHOUT the leading `--`.
|
|
19
|
+
*
|
|
20
|
+
* This is the single source of truth for which tokens a preset produces. It
|
|
21
|
+
* covers exactly the keys returned by `getPresetVars(name, mode)` (the base
|
|
22
|
+
* shadcn palette plus the synthesized extended tokens: card/chart/content-area/
|
|
23
|
+
* sidebar-*). The list is intentionally hand-maintained and verified by
|
|
24
|
+
* `token-registry.test.ts` against the live `getPresetVars('oxy', 'light')`
|
|
25
|
+
* output, so any drift in the preset shape fails CI.
|
|
26
|
+
*
|
|
27
|
+
* Order mirrors `getPresetVars`'s insertion order: base tokens first (in the
|
|
28
|
+
* order they appear in the preset data), then the synthesized extended tokens.
|
|
29
|
+
*/
|
|
30
|
+
const CANONICAL_TOKENS = exports.CANONICAL_TOKENS = ['background', 'foreground', 'surface', 'surface-foreground', 'popover', 'popover-foreground', 'primary', 'primary-foreground', 'secondary', 'secondary-foreground', 'muted', 'muted-foreground', 'accent', 'accent-foreground', 'destructive', 'border', 'input', 'ring', 'sidebar', 'card', 'card-foreground', 'chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5', 'content-area', 'sidebar-foreground', 'sidebar-primary', 'sidebar-primary-foreground', 'sidebar-accent', 'sidebar-accent-foreground', 'sidebar-border', 'sidebar-ring'];
|
|
31
|
+
|
|
32
|
+
/** A canonical token name (no leading `--`). */
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Matches a shadcn-style raw HSL triple — `H S% L%`, optionally with an alpha
|
|
36
|
+
* tail `H S% L% / A`. The value starts with a digit (or a leading `-`) and
|
|
37
|
+
* carries at least one `%` (the saturation/lightness units), which distinguishes
|
|
38
|
+
* a bare triple from an already-resolved color (`rgb(...)`, `#fff`) or a
|
|
39
|
+
* unitless/length token (`--radius: 0.5rem`).
|
|
40
|
+
*/
|
|
41
|
+
const RAW_HSL_TRIPLE = /^-?\d[\d.]*\s+[\d.]+%/;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Convert a shadcn-style HSL triple (`'H S% L%'`, optionally with an alpha tail
|
|
45
|
+
* `'H S% L% / A'`) into an sRGB `rgb(...)` string.
|
|
46
|
+
*
|
|
47
|
+
* Standard HSL→sRGB math with integer-rounded channels and modern
|
|
48
|
+
* space-separated output (`rgb(r g b)` / `rgb(r g b / a)`). This is the SINGLE
|
|
49
|
+
* conversion the whole library uses — web document writes, web scope vars, and
|
|
50
|
+
* native `rootVariables` all flow through `getResolvedTokens`, which calls this.
|
|
51
|
+
* The byte-for-byte output is frozen by the golden parity fixture
|
|
52
|
+
* (`__fixtures__/golden-resolved-tokens.json`), so the visible palette cannot
|
|
53
|
+
* drift.
|
|
54
|
+
*
|
|
55
|
+
* Task 2's `oklchToSrgb` (in `color-space.ts`) stays available for a FUTURE
|
|
56
|
+
* OKLCH re-authoring of the seed palette; it is intentionally NOT used here —
|
|
57
|
+
* routing through OKLCH would shift the rounded channels off the frozen palette.
|
|
58
|
+
*
|
|
59
|
+
* Pure function — no side effects.
|
|
60
|
+
*/
|
|
61
|
+
function hslToSrgb(triple) {
|
|
62
|
+
const [colorPart, alphaPart] = triple.split('/').map(part => part.trim());
|
|
63
|
+
const channels = (colorPart ?? '').split(/\s+/).filter(Boolean);
|
|
64
|
+
const hue = parseFloat((channels[0] ?? '0').replace(/deg$/i, ''));
|
|
65
|
+
const sat = parseFloat((channels[1] ?? '0').replace('%', '')) / 100;
|
|
66
|
+
const light = parseFloat((channels[2] ?? '0').replace('%', '')) / 100;
|
|
67
|
+
const h = Number.isFinite(hue) ? hue : 0;
|
|
68
|
+
const s = Number.isFinite(sat) ? sat : 0;
|
|
69
|
+
const l = Number.isFinite(light) ? light : 0;
|
|
70
|
+
const chroma = (1 - Math.abs(2 * l - 1)) * s;
|
|
71
|
+
const huePrime = (h % 360 + 360) % 360 / 60;
|
|
72
|
+
const second = chroma * (1 - Math.abs(huePrime % 2 - 1));
|
|
73
|
+
let r = 0;
|
|
74
|
+
let g = 0;
|
|
75
|
+
let b = 0;
|
|
76
|
+
if (huePrime < 1) {
|
|
77
|
+
[r, g, b] = [chroma, second, 0];
|
|
78
|
+
} else if (huePrime < 2) {
|
|
79
|
+
[r, g, b] = [second, chroma, 0];
|
|
80
|
+
} else if (huePrime < 3) {
|
|
81
|
+
[r, g, b] = [0, chroma, second];
|
|
82
|
+
} else if (huePrime < 4) {
|
|
83
|
+
[r, g, b] = [0, second, chroma];
|
|
84
|
+
} else if (huePrime < 5) {
|
|
85
|
+
[r, g, b] = [second, 0, chroma];
|
|
86
|
+
} else {
|
|
87
|
+
[r, g, b] = [chroma, 0, second];
|
|
88
|
+
}
|
|
89
|
+
const match = l - chroma / 2;
|
|
90
|
+
const red = Math.round((r + match) * 255);
|
|
91
|
+
const green = Math.round((g + match) * 255);
|
|
92
|
+
const blue = Math.round((b + match) * 255);
|
|
93
|
+
if (alphaPart !== undefined && alphaPart !== '') {
|
|
94
|
+
const alpha = alphaPart.endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart);
|
|
95
|
+
const safeAlpha = Number.isFinite(alpha) ? alpha : 1;
|
|
96
|
+
return `rgb(${red} ${green} ${blue} / ${safeAlpha})`;
|
|
97
|
+
}
|
|
98
|
+
return `rgb(${red} ${green} ${blue})`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Resolve a preset's canonical runtime color tokens to sRGB `rgb(...)` strings.
|
|
103
|
+
*
|
|
104
|
+
* THE single source of runtime color tokens for the whole library, on BOTH web
|
|
105
|
+
* and native. Takes the raw triple map from `getPresetVars(preset, mode)` (base
|
|
106
|
+
* + extended) and converts every value that looks like an HSL triple via
|
|
107
|
+
* `hslToSrgb`. Non-triple values (already-resolved colors, length/radius tokens)
|
|
108
|
+
* pass through unchanged. Keys retain the `--` prefix, so each `--x` token IS a
|
|
109
|
+
* full CSS color — no resolved-color companion universe, no per-platform wrapping.
|
|
110
|
+
*
|
|
111
|
+
* The result is frozen by the golden parity fixture
|
|
112
|
+
* (`__fixtures__/golden-resolved-tokens.json`), guaranteeing the visible palette
|
|
113
|
+
* matches the previous resolved-color pipeline byte-for-byte.
|
|
114
|
+
*/
|
|
115
|
+
function getResolvedTokens(preset, mode) {
|
|
116
|
+
const raw = (0, _presetVars.getPresetVars)(preset, mode);
|
|
117
|
+
const resolved = {};
|
|
118
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
119
|
+
resolved[key] = RAW_HSL_TRIPLE.test(value) ? hslToSrgb(value) : value;
|
|
120
|
+
}
|
|
121
|
+
return resolved;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=token-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_colorPresets","require","_presetVars","CANONICAL_TOKENS","exports","RAW_HSL_TRIPLE","hslToSrgb","triple","colorPart","alphaPart","split","map","part","trim","channels","filter","Boolean","hue","parseFloat","replace","sat","light","h","Number","isFinite","s","l","chroma","Math","abs","huePrime","second","r","g","b","match","red","round","green","blue","undefined","alpha","endsWith","safeAlpha","getResolvedTokens","preset","mode","raw","getPresetVars","resolved","key","value","Object","entries","test"],"sourceRoot":"../../../src","sources":["theme/token-registry.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["normalize-colors.d.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -2,12 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
4
|
import { APP_COLOR_PRESETS } from "./color-presets.js";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
// Re-exported so the web var-contract helper is reachable from this file (the
|
|
8
|
-
// home of the web write path). Defined in `preset-vars.ts` next to the related
|
|
9
|
-
// HSL parsing so native (which never imports this module) doesn't pull it in.
|
|
10
|
-
export { toWebColorValue } from "./preset-vars.js";
|
|
5
|
+
import { getResolvedTokens } from "./token-registry.js";
|
|
11
6
|
export function applyDarkClass(resolved) {
|
|
12
7
|
if (Platform.OS === 'web' && typeof document !== 'undefined') {
|
|
13
8
|
document.documentElement.classList.toggle('dark', resolved === 'dark');
|
|
@@ -22,28 +17,22 @@ export function applyDarkClass(resolved) {
|
|
|
22
17
|
* -------------------------------------------------------------------
|
|
23
18
|
* The shadcn/Tailwind-v4 web apps compile their color utilities to reference the
|
|
24
19
|
* BASE token directly (`.bg-background { background-color: var(--background) }`),
|
|
25
|
-
* so on web the base `--x` tokens MUST be FULL CSS colors.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* unchanged. See `toWebColorValue`.
|
|
20
|
+
* so on web the base `--x` tokens MUST be FULL CSS colors. `getResolvedTokens`
|
|
21
|
+
* returns every canonical token already resolved to an sRGB `rgb(...)` string,
|
|
22
|
+
* so `var(--x)` resolves to a valid color directly — no per-value wrapping. The
|
|
23
|
+
* same rgb values feed native (`color-mix` alpha utilities resolve on sRGB), so
|
|
24
|
+
* web and native share one canonical token pipeline.
|
|
31
25
|
*
|
|
32
|
-
* NATIVE writes the SAME tokens as RAW HSL triples (no `hsl()` wrapper) via
|
|
33
|
-
* `rootVariables` (`native-root-vars.native.ts`), consumed through bloom's
|
|
34
|
-
* native `global.css` `hsl(var(--x))` indirection — that path is untouched here.
|
|
35
26
|
* Includes extended tokens (card, chart-*, content-area, sidebar-*) so consumer
|
|
36
27
|
* apps don't need to synthesize them.
|
|
37
28
|
*/
|
|
38
29
|
export function applyColorPresetVars(preset, resolved) {
|
|
39
30
|
if (Platform.OS !== 'web' || typeof document === 'undefined') return;
|
|
40
31
|
if (!APP_COLOR_PRESETS[preset]) return;
|
|
41
|
-
const vars =
|
|
42
|
-
includeResolvedColorVars: true
|
|
43
|
-
});
|
|
32
|
+
const vars = getResolvedTokens(preset, resolved);
|
|
44
33
|
const root = document.documentElement.style;
|
|
45
34
|
for (const [key, value] of Object.entries(vars)) {
|
|
46
|
-
root.setProperty(key,
|
|
35
|
+
root.setProperty(key, value);
|
|
47
36
|
}
|
|
48
37
|
}
|
|
49
38
|
//# sourceMappingURL=apply-dark-class.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","APP_COLOR_PRESETS","
|
|
1
|
+
{"version":3,"names":["Platform","APP_COLOR_PRESETS","getResolvedTokens","applyDarkClass","resolved","OS","document","documentElement","classList","toggle","applyColorPresetVars","preset","vars","root","style","key","value","Object","entries","setProperty"],"sourceRoot":"../../../src","sources":["theme/apply-dark-class.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,iBAAiB,QAA2B,oBAAiB;AACtE,SAASC,iBAAiB,QAAQ,qBAAkB;AAEpD,OAAO,SAASC,cAAcA,CAACC,QAA0B,EAAE;EACzD,IAAIJ,QAAQ,CAACK,EAAE,KAAK,KAAK,IAAI,OAAOC,QAAQ,KAAK,WAAW,EAAE;IAC5DA,QAAQ,CAACC,eAAe,CAACC,SAAS,CAACC,MAAM,CAAC,MAAM,EAAEL,QAAQ,KAAK,MAAM,CAAC;EACxE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASM,oBAAoBA,CAACC,MAAoB,EAAEP,QAA0B,EAAE;EACrF,IAAIJ,QAAQ,CAACK,EAAE,KAAK,KAAK,IAAI,OAAOC,QAAQ,KAAK,WAAW,EAAE;EAC9D,IAAI,CAACL,iBAAiB,CAACU,MAAM,CAAC,EAAE;EAEhC,MAAMC,IAAI,GAAGV,iBAAiB,CAACS,MAAM,EAAEP,QAAQ,CAAC;EAChD,MAAMS,IAAI,GAAGP,QAAQ,CAACC,eAAe,CAACO,KAAK;EAE3C,KAAK,MAAM,CAACC,GAAG,EAAEC,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACN,IAAI,CAAC,EAAE;IAC/CC,IAAI,CAACM,WAAW,CAACJ,GAAG,EAAEC,KAAK,CAAC;EAC9B;AACF","ignoreList":[]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
|
-
import { APP_COLOR_PRESETS } from "./color-presets.js";
|
|
5
4
|
import { getAdaptiveColors } from "./adaptive-colors.js";
|
|
5
|
+
import { getResolvedTokens } from "./token-registry.js";
|
|
6
|
+
import { parseRgbString, srgbToRgbString } from "./color-space.js";
|
|
6
7
|
/**
|
|
7
8
|
* Status colors used across the design system. Independent of the accent
|
|
8
9
|
* preset so semantic intent stays stable across themes.
|
|
@@ -15,72 +16,49 @@ export const STATUS_COLORS = {
|
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* Build the JS `theme.colors` object from the SAME canonical rgb token source
|
|
20
|
+
* the web/native CSS-var writes use (`getResolvedTokens`). JS styles and the
|
|
21
|
+
* `var(--x)` document tokens therefore share one rgb pipeline — no second,
|
|
22
|
+
* drift-prone HSL conversion lives here. Subtle/alpha mixes derive from the
|
|
23
|
+
* resolved rgb via `parseRgbString` + `srgbToRgbString`.
|
|
21
24
|
*/
|
|
22
|
-
function hslVarToColor(hslVar) {
|
|
23
|
-
const parts = hslVar.split('/').map(p => p.trim());
|
|
24
|
-
const triple = parts[0] ?? '0 0% 0%';
|
|
25
|
-
const components = triple.replace(/\s+/g, ', ');
|
|
26
|
-
if (parts.length === 2) {
|
|
27
|
-
const alpha = parseFloat(parts[1] ?? '100') / 100;
|
|
28
|
-
return `hsla(${components}, ${alpha})`;
|
|
29
|
-
}
|
|
30
|
-
return `hsl(${components})`;
|
|
31
|
-
}
|
|
32
|
-
function extractHue(hslVar) {
|
|
33
|
-
const first = hslVar.split(/\s+/)[0] ?? '0';
|
|
34
|
-
const hue = parseInt(first, 10);
|
|
35
|
-
return Number.isFinite(hue) ? hue : 0;
|
|
36
|
-
}
|
|
37
|
-
function hsl(h, s, l) {
|
|
38
|
-
return `hsl(${h}, ${s}%, ${l}%)`;
|
|
39
|
-
}
|
|
40
|
-
function readToken(tokens, key, fallback = '0 0% 0%') {
|
|
41
|
-
return hslVarToColor(tokens[key] ?? fallback);
|
|
42
|
-
}
|
|
43
25
|
function buildColorsFromPreset(preset, resolved) {
|
|
44
|
-
const
|
|
45
|
-
const tokens = resolved === 'dark' ? config.dark : config.light;
|
|
26
|
+
const t = getResolvedTokens(preset, resolved);
|
|
46
27
|
const isDark = resolved === 'dark';
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
const primaryColor = readToken(tokens, '--primary', '0 0% 50%');
|
|
53
|
-
const primaryForeground = readToken(tokens, '--primary-foreground', '0 0% 100%');
|
|
28
|
+
|
|
29
|
+
// Read a resolved `rgb(...)` token by its bare name (no leading `--`).
|
|
30
|
+
const g = k => t[`--${k}`] ?? 'rgb(0 0 0)';
|
|
31
|
+
// Re-emit a resolved token at a given alpha (sRGB rgb-with-alpha).
|
|
32
|
+
const mix = (k, a) => srgbToRgbString(parseRgbString(g(k)), a);
|
|
54
33
|
return {
|
|
55
|
-
background,
|
|
56
|
-
backgroundSecondary: surface,
|
|
57
|
-
backgroundTertiary:
|
|
58
|
-
text:
|
|
59
|
-
textSecondary:
|
|
60
|
-
textTertiary:
|
|
61
|
-
border:
|
|
62
|
-
borderLight:
|
|
63
|
-
primary:
|
|
64
|
-
primaryForeground,
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
iconActive: primaryColor,
|
|
34
|
+
background: g('background'),
|
|
35
|
+
backgroundSecondary: g('surface'),
|
|
36
|
+
backgroundTertiary: g('muted'),
|
|
37
|
+
text: g('foreground'),
|
|
38
|
+
textSecondary: g('muted-foreground'),
|
|
39
|
+
textTertiary: g('muted-foreground'),
|
|
40
|
+
border: g('border'),
|
|
41
|
+
borderLight: g('input'),
|
|
42
|
+
primary: g('primary'),
|
|
43
|
+
primaryForeground: g('primary-foreground'),
|
|
44
|
+
// Corrected aliases (see types.ts): `primaryLight` is the preset accent
|
|
45
|
+
// tint, `primaryDark` is the focus-ring shade — NOT the surface/background.
|
|
46
|
+
primaryLight: g('accent'),
|
|
47
|
+
primaryDark: g('ring'),
|
|
48
|
+
// Corrected: `secondary` is the preset's secondary surface, NOT a primary mirror.
|
|
49
|
+
secondary: g('secondary'),
|
|
50
|
+
tint: g('primary'),
|
|
51
|
+
icon: g('muted-foreground'),
|
|
52
|
+
iconActive: g('primary'),
|
|
75
53
|
...STATUS_COLORS,
|
|
76
|
-
primarySubtle: isDark ?
|
|
77
|
-
primarySubtleForeground:
|
|
78
|
-
negative:
|
|
54
|
+
primarySubtle: mix('primary', isDark ? 0.16 : 0.12),
|
|
55
|
+
primarySubtleForeground: g('primary'),
|
|
56
|
+
negative: g('destructive'),
|
|
79
57
|
negativeForeground: '#FFFFFF',
|
|
80
|
-
negativeSubtle: isDark ?
|
|
81
|
-
negativeSubtleForeground:
|
|
82
|
-
contrast50:
|
|
83
|
-
card:
|
|
58
|
+
negativeSubtle: mix('destructive', isDark ? 0.16 : 0.12),
|
|
59
|
+
negativeSubtleForeground: g('destructive'),
|
|
60
|
+
contrast50: mix('foreground', 0.5),
|
|
61
|
+
card: g('card'),
|
|
84
62
|
shadow: isDark ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.1)',
|
|
85
63
|
overlay: 'rgba(0, 0, 0, 0.5)'
|
|
86
64
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","
|
|
1
|
+
{"version":3,"names":["Platform","getAdaptiveColors","getResolvedTokens","parseRgbString","srgbToRgbString","STATUS_COLORS","success","error","warning","info","buildColorsFromPreset","preset","resolved","t","isDark","g","k","mix","a","background","backgroundSecondary","backgroundTertiary","text","textSecondary","textTertiary","border","borderLight","primary","primaryForeground","primaryLight","primaryDark","secondary","tint","icon","iconActive","primarySubtle","primarySubtleForeground","negative","negativeForeground","negativeSubtle","negativeSubtleForeground","contrast50","card","shadow","overlay","buildTheme","isAdaptive","adaptive","OS","undefined","colors","mode","isLight"],"sourceRoot":"../../../src","sources":["theme/build-theme.ts"],"mappings":"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","ignoreList":[]}
|