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

Support using closures as theme values to enable self-referencing #645

merged 3 commits into from Feb 6, 2019


None yet
2 participants
Copy link

adamwathan commented Feb 6, 2019

Yet another alternative to #639 and #643...

This time instead of any fancy merging logic that's tightly coupled to the theme structure or anything, I've added generic support for using functions as values in the theme.

Any theme values specified as functions will receive the theme as an argument so it can reference itself.

Looks like this in use:

module.exports = {
  theme: {
    colors: {
      cyan: 'cyan',
      magenta: 'magenta',
      yellow: 'yellow',
    backgroundColors: ({ colors }) => colors,
    textColors: ({ colors }) => colors,

There is potential for infinite recursion and circular dependencies if you use this feature in a stupid way, but I'm comfortable shifting that responsibility to the end user. Basically, don't try to reference other theme values that are functions inside of another theme function or it's impossible to resolve the final value, of course.

I've updated the defaultTheme to take advantage of this under the hood which magically makes all color inheritance work, and removes the need to have that horrible colors constant at the top of the file.

adamwathan added some commits Feb 6, 2019

Rename mergeConfig to resolveConfig
Accept configs to resolve as an array to allow reuse when only resolving from a single config, update processTailwindFeatures to use resolveConfig even when no config is provided, update defaultTheme to self-reference colors.

@adamwathan adamwathan changed the title Theme closures Support using closures as theme values to enable self-referencing Feb 6, 2019


This comment has been minimized.

Copy link

aparajita commented Feb 6, 2019

Much cleaner. And way more powerful.

@adamwathan adamwathan merged commit 5da2036 into next Feb 6, 2019

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed

@adamwathan adamwathan deleted the theme-closures branch Feb 6, 2019

@@ -169,7 +167,9 @@ module.exports = function() {
'4': '4px',
'8': '8px',
borderColors: global.Object.assign({ default: colors['grey-light'] }, colors),
borderColors: theme => {
return global.Object.assign({ default: theme.colors['grey-light'] }, theme.colors)

This comment has been minimized.


aparajita Feb 11, 2019

Just curious why you use global. Are you worried about Object existing in the local namespace? Seems pretty unlikely...

This comment has been minimized.


adamwathan Feb 11, 2019

Author Member

Very reasonable question! Check this out: #402

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment