Skip to content

Commit 38210cc

Browse files
committed
Parse breakpoint value
1 parent f5d522d commit 38210cc

File tree

10 files changed

+363
-10
lines changed

10 files changed

+363
-10
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
"tsafe": "^1.0.1"
7777
},
7878
"devDependencies": {
79+
"@emotion/react": "^11.10.4",
80+
"@emotion/styled": "^11.10.4",
81+
"@mui/material": "^5.10.7",
7982
"@types/css": "^0.0.33",
8083
"@types/node": "^18.7.18",
8184
"@types/react": "18.0.21",
@@ -93,7 +96,6 @@
9396
"react": "18.2.0",
9497
"rimraf": "^3.0.2",
9598
"ts-node": "^10.2.1",
96-
"@mui/material": "^5.10.7",
9799
"typescript": "^4.8.3"
98100
}
99101
}

src/bin/css_to_ts/breakpoints.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import css from "css";
2+
import { assert } from "tsafe/assert";
3+
4+
export type BreakpointsValues = {
5+
unit: string /* em, px ... */;
6+
sm: number;
7+
md: number;
8+
lg: number;
9+
xl: number;
10+
};
11+
12+
export function parseBreakpointsValues(rawCssCode: string): BreakpointsValues {
13+
const parsedCss = css.parse(rawCssCode);
14+
15+
let prevUnit: string | undefined = undefined;
16+
17+
const values: number[] = [];
18+
19+
parsedCss.stylesheet?.rules
20+
.filter(rule => rule.type === "media")
21+
.forEach(rule => {
22+
const match = (rule as { media: string }).media.match(
23+
/^\(min-width:\s*([0-9]+)([^)]+)\)$/
24+
);
25+
26+
if (match === null) {
27+
return;
28+
}
29+
30+
const [, valueStr, unit] = match;
31+
32+
if (prevUnit === undefined) {
33+
prevUnit = unit;
34+
} else {
35+
assert(prevUnit === unit);
36+
}
37+
38+
values.push(parseFloat(valueStr));
39+
});
40+
41+
assert(values.length === 4);
42+
assert(prevUnit !== undefined);
43+
44+
const [sm, md, lg, xl] = values;
45+
46+
return {
47+
"unit": prevUnit,
48+
sm,
49+
md,
50+
lg,
51+
xl
52+
};
53+
}
54+
55+
export function generateBreakpointsValuesTsCode(breakpointsValues: BreakpointsValues): string {
56+
return [
57+
`export const breakpointsValues = {`,
58+
JSON.stringify(breakpointsValues, null, 2)
59+
.replace(/^{\n/, "")
60+
.replace(/\n}$/, "")
61+
.split("\n")
62+
.map(line => line.replace(/^[ ]{2}/, ""))
63+
.map(line => ` ${line}`)
64+
.join("\n"),
65+
`} as const;`
66+
].join("\n");
67+
}

src/bin/css_to_ts/colorDecisions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export function parseColorDecision(params: {
174174

175175
const { declarations } = (() => {
176176
const node = parsedCss.stylesheet?.rules.find(
177-
rule => rule.type === "rule" && (rule as any)?.selectors?.[0] === ":root"
177+
rule => rule.type === "rule" && (rule as any).selectors?.[0] === ":root"
178178
);
179179

180180
assert(node !== undefined);

src/bin/css_to_ts/colorOptions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ export function parseColorOptions(rawCssCode: string): ColorOption[] {
345345
const node = parsedCss.stylesheet?.rules.find(
346346
rule =>
347347
rule.type === "rule" &&
348-
(rule as any)?.selectors?.[0] === `:root:where([${data_fr_theme}="dark"])`
348+
(rule as any).selectors?.[0] === `:root:where([${data_fr_theme}="dark"])`
349349
);
350350

351351
assert(node !== undefined);

src/lib/mui.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ function createMuiDsfrThemeFromTheme(params: { theme: Theme }): MuiTheme {
1212

1313
/*
1414
const muiTheme = createMuiTheme({
15+
"shape": {
16+
"borderRadius": 0
17+
},
18+
"breakpoints": {
19+
"unit": "em",
20+
"values": {
21+
"xs": 0,
22+
"sm": number,
23+
"md": number,
24+
"lg": number,
25+
"xl": number,
26+
},
27+
},
1528
"typography": createMuiTypographyOptions({
1629
typographyDesc,
1730
}),
@@ -21,9 +34,6 @@ function createMuiDsfrThemeFromTheme(params: { theme: Theme }): MuiTheme {
2134
useCases,
2235
}),
2336
spacing,
24-
"breakpoints": {
25-
"values": { "xs": 0, ...breakpointsValues },
26-
},
2737
"components": {
2838
"MuiLink": {
2939
"defaultProps": {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { generateBreakpointsValuesTsCode } from "../../../bin/css_to_ts/breakpoints";
2+
import type { BreakpointsValues } from "../../../bin/css_to_ts/breakpoints";
3+
import { assert } from "tsafe/assert";
4+
5+
console.log(`Running test ${__filename}`);
6+
7+
const input: BreakpointsValues = {
8+
"unit": "em",
9+
"sm": 36,
10+
"md": 48,
11+
"lg": 62,
12+
"xl": 78
13+
};
14+
15+
const expected = `
16+
export const breakpointsValues = {
17+
"unit": "em",
18+
"sm": 36,
19+
"md": 48,
20+
"lg": 62,
21+
"xl": 78
22+
} as const;`.replace(/^\n/, "");
23+
24+
const got = generateBreakpointsValuesTsCode(input);
25+
26+
assert(got === expected);
27+
28+
console.log("PASS");

src/test/bin/breakpoints/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import "./parseBreakpointsValues";
2+
import "./generateBreakpointsValuesTsCode";
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { parseBreakpointsValues } from "../../../bin/css_to_ts/breakpoints";
2+
import type { BreakpointsValues } from "../../../bin/css_to_ts/breakpoints";
3+
import { assert } from "tsafe/assert";
4+
import { same } from "evt/tools/inDepth/same";
5+
6+
console.log(`Running test ${__filename}`);
7+
8+
const input = `
9+
@media (min-width: 36em) {
10+
/*! media sm */
11+
12+
/*! media sm */
13+
.fr-hidden-sm {
14+
display: none !important;
15+
}
16+
}
17+
18+
@media (min-width: 48em) {
19+
/*! media md */
20+
21+
/*! media md */
22+
h6 {
23+
font-size: 1.25rem;
24+
line-height: 1.75rem;
25+
}
26+
}
27+
28+
@media (min-width: 62em) {
29+
/*! media lg */
30+
31+
/*! media lg */
32+
.fr-hidden-lg {
33+
display: none !important;
34+
}
35+
}
36+
37+
@media (min-width: 78em) {
38+
/*! media xl */
39+
40+
/*! media xl */
41+
.fr-hidden-xl {
42+
display: none !important;
43+
}
44+
}
45+
`;
46+
47+
const expected: BreakpointsValues = {
48+
"unit": "em",
49+
"sm": 36,
50+
"md": 48,
51+
"lg": 62,
52+
"xl": 78
53+
};
54+
55+
const got = parseBreakpointsValues(input);
56+
57+
assert(same(got, expected));
58+
59+
console.log("PASS");

src/test/bin/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
import "./colorOptions";
22
import "./colorDecisions";
3+
import "./breakpoints";

0 commit comments

Comments
 (0)