Skip to content

Commit 97f09b7

Browse files
committed
test(extract-theme-css): add two tests with all possible string orders
1 parent 63b4258 commit 97f09b7

File tree

4 files changed

+208
-9
lines changed

4 files changed

+208
-9
lines changed

apps/website/src/components/copy-css-config/copy-css-config.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ export default component$(() => {
1414
const { theme } = useTheme();
1515

1616
const generateCSSThemeOutput = $(async () => {
17-
const cssRules = extractThemeCSS(theme, globalCSS);
17+
const cssRules = extractThemeCSS(
18+
'border-radius-0 simple primary-green-600 light base-slate',
19+
globalCSS,
20+
);
1821
cssThemeOutput.value = cssRules;
1922
});
2023

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"story.build.headless": "nx build-storybook headless",
3131
"story.headless": "nx storybook headless",
3232
"test.cli": "nx test cli",
33+
"test.utils": "nx test utils",
3334
"test.headless": "nx component-test headless",
3435
"test.headless.ci": "nx component-test-ci headless"
3536
},

packages/kit-styled/src/templates/global.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,3 +1332,10 @@ body {
13321332
animation: 500ms cubic-bezier(0.87, 0, 0.13, 1) 0s 1 normal forwards accordion-close;
13331333
}
13341334
}
1335+
1336+
/* Not used yet - could be used for the colored text on the landing page when the make-it-yours color is too bright in light mode or too dim in dark mode */
1337+
@layer components {
1338+
.text-outlined {
1339+
@apply [text-shadow:-1px_0_black,_0_1px_black,_1px_0_black,_0_-1px_black] dark:[text-shadow:-1px_0_white,_0_1px_white,_1px_0_white,_0_-1px_white];
1340+
}
1341+
}

packages/utils/src/theme/extract-theme-css.spec.ts

Lines changed: 196 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
11
import { extractThemeCSS } from './extract-theme-css';
22

3+
function generateStringInAllPossibleOrders(str: string): string[] {
4+
const result: string[] = [];
5+
6+
// Split the string into parts based on spaces
7+
const parts = str.split(' ');
8+
9+
// Recursive function to generate permutations
10+
function permute(arr: string[], m: string[] = []) {
11+
if (arr.length === 0) {
12+
result.push(m.join(' '));
13+
} else {
14+
for (let i = 0; i < arr.length; i++) {
15+
const curr = arr.slice();
16+
const next = curr.splice(i, 1);
17+
permute(curr, m.concat(next));
18+
}
19+
}
20+
}
21+
22+
permute(parts);
23+
24+
return result;
25+
}
26+
327
describe('Extract theme from css', () => {
4-
test(`GIVEN primary color is "cyan-600",
5-
border-radius is 0,
6-
base color is "neutral"
7-
and style is "simple"
28+
test(`GIVEN theme string is 'simple base-neutral primary-cyan-600 border-radius-0'
829
THEN generate the right css variables`, () => {
930
const inputThemeString = 'simple base-neutral primary-cyan-600 border-radius-0';
1031

@@ -79,12 +100,94 @@ describe('Extract theme from css', () => {
79100
}"
80101
`);
81102
});
103+
104+
test(`GIVEN primary color is "cyan-600",
105+
border-radius is 0,
106+
base color is "neutral",
107+
and style is "simple",
108+
in whatever order,
109+
THEN generate the right css variables`, () => {
110+
const output = `
111+
"@layer base {
112+
:root {
113+
--background: 0 0% 100%;
114+
--foreground: 0 0% 9%;
115+
--muted: 0 0% 96.1%;
116+
--muted-foreground: 0 0% 45.1%;
117+
--popover: 0 0% 100%;
118+
--popover-foreground: 0 0% 9%;
119+
--card: 0 0% 100%;
120+
--card-foreground: 0 0% 9%;
121+
--border: 0 0% 89.8%;
122+
--input: 0 0% 89.8%;
123+
--primary: 191.6 91.4% 36.5%;
124+
--primary-foreground: 0 0% 100%;
125+
--secondary: 0 0% 83.1%;
126+
--secondary-foreground: 0 0% 9%;
127+
--accent: 0 0% 96.1%;
128+
--accent-foreground: 0 0% 9%;
129+
--alert: 0 84.2% 60.2%;
130+
--alert-foreground: 0 0% 98%;
131+
--ring: 0 0% 9%;
132+
--border-width: 0px;
133+
--border-radius: 0;
134+
--shadow-base: 0 1px 2px 0 rgba(0, 0, 0, 0.01);
135+
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
136+
--shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.1), 0 1px 5px 0px rgba(0, 0, 0, 0.1);
137+
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
138+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
139+
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
140+
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 1);
141+
--shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.01);
142+
--transform-press: scale(0.95);
143+
}
144+
.dark {
145+
--background: 0 0% 9%;
146+
--foreground: 0 0% 98%;
147+
--muted: 0 0% 14.9%;
148+
--muted-foreground: 0 0% 63.9%;
149+
--popover: 0 0% 9%;
150+
--popover-foreground: 0 0% 98%;
151+
--card: 0 0% 9%;
152+
--card-foreground: 0 0% 98%;
153+
--border: 0 0% 14.9%;
154+
--input: 0 0% 14.9%;
155+
--primary: 191.6 91.4% 36.5%;
156+
--primary-foreground: 0 0% 100%;
157+
--secondary: 0 0% 25.1%;
158+
--secondary-foreground: 0 0% 98%;
159+
--accent: 0 0% 14.9%;
160+
--accent-foreground: 0 0% 98%;
161+
--alert: 0 84.2% 60.2%;
162+
--alert-foreground: 0 0% 98%;
163+
--ring: 0 0% 83.1%;
164+
--border-width: 0px;
165+
--border-radius: 0;
166+
--shadow-base: 0 1px 2px 0 rgba(0, 0, 0, 0.01);
167+
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
168+
--shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.1), 0 1px 5px 0px rgba(0, 0, 0, 0.1);
169+
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
170+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
171+
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
172+
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 1);
173+
--shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.01);
174+
--transform-press: scale(0.95);
175+
}
176+
}"
177+
`;
178+
179+
const themeStringInEveryOrder = generateStringInAllPossibleOrders(
180+
'simple base-neutral primary-cyan-600 border-radius-0',
181+
);
182+
183+
themeStringInEveryOrder.forEach((themeString) => {
184+
const theme = extractThemeCSS(themeString, exampleRootCssContent);
185+
expect(theme).toMatchInlineSnapshot(output);
186+
});
187+
});
82188
});
83189

