From 5f76447e05525bbbc6647836bc54692739d2f484 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Sirois Date: Thu, 12 Sep 2019 11:13:53 -0400 Subject: [PATCH] feat: implement dark mode --- package-lock.json | 56 ++++++++------------ package.json | 1 + src/ThemeProvider.tsx | 35 ++++++++++++ src/components/DiscordButton/styles.tsx | 4 +- src/components/Layout/index.tsx | 31 ++++++----- src/components/MobileHeader/styles.tsx | 5 +- src/components/ResourceBreadcrumb/styles.tsx | 9 +++- src/components/ResourceHeader/styles.tsx | 10 ++-- src/components/ResourcesLayout/index.tsx | 33 +++++++----- src/components/ResourcesLayout/styles.tsx | 2 + src/components/ResourcesSidebar/index.tsx | 37 +++++++------ src/components/ResourcesSidebar/styles.tsx | 23 ++++---- src/components/ThemeToggler/index.tsx | 13 +++++ src/components/ThemeToggler/styles.tsx | 15 ++++++ src/design/themes.ts | 51 ++++++++++++++++++ src/hooks/useLocalStorage.tsx | 20 +++++++ src/hooks/useTheme.tsx | 12 +++++ typings.d.ts | 7 +++ 18 files changed, 266 insertions(+), 98 deletions(-) create mode 100644 src/ThemeProvider.tsx create mode 100644 src/components/ThemeToggler/index.tsx create mode 100644 src/components/ThemeToggler/styles.tsx create mode 100644 src/design/themes.ts create mode 100644 src/hooks/useLocalStorage.tsx create mode 100644 src/hooks/useTheme.tsx diff --git a/package-lock.json b/package-lock.json index cd23d6e..9e48963 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6830,8 +6830,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -6849,13 +6848,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6868,18 +6865,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -6982,8 +6976,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -6993,7 +6986,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7006,20 +6998,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.3.5", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7036,7 +7025,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -7109,8 +7097,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -7120,7 +7107,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -7196,8 +7182,7 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -7227,7 +7212,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7245,7 +7229,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7284,13 +7267,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.0.3", - "bundled": true, - "optional": true + "bundled": true } } }, @@ -9634,14 +9615,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "optional": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "optional": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "slice-ansi": { "version": "1.0.0", @@ -9667,7 +9646,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "optional": true, "requires": { "ansi-regex": "^4.1.0" } @@ -12810,6 +12788,14 @@ "ts-pnp": "^1.1.2" } }, + "polished": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/polished/-/polished-3.4.1.tgz", + "integrity": "sha512-GflTnlP5rrpDoigjczEkS6Ye7NDA4sFvAnlr5hSDrEvjiVj97Xzev3hZlLi3UB27fpxyTS9rWU64VzVLWkG+mg==", + "requires": { + "@babel/runtime": "^7.4.5" + } + }, "portfinder": { "version": "1.0.21", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.21.tgz", diff --git a/package.json b/package.json index 8b13722..376ce8f 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "gatsby-source-filesystem": "^2.1.8", "gatsby-transformer-remark": "^2.6.10", "gatsby-transformer-sharp": "^2.2.5", + "polished": "^3.4.1", "prismjs": "^1.17.1", "ramda": "^0.26.1", "react": "^16.8.6", diff --git a/src/ThemeProvider.tsx b/src/ThemeProvider.tsx new file mode 100644 index 0000000..7804771 --- /dev/null +++ b/src/ThemeProvider.tsx @@ -0,0 +1,35 @@ +import React, { createContext } from "react" +import { ThemeProvider as BaseThemeProvider } from "styled-components" + +import { darkTheme, lightTheme } from "./design/themes" +import { useLocalStorage } from "./hooks/useLocalStorage" + +interface IThemeProviderProps { + // TODO: type this properly, BaseThemeProvider doesn't like React.ReactNode + children: any +} + +export interface IThemeContext { + theme: "dark" | "light" + setTheme: () => void + toggleTheme: () => void +} + +export const ThemeContext = createContext(null) + +const ThemeProvider = ({ children }: IThemeProviderProps) => { + const [theme, setTheme] = useLocalStorage("theme", "light") + const themeObject = theme === "dark" ? darkTheme : lightTheme + + const toggleTheme = () => { + setTheme(theme === "light" ? "dark" : "light") + } + + return ( + + {children} + + ) +} + +export { ThemeProvider } diff --git a/src/components/DiscordButton/styles.tsx b/src/components/DiscordButton/styles.tsx index 413da38..5cec151 100644 --- a/src/components/DiscordButton/styles.tsx +++ b/src/components/DiscordButton/styles.tsx @@ -9,7 +9,7 @@ export const DiscordButtonWrapper = styled.div` font-size: 30px; font-weight: 700; text-transform: uppercase; - background: #7289da; + background: ${props => props.theme.discord.base}; color: #fff; padding: 22px 35px; border-radius: 5px; @@ -18,7 +18,7 @@ export const DiscordButtonWrapper = styled.div` box-shadow: 0 3px 18px rgba(0, 0, 0, 0.3); &:hover { - background: #5265ad; + background: ${props => props.theme.discord.darker}; } ` diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index ae18af2..c8bc6ea 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -8,6 +8,7 @@ import React, { Fragment, PropsWithChildren } from "react" import { GlobalStyles } from "../../globalStyles" +import { ThemeProvider } from "../../ThemeProvider" import { Container } from "../Container" import { Footer } from "../Footer" import { Header } from "../Header" @@ -21,19 +22,21 @@ export function Layout({ const isHome = location.pathname === "/" return ( - - -
- {!isHome && ( - - - {children} - -