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

Allow for multiple theme files #5

Open
fcisio opened this issue Nov 19, 2020 · 16 comments
Open

Allow for multiple theme files #5

fcisio opened this issue Nov 19, 2020 · 16 comments

Comments

@fcisio
Copy link
Contributor

fcisio commented Nov 19, 2020

I've started to implement the plugin in one of my projects and I was able to notice this.

Everything works, as long as the theme is contained in a single file.
theme.js/ts

In many cases, the theme will get pretty big and will need to be split-up. For example:

theme/
  variants/
  scales.js
  index.js
// index.js

export default {
  // space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
  ...scales,

  speed: ["0.35s", "0.5s", "0.75"],

  colors: {
    primary: '#333',
  },

  // Variants
  layout,
  header,

  styles: {
    root: {},
    a: {
      // input
      '--test': 'space.4',
      '--other-value': 'speed.1',

       // output
       '--test': 'space.4',
       '--other-value': '0.5s',
    },
  },
}

I can make a new example if needed!

@atanasster
Copy link
Owner

ah, that might not be as easy :) babel plugins are processing one file at a time.

let me think about it?

@atanasster
Copy link
Owner

...still nothing comes to mind :) It might have to be a limitation of the plugin to require themes to be in a single file.

Are your themes too large if consolidated into a single file?

@fcisio
Copy link
Contributor Author

fcisio commented Nov 20, 2020

Very much haha!
From what I've seen, there's two main use case for Theme UI

  • Extend a starter theme and add a little extra code in there
  • Create a robust Design System

Now the goal is to create a preset with the first (big) theme, then extend and overwrite parts of it. In this case, it could all be contained in a single file.

The doc also mentions the advantage of splitting the code.

 In any case, this is a great tool. It would be nice to work with multiple files, but without it, it would still suit a lot of projects.

I'll think about possible solutions!


This is what my theme currently looks like:

Shot_0 6

@atanasster
Copy link
Owner

got it - its BIG :)
ok, we will need to figure out a way to get the parts - is your repo public, or can you upload a sample into the test fixtures?

@fcisio
Copy link
Contributor Author

fcisio commented Nov 20, 2020

My repo is private, but I can create a fixture for sure. I should be sending that over by tomorrow 👌

@atanasster
Copy link
Owner

@fcisio - my best guess so far would be to use a webpack source loader that will merge all theme imports into a single theme file at build-time.

Haven't found a ready-made webpack loader that does this. If none is found, we can go ahead and make our own.

@hasparus
Copy link

Oh damn... Could we actually import the file to resolve the value of the theme?

@atanasster
Copy link
Owner

atanasster commented Nov 20, 2020

@hasparus - don't think so - as there might be values that need instrumenting in the imported file (a variation of theme composition : https://github.com/atanasster/babel-plugin-theme-ui#theme-composition)

example:
header.js

  export const headers {
    color: 'primary',
    --bg-color: 'primary'
  }

theme.js

  import { header } from './header';

  export const theme = { 
    colors: {},
    styles: { h1: { ...header, fontSize: 6 } }
  }

@hasparus
Copy link

hasparus commented Nov 20, 2020

But if we imported theme.js, we'd have the final value, right?

Right now you're transforming one expression to another, and my idea is

  1. Grab theme declaration. Get that object literal expression.
  2. Don't do anything with it, import the file.
  3. Transform the value.
  4. Print the transformed value and substitute that object literal expression from step 1 with your result.

I may be missing some context, though.

@atanasster
Copy link
Owner

ah maybe, let me try :

  • it will have to be a webpack source loader so it can return back the modified source code.
  • it will only work for isomorphic code, since it wil be executed in the node process - I guess themes dont need browser-only code often

@hasparus
Copy link

Can't this be done in a babel plugin or macro?

@hasparus
Copy link

I'll try to test my idea this weekend.

@atanasster
Copy link
Owner

Great, looking forward to your results. I dont see how to do it in a babel plugin, and havent used babel macros.

@fcisio
Copy link
Contributor Author

fcisio commented Nov 24, 2020

Hey, just had an idea! Now I think we should still prioritize alternatives, but essentially...

We could transform all the theme scales into variables printed on the body (same as colors currently are).
Once these scales are accessible as CSS Custom Properties, all we would have to do is transform the references into custom properties.

Using the same pattern as colors, this would mean:

  • space.3 == var(--theme-ui-space-3)
  • borders.body == var(--theme-ui-borders-body)
  • sizes.sidebar == var(--theme-ui-sizes-sidebar)
  • zIndices.popup == var(--theme-ui-zindices-popup)

This means using the references to generate variable names following a pattern and no longer relying on actual links made by Babel. That way files can be separate and it wouldn't matter.

@atanasster
Copy link
Owner

@fcisio - thats a good idea, however it will have a big impact (including we will have to separate the spaces into their own key of the theme or some other mean of identifying the spaces). Also it doest really solve the general problem of modifying 'sub-files'. But we can put it to voting from the community.

I am still on the webpack source loader bandwagon (mostly because it would not rely on internal changes to the library itself), if @hasparus idea test doesnt work out.

@deckchairlabs
Copy link

I started work on a babel macro last week which explores others ideas in addition to those in this thread. https://github.com/deckchairlabs/theme-ui.macro

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

No branches or pull requests

4 participants