Skip to content

Instantly share code, notes, and snippets.

@trevorblades
Created November 13, 2020 21:18
Show Gist options
  • Save trevorblades/1bd240c58ad4790fd6c11006e77ab9db to your computer and use it in GitHub Desktop.
Save trevorblades/1bd240c58ad4790fd6c11006e77ab9db to your computer and use it in GitHub Desktop.
Chakra color mode w/ CSS variables
import React from 'react';
import theme from './src/gatsby-plugin-chakra-ui/theme';
import {getColor} from '@chakra-ui/theme-tools';
// a helper function to create color variables given a variable name and theme keys
function createVar(name, light, dark) {
return `
root.style.setProperty(
'${name}',
mql.matches
? '${getColor(theme, dark)}'
: '${getColor(theme, light)}'
);
`;
}
export const onRenderBody = ({setHeadComponents, setPreBodyComponents}) => {
// create a script that sets some basic color variables (bg, text, placeholder, etc.)
// also iterates through all theme colors and creates button color vars
setPreBodyComponents([
<script
key="cm"
dangerouslySetInnerHTML={{
__html: `
const mql = window.matchMedia('(prefers-color-scheme: dark)');
const root = document.documentElement;
${createVar('--bg-color', 'white', 'gray.800')}
${createVar('--text-color', 'gray.800', 'whiteAlpha.900')}
${createVar('--placeholder-text-color', 'gray.400', 'whiteAlpha.400')}
${createVar('--border-color', 'gray.200', 'whiteAlpha.300')}
${createVar('--button-text-color', 'white', 'gray.800')}
${createVar('--button-bg-color-gray', 'gray.100', 'whiteAlpha.200')}
${createVar(
'--button-bg-color-gray-hover',
'gray.200',
'whiteAlpha.300'
)}
${createVar(
'--button-bg-color-gray-active',
'gray.300',
'whiteAlpha.400'
)}
${Object.keys(theme.colors)
.filter(color => color !== 'gray')
.map(
color => `
${createVar(
`--button-bg-color-${color}`,
`${color}.500`,
`${color}.200`
)}
${createVar(
`--button-bg-color-${color}-hover`,
`${color}.600`,
`${color}.300`
)}
${createVar(
`--button-bg-color-${color}-active`,
`${color}.700`,
`${color}.400`
)}
`
)
.join('\n')}
`
}}
/>
]);
};
import {colors} from '@apollo/space-kit/colors';
import {extendTheme} from '@chakra-ui/core';
import {mix} from 'polished';
const body = "'Source Sans Pro', sans-serif";
const {grey, silver, black, indigo} = colors;
const theme = extendTheme({
config: {
useSystemColorMode: true
},
styles: {
global: {
// use the CSS variables created in the script tag
body: {
bg: 'var(--bg-color)',
color: 'var(--text-color)'
},
'*::placeholder': {
color: 'var(--placeholder-text-color)'
},
'*, *::before, &::after': {
borderColor: 'var(--border-color)'
}
}
},
components: {
Heading: {
baseStyle: {
fontWeight: 'semibold'
}
},
Button: {
variants: {
// I'm just covering solid buttons, but this technique can be expanded for other button variants
solid: ({colorScheme: c}) => ({
color: c !== 'gray' && 'var(--button-text-color)',
bg: `var(--button-bg-color-${c})`,
_hover: {bg: `var(--button-bg-color-${c}-hover)`},
_active: {bg: `var(--button-bg-color-${c}-active)`}
})
}
}
},
fonts: {
body,
heading: body,
mono: "'Source Code Pro', monospace"
},
colors: {
gray: {
50: silver.light,
100: silver.base,
200: silver.dark,
300: silver.darker,
400: grey.lighter,
500: grey.base,
600: grey.darker,
700: black.lighter,
800: black.base,
900: black.darker
},
indigo: {
50: indigo.lightest,
100: indigo.lighter,
200: indigo.light,
300: mix(0.5, indigo.light, indigo.base),
400: indigo.base,
500: mix(0.5, indigo.base, indigo.dark),
600: indigo.dark, // primary color
700: mix(0.5, indigo.dark, indigo.darker),
800: indigo.darker,
900: indigo.darkest
}
}
});
export default theme;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment