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 complex addUtilities() configs #15029

Merged
merged 7 commits into from
Nov 19, 2024

Conversation

philipp-spiess
Copy link
Member

@philipp-spiess philipp-spiess commented Nov 18, 2024

This PR adds support for complex addUtilities() configuration objects that use child combinators and other features.

For example, in v3 it was possible to add a utility that changes the behavior of all children of the utility class node by doing something like this:

addUtilities({
  '.red-children > *': {
    color: 'red',
  },
});

This is a pattern that was used by first-party plugins like @tailwindcss/aspect-ratio but that we never made working in v4, since it requires parsing the selector and properly extracting all utility candidates.

While working on the codemod that can transform @layer utilities scoped declarations like the above, we found out a pretty neat heuristics on how to migrate these cases. We're basically finding all class selectors and replace them with &. Then we create a nested CSS structure like this:

.red-children {
  & > * {
    color: red;
  }
}

Due to first party support for nesting, this works as expected in v4.

Test Plan

We added unit tests to ensure the rewriting works in some edge cases. Furthermore we added an integration test running the @tailwindcss/aspect-ratio plugin. We've also installed the tarballs in the Remix example from the playgrounds and ensure we can use the @tailwindcss/aspect-ratio plugin just like we could in v3:

Screenshot 2024-11-18 at 13 44 52

@RobinMalfait RobinMalfait changed the title Support complex addUtility() configs Support complex addUtilities() configs Nov 18, 2024
@philipp-spiess philipp-spiess marked this pull request as ready for review November 18, 2024 14:42
@philipp-spiess philipp-spiess requested a review from a team as a code owner November 18, 2024 14:42
@RobinMalfait RobinMalfait force-pushed the feat/support-complex-add-utility-config branch from bf3770a to 298a8dd Compare November 18, 2024 16:47
Copy link
Contributor

@thecrypticace thecrypticace left a comment

Choose a reason for hiding this comment

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

a small thing in the tests but otherwise seems good

@philipp-spiess philipp-spiess merged commit ab9e2b7 into next Nov 19, 2024
1 check passed
@philipp-spiess philipp-spiess deleted the feat/support-complex-add-utility-config branch November 19, 2024 14:52
philipp-spiess added a commit that referenced this pull request Nov 19, 2024
Closes #15012

We do not have replacements for these plugins _just yet_. In order to
increase compatibility with setups that rely on some of these legacy
plugins, this PR bundles `@tailwindcss/forms`,
`@tailwindcss/typography`, and `@tailwindcss/aspect-ratio` (after
#15029) with the
standalone build now.

In comparison to v3, this omits the `@tailwindcss/container-queries`
plugin since is not a first-party feature of Tailwind CSS v4.

## Test Plan

Added an integration test. I also tested this by running the standalone
binary in a temporary folder with as simple input css:

```css
@import "tailwindcss";
@plugin "@tailwindcss/typography";
```
@davidmatter
Copy link

davidmatter commented Nov 22, 2024

@philipp-spiess Am I right to assume that in v4, we need to migrate from

addUtilities({
  "@media (min-width: 768px)": {
    ".article-display-m": {
      "font-size": 60px;
    }
  }
})

to:

addUtilities({
 ".article-display-m": {
   "@media (min-width: 768px)": {
     "font-size": 60px;
   }
 }
})

@philipp-spiess
Copy link
Member Author

@davidmatter Huh this is... interesting! Yes if you can migrate to that that would be easiest. Is this a plugin doing or how did you discover this?

@davidmatter
Copy link

davidmatter commented Nov 22, 2024

We're quite a large company with an extensive CSS-based design system with hundreds of (for example) typography definitions. Now, to get proper intellisense in our code editors and to integrate better with our tailwind projects, we've come up with a custom plugin that parses some of our foundational CSS utilities and adds the definitions to tailwind using addUtilities.

e.g.

  const root = parse(css)
  const jss = objectify(root)
  addUtilities(jss)

It works quite well actually in v3 :) In a perfect world, these definitions would of course be extracted to their own components to support the official tailwind way of doing things etc. but that would be A LOT of work.

@davidmatter
Copy link

For parsing and objectify, we use https://github.com/postcss/postcss-js

@philipp-spiess
Copy link
Member Author

I see, so you're not expecting this to generate the right CSS anyways and only use this to extend the type hints for intellisense? I think it should be possible to write a quick function that inverts the object properties in this case?

@davidmatter
Copy link

@philipp-spiess Thanks for taking the time. Well, we actually use it to generate prunable CSS. TBH I think it's the best pattern to work with legacy CSS code because of 1) Intellisense and 2) Resulting CSS can be pruned by tailwind and runs through the official plugin system.

Inverting the objects is alright for us. I suspect that we're not the only ones using this pattern, though. Might be advisable to mark this as a breaking change to save everyone's time :)

@davidmatter
Copy link

BTW: Good to see an Austrian engineer being part of tailwind! Keep it up

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.

4 participants