Skip to content

Commit b9ebdd1

Browse files
committed
Better breakpoints API
1 parent ec0cfd8 commit b9ebdd1

File tree

5 files changed

+91
-13
lines changed

5 files changed

+91
-13
lines changed

scripts/build/cssToTs/breakpoints.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,15 @@ export function generateBreakpointsTsCode(rawCssCode: string): string {
149149
`import { assert } from "tsafe/assert";`,
150150
`import type { Extends } from "tsafe";`,
151151
``,
152-
`export const BreakpointsValuesUnit = "em";`,
152+
`export const breakpointsValuesUnit = "em";`,
153153
``,
154154
`export const breakpointKeys = ["xs", ${sortedKeys
155155
.map(key => `"${key}"`)
156156
.join(", ")}] as const;`,
157157
``,
158158
`export type BreakpointKeys = typeof breakpointKeys[number];`,
159159
``,
160-
`export const BreakpointsValues = {`,
160+
`export const breakpointsValues = {`,
161161
JSON.stringify(
162162
Object.fromEntries(
163163
(["xs", ...sortedKeys] as const).map(key => [
@@ -176,7 +176,7 @@ export function generateBreakpointsTsCode(rawCssCode: string): string {
176176
.join("\n"),
177177
`} as const;`,
178178
``,
179-
`assert<Extends<typeof BreakpointsValues, Record<BreakpointKeys, number>>>();`,
179+
`assert<Extends<typeof breakpointsValues, Record<BreakpointKeys, number>>>();`,
180180
``
181181
].join("\n");
182182
}

src/fr/breakpoints.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { BreakpointKeys } from "./generatedFromCss/breakpoints";
22
import {
3-
BreakpointsValues as values,
4-
BreakpointsValuesUnit as unit,
3+
breakpointsValues as values,
4+
breakpointsValuesUnit as unit,
55
breakpointKeys as keys
66
} from "./generatedFromCss/breakpoints";
77
import { type Equals, assert } from "tsafe/assert";
@@ -43,21 +43,51 @@ export const breakpoints = {
4343
.between(key, keys[keys.indexOf(key) + 1])
4444
.replace("@media", "@media not all and");
4545
},
46+
"values": (() => {
47+
const out = {
48+
...(() => {
49+
const key = "sm" satisfies BreakpointKeys;
50+
51+
return { [key]: `${values[key]}${unit}` as const };
52+
})(),
53+
...(() => {
54+
const key = "md" satisfies BreakpointKeys;
55+
56+
return { [key]: `${values[key]}${unit}` as const };
57+
})(),
58+
...(() => {
59+
const key = "lg" satisfies BreakpointKeys;
60+
61+
return { [key]: `${values[key]}${unit}` as const };
62+
})(),
63+
...(() => {
64+
const key = "xl" satisfies BreakpointKeys;
65+
66+
return { [key]: `${values[key]}${unit}` as const };
67+
})()
68+
};
69+
70+
assert<Equals<keyof typeof out | "xs", BreakpointKeys>>();
71+
72+
return out;
73+
})(),
4674
/**
4775
* Returns the breakpoint values in px.
4876
*
4977
* Warning: It reflects the values at a given time, if the root font size changes so will the breakpointsValues.
5078
* Plus this function is rather expensive to call.
5179
* If you're in react you should use the
52-
* import { useBreakpointsValues } from "@codegouvfr/react-dsfr/useBreakpointsValues";
80+
* import { useBreakpointsValuesPx } from "@codegouvfr/react-dsfr/useBreakpointsValuesPx";
5381
*/
54-
"getBreakpointsValues": (): BreakpointsValues => {
82+
"getPxValues": (): BreakpointsValues => {
5583
assert<Equals<typeof unit, "em">>();
5684

5785
const factor = getBaseFontSizePx();
5886

5987
return Object.fromEntries(
6088
Object.entries(values).map(([key, value]) => [key, value * factor])
6189
) as any;
62-
}
90+
},
91+
/** @deprecated use breakpoints.values if you're ok with getting the value in em or breakpoints.getPxValues() if you want the value in pixel */
92+
"getBreakpointsValues": () => breakpoints.getPxValues()
6393
};

src/useBreakpointsValues.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import { breakpoints, type BreakpointKeys, type BreakpointsValues } from "./fr/b
44

55
export type { BreakpointKeys, BreakpointsValues };
66

7-
/** Return the breakpoint values in px, the values ger refreshed
8-
* when the base font size change. */
7+
/** @deprecated Use import { useBreakpointsValuesPx } from "@codegouvfr/react-dsfr/useBreakpointsValuesPx"; instead */
98
export function useBreakpointsValues() {
109
const [breakpointsValuesDependency, triggerRefresh] = useReducer(() => ({}), {});
1110

src/useBreakpointsValuesPx.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { useReducer, useEffect, useMemo } from "react";
2+
import { assert } from "tsafe/assert";
3+
import { breakpoints, type BreakpointKeys, type BreakpointsValues } from "./fr/breakpoints";
4+
5+
export type { BreakpointKeys, BreakpointsValues };
6+
7+
/** Return the breakpoint values in px, the values ger refreshed
8+
* when the base font size change. */
9+
export function useBreakpointsValuesPx() {
10+
const [breakpointsValuesDependency, triggerRefresh] = useReducer(() => ({}), {});
11+
12+
useEffect(() => {
13+
const htmlElement = document.querySelector("html");
14+
15+
assert(htmlElement !== null);
16+
17+
// Create a new MutationObserver to detect changes in the base font size
18+
const observer = new MutationObserver(mutationsList => {
19+
if (
20+
mutationsList.find(
21+
mutation =>
22+
mutation.target === htmlElement &&
23+
mutation.attributeName === "style" &&
24+
(mutation.oldValue ?? "").indexOf("font-size") !== -1
25+
) !== undefined
26+
) {
27+
triggerRefresh();
28+
}
29+
});
30+
31+
// Observe changes to the style attribute of the html element
32+
observer.observe(htmlElement, {
33+
"attributes": true,
34+
"attributeOldValue": true,
35+
"attributeFilter": ["style"]
36+
});
37+
38+
return () => {
39+
observer.disconnect();
40+
};
41+
}, []);
42+
43+
const breakpointsValues = useMemo(
44+
() => breakpoints.getPxValues(),
45+
[breakpointsValuesDependency]
46+
);
47+
48+
return { breakpointsValues };
49+
}

test/runtime/scripts/breakpoints/generateBreakpointsTsCode.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,21 @@ it("Generation of TS code for breakpoints", () => {
4545
import { assert } from "tsafe/assert";
4646
import type { Extends } from "tsafe";
4747
48-
export const BreakpointsValuesUnit = "em";
48+
export const breakpointsValuesUnit = "em";
4949
5050
export const breakpointKeys = ["xs", "sm", "md", "lg", "xl"] as const;
5151
5252
export type BreakpointKeys = typeof breakpointKeys[number];
5353
54-
export const BreakpointsValues = {
54+
export const breakpointsValues = {
5555
"xs": 0,
5656
"sm": 36,
5757
"md": 48,
5858
"lg": 62,
5959
"xl": 78
6060
} as const;
6161
62-
assert<Extends<typeof BreakpointsValues, Record<BreakpointKeys, number>>>();
62+
assert<Extends<typeof breakpointsValues, Record<BreakpointKeys, number>>>();
6363
`.replace(/^\n/, "");
6464

6565
const got = generateBreakpointsTsCode(input);

0 commit comments

Comments
 (0)