Skip to content

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

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

Merged
merged 3 commits into from
Feb 6, 2019

Conversation

adamwathan
Copy link
Member

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.

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
@aparajita
Copy link

Much cleaner. And way more powerful.

@@ -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)

Choose a reason for hiding this comment

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

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

Copy link
Member Author

Choose a reason for hiding this comment

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

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
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants