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

tokens 🤝 global theming #184

Closed
wants to merge 36 commits into from
Closed

tokens 🤝 global theming #184

wants to merge 36 commits into from

Conversation

itsdouges
Copy link
Collaborator

@itsdouges itsdouges commented Apr 30, 2020

Investigating #18 #182

  • introduces createThemeProvider() api
  • introduces useMode() hook

TODO

  • Enable nesting support in tokens json
  • Fix theme inlining not working
  • Fix setting of tokens being broken (see example storybook)
  • Add limited support for runtime token overrides
  • Rename from theme provider to token provider(?)

Questions

  • Does the tokens JSON look ok? The point is - define your base and then use those references in the modes.
  • Do we think this is a problem if tokens are primarily built around base tokens and then themes - with default a mandatory theme?
  • How should we handle runtime tokens? Tokens that aren't known until runtime, use case could be overriding tokens, for example Confluence changing primary to another color.
    I was imagining this could be something like:
// Don't have to pass all properties in
<ThemeProvider overrides={{ default: { primary: 'red' } }}>

And if you want to add an entire new theme:

// Have to pass all properties in
<ThemeProvider overrides={{ batman: { primary: 'red' } }}>
  • How could we enforce "must use base tokens" even during runtime? Currently they get compiled away. Do we add it back?

Usage

  1. Create a tokens json
{
  "base": {
    "r300": "#FF5630",
    "b400": "#0052CC"
  },
  "default": {
    "primary": "b400"
  },
  "dark": {
    "primary": "r300"
  }
}
  • define your base tokens
  • use these tokens in default and others
  • mode definitions can only tokens from base - anything else results in an error
  • other modes mandate they have the same shape as default
  • nested tokens also possible - see next:
Nested tokens We can support nested tokens we just need to do some extra work because the transformed appearance needs to be flat.
{
  "base": {
    "r300": "#FF5630",
    "b400": "#0052CC"
  },
  "default": {
    "borderRadius": "3px",
    "colors": {
      "primary": "b400"
     }
  },
  "dark": {
    // Don't need to define everything here purely an additive thing.
    "colors": {
      "primary": "r300"
     }
  }
}

Transforms top level tokens that would be CSS variables to:

const tokens = {
  default: { '--borderRadiusHash': '3px', '--colorsPrimaryHash': '#0052CC' },
  dark: {  '--colorsPrimaryHash': '#FF5630' },
};

And then transform the token access to:

const theme = {
  borderRadius: 'var(--borderRadiusHash)',
  colors: { primary: 'var(--colorsPrimaryHash)' }
};

theme.borderRadius;
theme.colors.primary;
  1. Turn on tokens
"options": {
  "tokens": "./tokens.json"
}
  1. Create and use your provider
const { ThemeProvider, theme } = createThemeProvider();

export ThemeProvider;
export theme;
  • ThemeProvider ends up being a component with react context
  • theme ends up being an object to access tokens.
import { ThemeProvider } from './theme';

const App = ({ children }) => (
  <ThemeProvider theme="default">
    {style => <div style={style}>{children}</div>
  </ThemeProvider>
);
  1. Use tokens in a component
import { styled } from '@compiled/css-in-js';
import { theme } from './theme';

export const StyledDiv = styled.div`
  color: ${theme.primary};
`;

Ends up being inlined and looking like this CSS, uses default css variable so it works without the theme provider as well.

color: var(--cc-1tivpv1,#0052CC);

If we want to provide basic support for IE11 we can also do this (but let's not):

color: #0052CC;
color: var(--cc-1tivpv1,#0052CC);

@itsdouges itsdouges added wip 🚧 Work in progress - don't judge too harshly. rfc 💬 Request for comments labels Apr 30, 2020
@itsdouges itsdouges changed the title [WIP] tokens [WIP] tokens ❤️ theming Apr 30, 2020
@itsdouges itsdouges changed the title [WIP] tokens ❤️ theming tokens ❤️ theming Apr 30, 2020
}
)
).toThrowError(
new Error(`You've defined hard-coded colors which is not allowed in strict mode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is sick 🎉

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the whole concept of strict has been removed for now

@itsdouges itsdouges force-pushed the tokens branch 2 times, most recently from 397c880 to 7729f0a Compare May 1, 2020 12:07
@itsdouges itsdouges changed the title tokens ❤️ theming tokens 🤝 theming May 1, 2020
@itsdouges

This comment has been minimized.

@itsdouges
Copy link
Collaborator Author

itsdouges commented May 8, 2020

@gwyneplaine yo chime in sometime about the theming api :)

i think global api is probably a little easier so i might remove all the variant stuff for now - but would be keen for a look over that too

i quite like the css prop api because it can be typed + transformed easily and its pretty easy to use api - everything else is 🤷

the other missing piece is allowing consumers to pass runtime themes which should be not hard to implement - just a matter of passing the same object in and then transforming it to css variables at runtime.

examples/theming.tsx Outdated Show resolved Hide resolved
@itsdouges itsdouges changed the title tokens 🤝 theming tokens 🤝 global theming May 9, 2020
@itsdouges itsdouges force-pushed the tokens branch 2 times, most recently from fbb7e8d to df4a97d Compare May 26, 2020 22:44
@itsdouges itsdouges changed the title tokens 🤝 global theming [spike] tokens 🤝 global theming Aug 2, 2020
@itsdouges itsdouges added spike 🏐 Testing something with some throw away code. and removed wip 🚧 Work in progress - don't judge too harshly. labels Aug 2, 2020
@itsdouges itsdouges changed the title [spike] tokens 🤝 global theming tokens 🤝 global theming Aug 2, 2020
@itsdouges itsdouges closed this Aug 28, 2020
@itsdouges itsdouges deleted the tokens branch December 19, 2020 10:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rfc 💬 Request for comments spike 🏐 Testing something with some throw away code.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants