Skip to content

Commit 2280c8d

Browse files
committed
Do the patching of the dsfr.css ahead of time
1 parent 9365c66 commit 2280c8d

File tree

6 files changed

+59
-64
lines changed

6 files changed

+59
-64
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@
7070
"dependencies": {
7171
"@gouvfr/dsfr": "1.7.2",
7272
"remixicon": "^2.5.0",
73-
"tsafe": "^1.1.1",
74-
"css": "^3.0.0"
73+
"tsafe": "^1.1.1"
7574
},
7675
"devDependencies": {
7776
"@emotion/react": "^11.10.4",

src/bin/copy_dsfr_dist_to_root.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { join as pathJoin } from "path";
22
import * as fs from "fs";
33
import { getProjectRoot } from "./tools/getProjectRoot";
4+
import {
5+
pathOfPatchedRawCssCodeForCompatWithRemixIconRelativeToDsfrDist,
6+
getPatchedRawCssCodeForCompatWithRemixIcon
7+
} from "./css_to_ts/icons";
48

59
const projectRootDirPath = getProjectRoot();
610

@@ -13,3 +17,15 @@ if (fs.existsSync(dsfrDirPath)) {
1317
fs.cpSync(pathJoin(projectRootDirPath, "node_modules", "@gouvfr", "dsfr", "dist"), dsfrDirPath, {
1418
"recursive": true
1519
});
20+
21+
(async () => {
22+
fs.writeFileSync(
23+
pathJoin(dsfrDirPath, pathOfPatchedRawCssCodeForCompatWithRemixIconRelativeToDsfrDist),
24+
Buffer.from(
25+
await getPatchedRawCssCodeForCompatWithRemixIcon({
26+
"rawCssCode": fs.readFileSync(pathJoin(dsfrDirPath, "dsfr.css")).toString("utf8")
27+
}),
28+
"utf8"
29+
)
30+
);
31+
})();

src/bin/css_to_ts/icons.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
import memoize from "memoizee";
21
import type { Icon } from "./css_to_ts";
3-
import { parseCss } from "./parseCss";
4-
import * as css from "css";
52
import { exclude } from "tsafe/exclude";
3+
import { join as pathJoin } from "path";
64

75
type IconLike = Icon.Dsfr | Omit<Icon.Remixicon, "rawSvgCode">;
86

97
export function generateIconsRawCssCode(params: {
108
usedIcons: IconLike[];
11-
rawCssCode: string;
9+
patchedRawCssCodeForCompatWithRemixIcon: string;
1210
}): string {
13-
const { usedIcons, rawCssCode } = params;
11+
const { usedIcons, patchedRawCssCodeForCompatWithRemixIcon } = params;
1412

1513
const buildRule = (icon: IconLike, isHighContrast: boolean) => {
1614
const { iconId, prefix } = icon;
@@ -52,17 +50,24 @@ export function generateIconsRawCssCode(params: {
5250
`}`,
5351
``
5452
]),
55-
...(usedIcons.find(({ prefix }) => prefix === "ri-") !== undefined
56-
? [
57-
`/* This is all the parts of dsfr.css related to icons with .fr-icon- replaced by .ri- so that we can use remixicon as dsfr icons*/`,
58-
getPatchedRawCssCodeForCompatWithRemixIcon(rawCssCode)
59-
]
60-
: [])
53+
...(usedIcons.find(({ prefix }) => prefix === "ri-") === undefined
54+
? []
55+
: [patchedRawCssCodeForCompatWithRemixIcon])
6156
].join("\n");
6257
}
6358

64-
export const getPatchedRawCssCodeForCompatWithRemixIcon = memoize((rawCssCode: string) => {
65-
const parsedCss = parseCss(rawCssCode);
59+
export const pathOfPatchedRawCssCodeForCompatWithRemixIconRelativeToDsfrDist = pathJoin(
60+
"utility",
61+
"icons",
62+
"dsfr_remixicon.css"
63+
);
64+
65+
export async function getPatchedRawCssCodeForCompatWithRemixIcon(params: { rawCssCode: string }) {
66+
const { rawCssCode } = params;
67+
68+
const css = await import("css");
69+
70+
const parsedCss = css.parse(rawCssCode);
6671

6772
const prefixRegExp = /fr-icon-[^-]/;
6873

@@ -103,4 +108,4 @@ export const getPatchedRawCssCodeForCompatWithRemixIcon = memoize((rawCssCode: s
103108
.filter(exclude(undefined));
104109

105110
return css.stringify(parsedCss).replace(/fr-icon-/g, "ri-");
106-
});
111+
}

src/bin/only_include_used_icons.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env node
22
import { collectIcons } from "./css_to_ts";
3-
import { generateIconsRawCssCode } from "./css_to_ts/icons";
3+
import {
4+
generateIconsRawCssCode,
5+
pathOfPatchedRawCssCodeForCompatWithRemixIconRelativeToDsfrDist
6+
} from "./css_to_ts/icons";
47
import { getProjectRoot } from "./tools/getProjectRoot";
58
import * as fs from "fs";
69
import { join as pathJoin } from "path";
@@ -137,7 +140,14 @@ import type { Equals } from "tsafe";
137140

138141
const rawIconCssCodeBuffer = Buffer.from(
139142
generateIconsRawCssCode({
140-
"rawCssCode": fs.readFileSync(pathJoin(dsfrDistDirPath, "dsfr.css")).toString("utf8"),
143+
"patchedRawCssCodeForCompatWithRemixIcon": fs
144+
.readFileSync(
145+
pathJoin(
146+
dsfrDistDirPath,
147+
pathOfPatchedRawCssCodeForCompatWithRemixIconRelativeToDsfrDist
148+
)
149+
)
150+
.toString("utf8"),
141151
usedIcons
142152
}),
143153
"utf8"

test/behavior/bin/icons/generateIconsRawCssCode.test.ts

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@ import { it, expect } from "vitest";
22
import { generateIconsRawCssCode } from "../../../../src/bin/css_to_ts/icons";
33

44
it("Successfully css with only used icons", () => {
5-
const rawCssCode = `
6-
[target=_blank]::after {
7-
flex: 0 0 auto;
8-
}
9-
10-
[target=_blank][class^=fr-icon-]::after,
11-
[target=_blank][class*=" fr-icon-"]::after,
5+
const patchedRawCssCodeForCompatWithRemixIcon = `
6+
[target=_blank][class^=ri-]::after,
7+
[target=_blank][class*=" ri-"]::after,
128
[target=_blank][class^=fr-fi-]::after,
139
[target=_blank][class*=" fr-fi-"]::after {
1410
flex: 0 0 auto;
@@ -26,19 +22,14 @@ it("Successfully css with only used icons", () => {
2622
margin-left: 0.25rem;
2723
}
2824
29-
.fr-icon--xs::before,
30-
.fr-icon--xs::after {
31-
--icon-size: 0.75rem;
32-
}
33-
34-
.fr-btns-group--sm .fr-btn:not([class^=fr-icon-]):not([class*=" fr-icon-"]):not([class^=fr-fi-]):not([class*=" fr-fi-"]) {
25+
.fr-btns-group--sm .fr-btn:not([class^=ri-]):not([class*=" ri-"]):not([class^=fr-fi-]):not([class*=" fr-fi-"]) {
3526
font-size: 0.875rem;
3627
line-height: 1.5rem;
3728
min-height: 2rem;
3829
padding: 0.25rem 0.75rem;
3930
}
4031
41-
.fr-follow__social .fr-btns-group:not(.fr-btns-group--sm):not(.fr-btns-group--lg) .fr-btn:not([class^=fr-icon-]):not([class*=" fr-icon-"]):not([class^=fr-fi-]):not([class*=" fr-fi-"]) {
32+
.fr-follow__social .fr-btns-group:not(.fr-btns-group--sm):not(.fr-btns-group--lg) .fr-btn:not([class^=ri-]):not([class*=" ri-"]):not([class^=fr-fi-]):not([class*=" fr-fi-"]) {
4233
font-size: 1rem;
4334
line-height: 1.5rem;
4435
min-height: 2.5rem;
@@ -52,18 +43,8 @@ it("Successfully css with only used icons", () => {
5243
}
5344
5445
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
55-
.fr-enlarge-link [href] {
56-
text-decoration: none;
57-
}
58-
59-
[href],
60-
.fr-reset-link {
61-
text-decoration: underline;
62-
}
63-
64-
65-
[class^=fr-icon-]::before,
66-
[class*=" fr-icon-"]::before,
46+
[class^=ri-]::before,
47+
[class*=" ri-"]::before,
6748
[class^=fr-fi-]::before,
6849
[class*=" fr-fi-"]::before {
6950
background-color: transparent;
@@ -72,22 +53,7 @@ it("Successfully css with only used icons", () => {
7253
width: 1.5rem;
7354
height: 1.5rem;
7455
}
75-
76-
.fr-icon--xs::before {
77-
width: 0.75rem;
78-
height: 0.75rem;
79-
}
80-
81-
}
82-
83-
@media (min-width: 36em) { }
84-
85-
@media (min-width: 48em) { }
86-
87-
@media (min-width: 62em) { }
88-
89-
@media (min-width: 78em) { }
90-
`;
56+
}`.replace(/^\n/, "");
9157

9258
const expected = `
9359
.fr-icon-ancient-gate-fill::before,
@@ -126,7 +92,6 @@ it("Successfully css with only used icons", () => {
12692
12793
}
12894
129-
/* This is all the parts of dsfr.css related to icons with .fr-icon- replaced by .ri- so that we can use remixicon as dsfr icons*/
13095
[target=_blank][class^=ri-]::after,
13196
[target=_blank][class*=" ri-"]::after,
13297
[target=_blank][class^=fr-fi-]::after,
@@ -180,7 +145,7 @@ it("Successfully css with only used icons", () => {
180145
}`.replace(/^\n/, "");
181146

182147
const got = generateIconsRawCssCode({
183-
rawCssCode,
148+
patchedRawCssCodeForCompatWithRemixIcon,
184149
"usedIcons": [
185150
{
186151
"prefix": "fr-icon-",

test/behavior/bin/icons/getPatchedRawCssCodeForCompatWithRemixIcon.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { it, expect } from "vitest";
22
import { getPatchedRawCssCodeForCompatWithRemixIcon } from "../../../../src/bin/css_to_ts/icons";
33

4-
it("Successfully generates patched css for remixicon support", () => {
4+
it("Successfully generates patched css for remixicon support", async () => {
55
const rawCssCode = `
66
[target=_blank]::after {
77
flex: 0 0 auto;
@@ -142,7 +142,7 @@ it("Successfully generates patched css for remixicon support", () => {
142142
}
143143
}`.replace(/^\n/, "");
144144

145-
const got = getPatchedRawCssCodeForCompatWithRemixIcon(rawCssCode);
145+
const got = await getPatchedRawCssCodeForCompatWithRemixIcon({ rawCssCode });
146146

147147
expect(got).toEqual(expected);
148148
});

0 commit comments

Comments
 (0)