Open
Description
Right now we can't use theme values when styling native HTML elements. We have to either
- Wrap them in custom components
<H1>
,<H2>
, etc - Use the
sx
prop
I'd like to extend ThemeProvider
with the ability to expose theme values as CSS Variables so that in a stylesheet we could do something like:
h1 {
margin: var(--space-3);
font-size: var(--font-sizes-3);
}
h2 {
margin: var(--space-2);
font-size: var(--font-sizes-2);
}
I've already done this (just for the colors property as a proof of concept), here's the code:
import React, { useRef, useEffect } from 'react';
import { ThemeProvider, ThemeProviderProps, Theme, useThemeUI } from 'theme-ui';
export const ThemeAdapter = (props: ThemeProviderProps<Theme>) => {
const ref = useRef(null);
const { theme: outerTheme } = useThemeUI();
useEffect(() => {
const theme =
typeof props.theme === 'function' ? props.theme(outerTheme) : props.theme;
Object.entries(theme?.colors || {}).forEach(([key, value]) => {
ref.current.style.setProperty(`--colors-${key}`, value);
});
});
return (
<div ref={ref} className='theme-ui-adapter'>
<ThemeProvider {...props} />
</div>
);
};
Thus, any elements inside the <div className="theme-ui-adapter">
can make use of the CSS Variables. Also, because of the way scope works, we have theme/sub-theme functionality by default.