Browse Source

WIP: add dark mode toggle

feature/color-scheme-button
Garrit Franke 4 months ago
parent
commit
f490347efe
Signed by: garrit
GPG Key ID: BB54AF7EB0939F3D
  1. 41
      hooks/useDarkTheme.ts
  2. 22
      package-lock.json
  3. 3
      package.json
  4. 3
      pages/404.tsx
  5. 4
      styles/components/page.scss
  6. 5
      styles/foundation/base.scss
  7. 2
      styles/index.scss

41
hooks/useDarkTheme.ts

@ -0,0 +1,41 @@
import { useLocalStorage, useMediaQuery, useUpdateEffect } from "usehooks-ts";
import useSSR from "./useSSR";
import { useEffect } from "react";
const COLOR_SCHEME_QUERY = "(prefers-color-scheme: dark)";
interface UseDarkThemeOutput {
isDarkTheme: boolean;
toggleDarkTheme: () => void;
enableDarkTheme: () => void;
disableDarkTHeme: () => void;
}
export function useDarkTheme(defaultValue?: boolean): UseDarkThemeOutput {
const isDarkOS = useMediaQuery(COLOR_SCHEME_QUERY);
const [isDarkTheme, setDarkTheme] = useLocalStorage<boolean>(
"usehooks-ts-dark-mode",
defaultValue ?? isDarkOS ?? false
);
// Update darkTheme if os prefers changes
useUpdateEffect(() => {
setDarkTheme(isDarkOS);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isDarkOS]);
useEffect(() => {
console.log(isDarkTheme)
document.documentElement.setAttribute(
"data-theme",
isDarkTheme ? "dark" : "light"
);
}, [isDarkTheme]);
return {
isDarkTheme,
toggleDarkTheme: () => setDarkTheme((prev) => !prev),
enableDarkTheme: () => setDarkTheme(true),
disableDarkTHeme: () => setDarkTheme(false),
};
}

22
package-lock.json generated

@ -16,7 +16,8 @@
"react-snowfall": "^1.2.1",
"react-web-share": "^2.0.2",
"rehype-raw": "7.0.0",
"remark-gfm": "4.0.0"
"remark-gfm": "4.0.0",
"usehooks-ts": "^2.9.1"
},
"devDependencies": {
"glob": "10.3.10",
@ -4076,6 +4077,19 @@
"punycode": "^2.1.0"
}
},
"node_modules/usehooks-ts": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-2.9.1.tgz",
"integrity": "sha512-2FAuSIGHlY+apM9FVlj8/oNhd+1y+Uwv5QNkMQz1oSfdHk4PXo1qoCw9I5M7j0vpH8CSWFJwXbVPeYDjLCx9PA==",
"engines": {
"node": ">=16.15.0",
"npm": ">=8"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
@ -7229,6 +7243,12 @@
"punycode": "^2.1.0"
}
},
"usehooks-ts": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-2.9.1.tgz",
"integrity": "sha512-2FAuSIGHlY+apM9FVlj8/oNhd+1y+Uwv5QNkMQz1oSfdHk4PXo1qoCw9I5M7j0vpH8CSWFJwXbVPeYDjLCx9PA==",
"requires": {}
},
"v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",

3
package.json

@ -18,7 +18,8 @@
"react-snowfall": "^1.2.1",
"react-web-share": "^2.0.2",
"rehype-raw": "7.0.0",
"remark-gfm": "4.0.0"
"remark-gfm": "4.0.0",
"usehooks-ts": "^2.9.1"
},
"devDependencies": {
"glob": "10.3.10",

3
pages/404.tsx

@ -1,7 +1,9 @@
import { useEffect } from "react";
import Page from "../components/Page";
import { useDarkTheme } from "../hooks/useDarkTheme";
export default function FourOhFour() {
const { toggleDarkTheme } = useDarkTheme();
const setupEditRoute = () => {
if (window.location.href.endsWith("/edit")) {
const baseUrl =
@ -18,6 +20,7 @@ export default function FourOhFour() {
return (
<Page>
<button onClick={toggleDarkTheme}>Toggle</button>
<h1>404 - Page Not Found</h1>
<a href="/">Go back home</a>
</Page>

4
styles/components/page.scss

@ -36,7 +36,7 @@
text-decoration: underline;
text-decoration-color: $color-text-dark;
color: $color-text-dark;
@media (prefers-color-scheme: light) {
[data-theme="dark"] {
color: $color-text-light;
}
}
@ -90,7 +90,7 @@
margin-right: 4px;
}
@media (prefers-color-scheme: light) {
[data-theme="dark"] {
.page__tag-icon {
filter: invert(1);
}

5
styles/foundation/base.scss

@ -1,7 +1,7 @@
:root {
background: $color-secondary-dark;
color: $color-text-dark;
@media (prefers-color-scheme: light) {
[data-theme="dark"] {
background: $color-secondary-light;
color: $color-text-light;
}
@ -64,7 +64,7 @@ code {
border-radius: 3px;
overflow: auto;
word-wrap: normal;
@media (prefers-color-scheme: light) {
[data-theme="dark"] {
background: $color-accent-light;
}
}
@ -152,6 +152,7 @@ article p a[href^="https://"]::after
width: 11px;
height: 11px;
margin-left: 4px;
/* stylelint-disable-next-line CssSyntaxError */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z'/%3E%3Cpath fill-rule='evenodd' d='M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;

2
styles/index.scss

@ -23,7 +23,7 @@
}
/* Dark theme */
@media (prefers-color-scheme: dark) {
:root[data-theme="dark"] {
:root {
color-scheme: dark;
--bg: #212121;

Loading…
Cancel
Save