Skip to content

Expose theme values as CSS Variables #979

Open
@iampava

Description

@iampava

Right now we can't use theme values when styling native HTML elements. We have to either

  1. Wrap them in custom components <H1>, <H2>, etc
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions