From eddce7c909bb118078cc523dc251f0229460e0a2 Mon Sep 17 00:00:00 2001 From: Aditya Thakral Date: Wed, 28 Apr 2021 04:22:30 -0400 Subject: [PATCH] Add ThemeContext This implementation uses CSS variables, and not CSS in JS. This is done so that we can support users who disable JS on their browsers. Fixes #20 --- components/playground.module.css | 4 ++-- components/theme.tsx | 36 ++++++++++++++++++++++++++++++++ pages/_app.css | 30 ++++++++++++++++++++++++++ pages/_app.tsx | 10 ++++++--- 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 components/theme.tsx create mode 100644 pages/_app.css diff --git a/components/playground.module.css b/components/playground.module.css index ceba2ed8..8b14457a 100644 --- a/components/playground.module.css +++ b/components/playground.module.css @@ -7,6 +7,6 @@ width: 250px; height: 250px; border-radius: 50%; - border: 2px solid #333; - background-color: #ddd; + border: 4px solid var(--blue-2); + background-color: var(--off-white); } \ No newline at end of file diff --git a/components/theme.tsx b/components/theme.tsx new file mode 100644 index 00000000..8f972eb2 --- /dev/null +++ b/components/theme.tsx @@ -0,0 +1,36 @@ +import React, { createContext, ReactElement, useEffect, useState } from "react"; + +type Theme = "light" | "dark"; + +const ThemeContext = createContext<{ + theme: Theme; + setTheme(newTheme: Theme): void; +}>({ + theme: "light", + setTheme: () => { + throw new Error("Use ThemeProvider instead."); + }, +}); + +interface Props { + theme: Theme; + children?: ReactElement; +} + +export function ThemeProvider({ children, theme }: Props) { + const [currentTheme, setTheme] = useState(theme); + + useEffect(() => { + if (currentTheme === "light") { + document.body.classList.remove("dark"); + } else if (currentTheme === "dark") { + document.body.classList.add("dark"); + } + }, [currentTheme]); + + return ( + + {children} + + ); +} diff --git a/pages/_app.css b/pages/_app.css new file mode 100644 index 00000000..e2dcd933 --- /dev/null +++ b/pages/_app.css @@ -0,0 +1,30 @@ +/* Default is light theme */ +body { + --off-white: #fdf8f5; + --teal-1: #76ffdc; + --teal-2: #4ed4b2; + --blue-1: #5caff9; + --blue-2: #5caff9; + --purple-1: #525284; + --purple-2: #2a2a62; + --gradient-blue-green: linear-gradient( + 99.94deg, + #1481e3 -17.95%, + #4ed4b2 172.82% + ); +} + +.dark { + --off-white: #fdf8f5; + --teal-1: #76ffdc; + --teal-2: #4ed4b2; + --blue-1: #5caff9; + --blue-2: #5caff9; + --purple-1: #525284; + --purple-2: #2a2a62; + --gradient-blue-green: linear-gradient( + 99.94deg, + #1481e3 -17.95%, + #4ed4b2 172.82% + ); +} \ No newline at end of file diff --git a/pages/_app.tsx b/pages/_app.tsx index 741e1ef8..551a9166 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,11 +1,15 @@ import React from "react"; import { AppProps } from "next/app"; import { MDXProvider } from "@mdx-js/react"; +import { ThemeProvider } from "../components/theme"; +import "./_app.css"; export default function App({ Component, pageProps }: AppProps): JSX.Element { return ( - - - + + + + + ); }