From a883a5f3530e2115890463868c49f99cc9b56735 Mon Sep 17 00:00:00 2001 From: Vivek T A <32357540+vivek32ta@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:29:03 +0530 Subject: [PATCH] Dark Mode in progress. (#101) * added toggle button * added toggle button (#103) Co-authored-by: Vivek T A * website: add theme hook * Update gatsby-config.js * Update hook.js Co-authored-by: anotherjsguy --- website/src/components/Header.jsx | 12 +- website/src/components/Layout.jsx | 28 +-- website/src/components/markdown-overrides.js | 5 +- website/src/images/icons/theme.svg | 1 + website/src/themes/dark.js | 176 +++++++++++++++++++ website/src/themes/hook.js | 42 +++++ 6 files changed, 248 insertions(+), 16 deletions(-) create mode 100644 website/src/images/icons/theme.svg create mode 100644 website/src/themes/dark.js create mode 100644 website/src/themes/hook.js diff --git a/website/src/components/Header.jsx b/website/src/components/Header.jsx index e56e287..1c6d303 100644 --- a/website/src/components/Header.jsx +++ b/website/src/components/Header.jsx @@ -2,14 +2,18 @@ import LogoIcon from './../images/icons/github.svg'; import React from 'react'; import { Stack } from 'layout-ui'; import TwitterIcon from './../images/icons/twitter.svg'; +import ThemeIcon from './../images/icons/theme.svg'; import { styled } from '@filbert-js/core'; +import { colors } from './../themes/utils'; const Link = styled.a` display: inline-flex; align-items: center; + color: ${colors(`app.color`)}; `; -export function Header() { +export function Header(props) { + return ( + + + ); } diff --git a/website/src/components/Layout.jsx b/website/src/components/Layout.jsx index 30929ba..166d725 100644 --- a/website/src/components/Layout.jsx +++ b/website/src/components/Layout.jsx @@ -7,7 +7,7 @@ import React from 'react'; import { Sidebar } from './Sidebar'; import { ThemeProvider } from '@filbert-js/theming'; import { colors } from './../themes/utils'; -import { tokens as lightTheme } from '../themes/light'; +import { useTheme } from '../themes/hook'; const Screen = styled.div` display: grid; @@ -18,7 +18,9 @@ const Screen = styled.div` padding: 1rem 2rem; width: 100%; max-width: 64em; - color: ${colors(`text.body`)}; + + background: ${colors(`app.background-color`)}; + color: ${colors(`app.color`)}; @media screen and (max-width: 52em) { grid-template-columns: 1fr; } @@ -62,33 +64,33 @@ const ToggleButton = styled.button` border: 0; } `; -const globalStyles = ` - @import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap'); +export function Layout({ children }) { + const [theme, toggleTheme] = useTheme(); + const [toggle, setToggle] = React.useState(true); + + const globalStyles = ` + @import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap'); body { font-family: 'Inter', sans-serif; margin: 0; - } - + background: ${colors(`app.background-color`)({ theme })}; + color: ${colors(`app.color`)({ theme })}; + } * { box-sizing: border-box; } `; -export function Layout({ children }) { - const [toggle, setToggle] = React.useState(true); - return ( - + -
+
- -
{children}
setToggle(!toggle)}> diff --git a/website/src/components/markdown-overrides.js b/website/src/components/markdown-overrides.js index dd23ccb..6ba1e84 100644 --- a/website/src/components/markdown-overrides.js +++ b/website/src/components/markdown-overrides.js @@ -16,11 +16,12 @@ export const Paragraph = styled.p` `; export const Pre = styled.pre` padding: 10px 20px; - background-color: #f6f8fa; + background: ${colors(`app.background-color`)}; border-radius: 6px; + color: ${colors(`text.body`)}; `; export const Blockquote = styled.div` - background: #f9f9f9; + background: ${colors(`app.background-color`)}; border-left: 10px solid #ccc; margin: 1.5em 0; padding: 1em 10px 1em 10px; diff --git a/website/src/images/icons/theme.svg b/website/src/images/icons/theme.svg new file mode 100644 index 0000000..4731abc --- /dev/null +++ b/website/src/images/icons/theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/src/themes/dark.js b/website/src/themes/dark.js new file mode 100644 index 0000000..5d345e9 --- /dev/null +++ b/website/src/themes/dark.js @@ -0,0 +1,176 @@ +/* + Tokens: + Define your scales first + + Source: react-ui +*/ + +export const tokens = { + name: 'React UI Light', + space: { + 0: 0, + 1: '4px', + 2: '8px', + 3: '12px', + 4: '16px', + 5: '20px', + 6: '24px', + 7: '28px', + 8: '32px', + 9: '36px', + 10: '40px', + 11: '44px', + 12: '48px', + 13: '52px', + 14: '56px', + 15: '60px', + 16: '64px', + }, + radii: [0, '2px', '4px', '16px', '50%'], + fontSizes: { + 0: 0, + 1: '10px', + 2: '12px', + 3: '14px', + 4: '16px', + 5: '20px', + 6: '24px', + 7: '32px', + 8: '48px', + 9: '64px', + 10: '72px', + }, + fontWeights: { + thin: 100, + light: 300, + normal: 400, + medium: 500, + semibold: 600, + bold: 700, + extrabold: 800, + black: 900, + }, + lineHeights: { + compact: '1.2', + default: '1.6', + cosy: '2', + }, + breakpoints: { + 0: '576px', + 1: '768px', + 2: '992px', + }, + + durations: { + 0: 0, + 1: '75ms', + 2: '100ms', + 3: '150ms', + 4: '200ms', + 5: '300ms', + 6: '500ms', + 7: '1000ms', + 8: '2500ms', + }, + + // based on elevation levels + shadows: { + 0: 'none', + 1: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', + 2: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', + 3: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', + 4: '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + }, + + colors: { + white: '#fff', + reds: { + 100: '#F8E4E4', + 200: '#EFA6A6', + 300: '#E06161', + 400: '#D95252', + 500: '#D12D2D', + 600: '#B41F1F', + 700: '#A20808', + 800: '#821919', + 900: '#5E1717', + }, + yellows: { + 100: '#FDF3D7', + 200: '#FAECC2', + 300: '#F8E8BA', + 400: '#FAE29F', + 500: '#FFD97E', + 600: '#F4CA64', + 700: '#CAA53D', + 800: '#8C6D1F', + 900: '#5C4813', + }, + blues: { + 100: '#EFF8FF', + 200: '#B7DBF7', + 300: '#A8D1F2', + 400: '#63A2D8', + 500: '#036FCA', + 600: '#217CC9', + 700: '#2368A2', + 800: '#1A4971', + 900: '#203D54', + }, + greens: { + 100: '#E3FCEC', + 200: '#A8EEC1', + 300: '#8FF2B2', + 400: '#4BE38C', + 500: '#22D66F', + 600: '#38C172', + 700: '#259D58', + 800: '#197741', + 900: '#145239', + }, + grays: { + 100: '#f5faff', + 200: '#E1E7EC', + 300: '#D1D9E0', + 400: '#C8D0D7', + 500: '#AEBECD', + 600: '#929FB1', + 700: '#6E7A8A', + 800: '#404B5A', + 900: '#202833', + }, + }, +}; + +// recommended: use the same space grid for size +tokens.sizes = { ...tokens.space }; + +/* + Decisions: + You can create aliases in scales based on the scale. + */ + +tokens.colors.text = { + subtle: 'grays.200', + body: 'white', + link: 'grays.400', + 'link-hover': 'white', +}; + +tokens.colors.error = { + background: 'reds.100', + border: 'reds.300', + text: 'reds.700', +}; + +tokens.colors.app = { + 'background-color': 'grays.900', + color: 'white', + 'border-color': 'grays.200', +}; + +tokens.fontSizes.Heading = { + page: 8, // reads from tokens.fontSizes.8 + section: 6, + paragraph: 4, +}; diff --git a/website/src/themes/hook.js b/website/src/themes/hook.js new file mode 100644 index 0000000..d7a0c7d --- /dev/null +++ b/website/src/themes/hook.js @@ -0,0 +1,42 @@ +import { useCallback, useEffect, useState } from 'react'; + +import { tokens as darkTheme } from './dark'; +import { tokens as lightTheme } from './light'; + +const themes = { light: lightTheme, dark: darkTheme }; +function getThemeName() { + if(typeof window==='object'){ + const localTheme = window.localStorage.getItem('theme'); + return window.matchMedia && + window.matchMedia('(prefers-color-scheme: dark)').matches && + !localTheme + ? 'dark' + : localTheme + ? localTheme + : 'light'; + }else{ + return 'light'; + } +} +export const useTheme = () => { + const [theme, setTheme] = useState(getThemeName()); + + const setMode = useCallback((mode) => { + window.localStorage.setItem('theme', mode); + setTheme(mode); + }, []); + + const toggleTheme = () => { + if (theme === 'light') { + setMode('dark'); + } else { + setMode('light'); + } + }; + + useEffect(() => { + setMode(getThemeName()); + }, [setMode]); + + return [themes[theme], toggleTheme]; +};