Skip to content

Commit d9c7df1

Browse files
committed
Alternative artwork for display component in white label mode
1 parent 4357a80 commit d9c7df1

File tree

8 files changed

+181
-58
lines changed

8 files changed

+181
-58
lines changed

src/Display/Artwork/Artwork.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"use client";
2+
3+
import React, { Suspense, lazy } from "react";
4+
import { ArtworkGov } from "./ArtworkGov";
5+
import { useIsGov } from "../../mui/useIsGov";
6+
const ArtworkWhiteLabel = lazy(() => import("./ArtworkWhiteLabel"));
7+
8+
export function Artwork(props: { theme: "light" | "dark" | "system" }) {
9+
const { theme } = props;
10+
11+
const { isGov } = useIsGov();
12+
13+
if (!isGov) {
14+
return (
15+
<Suspense>
16+
<ArtworkWhiteLabel theme={theme} sizePx={80} />
17+
</Suspense>
18+
);
19+
}
20+
21+
return <ArtworkGov theme={theme} />;
22+
}

src/Display/Artwork/ArtworkGov.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from "react";
2+
import { fr } from "../../fr";
3+
import ArtworkLightSvg from "../../dsfr/artwork/light.svg";
4+
import ArtworkDarkSvg from "../../dsfr/artwork/dark.svg";
5+
import ArtworkSystemSvg from "../../dsfr/artwork/system.svg";
6+
import { getAssetUrl } from "../../tools/getAssetUrl";
7+
8+
export function ArtworkGov(props: { theme: "light" | "dark" | "system" }) {
9+
const { theme } = props;
10+
11+
return (
12+
<svg
13+
aria-hidden="true"
14+
xmlns="http://www.w3.org/2000/svg"
15+
//className={fr.cx("fr-artwork")}
16+
width="80px"
17+
height="80px"
18+
viewBox="0 0 80 80"
19+
>
20+
{(["artwork-decorative", "artwork-minor", "artwork-major"] as const).map(label => (
21+
<use
22+
key={label}
23+
className={fr.cx(`fr-${label}`)}
24+
xlinkHref={`${getAssetUrl(
25+
(() => {
26+
switch (theme) {
27+
case "dark":
28+
return ArtworkDarkSvg;
29+
case "light":
30+
return ArtworkLightSvg;
31+
case "system":
32+
return ArtworkSystemSvg;
33+
}
34+
})()
35+
)}#${label}`}
36+
/>
37+
))}
38+
</svg>
39+
);
40+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"use client";
2+
3+
import React from "react";
4+
import { useTheme } from "@mui/material/styles";
5+
import { assert, type Equals } from "tsafe/assert";
6+
7+
export default function ArtworkWhiteLabel(props: {
8+
theme: "light" | "dark" | "system";
9+
sizePx?: number;
10+
}) {
11+
const { theme, sizePx = 24 } = props;
12+
13+
switch (theme) {
14+
case "light":
15+
return <LightMode sizePx={sizePx} />;
16+
case "dark":
17+
return <DarkMode sizePx={sizePx} />;
18+
case "system":
19+
return <AutoMode sizePx={sizePx} />;
20+
default:
21+
assert<Equals<typeof theme, never>>(false);
22+
}
23+
}
24+
25+
function LightMode(props: { sizePx: number }) {
26+
const { sizePx } = props;
27+
28+
const theme = useTheme();
29+
30+
return (
31+
<svg
32+
xmlns="http://www.w3.org/2000/svg"
33+
height={sizePx}
34+
viewBox={`0 0 24 ${sizePx}`}
35+
width={sizePx}
36+
fill={theme.palette.primary.main}
37+
>
38+
<path d="M0 0h24v24H0z" fill="none" />
39+
<path d="M20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zm0-10c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z" />
40+
</svg>
41+
);
42+
}
43+
44+
function AutoMode(props: { sizePx: number }) {
45+
const { sizePx } = props;
46+
47+
const theme = useTheme();
48+
49+
return (
50+
<svg
51+
xmlns="http://www.w3.org/2000/svg"
52+
height={sizePx}
53+
viewBox={`"0 0 ${sizePx} ${sizePx}`}
54+
width={sizePx}
55+
fill={theme.palette.primary.main}
56+
>
57+
<path d="M0 0h24v24H0z" fill="none" />
58+
<path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02zM8 16h2.5l1.5 1.5 1.5-1.5H16v-2.5l1.5-1.5-1.5-1.5V8h-2.5L12 6.5 10.5 8H8v2.5L6.5 12 8 13.5V16zm4-7c1.66 0 3 1.34 3 3s-1.34 3-3 3V9z" />
59+
</svg>
60+
);
61+
}
62+
63+
function DarkMode(props: { sizePx: number }) {
64+
const { sizePx } = props;
65+
66+
const theme = useTheme();
67+
68+
return (
69+
<svg
70+
xmlns="http://www.w3.org/2000/svg"
71+
enable-background={`new 0 0 ${sizePx} ${sizePx}`}
72+
height={sizePx}
73+
viewBox={`0 0 ${sizePx} ${sizePx}`}
74+
width={sizePx}
75+
fill={theme.palette.primary.main}
76+
>
77+
<rect fill="none" height={sizePx} width={sizePx} />
78+
<path d="M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36c-0.98,1.37-2.58,2.26-4.4,2.26 c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z" />
79+
</svg>
80+
);
81+
}

src/Display/Artwork/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Artwork";

src/Display/Display.tsx

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1+
"use client";
2+
13
import React, { useId } from "react";
24
import { fr } from "../fr";
35
import { symToStr } from "tsafe/symToStr";
46
import { createComponentI18nApi } from "../i18n";
5-
import ArtworkLightSvg from "../dsfr/artwork/light.svg";
6-
import ArtworkDarkSvg from "../dsfr/artwork/dark.svg";
7-
import ArtworkSystemSvg from "../dsfr/artwork/system.svg";
8-
import { getAssetUrl } from "../tools/getAssetUrl";
97
import type { HeaderProps } from "../Header";
108
import type { FooterProps } from "../Footer";
119
import { createModal } from "../Modal";
10+
import { Artwork } from "./Artwork";
1211

1312
const modal = createModal({
1413
"isOpenedByDefault": false,
@@ -75,39 +74,7 @@ export function Display() {
7574
)}
7675
</label>
7776
<div className={fr.cx("fr-radio-rich__img")}>
78-
<svg
79-
aria-hidden="true"
80-
xmlns="http://www.w3.org/2000/svg"
81-
//className={fr.cx("fr-artwork")}
82-
width="80px"
83-
height="80px"
84-
viewBox="0 0 80 80"
85-
>
86-
{(
87-
[
88-
"artwork-decorative",
89-
"artwork-minor",
90-
"artwork-major"
91-
] as const
92-
).map(label => (
93-
<use
94-
key={label}
95-
className={fr.cx(`fr-${label}`)}
96-
xlinkHref={`${getAssetUrl(
97-
(() => {
98-
switch (theme) {
99-
case "dark":
100-
return ArtworkDarkSvg;
101-
case "light":
102-
return ArtworkLightSvg;
103-
case "system":
104-
return ArtworkSystemSvg;
105-
}
106-
})()
107-
)}#${label}`}
108-
/>
109-
))}
110-
</svg>
77+
<Artwork theme={theme} />
11178
</div>
11279
</div>
11380
))}

