@astryxdesign/theme-stone 0.7.3 → 0.7.4-canary.1a552f2
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 +42 -5
- package/dist/source.d.ts +1 -1
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +201 -235
- package/dist/source.mjs +201 -235
- package/dist/stone.d.ts +2 -2
- package/dist/stone.js +134 -134
- package/dist/stoneColorMapping.test.d.ts +2 -0
- package/dist/stoneColorMapping.test.d.ts.map +1 -0
- package/dist/stonePaletteRefs.generated.d.ts +158 -0
- package/dist/stonePaletteRefs.generated.d.ts.map +1 -0
- package/dist/stonePalettes.generated.d.ts +496 -0
- package/dist/stonePalettes.generated.d.ts.map +1 -0
- package/dist/stonePalettes.test.d.ts +2 -0
- package/dist/stonePalettes.test.d.ts.map +1 -0
- package/dist/stoneTheme.d.ts +5 -3
- package/dist/stoneTheme.d.ts.map +1 -1
- package/dist/theme.css +134 -134
- package/dist/theme.css.d.ts +2 -2
- package/package.json +6 -5
- package/palette.config.json +262 -0
- package/src/source.ts +1 -1
- package/src/stoneColorMapping.test.ts +44 -0
- package/src/stonePaletteRefs.generated.ts +51 -0
- package/src/stonePalettes.generated.receipt.json +840 -0
- package/src/stonePalettes.generated.ts +501 -0
- package/src/stonePalettes.test.ts +87 -0
- package/src/stoneTheme.test.ts +124 -1
- package/src/stoneTheme.ts +190 -207
package/src/stoneTheme.test.ts
CHANGED
|
@@ -1,9 +1,45 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
import {describe, expect, it} from 'vitest';
|
|
4
|
-
import {generateThemeCSS} from '@astryxdesign/core/theme';
|
|
4
|
+
import {generateThemeCSS, resolveThemeTokens} from '@astryxdesign/core/theme';
|
|
5
|
+
import {palette as stoneModePalettes} from './stonePalettes.generated';
|
|
5
6
|
import {stoneTheme} from './stoneTheme';
|
|
6
7
|
|
|
8
|
+
function channels(color: string): [number, number, number] {
|
|
9
|
+
return [1, 3, 5].map(index =>
|
|
10
|
+
Number.parseInt(color.slice(index, index + 2), 16),
|
|
11
|
+
) as [number, number, number];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function luminance(color: string): number {
|
|
15
|
+
const [red, green, blue] = channels(color).map(channel => {
|
|
16
|
+
const value = channel / 255;
|
|
17
|
+
return value <= 0.04045
|
|
18
|
+
? value / 12.92
|
|
19
|
+
: Math.pow((value + 0.055) / 1.055, 2.4);
|
|
20
|
+
});
|
|
21
|
+
return 0.2126 * red + 0.7152 * green + 0.0722 * blue;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function contrast(foreground: string, background: string): number {
|
|
25
|
+
const [lighter, darker] = [luminance(foreground), luminance(background)].sort(
|
|
26
|
+
(left, right) => right - left,
|
|
27
|
+
);
|
|
28
|
+
return (lighter + 0.05) / (darker + 0.05);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function blend(foreground: string, background: string, alpha: number): string {
|
|
32
|
+
const front = channels(foreground);
|
|
33
|
+
const back = channels(background);
|
|
34
|
+
return `#${front
|
|
35
|
+
.map((channel, index) =>
|
|
36
|
+
Math.round(channel * alpha + back[index] * (1 - alpha))
|
|
37
|
+
.toString(16)
|
|
38
|
+
.padStart(2, '0'),
|
|
39
|
+
)
|
|
40
|
+
.join('')}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
7
43
|
describe('stone touch + narrow type pin', () => {
|
|
8
44
|
it('floors body to 16px and holds Display 1 at its desktop size', () => {
|
|
9
45
|
const rule = stoneTheme.__adaptationRules?.[0];
|
|
@@ -31,3 +67,90 @@ describe('stone secondary ComplexSelector', () => {
|
|
|
31
67
|
);
|
|
32
68
|
});
|
|
33
69
|
});
|
|
70
|
+
|
|
71
|
+
const categoricalFamilies = [
|
|
72
|
+
'blue',
|
|
73
|
+
'cyan',
|
|
74
|
+
'green',
|
|
75
|
+
'orange',
|
|
76
|
+
'pink',
|
|
77
|
+
'purple',
|
|
78
|
+
'red',
|
|
79
|
+
'teal',
|
|
80
|
+
'yellow',
|
|
81
|
+
] as const;
|
|
82
|
+
|
|
83
|
+
describe('stone palette mapping', () => {
|
|
84
|
+
it.each(['light', 'dark'] as const)(
|
|
85
|
+
'resolves the neutral surface ladder from reviewed %s stops',
|
|
86
|
+
mode => {
|
|
87
|
+
const tokens = resolveThemeTokens(stoneTheme, {mode});
|
|
88
|
+
const ramp = stoneModePalettes.neutral[mode];
|
|
89
|
+
|
|
90
|
+
expect(tokens['--color-background-body']).toBe(
|
|
91
|
+
ramp[mode === 'light' ? 95 : 5],
|
|
92
|
+
);
|
|
93
|
+
expect(tokens['--color-background-surface']).toBe(
|
|
94
|
+
ramp[mode === 'light' ? 100 : 10],
|
|
95
|
+
);
|
|
96
|
+
expect(tokens['--color-background-card']).toBe(
|
|
97
|
+
ramp[mode === 'light' ? 100 : 15],
|
|
98
|
+
);
|
|
99
|
+
expect(tokens['--color-background-popover']).toBe(
|
|
100
|
+
ramp[mode === 'light' ? 100 : 20],
|
|
101
|
+
);
|
|
102
|
+
expect(tokens['--color-text-primary']).toBe(
|
|
103
|
+
ramp[mode === 'light' ? 15 : 95],
|
|
104
|
+
);
|
|
105
|
+
expect(tokens['--color-text-secondary']).toBe(
|
|
106
|
+
ramp[mode === 'light' ? 40 : 70],
|
|
107
|
+
);
|
|
108
|
+
},
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
it.each(['light', 'dark'] as const)(
|
|
112
|
+
'keeps every categorical %s role on the same four-stop pattern',
|
|
113
|
+
mode => {
|
|
114
|
+
const tokens = resolveThemeTokens(stoneTheme, {mode});
|
|
115
|
+
for (const family of categoricalFamilies) {
|
|
116
|
+
const ramp = stoneModePalettes[family][mode];
|
|
117
|
+
expect(tokens[`--color-background-${family}`]).toBe(
|
|
118
|
+
ramp[mode === 'light' ? 90 : 35],
|
|
119
|
+
);
|
|
120
|
+
expect(tokens[`--color-border-${family}`]).toBe(
|
|
121
|
+
ramp[mode === 'light' ? 85 : 25],
|
|
122
|
+
);
|
|
123
|
+
expect(tokens[`--color-icon-${family}`]).toBe(
|
|
124
|
+
ramp[mode === 'light' ? 30 : 90],
|
|
125
|
+
);
|
|
126
|
+
expect(tokens[`--color-text-${family}`]).toBe(
|
|
127
|
+
ramp[mode === 'light' ? 30 : 90],
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
it('keeps light input rims and syntax attributes above their thresholds', () => {
|
|
134
|
+
const {green, neutral, red, yellow} = stoneModePalettes;
|
|
135
|
+
const surface = neutral.light[100];
|
|
136
|
+
const syntaxBackground = neutral.light[95];
|
|
137
|
+
const diffAlpha = 0x40 / 255;
|
|
138
|
+
const addedRow = blend(green.light[90], syntaxBackground, diffAlpha);
|
|
139
|
+
const removedRow = blend(red.light[90], syntaxBackground, diffAlpha);
|
|
140
|
+
|
|
141
|
+
expect(contrast(green.light[55], surface)).toBeGreaterThanOrEqual(3);
|
|
142
|
+
expect(contrast(yellow.light[55], surface)).toBeGreaterThanOrEqual(3);
|
|
143
|
+
for (const background of [syntaxBackground, addedRow, removedRow]) {
|
|
144
|
+
expect(contrast(yellow.light[40], background)).toBeGreaterThanOrEqual(
|
|
145
|
+
4.5,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
expect(stoneTheme.components?.['text-input']?.['status:success']).toEqual({
|
|
150
|
+
'--color-success': `light-dark(${green.light[55]}, ${green.dark[70]})`,
|
|
151
|
+
});
|
|
152
|
+
expect(stoneTheme.components?.['text-input']?.['status:warning']).toEqual({
|
|
153
|
+
'--color-warning': `light-dark(${yellow.light[55]}, ${yellow.dark[70]})`,
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|