-
Notifications
You must be signed in to change notification settings - Fork 72
Closed
Labels
rfc 💬Request for commentsRequest for comments
Description
Fresh eyes needed. We should also take inspiration from https://theme-ui.com/
We can even create a TS language service to tell us what themes are available with intellisense!
Global theming
Define your tokens in your options:
{
base: {},
default: {},
[optionalotherthemes]: {} // every other theme needs to have the same keys from default
}Then use them in your CSS sourced from default:
css`
color: primary; // or
color: theme(primary);
`Transforms to:
color: #fff;
color: var(--var-123abc);Hardcodes and use the variable so it works with/without a parent theme.
Prepare a theme provider for consumers (you should only ever create one of these):
import { createThemeProvider } from '@compiled/css-in-js';
export const ThemeProvider = createThemeProvider();
// Optional "runtime" themes.
export const ThemeProvider = createThemeProvider({ ... });Transforms to:
import { _TP } from '@compiled/css-in-js';
const theme = { base: { ... }, default: { '--var-abc123': '#000', ... }, ... };
// optional runtime themes would be merged in and converted to css variables
export const ThemeProvider = (props) => (
<_TP theme={props.theme}>
{props.children(theme[props.mode])
<_TP>
);And then your consumers use like:
import { ThemeProvider } from 'your-design-system';
const App = () => (
<ThemeProvider theme="dark">
{style => <div style={style}>...</div>
</ThemeProvider>
);Component theming
Would be the same as above with one key difference - the theme isn't sourced from the config. It's sourced inline.
import { createVariants } from '@compiled/css-in-js';
const useVariants = createVariants<'primary' | 'danger'>({
default: { default: {}, [optionalotherthemes]: {} },
[optionalotherthemes]: {},
});
<button style={useVariants('primary')} css={{ border: 'border', color: 'color' }}>
blah
</button>import { useMode } from '@compiled/style;
// transformed to css variables
const variants = { default: {}, ... };
const useVariants = (variant: string) => {
const mode = useMode();
const defaultVariant = variants.default;
return {
...defaultVariant.default,
...defaultVariant[mode],
...variants[variant][mode],
};
};The type safety aspect is missing a little. Perhaps instead of using string literals theme(primary) and variant(color) we could import them?
import { themeRefs, createVariants } from '@compiled/css-in-js';
const { useVariants, variant } = createVariants({});
const theme = themeRefs();
<div
style={useVariants('primary')}
css={{
backgroundColor: variant('backgroundColor'),
color: theme('primary'),
}}
/>???
Goals
- Minimal use of react context
- Css variables for passing style values around
- Don't force specific markup to consumers
- Ensure bleeding of css variables doesn't affect things it shouldn't
Lingering thoughts
- What about runtime themes (i.e. they aren't known until runtime)?
Grsmto, Dattaya, uptonking, Greenheart, ruedap and 4 moreaxaxaman and athammermmgeorge
Metadata
Metadata
Assignees
Labels
rfc 💬Request for commentsRequest for comments