Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose theme values as CSS Variables #979

Open
iampava opened this issue Jun 4, 2020 · 12 comments · May be fixed by #982
Open

Expose theme values as CSS Variables #979

iampava opened this issue Jun 4, 2020 · 12 comments · May be fixed by #982
Labels
enhancement New feature or request

Comments

@iampava
Copy link

iampava commented Jun 4, 2020

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.

@jxnblk
Copy link
Member

jxnblk commented Jun 4, 2020

You might be interested in this package: https://github.com/system-ui/theme-ui/tree/master/packages/custom-properties -- it's missing a few nice-to-have features, so PRs are welcome :)

@iampava
Copy link
Author

iampava commented Jun 4, 2020

Yep, seen it. Could be used to create the name/value pairs, but it doesn't fix the need for adjusting code inside ThemeProvider (as in the snippet above).

Or maybe, we could export a HOC from there, and use it something like

import { ThemeProvider } from 'theme-ui`;
import { withCustomProperties } from '@theme-ui/custom-properties';

export const ThemeAdapter = withCustomProperties(ThemeProvider);

What do you think?

PS: I'd be happy to do the PRs, but first "point me in the right direction" as it's said :D

@jxnblk
Copy link
Member

jxnblk commented Jun 4, 2020

I don't think this sort of functionality should be part of the core packages, but I think you could achieve what you're looking for in the @theme-ui/custom-properties package as an additional export, if you want to look into a PR there then go for it!

@iampava
Copy link
Author

iampava commented Jun 4, 2020

Great! I'll work on it as soon as possible. Thanks for the input

@lachlanjc
Copy link
Member

I believe our recent work on color modes has implemented this for colors—since we now use a wrapping div for ThemeProvider, any element inside the ThemeProvider component can consume the colors:
image

@iampava
Copy link
Author

iampava commented Nov 4, 2021

Sweet! 👍

@TranquilMarmot
Copy link

TranquilMarmot commented Jan 15, 2022

@lachlanjc is there anything special you have to do to get those variables to show up? I'm using @theme-ui/core version 0.13.1 and they aren't showing up for me.

Switching to the "all-in-one" theme-ui package makes them show up, but I'd rather be able to use just @theme-ui/core.

@lachlanjc
Copy link
Member

Ah, I believe that's the issue. Those custom properties are part of the color-modes package, which isn't included in core. What's your use case?

@TranquilMarmot
Copy link

Use case is just trying to keep the end result of my app small 😉
I ended up just switching to theme-ui from @theme-ui/core

@lachlanjc
Copy link
Member

That makes sense! I was wondering why you wanted these custom properties though—I've personally never used them, since if I'm using Theme UI on a site typically all my styling is going through it

@TranquilMarmot
Copy link

The main reason I need the custom properties is for things like linear-gradient.

i.e. if I want to do...

backgroundImage: "linear-gradient(to top, var(--theme-ui-colors-buttonPrimary1), var(--theme-ui-colors-buttonPrimary2))",

It seems like theme-ui doesn't work with something like linear-gradient(to top, buttonPrimary1, buttonPrimary2).

In another project, we added theme-ui on top of a bunch of existing SCSS files. We reference the --theme-ui-colors- variables a lot in the SCSS.

@lachlanjc
Copy link
Member

Is there still a usecase/desire for non-color theme values to be accessible via custom properties?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants