Skip to content

Commit f7129db

Browse files
committed
Generate decision object 🚀
1 parent 69c1284 commit f7129db

File tree

8 files changed

+126
-72
lines changed

8 files changed

+126
-72
lines changed

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ node_modules/
44
/.yarn_home/
55
/src/test/frameworks/
66
/src/tools/types/
7+
/dsfr/
8+
/dist_test/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
This module is a wrapper/compatibility layer for [@gouvfr/dsfr](https://github.com/GouvernementFR/dsfr), the vanilla JS/CSS implementation of the DSFR.
2626

2727
- [x] Fully TypeSafe, well documented API.
28-
- [ ] Always in up to date with latest the DSFR evolutions.
28+
- [x] Always in up to date with latest the DSFR evolutions.
2929
Code and Types generated from [`@gouvfr/dsfr`](https://www.npmjs.com/package/@gouvfr/dsfr)`/dist/dsfr.css`.
3030
- [x] Exactly the same look and feel than with [@gouvfr/dsfr](https://www.npmjs.com/package/@gouvfr/dsfr).
3131
- [x] No [white flash when reloading in SSR setup](https://github.com/codegouvfr/@codegouvfr/react-dsfr/issues/2#issuecomment-1257263480).

src/bin/css_to_ts/colorDecisions.ts

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -156,63 +156,55 @@ export type ColorDecision = {
156156
optionThemePath: string[];
157157
};
158158

159-
export function createParseColorDecision(params: {
160-
/** Like [ "grey", "blueFrance", ... ]
161-
* All the the color name in camel case that we deduce from Options
162-
* it help parsing without making assumption on what is a valid Usage
163-
*/
164-
colorNames: string[];
159+
export function parseColorDecision(params: {
165160
/** ["--grey-1000-50-hover", "--grey-1000-50", ... ] */
166161
colorOptionNames: `--${string}`[];
167-
}) {
168-
const { colorNames, colorOptionNames } = params;
162+
rawCssCode: string;
163+
}): ColorDecision[] {
164+
const { colorOptionNames, rawCssCode } = params;
165+
166+
const colorNames = colorOptionNames.map(parseColorOptionName).map(o => o.colorName);
169167

170168
const { parseColorDecisionName } = createParseColorDecisionName({ colorNames });
171169

172-
function parseColorDecision(rawCssCode: string): ColorDecision[] {
173-
const parsedCss = css.parse(rawCssCode);
170+
const parsedCss = css.parse(rawCssCode);
174171

175-
const { declarations } = (() => {
176-
const node = parsedCss.stylesheet?.rules.find(
177-
rule => rule.type === "rule" && (rule as any)?.selectors?.[0] === ":root"
178-
);
172+
const { declarations } = (() => {
173+
const node = parsedCss.stylesheet?.rules.find(
174+
rule => rule.type === "rule" && (rule as any)?.selectors?.[0] === ":root"
175+
);
179176

180-
assert(node !== undefined);
177+
assert(node !== undefined);
181178

182-
const { declarations } = node as any;
179+
const { declarations } = node as any;
183180

184-
return { declarations };
185-
})();
181+
return { declarations };
182+
})();
186183

187-
return declarations
188-
.map(({ property, value }: { property: string; value: string }) => {
189-
const mathArray = value.match(/^var\((--[^)]+)\)$/);
184+
return declarations
185+
.map(({ property, value }: { property: string; value: string }) => {
186+
const mathArray = value.match(/^var\((--[^)]+)\)$/);
190187

191-
if (mathArray === null) {
192-
return undefined;
193-
}
194-
195-
const colorOptionName = mathArray[1];
188+
if (mathArray === null) {
189+
return undefined;
190+
}
196191

197-
assert(is<`--${string}`>(colorOptionName));
192+
const colorOptionName = mathArray[1];
198193

199-
if (!id<string[]>(colorOptionNames).includes(colorOptionName)) {
200-
return undefined;
201-
}
194+
assert(is<`--${string}`>(colorOptionName));
202195

203-
assert(is<`--${string}`>(property));
196+
if (!id<string[]>(colorOptionNames).includes(colorOptionName)) {
197+
return undefined;
198+
}
204199

205-
return {
206-
"themePath": getThemePath(parseColorDecisionName(property)),
207-
"optionThemePath": getColorOptionThemePath(
208-
parseColorOptionName(colorOptionName)
209-
)
210-
};
211-
})
212-
.filter(exclude(undefined));
213-
}
200+
assert(is<`--${string}`>(property));
214201

215-
return { parseColorDecision };
202+
return {
203+
"themePath": getThemePath(parseColorDecisionName(property)),
204+
"optionThemePath": getColorOptionThemePath(parseColorOptionName(colorOptionName))
205+
};
206+
})
207+
.filter(exclude(undefined));
216208
}
217209

218210
export function generateGetColorDecisionsTsCode(colorDecisions: ColorDecision[]): string {

src/bin/css_to_ts/colorOptions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ export function getThemePath(parsedColorOptionName: ParsedColorOptionName): stri
316316
}
317317

318318
export type ColorOption = {
319+
colorOptionName: `--${string}`;
319320
themePath: string[];
320321
color:
321322
| string
@@ -376,6 +377,7 @@ export function parseColorOptions(rawCssCode: string): ColorOption[] {
376377
}
377378

378379
return {
380+
"colorOptionName": colorName,
379381
"themePath": getThemePath(parsedName),
380382
"color": parsedName.brightness.isInvariant
381383
? color

src/bin/css_to_ts/css_to_ts.ts

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,66 @@
11
import { generateGetColorOptionsTsCode, parseColorOptions } from "./colorOptions";
2+
import { generateGetColorDecisionsTsCode, parseColorDecision } from "./colorDecisions";
23
import { getProjectRoot } from "../tools/getProjectRoot";
34
import * as fs from "fs";
4-
import { join as pathJoin, dirname as pathDirname, relative as pathRelative } from "path";
5+
import { join as pathJoin, basename as pathBasename, relative as pathRelative } from "path";
56

67
const projectRoot = getProjectRoot();
78

89
const rawCssCode = fs.readFileSync(pathJoin(projectRoot, "dsfr", "dsfr.css")).toString("utf8");
910

10-
const tsCode = generateGetColorOptionsTsCode(parseColorOptions(rawCssCode));
11+
const generatedDirPath = pathJoin(projectRoot, "src", "lib", "useTheme", "generated");
1112

12-
const targetFilePath = pathJoin(
13-
projectRoot,
14-
"src",
15-
"lib",
16-
"useTheme",
17-
"generated",
18-
"getColorOptions.ts"
19-
);
13+
fs.mkdirSync(generatedDirPath, { "recursive": true });
14+
15+
const warningMessage = [
16+
`// This file is generated automatically by ${pathRelative(
17+
projectRoot,
18+
__filename
19+
)}, please don't edit.`
20+
].join("\n");
2021

21-
fs.mkdirSync(pathDirname(targetFilePath), { "recursive": true });
22+
const targetOptionFilePath = pathJoin(generatedDirPath, "getColorOptions.ts");
23+
24+
const colorOptions = parseColorOptions(rawCssCode);
2225

2326
fs.writeFileSync(
24-
targetFilePath,
27+
targetOptionFilePath,
2528
Buffer.from(
2629
[
27-
`// This file is generated automatically by ${pathRelative(
28-
projectRoot,
29-
__filename
30-
)}, please don't edit.`,
30+
warningMessage,
3131
`import type { ColorScheme } from "../../useColorScheme";`,
3232
``,
33-
tsCode,
33+
generateGetColorOptionsTsCode(colorOptions),
3434
``,
3535
`export type ColorOptions = ReturnType<typeof getColorOptions>;`,
3636
``
3737
].join("\n"),
3838
"utf8"
3939
)
4040
);
41+
42+
const targetDecisionFilePath = pathJoin(generatedDirPath, "getColorDecisions.ts");
43+
44+
fs.writeFileSync(
45+
targetDecisionFilePath,
46+
Buffer.from(
47+
[
48+
warningMessage,
49+
`import type { ColorOptions } from "./${pathBasename(targetOptionFilePath).replace(
50+
/\.ts$/,
51+
""
52+
)}";`,
53+
``,
54+
generateGetColorDecisionsTsCode(
55+
parseColorDecision({
56+
"colorOptionNames": colorOptions.map(({ colorOptionName }) => colorOptionName),
57+
rawCssCode
58+
})
59+
),
60+
``,
61+
`export type ColorDecisions = ReturnType<typeof getColorDecisions>;`,
62+
``
63+
].join("\n"),
64+
"utf8"
65+
)
66+
);

src/test/bin/colorDecisions/parseColorDecision.test.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
1-
import { createParseColorDecision } from "../../../bin/css_to_ts/colorDecisions";
1+
import { parseColorDecision } from "../../../bin/css_to_ts/colorDecisions";
22
import type { ColorDecision } from "../../../bin/css_to_ts/colorDecisions";
33
import { assert } from "tsafe/assert";
44
import { same } from "evt/tools/inDepth/same";
55

66
console.log(`Running test ${__filename}`);
77

8-
const { parseColorDecision } = createParseColorDecision({
9-
"colorNames": ["grey", "orangeTerreBattue"],
10-
"colorOptionNames": [
11-
"--grey-1000-50-hover",
12-
"--grey-1000-50",
13-
"--orange-terre-battue-850-200",
14-
"--grey-975-100-hover",
15-
"--grey-950-150"
16-
]
17-
});
18-
198
const rawCssCode = `
209
:root {
2110
--background-default-grey-hover: var(--grey-1000-50-hover);
@@ -26,7 +15,16 @@ const rawCssCode = `
2615
}
2716
`;
2817

29-
const got = parseColorDecision(rawCssCode);
18+
const got = parseColorDecision({
19+
"colorOptionNames": [
20+
"--grey-1000-50-hover",
21+
"--grey-1000-50",
22+
"--orange-terre-battue-850-200",
23+
"--grey-975-100-hover",
24+
"--grey-950-150"
25+
],
26+
rawCssCode
27+
});
3028

3129
const expected: ColorDecision[] = [
3230
{

src/test/bin/colorOptions/generateGetColorOptionsTsCode.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,70 +6,87 @@ console.log(`Running test ${__filename}`);
66

77
const input: ColorOption[] = [
88
{
9+
"colorOptionName": "--name1-name2-111",
910
"themePath": ["name1Name2", "_111", "default"],
1011
"color": "#000000"
1112
},
1213
{
14+
"colorOptionName": "--name1-name2-111-hover",
1315
"themePath": ["name1Name2", "_111", "hover"],
1416
"color": "#000001"
1517
},
1618
{
19+
"colorOptionName": "--name1-name2-sun-111",
1720
"themePath": ["name1Name2", "sun111", "default"],
1821
"color": "#000002"
1922
},
2023
{
24+
"colorOptionName": "--name1-name2-sun-111-hover",
2125
"themePath": ["name1Name2", "sun111", "hover"],
2226
"color": "#000003"
2327
},
2428
{
29+
"colorOptionName": "--name1-name2-111-222",
2530
"themePath": ["name1Name2", "_111_222", "default"],
2631
"color": { "light": "#000004", "dark": "#100000" }
2732
},
2833
{
34+
"colorOptionName": "--name1-name2-111-222-hover",
2935
"themePath": ["name1Name2", "_111_222", "hover"],
3036
"color": { "light": "#000005", "dark": "#200000" }
3137
},
3238
{
39+
"colorOptionName": "--name1-name2-sun-111-222",
3340
"themePath": ["name1Name2", "sun111_222", "default"],
3441
"color": { "light": "#000006", "dark": "#300000" }
3542
},
3643
{
44+
"colorOptionName": "--name1-name2-sun-111-222-hover",
3745
"themePath": ["name1Name2", "sun111_222", "hover"],
3846
"color": { "light": "#000007", "dark": "#400000" }
3947
},
4048
{
49+
"colorOptionName": "--name1-name2-111-moon-222",
4150
"themePath": ["name1Name2", "_111moon222", "default"],
4251
"color": { "light": "#000008", "dark": "#500000" }
4352
},
4453
{
54+
"colorOptionName": "--name1-name2-111-moon-222-hover",
4555
"themePath": ["name1Name2", "_111moon222", "hover"],
4656
"color": { "light": "#000009", "dark": "#600000" }
4757
},
4858
{
59+
"colorOptionName": "--name1-name2-sun-111-moon-222",
4960
"themePath": ["name1Name2", "sun111moon222", "default"],
5061
"color": { "light": "#00000a", "dark": "#700000" }
5162
},
5263
{
64+
"colorOptionName": "--name1-name2-sun-111-moon-222-hover",
5365
"themePath": ["name1Name2", "sun111moon222", "hover"],
5466
"color": { "light": "#00000b", "dark": "#800000" }
5567
},
5668
{
69+
"colorOptionName": "--grey-1000-50-hover",
5770
"themePath": ["grey", "_1000_50", "hover"],
5871
"color": { "light": "#00000c", "dark": "#900000" }
5972
},
6073
{
74+
"colorOptionName": "--blue-france-sun-113-625",
6175
"themePath": ["blueFrance", "sun113_625", "default"],
6276
"color": { "light": "#00000d", "dark": "#a00000" }
6377
},
6478
{
79+
"colorOptionName": "--blue-france-sun-113-625-active",
6580
"themePath": ["blueFrance", "sun113_625", "active"],
6681
"color": { "light": "#00000e", "dark": "#b00000" }
6782
},
6883
{
84+
"colorOptionName": "--blue-france-main-525",
6985
"themePath": ["blueFrance", "main525", "default"],
7086
"color": "#00000f"
7187
},
7288
{
89+
"colorOptionName": "--purple-glycine-sun-319-moon-630-hover",
7390
"themePath": ["purpleGlycine", "sun319moon630", "hover"],
7491
"color": { "light": "#000010", "dark": "#c00000" }
7592
}

0 commit comments

Comments
 (0)