Last active
October 29, 2020 22:30
-
-
Save phunkren/e16771da3e19f5351aa4d038241c7fd2 to your computer and use it in GitHub Desktop.
My custom Theme provider for ajames.dev
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import styled from 'styled-components'; | |
const Container = styled.div(({ theme }) => css` | |
background-color: ${theme.background}; | |
background-color: ${theme.copyColor}; | |
border-color: ${theme.borderColor}; | |
`); | |
export const Component = ({ children, ...props }) => { | |
return ( | |
<Container {...props}> | |
{ children } | |
</Container> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useEffect, useContext, createContext } from 'react'; | |
import styled, { ThemeProvider } from 'styled-components'; | |
import { CustomCheckboxContainer, CustomCheckboxInput } from '@reach/checkbox'; | |
import '@reach/checkbox/styles.css'; | |
import { THEMES, DEFAULT_THEME } from '../styles/themes'; | |
import { LightIcon } from './icons/LightIcon'; | |
export const ThemeContext = createContext(null); | |
export const Theme = props => { | |
const localTheme = retrieve(); | |
const [theme, setTheme] = useState(localTheme); | |
useEffect(theme ? persist : init, [theme]); | |
function validate(t) { | |
return Object.keys(THEMES).includes(t); | |
} | |
function update(t) { | |
validate(t) && setTheme(t); | |
} | |
function retrieve() { | |
return window.localStorage.getItem('theme'); | |
} | |
function persist() { | |
window.localStorage.setItem('theme', theme); | |
} | |
function init() { | |
setTheme(validate(localTheme) ? localTheme : DEFAULT_THEME); | |
} | |
return validate(theme) ? ( | |
<ThemeContext.Provider value={{ theme, update }}> | |
<ThemeProvider theme={THEMES[theme]} {...props} /> | |
</ThemeContext.Provider> | |
) : null; | |
}; | |
export const ThemeToggle = props => { | |
const { theme, update } = useContext(ThemeContext) || {}; | |
const checked = theme === 'light'; | |
function handleChange(e) { | |
update(e.target.checked ? 'light' : 'dark'); | |
} | |
return ( | |
<CustomCheckboxContainer | |
checked={checked} | |
onChange={handleChange} | |
{...props} | |
> | |
<label htmlFor="theme-toggle"> | |
<LightIcon on={!checked} aria-label="Theme toggle" /> | |
<CustomCheckboxInput | |
id="theme-toggle" | |
checked={checked} | |
onChange={handleChange} | |
{...props} | |
/> | |
</label> | |
</CustomCheckboxContainer> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mix } from 'polished'; | |
const LIGHT_THEME = { | |
background: 'var(--color-white)', | |
headerColor: 'var(--color-charcoal)', | |
copyColor: 'var(--color-black)', | |
linkColor: 'var(--color-blue-700)', | |
highlightColor: 'var(--color-blue-600)', | |
auxiliaryColor: 'var(--color-gray-700)', | |
borderColor: 'var(--color-charcoal)', | |
overlay5: `${mix(0.95, 'rgb(255,255,255)', 'rgb(0, 0, 0)')}`, | |
overlay10: `${mix(0.9, 'rgb(255,255,255)', 'rgba(,0,0,0)')}`, | |
}; | |
const DARK_THEME = { | |
background: 'var(--color-black)', | |
headerColor: 'var(--color-gray-200)', | |
copyColor: 'var(--color-white)', | |
linkColor: 'var(--color-blue-400)', | |
highlightColor: 'var(--color-orange-400)', | |
auxiliaryColor: 'var(--color-gray-400)', | |
borderColor: 'var(--color-charcoal)', | |
overlay5: `${mix(0.95, 'rgb(0,0,0)', 'rgb(255, 255, 255)')}`, | |
overlay10: `${mix(0.9, 'rgb(0,0,0)', 'rgb(255,255,255)')}`, | |
}; | |
export const THEMES = { | |
light: LIGHT_THEME, | |
dark: DARK_THEME, | |
}; | |
export const DEFAULT_THEME = 'dark'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment