RFC: Theming
See original GitHub issueFresh 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)?
Issue Analytics
- State:
- Created 4 years ago
- Reactions:12
- Comments:11 (1 by maintainers)
Top Results From Across the Web
RFC Theme - song and lyrics by Breakmaster Cylinder - Spotify
Listen to RFC Theme on Spotify. Breakmaster Cylinder · Song · 2016.
Read more >RFC: theme emacs with a 6-color palette with semantics theming
Inspired by work of u/Nicolas-Rougier, I have developed a package to give a coherent look to emacs, based on a palette of just...
Read more >Re: [community-group] [RFC] Theming (#2) - Mailing lists - W3C
However, since this thread is discussing possible approaches to support theming use-cases, I do think it's worth considering and debating ...
Read more >RFC Theme by Breakmaster Cylinder - Song on Apple Music
RFC Theme. Breakmaster Cylinder Songs for Broadcast, Part. III. Song. Play. United States. Español (México) · العربية · Русский · 简体中文 ...
Read more >Rfc designs, themes, templates and downloadable ... - Dribbble
Rfc. Inspirational designs, illustrations, and graphic elements from the world's best designers. Want more inspiration? Browse our search results.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Could the problem be split into two? Compile-time and runtime? I think most of us here are interested in compile-time since runtime is well covered by existing CSS-in-JS solutions.
Hey! Thanks. Agreed when we start tackling theming we’ll want to make sure theme variables are available in the head, which side-steps some gnarly issues with portaling.
Atlassian has a few use cases for this across a few products interestingly. Media components are always shown in “dark mode” for example.
We should be able to ensure any known theme (CSS) variables are in the head. It’s the “values not known until runtime” that is a bit more difficult. The easy answer is flushing it through inline styles, however the portaling issue comes up that needs either a good solution, or good example patterns to work with it.