84-
test(`GIVEN primary color is "cyan-600",
85-
border-radius is 0,
86-
base color is "neutral"
87-
and style is "simple"
190+
test(`GIVEN theme string is 'brutalist base-stone primary-pink-700 border-radius-dot-75'
88191
THEN generate the right css variables`, () => {
89192
const inputThemeString = 'brutalist base-stone primary-pink-700 border-radius-dot-75';
90193

@@ -160,6 +263,91 @@ test(`GIVEN primary color is "cyan-600",
160263
`);
161264
});
162265

266+
test(`GIVEN primary color is "pink-700",
267+
border-radius is 0.75,
268+
base color is "stone",
269+
and style is "brutalist",
270+
in whatever order,
271+
THEN generate the right css variables`, () => {
272+
const output = `
273+
"@layer base {
274+
:root {
275+
--background: 0 0% 100%;
276+
--foreground: 24 9.8% 10%;
277+
--muted: 60 4.8% 95.9%;
278+
--muted-foreground: 25 5.3% 44.7%;
279+
--popover: 0 0% 100%;
280+
--popover-foreground: 24 9.8% 10%;
281+
--card: 0 0% 100%;
282+
--card-foreground: 24 9.8% 10%;
283+
--border: 0 0% 0%;
284+
--input: 0 0% 0%;
285+
--primary: 335.1 77.6% 42%;
286+
--primary-foreground: 0 0% 100%;
287+
--secondary: 24 5.7% 82.9%;
288+
--secondary-foreground: 24 9.8% 10%;
289+
--accent: 60 4.8% 95.9%;
290+
--accent-foreground: 24 9.8% 10%;
291+
--alert: 0 84.2% 60.2%;
292+
--alert-foreground: 60 9.1% 97.8%;
293+
--ring: 0 0% 0%;
294+
--border-width: 2px;
295+
--border-radius: 0.75rem;
296+
--shadow-base: 0px 0px 0px 0 rgba(0, 0, 0, 1);
297+
--shadow-sm: 4px 4px 0px 0 rgba(0, 0, 0, 1);
298+
--shadow: 5px 5px 0px 0px rgba(0, 0, 0, 1);
299+
--shadow-md: 6px 6px 0px 0px rgba(0, 0, 0, 1);
300+
--shadow-lg: 8px 8px 0px 0px rgba(0, 0, 0, 1);
301+
--shadow-xl: 11px 11px 0px 0px rgba(0, 0, 0, 1);
302+
--shadow-2xl: 13px 13px 0px 0px rgba(0, 0, 0, 1);
303+
--shadow-inner: inset 2px 2px 0px 0px rgba(0, 0, 0, 0);
304+
--transform-press: translate(4px, 4px);
305+
}
306+
.dark {
307+
--background: 24 9.8% 10%;
308+
--foreground: 60 9.1% 97.8%;
309+
--muted: 12 6.5% 15.1%;
310+
--muted-foreground: 24 5.4% 63.9%;
311+
--popover: 24 9.8% 10%;
312+
--popover-foreground: 60 9.1% 97.8%;
313+
--card: 24 9.8% 10%;
314+
--card-foreground: 60 9.1% 97.8%;
315+
--border: 0 0% 0%;
316+
--input: 0 0% 0%;
317+
--primary: 335.1 77.6% 42%;
318+
--primary-foreground: 0 0% 100%;
319+
--secondary: 30 6.3% 25.1%;
320+
--secondary-foreground: 60 9.1% 97.8%;
321+
--accent: 12 6.5% 15.1%;
322+
--accent-foreground: 60 9.1% 97.8%;
323+
--alert: 0 84.2% 60.2%;
324+
--alert-foreground: 0 0% 98%;
325+
--ring: 0 0% 0%;
326+
--border-width: 3px;
327+
--border-radius: 0.75rem;
328+
--shadow-base: 0px 0px 0px 0 rgba(0, 0, 0, 1);
329+
--shadow-sm: 4px 4px 0px 0 rgba(0, 0, 0, 1);
330+
--shadow: 5px 5px 0px 0px rgba(0, 0, 0, 1);
331+
--shadow-md: 6px 6px 0px 0px rgba(0, 0, 0, 1);
332+
--shadow-lg: 8px 8px 0px 0px rgba(0, 0, 0, 1);
333+
--shadow-xl: 11px 11px 0px 0px rgba(0, 0, 0, 1);
334+
--shadow-2xl: 13px 13px 0px 0px rgba(0, 0, 0, 1);
335+
--shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.01);
336+
--transform-press: translate(4px, 4px);
337+
}
338+
}"
339+
`;
340+
341+
const themeStringInEveryOrder = generateStringInAllPossibleOrders(
342+
'brutalist base-stone primary-pink-700 border-radius-dot-75',
343+
);
344+
345+
themeStringInEveryOrder.forEach((themeString) => {
346+
const theme = extractThemeCSS(themeString, exampleRootCssContent);
347+
expect(theme).toMatchInlineSnapshot(output);
348+
});
349+
});
350+
163351
const exampleRootCssContent = `
164352
165353
@layer base {

0 commit comments

Comments
 (0)