Skip to content

Commit c359951

Browse files
committed
Better support of the "system" color scheme #347
1 parent 04e3b02 commit c359951

File tree

2 files changed

+54
-38
lines changed

2 files changed

+54
-38
lines changed

src/useIsDark/client.ts

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { assert } from "tsafe/assert";
1+
import { assert, type Equals } from "tsafe/assert";
2+
import { isAmong } from "tsafe/isAmong";
23
import { createStatefulObservable, useRerenderOnChange } from "../tools/StatefulObservable";
34
import { useConstCallback } from "../tools/powerhooks/useConstCallback";
45
import { fr } from "../fr";
@@ -54,14 +55,14 @@ export const useIsDarkClientSide: UseIsDark = () => {
5455
newIsDarkOrDeduceNewIsDarkFromCurrentIsDark => {
5556
const data_fr_js_value = document.documentElement.getAttribute("data-fr-js");
5657

57-
const newColorScheme = ((): ColorScheme => {
58+
const newColorScheme = ((): ColorScheme | "system" => {
5859
switch (
5960
typeof newIsDarkOrDeduceNewIsDarkFromCurrentIsDark === "function"
6061
? newIsDarkOrDeduceNewIsDarkFromCurrentIsDark(isDark)
6162
: newIsDarkOrDeduceNewIsDarkFromCurrentIsDark
6263
) {
6364
case "system":
64-
return getSystemColorScheme();
65+
return "system";
6566
case true:
6667
return "dark";
6768
case false:
@@ -73,7 +74,10 @@ export const useIsDarkClientSide: UseIsDark = () => {
7374

7475
if (data_fr_js_value !== "true") {
7576
//NOTE: DSFR not started yet.
76-
document.documentElement.setAttribute(data_fr_theme, newColorScheme);
77+
document.documentElement.setAttribute(
78+
data_fr_theme,
79+
newColorScheme === "system" ? getSystemColorScheme() : newColorScheme
80+
);
7781
localStorage.setItem("scheme", newColorScheme);
7882
}
7983
}
@@ -118,7 +122,7 @@ export function startClientSideIsDarkLogic(params: {
118122
} = params;
119123

120124
reset_persisted_value_if_website_config_changed: {
121-
const localStorageKey = "scheme-default";
125+
const localStorageKey = "scheme-website-config-default";
122126

123127
const localStorageValue = localStorage.getItem(localStorageKey);
124128

@@ -131,26 +135,6 @@ export function startClientSideIsDarkLogic(params: {
131135
localStorage.setItem(localStorageKey, colorSchemeExplicitlyProvidedAsParameter);
132136
}
133137

134-
reset_persisted_value_if_system_pref_changed: {
135-
if (colorSchemeExplicitlyProvidedAsParameter !== "system") {
136-
break reset_persisted_value_if_system_pref_changed;
137-
}
138-
139-
const localStorageKey = "scheme-system";
140-
141-
const localStorageValue = localStorage.getItem(localStorageKey);
142-
143-
const systemColorScheme = getSystemColorScheme();
144-
145-
if (localStorageValue === systemColorScheme) {
146-
break reset_persisted_value_if_system_pref_changed;
147-
}
148-
149-
localStorage.removeItem("scheme");
150-
151-
localStorage.setItem(localStorageKey, systemColorScheme);
152-
}
153-
154138
const { clientSideIsDark, ssrWasPerformedWithIsDark: ssrWasPerformedWithIsDark_ } = ((): {
155139
clientSideIsDark: boolean;
156140
ssrWasPerformedWithIsDark: boolean;
@@ -170,7 +154,7 @@ export function startClientSideIsDarkLogic(params: {
170154
return undefined;
171155
}
172156

173-
switch (colorSchemeExplicitlyProvidedAsParameter as ColorScheme) {
157+
switch (colorSchemeExplicitlyProvidedAsParameter) {
174158
case "dark":
175159
return true;
176160
case "light":
@@ -185,26 +169,29 @@ export function startClientSideIsDarkLogic(params: {
185169
return undefined;
186170
}
187171

172+
assert(
173+
isAmong<ColorScheme | "system">(
174+
["dark", "light", "system"],
175+
colorSchemeReadFromLocalStorage
176+
)
177+
);
178+
188179
if (colorSchemeReadFromLocalStorage === "system") {
189180
return undefined;
190181
}
191182

192-
switch (colorSchemeReadFromLocalStorage as ColorScheme) {
183+
switch (colorSchemeReadFromLocalStorage) {
193184
case "dark":
194185
return true;
195186
case "light":
196187
return false;
197188
}
198-
})();
199189

200-
const isDarkFromOsPreference = (() => {
201-
if (!window.matchMedia) {
202-
return undefined;
203-
}
204-
205-
return window.matchMedia("(prefers-color-scheme: dark)").matches;
190+
assert<Equals<typeof colorSchemeReadFromLocalStorage, never>>;
206191
})();
207192

193+
const isDarkFromOsPreference = getSystemColorScheme() === "dark";
194+
208195
const isDarkFallback = false;
209196

210197
return {
@@ -229,9 +216,26 @@ export function startClientSideIsDarkLogic(params: {
229216

230217
$clientSideIsDark.current = clientSideIsDark;
231218

232-
[data_fr_scheme, data_fr_theme].forEach(attr =>
233-
document.documentElement.setAttribute(attr, clientSideIsDark ? "dark" : "light")
219+
document.documentElement.setAttribute(
220+
data_fr_scheme,
221+
((): ColorScheme | "system" => {
222+
const colorSchemeReadFromLocalStorage = localStorage.getItem("scheme");
223+
224+
if (colorSchemeReadFromLocalStorage === null) {
225+
return colorSchemeExplicitlyProvidedAsParameter;
226+
}
227+
228+
assert(
229+
isAmong<ColorScheme | "system">(
230+
["dark", "light", "system"],
231+
colorSchemeReadFromLocalStorage
232+
)
233+
);
234+
235+
return colorSchemeReadFromLocalStorage;
236+
})()
234237
);
238+
document.documentElement.setAttribute(data_fr_theme, clientSideIsDark ? "dark" : "light");
235239

236240
new MutationObserver(() => {
237241
const isDarkFromHtmlAttribute = getCurrentIsDarkFromHtmlAttribute();

src/useIsDark/scriptToRunAsap.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,20 @@ export const getScriptToRunAsap: GetScriptToRunAsap = ({
7878
);
7979
8080
})();
81-
82-
["${data_fr_scheme}", "${data_fr_theme}"].forEach(attr => document.documentElement.setAttribute(attr, isDark ? "dark" : "light"));
81+
82+
document.documentElement.setAttribute(
83+
"${data_fr_scheme}",
84+
(() => {
85+
const colorSchemeReadFromLocalStorage = localStorage.getItem("scheme");
86+
87+
if (colorSchemeReadFromLocalStorage === null) {
88+
return "${defaultColorScheme}";
89+
}
90+
91+
return colorSchemeReadFromLocalStorage;
92+
})()
93+
);
94+
document.documentElement.setAttribute("${data_fr_theme}", isDark ? "dark" : "light")
8395
8496
{
8597

0 commit comments

Comments
 (0)