src/mui/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./mui";
2+
export { useIsGov } from "./useIsGov";

src/mui.tsx renamed to src/mui/mui.tsx

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
"use client";
22

33
/* eslint-disable @typescript-eslint/no-non-null-assertion */
4-
import React, { useMemo, useEffect, createContext, useContext, type ReactNode } from "react";
4+
import React, { useMemo, useEffect, type ReactNode } from "react";
55
import * as mui from "@mui/material/styles";
66
import type { Shadows } from "@mui/material/styles";
7-
import { fr } from "./fr";
8-
import { useIsDark } from "./useIsDark";
9-
import { typography } from "./fr/generatedFromCss/typography";
10-
import { spacingTokenByValue } from "./fr/generatedFromCss/spacing";
7+
import { fr } from "../fr";
8+
import { useIsDark } from "../useIsDark";
9+
import { typography } from "../fr/generatedFromCss/typography";
10+
import { spacingTokenByValue } from "../fr/generatedFromCss/spacing";
1111
import { assert } from "tsafe/assert";
1212
import { objectKeys } from "tsafe/objectKeys";
1313
import { id } from "tsafe/id";
14-
import { useBreakpointsValuesPx, type BreakpointsValues } from "./useBreakpointsValuesPx";
15-
import { structuredCloneButFunctions } from "./tools/structuredCloneButFunctions";
16-
import { deepAssign } from "./tools/deepAssign";
14+
import { useBreakpointsValuesPx, type BreakpointsValues } from "../useBreakpointsValuesPx";
15+
import { structuredCloneButFunctions } from "../tools/structuredCloneButFunctions";
16+
import { deepAssign } from "../tools/deepAssign";
1717
import { Global, css } from "@emotion/react";
18-
import { getAssetUrl } from "./tools/getAssetUrl";
19-
import marianneFaviconSvgUrl from "./dsfr/favicon/favicon.svg";
20-
import blankFaviconSvgUrl from "./assets/blank-favicon.svg";
18+
import { getAssetUrl } from "../tools/getAssetUrl";
19+
import { IsGovProvider } from "./useIsGov";
20+
import marianneFaviconSvgUrl from "../dsfr/favicon/favicon.svg";
21+
import blankFaviconSvgUrl from "../assets/blank-favicon.svg";
2122

2223
export function getMuiDsfrThemeOptions(params: {
2324
isDark: boolean;
@@ -574,20 +575,12 @@ export function createDsfrCustomBrandingProvider(params: {
574575
})}
575576
/>
576577
)}
577-
<context_isGov.Provider value={isGov}>
578+
<IsGovProvider isGov={isGov}>
578579
<mui.ThemeProvider theme={theme}>{children}</mui.ThemeProvider>
579-
</context_isGov.Provider>
580+
</IsGovProvider>
580581
</>
581582
);
582583
}
583584

584585
return { DsfrCustomBrandingProvider };
585586
}
586-
587-
const context_isGov = createContext<boolean>(true);
588-
589-
export function useIsGov() {
590-
const isGov = useContext(context_isGov);
591-
592-
return { isGov };
593-
}

src/mui/useIsGov.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"use client";
2+
3+
import React, { createContext, useContext, type ReactNode } from "react";
4+
5+
const react = createContext<boolean>(true);
6+
7+
export function useIsGov() {
8+
const isGov = useContext(react);
9+
10+
return { isGov };
11+
}
12+
13+
export function IsGovProvider(props: { children: ReactNode; isGov: boolean }) {
14+
const { children, isGov } = props;
15+
16+
return <react.Provider value={isGov}>{children}</react.Provider>;
17+
}

0 commit comments

Comments
 (0)