From e3a3994663c8380a155ae1a04fb663ff7f237131 Mon Sep 17 00:00:00 2001 From: Michal Bartosik Date: Fri, 4 Jun 2021 16:21:53 +0200 Subject: [PATCH] simplified userdarkmode hook, added check if user prefers dark theme based on OS settings --- README.md | 9 +++------ package.json | 7 +------ src/hooks/UseDarkMode.ts | 23 ++++++++++------------- yarn.lock | 5 +++++ 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 196cb22..c824cd4 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,8 @@ npm test - React Router Dom - Downshift - Axios -- React Paginate +- react-paginate +- react-media-hook - Mobile-first workflow ### What I learned @@ -74,13 +75,9 @@ Making accessible UI components like custom select is difficult, we all know tha Also, this is my first React project with TypeScript. At the beginning it was tough, there was a lot of googling for sure, but on the second day I started to see the benefits that static typing provides. Since I'm still learning, I didn't want TypeScript to slow me down, so to make progress with the project I used 'any' in some places and moved on. -To be added: - -1. Checking if user prefers dark mode based on OS settings. - ### Useful resources -- [Dark mode in react](https://www.smashingmagazine.com/2020/04/dark-mode-react-apps-styled-components/) - This helped me implement my custom hook, but I had to adjust it for my app, since I'm not using ThemeProvider +- [Dark mode in react](https://www.npmjs.com/package/react-media-hook/) - great package that you can use to check whether user prefers dark or light mode based on their OS settings ## Author diff --git a/package.json b/package.json index 2820267..00315ee 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "react-icons": "^4.2.0", + "react-media-hook": "^0.4.9", "react-paginate": "^7.1.2", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", @@ -37,12 +38,6 @@ "resolutions": { "babel-loader": "8.1.0" }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, "lint-staged": { "src/**/*.{ts,tsx,js,jsx,json}": [ "prettier --write" diff --git a/src/hooks/UseDarkMode.ts b/src/hooks/UseDarkMode.ts index dff501a..9bef35d 100644 --- a/src/hooks/UseDarkMode.ts +++ b/src/hooks/UseDarkMode.ts @@ -1,25 +1,22 @@ -import { useEffect, useState, useCallback } from 'react'; +import { useEffect, useState } from 'react'; import Theme from 'enums/Theme'; +import { useMediaPredicate } from 'react-media-hook'; const useDarkMode = (): [string, () => void] => { - const [theme, setTheme] = useState(Theme.Light); - - const setMode = useCallback((mode: string) => { - window.localStorage.setItem('theme', mode); - setTheme(mode); - }, []); + const preferredTheme = useMediaPredicate('(prefers-color-scheme: dark)') + ? Theme.Dark + : Theme.Light; + const [theme, setTheme] = useState( + localStorage.getItem('theme') || preferredTheme + ); const themeToggler = (): void => { - theme === Theme.Light ? setMode(Theme.Dark) : setMode(Theme.Light); + theme === Theme.Light ? setTheme(Theme.Dark) : setTheme(Theme.Light); }; - useEffect(() => { - const localTheme = window.localStorage.getItem('theme'); - localTheme ? setTheme(localTheme) : setMode(Theme.Light); - }, [setMode]); - useEffect(() => { document.body.className = theme; + window.localStorage.setItem('theme', theme); }, [theme]); return [theme, themeToggler]; diff --git a/yarn.lock b/yarn.lock index 480ee62..2e64e09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9528,6 +9528,11 @@ react-is@^17.0.1, react-is@^17.0.2: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-media-hook@^0.4.9: + version "0.4.9" + resolved "https://registry.yarnpkg.com/react-media-hook/-/react-media-hook-0.4.9.tgz#7e57092f5800c53787dc9e912ad09e749dfb7bc7" + integrity sha512-FZr/2xA1+23vDJ1IZ794yLqMRRkBoCNOiJATdtTfB5GyVc5djf8FL2qEB/68pSkiNgHdHsmKknMSDr0sC4zBKQ== + react-paginate@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/react-paginate/-/react-paginate-7.1.2.tgz#3a94f36a774f9d2e82b877e30474a16088b00a4d"