-
Notifications
You must be signed in to change notification settings - Fork 2
/
gatsby-ssr.js
116 lines (88 loc) · 3.17 KB
/
gatsby-ssr.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* eslint-disable import/prefer-default-export */
import React from 'react';
import ThemeProvider from './ThemeProvider';
import { baseTheme as theme } from './src/styles/themes';
function setColorsByTheme() {
const colors = '🌈';
const colorModeKey = 'color-mode';
const colorModeCssProp = '--initial-color-mode';
const mql = window.matchMedia('(prefers-color-scheme: dark)');
const prefersDarkFromMQ = mql.matches;
const persistedPreference = localStorage.getItem(colorModeKey);
let colorMode = 'light';
const hasUsedToggle = typeof persistedPreference === 'string';
if (hasUsedToggle) {
colorMode = persistedPreference;
} else {
colorMode = prefersDarkFromMQ ? 'dark' : 'light';
}
const root = document.documentElement;
root.style.setProperty(colorModeCssProp, colorMode);
Object.entries(colors).forEach(([name, values]) => {
values.forEach((color, index) => {
const cssVarName = `--color-${name}-${index}`;
root.style.setProperty(cssVarName, color);
});
});
if (colorMode === 'dark') {
colors.dark.forEach((color, index) => {
const cssVarName = `--color-bg-${index}`;
root.style.setProperty(cssVarName, color);
});
colors.light.forEach((color, index) => {
const cssVarName = `--color-text-${index}`;
root.style.setProperty(cssVarName, color);
});
colors.primary.forEach((color, index) => {
const cssVarName = `--color-accent-${
colors.primary.length - (index + 1)
}`;
root.style.setProperty(cssVarName, color);
});
} else {
colors.light.forEach((color, index) => {
const cssVarName = `--color-bg-${index}`;
root.style.setProperty(cssVarName, color);
});
colors.dark.forEach((color, index) => {
const cssVarName = `--color-text-${index}`;
root.style.setProperty(cssVarName, color);
});
colors.primary.forEach((color, index) => {
const cssVarName = `--color-accent-${index}`;
root.style.setProperty(cssVarName, color);
});
}
}
const MagicScriptTag = () => {
const boundFn = String(setColorsByTheme).replace(
"'🌈'",
JSON.stringify(theme.colors)
);
const calledFunction = `(${boundFn})()`;
// eslint-disable-next-line react/no-danger
return <script dangerouslySetInnerHTML={{ __html: calledFunction }} />;
};
const FallbackStyles = () => {
let colorString = ``;
Object.entries(theme.colors).forEach(([name, values], nameIndex) => {
values.forEach((color, index) => {
colorString += `${
nameIndex === 0 && index === 0 ? '' : '\n'
}--color-${name}-${index}: ${color};`;
});
});
theme.colors.light.forEach((color, index) => {
colorString += `\n--color-bg-${index}: ${color};`;
});
theme.colors.dark.forEach((color, index) => {
colorString += `\n--color-text-${index}: ${color};`;
});
const wrappedInSelector = `html { ${colorString} }`;
return <style>{wrappedInSelector}</style>;
};
export const onRenderBody = ({ setPreBodyComponents, setHeadComponents }) => {
setHeadComponents(<FallbackStyles key="theme-colors-fallback" />);
setPreBodyComponents(<MagicScriptTag key="theme-colors" />);
};
export const wrapRootElement = ThemeProvider;