Skip to content

Bil Benhamou

Turn to the dark side with javascript.

1 min read

Automate your dark & light switch with sunset

Ever opened a white webpage at 1 AM in bed? Right? Unless an input from the user or the color-mode fairy, the color mode won't happen by itself.

I decided to implement it on my website.

What do we need to make this happen?

I wrote a little helper, which does the trick.

1import timezones from "../utils/timezones";
2import { getSunsetDateTimeUtc } from "suntimes";
3
4export default function detectSunset() {
5 /**
6 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/resolvedOptions
7 */
8
9 const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
10 /**
11 * World's timezones
12 * https://gist.github.com/thebiltheory/bfab7316360a3677a5d3e69f57f9898b
13 */
14 const [lat, long] = timezones[timezone];
15
16 /**
17 * Date Objects
18 */
19 const date = new Date();
20 const now = Date.now();
21
22 /**
23 * Suntimes
24 * https://www.npmjs.com/package/suntimes
25 * getSunsetDateTimeUtc :
26 * Gets the sunset date and time in UTC
27 * expressed in an ISO 8601 format for date instance,
28 * latitude and longitude value.
29 */
30 const sunsetTime = new Date(getSunsetDateTimeUtc(date, lat, long)).getTime();
31
32 return now >= sunsetTime;
33}

I came across the case where I, as a visitor, switched back to the light theme even though it was night. React rechecks for sunset every time the component re-render. To remember the visitors' choice, I decided to store manual input in the browsers Session Storage.

Any of the useSessionStorage hooks found online will suffice.

1const [userColorMode, setUserColorMode] = useSessionStorage(
2 "color-mode",
3 "null"
4);
5const [colorMode, setColorMode] = useColorMode();
6const isSunset = detectSunset();
7
8const toggleColorMode = (e) => {
9 const mode = isDark ? `light` : `dark`;
10 setUserColorMode(mode);
11};
12
13useEffect(() => {
14 if (isSunset && userColorMode === "null") {
15 setColorMode("dark");
16 } else if (userColorMode === "null") {
17 setColorMode("light");
18 }
19}, [isSunset, setColorMode]);

The automatic switch will keep happening unless color-key holds light or dark, this would mean the visitor has manually interacted the switch.

Hence we'll remember the choice when components are re-rendering.

Cheers,

Happy Weekend.

© 2020 by Bil Benhamou. All rights reserved.