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

Support new presets key + extending core plugins config #2474

Merged
merged 4 commits into from
Oct 8, 2020

Conversation

adamwathan
Copy link
Member

@adamwathan adamwathan commented Sep 30, 2020

This PR adds support for adding a presets key to your Tailwind config to make it possible to ignore Tailwind's default config file.

This configuration is identical to Tailwind's default behavior, and this is what happens if the presets key is omitted:

// tailwind.config.js
module.exports = {
  presets: [require('tailwindcss/defaultConfig')],
  theme: { ... }
}

This configuration removes Tailwind's default config from the list of configs to resolve, essentially disabling all defaults:

// tailwind.config.js
module.exports = {
  presets: [],
  theme: { ... }
}

This configuration specifies a custom base config file, useful if you have a config you share across different properties at your company:

// tailwind.config.js
module.exports = {
  presets: [require('@acmecorp/tailwind-config')],
  theme: { ... }
}

Multiple presets can be applied, and they will be resolved in order, with presets at the end taking precedence over presets at the beginning:

// tailwind.config.js
module.exports = {
  presets: [
    require('@acmecorp/base-tailwind-config')
    require('@acmecorp/marketing-tailwind-config')
  ],
  theme: { ... }
}

Presets can also have their own presets, so the above configuration could be rewritten like this:

// @acmecorp/marketing-tailwind-config
module.exports = {
  presets: [require('@acmecorp/base-tailwind-config')]
  // ...
}

// tailwind.config.js
module.exports = {
  presets: [
    require('@acmecorp/marketing-tailwind-config')
  ],
  theme: { ... }
}

This PR also adds better support for merging the corePlugins key, so now your custom default config can specify the core plugins you want to enable while still being able to extend it in a project specific config:

// tailwind.config.
const sharedConfig = {
  // ...
  corePlugins: ['backgroundColor', 'float', 'opacity', 'padding']
}

module.exports = [
  sharedConfig,
  {
    // ...
    corePlugins: {
      float: false,
    }
  }
]

If you'd like to add core plugins to your base config, you can use a function syntax that receives the so-far-resolved corePlugins array as a destructurable argument:

// tailwind.config.js
const sharedConfig = {
  // ...
  corePlugins: ['backgroundColor', 'float', 'opacity', 'padding']
}

module.exports = {
  // ...
  presets: [sharedConfig],
  corePlugins: ({ corePlugins }) => {
    return [...corePlugins, 'margin']
  }
}

We may add helpers like after and before in the future, to mimic the API that is available for variants.

This PR in general is in service of introducing a new "lite" config mode for Tailwind, for folks who want a more minimal starting point.

@adamwathan
Copy link
Member Author

To do: consider changing to a preset key instead of an array config, and make sure it works recursively.

@adamwathan adamwathan changed the title Support array of config objects + extending core plugins config Support new presets key + extending core plugins config Oct 4, 2020
@adamwathan
Copy link
Member Author

Updated to drop the top level array format and instead use a presets key.

Comment on lines +230 to +231
return configurePlugins(corePluginConfig, Object.keys(corePluginList)).map(pluginName => {
return corePluginList[pluginName]()
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return configurePlugins(corePluginConfig, Object.keys(corePluginList)).map(pluginName => {
return corePluginList[pluginName]()
return configurePlugins(corePluginConfig, Object.values(corePluginList)).map(plugin => {
return plugin()

@leodr
Copy link

leodr commented Oct 4, 2020

Since tailwind.config.js is already a JavaScript file, can't you just use the object spread syntax to extend other themes? And disable the default theme by supplying an empty object to the theme property?

@adamwathan
Copy link
Member Author

Nope, the resolution logic is quite complex because of things like function values and the “extend” theme key. Check out the tests for resolveConfig 😳

@adamwathan adamwathan force-pushed the master branch 2 times, most recently from f3893d1 to 55dcc53 Compare October 7, 2020 18:14
@mnaderian
Copy link

I'm waiting for the day when Bootstrap is completely beaten. Then we can rule the world again!! Tailwind CSS should really rule the web cause it's really better than others and has better taste.

As all fathers say: Be patient son!

@adamwathan adamwathan merged commit b299b6f into master Oct 8, 2020
@adamwathan adamwathan deleted the array-config-format branch October 8, 2020 15:21
@soullivaneuh
Copy link

@adamwathan I am not really sure of the usage target of this feature.

I have a design project containing a common tailwind configuration file for our company: https://gitlab.com/nexylan/design/-/blob/6d853ad113e064d4d34e8240dacd47a462293edd/tailwind.config.js

As you can see on this version, I require some part of the default theme then merge them using the spread operators.

Will your feature help me on that case or should I keep my configuration like this?

The goal of this config is also to be re-used on other project containing a tailwind configuration.

In a more general way, will some documentation be added about this feature?

Regards

@adamwathan
Copy link
Member Author

You can use this feature to specify your custom config file as the base for any projects you work on like this:

// tailwind.config.js
module.exports = {
  presets: [require('./custom-base-config.js')],
  // ...
}

Can you explain more clearly what your question is? How were you extending your base config in your projects up until now?

@soullivaneuh
Copy link

@adamwathan The main goal is to maintain one common Tailwind configuration under our design project and maybe add some specific override on front projects.

@soullivaneuh
Copy link

By the way, I maybe didn't understand the goal of this feature, but I tried this:

presets: [
  require('tailwindcss/defaultConfig'),
  require('nexylan-design/tailwind.config.js'),
],

And the design is completely broken. However, if I remove the custom one, everything works well but without my theme (of course).

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.

5 participants