@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { APP_COLOR_NAMES, APP_COLOR_PRESETS } from '../theme/color-presets';
|
|
2
|
-
import { getPresetVars
|
|
2
|
+
import { getPresetVars } from '../theme/preset-vars';
|
|
3
|
+
import { getResolvedTokens } from '../theme/token-registry';
|
|
3
4
|
|
|
4
5
|
const EXTENDED_KEYS = [
|
|
5
6
|
'--card',
|
|
@@ -45,99 +46,52 @@ describe('getPresetVars', () => {
|
|
|
45
46
|
expect(vars['--sidebar-primary']).toBe(primary);
|
|
46
47
|
});
|
|
47
48
|
|
|
48
|
-
it('
|
|
49
|
+
it('returns raw HSL triples (no resolved colors) — getResolvedTokens owns rgb', () => {
|
|
50
|
+
// `getPresetVars` is the raw triple source feeding the single canonical
|
|
51
|
+
// resolver. It must NOT pre-resolve to rgb/hsl, and the legacy resolved-color
|
|
52
|
+
// companion universe must be gone (no key carries the resolved-color prefix).
|
|
49
53
|
const vars = getPresetVars('green', 'dark');
|
|
50
|
-
expect(vars['--
|
|
54
|
+
expect(vars['--primary']).toBe(APP_COLOR_PRESETS.green.dark['--primary']);
|
|
55
|
+
expect(/^-?\d[\d.]*\s+[\d.]+%/.test(vars['--primary'] ?? '')).toBe(true);
|
|
56
|
+
const legacyPrefix = `--${'color'}-`;
|
|
57
|
+
expect(Object.keys(vars).some((k) => k.startsWith(legacyPrefix))).toBe(false);
|
|
51
58
|
});
|
|
59
|
+
});
|
|
52
60
|
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
describe('getResolvedTokens (single canonical rgb pipeline)', () => {
|
|
62
|
+
it('resolves every base + extended token to a space-separated rgb() string', () => {
|
|
63
|
+
const resolved = getResolvedTokens('green', 'dark');
|
|
55
64
|
const primaryTriple = APP_COLOR_PRESETS.green.dark['--primary'] ?? '';
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
expect(
|
|
65
|
+
// No resolved-color companion universe anymore — the base token is rgb.
|
|
66
|
+
const legacyPrefix = `--${'color'}-`;
|
|
67
|
+
expect(Object.keys(resolved).some((k) => k.startsWith(legacyPrefix))).toBe(false);
|
|
68
|
+
expect(resolved['--primary']).toMatch(/^rgb\(\d+ \d+ \d+\)$/);
|
|
69
|
+
expect(resolved['--card']).toMatch(/^rgb\(\d+ \d+ \d+\)$/);
|
|
70
|
+
// primary triple resolves to the same rgb the registry produces.
|
|
71
|
+
expect(resolved['--primary']).toBe(getResolvedTokens('green', 'dark')['--primary']);
|
|
72
|
+
expect(primaryTriple).toMatch(/%/);
|
|
59
73
|
});
|
|
60
74
|
|
|
61
|
-
it('resolves --
|
|
75
|
+
it('resolves --primary to rgb for the blue preset (matches web reference)', () => {
|
|
62
76
|
// `blue` preset light `--primary` is `205 87% 53%` → rgb(31 153 239).
|
|
63
|
-
const
|
|
64
|
-
expect(
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('hslTripletToRgb', () => {
|
|
69
|
-
it('converts a plain HSL triple to a space-separated rgb() string', () => {
|
|
70
|
-
expect(hslTripletToRgb('205 87% 53%')).toBe('rgb(31 153 239)');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('converts the achromatic extremes', () => {
|
|
74
|
-
expect(hslTripletToRgb('0 0% 0%')).toBe('rgb(0 0 0)');
|
|
75
|
-
expect(hslTripletToRgb('0 0% 100%')).toBe('rgb(255 255 255)');
|
|
76
|
-
expect(hslTripletToRgb('0 0% 12%')).toBe('rgb(31 31 31)');
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('converts a saturated triple within ±1 per channel of the reference', () => {
|
|
80
|
-
// teal `185 100% 20%` ≈ rgb(0 94 102).
|
|
81
|
-
const match = /^rgb\((\d+) (\d+) (\d+)\)$/.exec(hslTripletToRgb('185 100% 20%'));
|
|
82
|
-
expect(match).not.toBeNull();
|
|
83
|
-
const r = Number(match?.[1] ?? NaN);
|
|
84
|
-
const g = Number(match?.[2] ?? NaN);
|
|
85
|
-
const b = Number(match?.[3] ?? NaN);
|
|
86
|
-
expect(Math.abs(r - 0)).toBeLessThanOrEqual(1);
|
|
87
|
-
expect(Math.abs(g - 94)).toBeLessThanOrEqual(1);
|
|
88
|
-
expect(Math.abs(b - 102)).toBeLessThanOrEqual(1);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('tolerates a deg suffix on the hue', () => {
|
|
92
|
-
expect(hslTripletToRgb('205deg 87% 53%')).toBe('rgb(31 153 239)');
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('emits rgb(r g b / a) for an alpha tail (decimal or percentage)', () => {
|
|
96
|
-
expect(hslTripletToRgb('205 87% 53% / 0.5')).toBe('rgb(31 153 239 / 0.5)');
|
|
97
|
-
expect(hslTripletToRgb('205 87% 53% / 50%')).toBe('rgb(31 153 239 / 0.5)');
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
describe('toWebColorValue (web var contract)', () => {
|
|
102
|
-
it('wraps a raw HSL triple base token in hsl()', () => {
|
|
103
|
-
expect(toWebColorValue('--background', '185 50% 5%')).toBe('hsl(185 50% 5%)');
|
|
104
|
-
expect(toWebColorValue('--primary', '185 100% 20%')).toBe('hsl(185 100% 20%)');
|
|
105
|
-
expect(toWebColorValue('--foreground', '0 0% 12%')).toBe('hsl(0 0% 12%)');
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('wraps a raw HSL triple with an alpha tail into modern hsl(H S% L% / A) syntax', () => {
|
|
109
|
-
expect(toWebColorValue('--ring', '0 0% 0% / 0.5')).toBe('hsl(0 0% 0% / 0.5)');
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('passes --color-* resolved rgb() vars through unchanged', () => {
|
|
113
|
-
expect(toWebColorValue('--color-primary', 'rgb(31 153 239)')).toBe('rgb(31 153 239)');
|
|
114
|
-
expect(toWebColorValue('--color-background', 'rgb(0 94 102 / 0.5)')).toBe(
|
|
115
|
-
'rgb(0 94 102 / 0.5)',
|
|
116
|
-
);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('passes non-color tokens (radius / lengths) through unchanged', () => {
|
|
120
|
-
expect(toWebColorValue('--radius', '0.5rem')).toBe('0.5rem');
|
|
121
|
-
expect(toWebColorValue('--radius-lg', '12px')).toBe('12px');
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('passes already-resolved color values through unchanged', () => {
|
|
125
|
-
expect(toWebColorValue('--primary', 'rgb(31 153 239)')).toBe('rgb(31 153 239)');
|
|
126
|
-
expect(toWebColorValue('--primary', 'hsl(185 100% 20%)')).toBe('hsl(185 100% 20%)');
|
|
127
|
-
expect(toWebColorValue('--primary', '#1d9bf0')).toBe('#1d9bf0');
|
|
77
|
+
const resolved = getResolvedTokens('blue', 'light');
|
|
78
|
+
expect(resolved['--primary']).toBe('rgb(31 153 239)');
|
|
128
79
|
});
|
|
129
80
|
|
|
130
81
|
it('produces a full CSS color for every base preset token of every preset/mode', () => {
|
|
131
82
|
for (const name of APP_COLOR_NAMES) {
|
|
132
83
|
for (const mode of ['light', 'dark'] as const) {
|
|
133
84
|
const base = mode === 'light' ? APP_COLOR_PRESETS[name].light : APP_COLOR_PRESETS[name].dark;
|
|
134
|
-
|
|
135
|
-
|
|
85
|
+
const resolved = getResolvedTokens(name, mode);
|
|
86
|
+
for (const key of Object.keys(base)) {
|
|
87
|
+
const value = resolved[key] ?? '';
|
|
136
88
|
// A bare triple (`185 50% 5%`) is INVALID CSS — the incident. Every
|
|
137
89
|
// base token must come out as a complete color the browser parses.
|
|
138
|
-
expect(
|
|
90
|
+
expect(value.startsWith('rgb(') || value.startsWith('hsl(') || value.startsWith('#')).toBe(
|
|
139
91
|
true,
|
|
140
92
|
);
|
|
93
|
+
// Never a bare HSL triple.
|
|
94
|
+
expect(/^-?\d[\d.]*\s+[\d.]+%/.test(value)).toBe(false);
|
|
141
95
|
}
|
|
142
96
|
}
|
|
143
97
|
}
|
|
@@ -50,12 +50,12 @@ describe('Theme system', () => {
|
|
|
50
50
|
|
|
51
51
|
describe('buildTheme primaryForeground', () => {
|
|
52
52
|
it('resolves a readable foreground for the primary fill per preset', () => {
|
|
53
|
-
// blue's --primary-foreground is `0 0% 100%` → white
|
|
54
|
-
expect(buildTheme('blue', 'light').colors.primaryForeground).toBe('
|
|
55
|
-
expect(buildTheme('blue', 'dark').colors.primaryForeground).toBe('
|
|
56
|
-
// yellow's --primary-foreground is `0 0% 0%` → black
|
|
57
|
-
expect(buildTheme('yellow', 'light').colors.primaryForeground).toBe('
|
|
58
|
-
expect(buildTheme('yellow', 'dark').colors.primaryForeground).toBe('
|
|
53
|
+
// blue's --primary-foreground is `0 0% 100%` → white (canonical sRGB rgb)
|
|
54
|
+
expect(buildTheme('blue', 'light').colors.primaryForeground).toBe('rgb(255 255 255)');
|
|
55
|
+
expect(buildTheme('blue', 'dark').colors.primaryForeground).toBe('rgb(255 255 255)');
|
|
56
|
+
// yellow's --primary-foreground is `0 0% 0%` → black (canonical sRGB rgb)
|
|
57
|
+
expect(buildTheme('yellow', 'light').colors.primaryForeground).toBe('rgb(0 0 0)');
|
|
58
|
+
expect(buildTheme('yellow', 'dark').colors.primaryForeground).toBe('rgb(0 0 0)');
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
it('sets a primaryForeground for every preset in both modes', () => {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ambient declaration for `@react-native/normalize-colors`.
|
|
3
|
+
*
|
|
4
|
+
* The package ships JS-only (`module.exports = normalizeColor`) with no bundled
|
|
5
|
+
* type declarations, so `tsc` can't see its shape. It arrives transitively via
|
|
6
|
+
* react-native / react-native-web — Bloom only references it in tests, as the
|
|
7
|
+
* exact parser React Native (native) and react-native-web use behind
|
|
8
|
+
* `StyleSheet`/`processColor` to validate that a color string is renderable.
|
|
9
|
+
*
|
|
10
|
+
* Typed to match the package's runtime contract (`index.js`): a default export
|
|
11
|
+
* that takes a CSS color string or a packed 32-bit RGBA number and returns the
|
|
12
|
+
* normalized packed RGBA integer, or `null` when the input is unparseable.
|
|
13
|
+
*/
|
|
14
|
+
declare module '@react-native/normalize-colors' {
|
|
15
|
+
/**
|
|
16
|
+
* Parse a CSS color string (or packed RGBA number) into a packed 32-bit RGBA
|
|
17
|
+
* integer (`0xRRGGBBAA`). Returns `null` when the input cannot be parsed — an
|
|
18
|
+
* unparseable color renders nothing in React Native / react-native-web.
|
|
19
|
+
*/
|
|
20
|
+
const normalizeColor: (color: string | number) => number | null;
|
|
21
|
+
export default normalizeColor;
|
|
22
|
+
}
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
declare module 'react-native-css/native-internal' {
|
|
21
21
|
/**
|
|
22
22
|
* A leaf style value. Mirrors react-native-css's `compiler.types`
|
|
23
|
-
* `StyleDescriptor`. Bloom only ever writes string color values (
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* `StyleDescriptor`. Bloom only ever writes string color values (sRGB
|
|
24
|
+
* `rgb(...)` strings from the single canonical token pipeline), but the family
|
|
25
|
+
* is typed against the full descriptor union.
|
|
26
26
|
*/
|
|
27
27
|
type StyleDescriptor =
|
|
28
28
|
| string
|