5586 Commits

Author SHA1 Message Date
Adam Wathan
5a2938dbfc
Update CHANGELOG.md 2024-10-11 09:50:53 -04:00
Philipp Spiess
0cfb98484b
Add simple JS config migration (#14639)
This PR implements the first version of JS config file migration to CSS.
It is based on the most simple config setups we are using in the
Tailwind UI templates Commit, Primer, Radiant, and Studio.

The example we use in the integration test is a config that looks like
this:

```js
import { type Config } from 'tailwindcss'
import defaultTheme from 'tailwindcss/defaultTheme'

module.exports = {
  darkMode: 'selector',
  content: ['./src/**/*.{html,js}'],
  theme: {
    boxShadow: {
      sm: '0 2px 6px rgb(15 23 42 / 0.08)',
    },
    colors: {
      red: {
        500: '#ef4444',
      },
    },
    fontSize: {
      xs: ['0.75rem', { lineHeight: '1rem' }],
      sm: ['0.875rem', { lineHeight: '1.5rem' }],
      base: ['1rem', { lineHeight: '2rem' }],
    },
    extend: {
      colors: {
        red: {
          600: '#dc2626',
        },
      },
      fontFamily: {
        sans: 'Inter, system-ui, sans-serif',
        display: ['Cabinet Grotesk', ...defaultTheme.fontFamily.sans],
      },
      borderRadius: {
        '4xl': '2rem',
      },
    },
  },
  plugins: [],
} satisfies Config
```

As you can see, this file only has a `darkMode` selector, custom
`content` globs, a `theme` (with some theme keys being overwriting the
default theme and some others extending the defaults). Note that it does
not support `plugins` and/or `presets` yet.

In the case above, we will find the CSS file containing the existing
`@tailwind` directives and are migrating it to the following:

```css
@import 'tailwindcss';

@source './**/*.{html,js}';

@variant dark (&:where(.dark, .dark *));

@theme {
  --box-shadow-*: initial;
  --box-shadow-sm: 0 2px 6px rgb(15 23 42 / 0.08);

  --color-*: initial;
  --color-red-500: #ef4444;

  --font-size-*: initial;
  --font-size-xs: 0.75rem;
  --font-size-xs--line-height: 1rem;
  --font-size-sm: 0.875rem;
  --font-size-sm--line-height: 1.5rem;
  --font-size-base: 1rem;
  --font-size-base--line-height: 2rem;

  --color-red-600: #dc2626;

  --font-family-sans: Inter, system-ui, sans-serif;
  --font-family-display: Cabinet Grotesk, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";

  --border-radius-4xl: 2rem;
} 
```

This replicates all features of the JS config so we can even delete the
existing JS config in this case.

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-10-11 15:27:53 +02:00
Robin Malfait
bd3d6bc09b
Migrate legacy classes to the v4 alternative (#14643)
This PR adds a mapping from legacy classes to new classes. For example,
the `flex-shrink-0` is still used in our projects, but is deprecated in
v3.

The migration does a tiny bit of parsing because we can't rely on
`designSystem.parseCandidate(…)` because this requires the utility to be
defined which is not the case for legacy classes.

This migration runs _after_ the migration where we handle prefixes, so
we don't have to worry about that. We do have to worry about the `!`
location, because the `important` migration also relies on the
`designSystem`.

| Old                 | New                    |
| ------------------- | ---------------------- |
| `overflow-clip`     | `text-clip`            |
| `overflow-ellipsis` | `text-ellipsis`        |
| `flex-grow-0`       | `grow-0`               |
| `flex-shrink-0`     | `shrink-0`             |
| `decoration-clone`  | `box-decoration-clone` |
| `decoration-slice`  | `box-decoration-slice` |
2024-10-11 14:22:55 +02:00
depfu[bot]
f0b65e360c
Update turbo 2.1.2 → 2.1.3 (patch) (#14646)
Here is everything you need to know about this update. Please take a
good look at what changed and the test results before merging this pull
request.

### What changed?




#### ✳️ turbo (2.1.2 → 2.1.3) ·
[Repo](https://github.com/turborepo/turbo)





Sorry, we couldn't find anything useful about this release.











---
![Depfu
Status](https://depfu.com/badges/edd6acd35d74c8d41cbb540c30442adf/stats.svg)

[Depfu](https://depfu.com) will automatically keep this PR
conflict-free, as long as you don't add any commits to this branch
yourself. You can also trigger a rebase manually by commenting with
`@depfu rebase`.

<details><summary>All Depfu comment commands</summary>
<blockquote><dl>
<dt>@​depfu rebase</dt><dd>Rebases against your default branch and
redoes this update</dd>
<dt>@​depfu recreate</dt><dd>Recreates this PR, overwriting any edits
that you've made to it</dd>
<dt>@​depfu merge</dt><dd>Merges this PR once your tests are passing and
conflicts are resolved</dd>
<dt>@​depfu cancel merge</dt><dd>Cancels automatic merging of this
PR</dd>
<dt>@​depfu close</dt><dd>Closes this PR and deletes the branch</dd>
<dt>@​depfu reopen</dt><dd>Restores the branch and reopens this PR (if
it's closed)</dd>
<dt>@​depfu pause</dt><dd>Ignores all future updates for this dependency
and closes this PR</dd>
<dt>@​depfu pause [minor|major]</dt><dd>Ignores all future minor/major
updates for this dependency and closes this PR</dd>
<dt>@​depfu resume</dt><dd>Future versions of this dependency will
create PRs again (leaves this PR as is)</dd>
</dl></blockquote>
</details>

Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
2024-10-11 12:50:15 +02:00
Robin Malfait
a3812942ac
Use consistent quotes (#14640)
Small improvement, we noticed that some quotes were not consistent with
others. Let's make them consistent!
2024-10-10 14:29:36 +00:00
Robin Malfait
fb1731a2de
Inject @config "..." when a tailwind.config.{js,ts,...} is detected (#14635)
This PR injects a `@config "…"` in the CSS file if a JS based config has
been found.

We will try to inject the `@config` in a sensible place:
1. Above the very first `@theme`
2. If that doesn't work, below the last `@import`
3. If that doesn't work, at the top of the file (as a last resort)
2024-10-10 14:02:42 +00:00
Jordan Pittman
4d1becd2f9
Migrate utilities in CSS files imported into layers (#14617)
When a stylesheet is imported with `@import “…” layer(utilities)` that
means that all classes in that stylesheet and any of its imported
stylesheets become candidates for `@utility` conversion.

Doing this correctly requires us to place `@utility` rules into separate
stylesheets (usually) and replicate the import tree without layers as
`@utility` MUST be root-level. If a file consists of only utilities we
won't create a separate file for it and instead place the `@utility`
rules in the same stylesheet.

Been doing a LOT of pairing with @RobinMalfait on this one but I think
this is finally ready to be looked at

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-10-10 15:44:04 +02:00
Philipp Spiess
75b906643c
Migrate simple PostCSS setup (#14612)
This PR attempts to detect simple postcss setups: These are setups that
do not load dynamic modules and are based off the examples we are
[recommending in our
docs](https://tailwindcss.com/docs/installation/using-postcss). We
detect wether a config is appropriate by having it use the object plugin
config and by not requiring any other modules:

```js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
```

When we find such a config file, we will go over it line-by-line and
attempt to:

- Upgrade `tailwindcss:` to `'@tailwindcss/postcss':`
- Remove `autoprefixer` if used

We then attempt to install and remove the respective npm packages based
on the package manger we detect.

And since we now have logic to upgrade packages, this also makes sure to
install `tailwindcss@next` at the end of a sucessful migration.

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-10-10 15:09:14 +02:00
Robin Malfait
3ae22f1f9d
Migrate @media screen(…) (#14603)
This PR adds a codemod that migrates the `@media screen(…)` to the
properly expanded `@media (…)` syntax.

```css
@media screen(md) {
  .foo {
    color: red;
  }
}
```

Will be converted to:
```css
@media (width >= 48rem) {
  .foo {
    color: red;
  }
}
```

If you happen to have custom screens (even complex ones), the screen
will be converted to a custom media query.

```css
@media screen(foo) {
  .foo {
    color: red;
  }
}
```
With a custom `tailwind.config.js` file with a config like this:
```js
module.exports = {
  // …
  theme: {
    screens: {
      foo: { min: '100px', max: '123px' },
    },
  }
}
```

Then the codemod will convert it to:
```css
@media (123px >= width >= 100px) {
  .foo {
    color: red;
  }
}
```
2024-10-10 15:06:53 +02:00
Jordan Pittman
958bfc9d89
Pass options when using addComponents and matchComponents (#14590)
We forgot to pass `options` from `addComponents` to `addUtilities` and
from `matchComponents` to `matchUtilities`.

This didn't affect anything using addComponents but anything that used
`matchComponents` wouldn't have worked 😬
2024-10-10 12:56:59 +00:00
Jordan Pittman
a6231b78c1
Ensure auto complete suggestions work when using matchUtilities (#14589)
Discovered `matchUtilities(…)` wasn't populating intellisense on v4 when
working on Tailwind Play earlier today. This PR fixes this so plugins
using matchUtilities also have intellisense suggestions.
2024-10-10 14:51:52 +02:00
Philipp Spiess
dc6980230d
Fix CSS theme() function resolution issue (#14614)
We currently have three different implementations of the
`resolveThemeValue()` Theme method:

1. The _core_ version which only resolves based on the exact CSS
variable name. This is the v4-only version.
2. A _compat light_ version which attempts to translate a dot-notation
keypath to a CSS variable name.
3. A _full compat_ version which resolves the legacy theme object which
is used whenever a `@plugin` or `@config` is added.

Unfortunately, there are some issues with this approach that we've
encountered when testing the CSS `theme()` function while upgrading
Tailwind Templates to v4 using our upgrading toolkit.

1. The _compat light_ resolver was trying to convert `theme(spacing.1)`
to tuple syntax. Tuples require a nested property access, though, and
instead this should be convert to `theme(--spacing-1)`.
2. We currently only load _full compat_ version if `@plugin` or
`@config` directives are used. It is possible, though, that we need the
full compat mapping in other cases as well. One example we encountered
is `theme(fontWeight.semibold)` which maps to a dictionary in the
default theme that that we do not have an equivalent for in v4
variables.

To fix both issues, we decided to remove the _compat light_ version of
the `theme()` function in favor of adding this behavior to an upgrade
codemod. Instead, the second layer now only decides wether it can use
the _core_ version or wether it needs to upgrade to the _full compat_
version. Since typos would trigger a _hard error_, we do not think this
has unintended performance consequences if someone wants to use the
_core_ version only (they would get an error regardless which they need
to fix in order to continue).
2024-10-10 12:31:46 +02:00
Philipp Spiess
df0600361d
Ensure custom variants using the JS API have access to modifiers (#14637)
Fixes https://github.com/tailwindlabs/tailwindcss/discussions/14623

We didn't properly pass through modifiers for all custom variant calls.
This PR fixes that.
2024-10-10 12:14:51 +02:00
Philipp Spiess
8b0d22435c
Fix CLI client crash when a file is removed before we process the change notification (#14616)
Fixes #14613

Don't crash when trying to read the modification time of a file that
might already be deleted.

Note: This fix is purely theoretical right now as I wasn't able to
reproduce the issue yet.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-10-09 14:56:08 +00:00
Robin Malfait
b1733ac1fd
Don't set display: none on elements that use hidden="until-found" (#14631)
Fixes an issue reported by the React Aria Components team here:

https://github.com/adobe/react-spectrum/issues/7160

Basically `hidden="until-found"` behaves very differently than `hidden`
and doesn't actually use `display: none`, so we don't want to apply the
behavior we apply for the regular `hidden` attribute.
2024-10-09 13:55:58 +02:00
Philipp Spiess
1467dab59e
Fix template migration issues (#14600)
This PR fixes two issues we found when testing the candidate codemodes:

1. Sometimes, core would emit the same candidate twice. This would
result into rewriting a range multiple times, without realizing that
this change might already be applied, causing it to swallow or duplicate
some bytes.
2. The codemods were mutating the `Candidate` object, however since the
`Candidate` parsing is _cached_ in core, it would sometimes return the
same instance. This is an issue especially since we monkey patch the
prefix to `null` when migrating prefixed candidates. This means that a
candidate would be cached that would be _invalid relative to the real
design system_. We fixed this by making sure the mutations would only be
applied to clones of the `Candidate` and I changed the `DesignSystem`
API to return `ReadOnly<T>` versions of these candidates. A better
solution would maybe be to disable the cache at all but this requires
broader changes in Core.
2024-10-08 18:06:43 +02:00
Philipp Spiess
fdb90ae630
Try out namespace GitHub Actions workers (#14587)
We're trialing [namespace.so](https://namespace.so/) for their custom
GitHub Action workers. So far we're seeing an improvement of 3 minutes
in our pipeline (used to take 6min 30sec and now it's 3min 30sec, an
almost 50% improvement!).

We can always revert this PR, but I recommend we try it out by enabling
it for our CI for the next few days.
2024-10-08 13:48:32 +02:00
Robin Malfait
68c32d1a60
Make custom @at-root private API (#14618)
This PR makes the internal `@at-root` API private. Before this PR you
could use `@at-root` in your own CSS, which means that it was part of
the public API. If you (accidentally) used it in variants, you could
generate CSS that was completely broken.

This now introduces a new private `AtRoot` node (similar to the recently
introduced `Context` node) and can only be constructed within the
framework.
2024-10-08 13:47:55 +02:00
Philipp Spiess
7be5346e2e
Ensure upgrade tool has access to a JS config (#14597)
In order to properly migrate your Tailwind CSS v3 project to v4, we need
access to the JavaScript configuration object. This was previously only
required for template migrations, but in this PR we're making it so that
this is also a prerequisite of the CSS migrations. This is because some
migrations, like `@apply`, also need to convert candidates that to the
v4 syntax and we need the full config in order to properly validate
them.

In addition to requiring a JS config, we also now attempt to
automatically find the right configuration file inside the current
working directory. This is now matching the behavior of the Tailwind CSS
v3 CLI where it will find the config automatically if it's in the
current directory and called `tailwind.conf.js`.

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-10-07 18:02:28 +02:00
Robin Malfait
c7a9e9bc39
improve CHANGELOG 2024-10-07 11:44:22 +02:00
Robin Malfait
ab0abcf8ff
Pretty print !important in declarations (#14611)
This PR is a very small improvement. We started pretty printing the
generated CSS (proper indentation) a while ago, so that we can use the
output as-is for intellisense (on hover).

The other day I noticed that when you use `!important` that we attach it
directly to the declaration. Not the end of the world, but this PR
injects a little space to make sure that the `!important` is separated
from the value which makes it a little easier to read and looks more
like what you would write by hand.

Before:
```css
.flex\! {
  display: flex!important;
}
```

After:
```css
.flex\! {
  display: flex !important;
}
```
2024-10-07 11:38:01 +02:00
depfu[bot]
1d1fd46844
Update bun 1.1.26 → 1.1.29 (patch) (#14608)
Here is everything you need to know about this update. Please take a
good look at what changed and the test results before merging this pull
request.

### What changed?




#### ✳️ bun (1.1.22 → 1.1.29) · [Repo](https://github.com/oven-sh/bun)





Sorry, we couldn't find anything useful about this release.











---
![Depfu
Status](https://depfu.com/badges/edd6acd35d74c8d41cbb540c30442adf/stats.svg)

[Depfu](https://depfu.com) will automatically keep this PR
conflict-free, as long as you don't add any commits to this branch
yourself. You can also trigger a rebase manually by commenting with
`@depfu rebase`.

<details><summary>All Depfu comment commands</summary>
<blockquote><dl>
<dt>@​depfu rebase</dt><dd>Rebases against your default branch and
redoes this update</dd>
<dt>@​depfu recreate</dt><dd>Recreates this PR, overwriting any edits
that you've made to it</dd>
<dt>@​depfu merge</dt><dd>Merges this PR once your tests are passing and
conflicts are resolved</dd>
<dt>@​depfu cancel merge</dt><dd>Cancels automatic merging of this
PR</dd>
<dt>@​depfu close</dt><dd>Closes this PR and deletes the branch</dd>
<dt>@​depfu reopen</dt><dd>Restores the branch and reopens this PR (if
it's closed)</dd>
<dt>@​depfu pause</dt><dd>Ignores all future updates for this dependency
and closes this PR</dd>
<dt>@​depfu pause [minor|major]</dt><dd>Ignores all future minor/major
updates for this dependency and closes this PR</dd>
<dt>@​depfu resume</dt><dd>Future versions of this dependency will
create PRs again (leaves this PR as is)</dd>
</dl></blockquote>
</details>

Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
2024-10-07 11:24:59 +02:00
Philipp Spiess
c01b8254e8
Add *.js export variants for compat files (#14595)
In v3 it was possible to import `*.js` variants of compat files, e.g.
`tailwindcss/plugin.js` in addition to `tailwindcss/plugin`. We need to
properly map the exports to support this.
2024-10-04 15:38:55 +02:00
Philipp Spiess
bc18a57113
Support keyframes in JS theme config (#14594)
Adds support for defining `keyframes` via the v3 JS config file. E.g.:

```js
module.exports = {
  theme: {
    extends: {
      keyframes: {
        "fade-in": {
          "0%": { opacity: "0" },
          "100%": { opacity: "1" },
        },
        "fade-out": {
          "0%": { opacity: "1" },
          "100%": { opacity: "0" },
        },
      },
    },
  },
};
```
2024-10-04 13:58:30 +02:00
Robin Malfait
e3764ac843
Ensure CSS before a layer stays unlayered (#14596)
This PR fixes an issue where CSS that existed before a layer:

```css
.foo {
  color: red;
}

@layer components {
  .bar {
    color: blue;
  }
}
```

Was turned into an `@layer` without a name:
```css
@layer {
  .foo {
    color: red;
  }
}

@utility bar {
  color: blue;
}
```

But in this case, it should stay as-is:
```css
.foo {
  color: red;
}

@utility bar {
  color: blue;
}
```
2024-10-04 12:47:05 +02:00
Jordan Pittman
60b0e9c6a0
Don’t crash when scanning candidate matching the prefix (#14588)
When a prefix is set in a stylesheet and we found a candidate that is
equal to the prefix we would crash:
```css
@import "tailwindcss" prefix(tomato);
```

```js
console.log("tomato")
```

This PR fixes this case by ensuring that we have something that looks
like a variant before considering a prefix.
2024-10-04 05:58:20 -04:00
Adam Wathan
0f37845a3d
Update CHANGELOG.md 2024-10-03 13:22:21 -04:00
Adam Wathan
51afa7d658
Update CHANGELOG.md 2024-10-03 12:52:18 -04:00
Philipp Spiess
42fdafaf58
Update CI wording (#14586)
We want to include a link to the build.
2024-10-03 17:11:23 +02:00
Robin Malfait
39e108d5f5
release v4.0.0-alpha.26 v4.0.0-alpha.26 2024-10-03 16:39:59 +02:00
Philipp Spiess
21c7624bd3
Bring back rust-toolchain.toml (#14585)
We accidentally removed this in #14565.
2024-10-03 14:37:24 +00:00
Robin Malfait
ec454b5a7d
update CHANGELOG 2024-10-03 16:26:22 +02:00
Jordan Pittman
af15e1bdc0
Add support for important in v4 (#14448)
This PR allows modifying utility output by wrapping all utility
declarations in a custom selector or marking all utility declarations as
`!important`. This is the v4 equivalent to the `important` option in the
`tailwind.config.js` file.

## Mark all utility declarations as `!important`

To add `!important` to all utility declarations, you add an `important`
flag after the `@import` statement for `tailwindcss` or
`tailwindcss/utilities`:

```css
/** Importing `tailwindcss` */
@import "tailwindcss" important;

/** Importing the utilities directly */
@import "tailwindcss/utilities" important;
```

Example utility output:

```css
.mx-auto {
  margin-left: auto !important;
  margin-right: auto !important;
}

.text-center {
  text-align: center !important;
}
```

This is equivalent to adding `important: true` to the
`tailwind.config.js` file — which is still supported for backwards
compatibility.

## Wrap all utility declarations in a custom selector

To nest all utilities in an `#app` selector you add `selector(#app)`
flag after the `@import` statement for `tailwindcss` or
`tailwindcss/utilities`:

```css
/** Importing `tailwindcss` */
@import "tailwindcss" selector(#app);

/** Importing the utilities directly */
@import "tailwindcss/utilities" selector(#app);
```

Example utility output:

```css
.mx-auto {
  #app & {
    margin-left: auto;
    margin-right: auto;
  }
}

.text-center {
  #app & {
    text-align: center;
  }
}
```

This is equivalent to adding `important: "#app"` to the
`tailwind.config.js` file — which is still supported for backwards
compatibility.

**This _does not_ bring back support for the `respectImportant` flag in
`addUtilities` / `matchUtilities`.**
2024-10-03 16:25:11 +02:00
Robin Malfait
35b84cc313
Improve @tailwindcss/postcss performance for initial builds (#14565)
This PR improves the performance of the `@tailwindcss/postcss` plugin.
Before this change we created 2 compiler instances instead of a single
one. On a project where a `tailwindcss.config.ts` file is used, this
means that the timings look like this:

```
[@tailwindcss/postcss] Setup compiler: 137.525ms
⋮
[@tailwindcss/postcss] Setup compiler: 43.95ms
```

This means that with this small change, we can easily shave of ~50ms for
initial PostCSS builds.

---------

Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-10-03 16:21:54 +02:00
Philipp Spiess
2e87288526
Migrate at-apply utilites with template migrations (#14574)
This PR extracts all _candidate migrations_ from the existing _template
migrations_ and reuses these in the `@apply` CSS migration. Seems like
this _JustWorks_.

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-10-03 09:35:28 -04:00
Philipp Spiess
aa343a9445
Fix @apply and CSS functions inside imported files (#14576)
Part-of #14558

After handling `@import` of stylesheets in core, we can no longer gate
out features based on finding a specific sequence in the input CSS, as
this string will not contain contents from other stylesheets.

So, consider the following input CSS:

```css
@import "tailwindcsss";
@import "./styles.css";
```

We can't opt-out of the traversal to search for `@apply` based on it
because it, of course, does not contain the contents of `./styles.css`
yet.

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-10-03 09:23:03 -04:00
Philipp Spiess
e4308da604
Template migrations: Add variant order codemods (#14524)
One of the breaking changes of v4 is the [inversion of variant order
application](https://github.com/tailwindlabs/tailwindcss/pull/13478). In
v3, variants are applied "inside-out".


For example a candidate like `*:first:underline` would produce the
following CSS in v3:

```css
.\*\:first\:underline:first-child > * {
  text-decoration-line: underline;
}
```

To get the same behavior in v4, you would need to invert the candidate
order to `first:*:underline`. This would generate the following CSS in
v4:

```css
:where(.first\:\*\:underline:first-child > *) {
  text-decoration-line: underline;
}
```

## The Migration

The most naive approach would be to invert the variants for every
candidate with at least two variants. This, however, runs into one issue
and some unexpected inconsistencies. I have identified the following
areas:

1. Some pseudo class variants _must appear at the end of the selector_.
v3 was patching over this by doing some manual reordering in for these
variants. For example, in v3, both of these variants create the same
output CSS: `hover:before:underline` and `before:hover:underline`. In v4
we simplified this system though and no longer generate the same output
in both cases. Instead, you'd always want to write
`hover:before:underline`, ensuring that these variants will appear at
the end.
   
For an exact list of which variants these affect, take a look [at this
diff](https://github.com/tailwindlabs/tailwindcss/pull/13478/files#diff-7779a0eebf6b980dd3abd63b39729b3023cf9a31c91594f5a25ea020b066e1c0L228-L246).

2. The `dark` variant and other at-rule variants are usually written
before other variants. This is more of a recommendation to make it
easier to read candidates rather than a difference in behavior as
`@media` queries are hoisted by the engine. For this reason, both of
these variants are _correct_ yet in real applications we prefer the
first one: `lg:hover:underline`, `hover:lg:underline`.
   
To avoid shuffling these rules across all candidates during the
migration, we bucket `dark` and other at-rule variants into a special
bucket that will not have their order changed (since people wrote stacks
like `sm:max-lg:` before and we want to keep them as-is) and appear
before all other variants.

3. For some variant stacks, the order does not matter. E.g.:
`focus:hover:underline` and `hover:focus:underline` will be the same. We
don't want to needlessly shuffle their order if we have to.

With these considerations, the migration now works as follows:

- If there is less then two variants, we do not need to migrate the
candidate
- If _every_ variant in the stack is an order-independent variant, we do
not need to migrate the candidate
- _Note that this is currently hardcoded to only support `&:hover` and
`&:focus`._
- Otherwise, we loop over the candidates and put them into three
buckets:
- `mediaVariants` hold variants that only contribute `@media` rules
_and_ the `dark` variant.
- `pseudoElementVariants` hold variants that _must appear at the end of
the selector_. This is based on the allow list from v3/early v4.
  - `regularVariants` contains the rest.
- We now compute if any of the variants inside `regularVariants` is
order dependent.
- With this list of variants, we now construct the new order of variants
as:
   
   ```ts
   [
     ...atRuleVariants,
...(anyRegularVariantOrderDependent ? regularVariants.reverse() :
regularVariants),
     ...pseudoElementVariants,
   ]
   ```

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-10-03 09:15:19 -04:00
Philipp Spiess
bbe08c3b84
Add binary extensions found in macOS traces (#14584)
While we were doing some tracing for Rust memory issues, we noticed that
the builds became slower and slower. Turns out we did store the macOS
`.trace` dirs within the auto content directory of the Tailwind CSS
instance we were profiling and that _some of the files were massive
binary files that we were now scanning_.

Here's the anatomy of a single trace:


```
[ 320]  .
├── [497K]  form.template
├── [5.1K]  open.creq
├── [ 261]  UI_state_metadata.bin
├── [ 160]  corespace
│   ├── [1.2K]  MANIFEST.plist
│   ├── [  96]  currentRun
│   │   └── [  96]  core
│   │       └── [ 128]  uniquing
│   │           ├── [ 128]  arrayUniquer
│   │           │   ├── [10.0K]  integeruniquer.data
│   │           │   └── [   0]  integeruniquer.index
│   │           └── [ 128]  typedArrayUniquer
│   │               ├── [10.0K]  integeruniquer.data
│   │               └── [   0]  integeruniquer.index
│   └── [  96]  run1
│       └── [ 192]  core
│           ├── [ 224]  uniquing
│           │   ├── [6.5K]  EngineeringTypes.etypes
│           │   ├── [3.5K]  strings
│           │   ├── [ 344]  TOC
│           │   ├── [ 128]  arrayUniquer
│           │   │   ├── [1.1K]  integeruniquer.data
│           │   │   └── [  96]  integeruniquer.index
│           │   └── [ 128]  typedArrayUniquer
│           │       ├── [1.0K]  integeruniquer.data
│           │       └── [  28]  integeruniquer.index
│           ├── [ 192]  stores
│           │   ├── [ 224]  indexed-store-0
│           │   │   ├── [1.6K]  bulkstore
│           │   │   ├── [1.2K]  spindex.0
│           │   │   ├── [1.1K]  bulkstore_descriptor
│           │   │   ├── [ 433]  spec.plist
│           │   │   └── [ 188]  schema.xml
│           │   ├── [ 224]  indexed-store-1
│           │   │   ├── [7.5K]  bulkstore
│           │   │   ├── [7.0K]  spindex.0
│           │   │   ├── [1.6K]  bulkstore_descriptor
│           │   │   ├── [ 522]  spec.plist
│           │   │   └── [ 352]  schema.xml
│           │   ├── [ 224]  indexed-store-2
│           │   │   ├── [ 17K]  bulkstore
│           │   │   ├── [7.2K]  spindex.0
│           │   │   ├── [2.0K]  bulkstore_descriptor
│           │   │   ├── [ 532]  spec.plist
│           │   │   └── [ 412]  schema.xml
│           │   └── [ 192]  indexed-store-3
│           │       ├── [1.8K]  bulkstore_descriptor
│           │       ├── [ 426]  spec.plist
│           │       ├── [ 399]  schema.xml
│           │       └── [  50]  bulkstore
│           ├── [  96]  core-config
│           │   └── [2.0K]  exposedTableInfo.plist
│           └── [  96]  table-manager
│               └── [1.6K]  tables.plist
├── [ 128]  Trace1.run
│   ├── [966M]  event_data_52237.oa
│   └── [ 52K]  RunIssues.storedata
├── [ 128]  instrument_data
│   ├── [  96]  EF4DC038-8A17-421A-8050-39DD0980C06F
│   │   └── [  96]  run_data
│   │       └── [ 17K]  1.run.zip
│   └── [  96]  F9F2B147-A042-43F0-A791-EA6D63C7C1E8
│       └── [  96]  run_data
│           └── [2.2K]  1.run.zip
├── [ 128]  symbols
│   ├── [ 608]  stores
│   │   ├── [453K]  D14A8304-5F09-385D-9AA6-1B0C815B6356.symbolsarchive
│   │   ├── [ 36K]  4E9DB999-EFF4-3C83-B4E8-E1914D2C331E.symbolsarchive
│   │   ├── [3.7K]  B5D897DF-D536-3668-BBAD-A17119439EF0.symbolsarchive
│   │   ├── [3.1K]  57FFCB9D-A6C9-3E9A-AA82-40F192626527.symbolsarchive
│   │   ├── [2.9K]  69AA9AB7-C5DE-3CAE-BF1A-384F9F36A3E0.symbolsarchive
│   │   ├── [2.8K]  F453C5AE-3568-3AAA-AAA0-D2FDFBB9BC7A.symbolsarchive
│   │   ├── [2.6K]  62D27203-665F-3AA7-8BE9-7E3C3A847353.symbolsarchive
│   │   ├── [2.4K]  9896C713-054D-377D-88B4-45E1DE3FB6C5.symbolsarchive
│   │   ├── [2.1K]  249D8F21-72A2-3A80-ADC1-7BEAF24B5B58.symbolsarchive
│   │   ├── [2.1K]  FA954AC0-FCC5-3711-800B-432011ACD89E.symbolsarchive
│   │   ├── [2.0K]  E7ED11EE-AFB0-3B96-90A8-F1835726B9B8.symbolsarchive
│   │   ├── [1.3K]  5B476F9B-DF8B-356A-8582-615D4AD08504.symbolsarchive
│   │   ├── [1.3K]  6102110F-7ED8-34C2-95D3-C5ACCB41497E.symbolsarchive
│   │   ├── [1.1K]  EC86EDBF-30B9-3BF8-A358-C8D51805B016.symbolsarchive
│   │   ├── [1.0K]  6740FF57-8D20-3FC7-97F5-B2AFB6E5F48A.symbolsarchive
│   │   ├── [ 963]  9A72FD37-D827-3D6D-B6F4-422621E36C94.symbolsarchive
│   │   └── [ 948]  67A46592-439B-36DA-8A08-A7CD777A43A8.symbolsarchive
│   └── [ 290]  MANIFEST.plist
└── [  96]  shared_data
    └── [  96]  1.run
        └── [ 14M]  533F36D4-2C90-4030-95CA-74077F2E26D7.zip

29 directories, 59 files
```

Note that the biggest binary file is a `.oa` but I've also added
`.storedata` and `.symbolsarchive` as binary extensions to this PR.
2024-10-03 14:40:07 +02:00
depfu[bot]
ffb36a7cf9
Update jiti 2.0.0-beta.3 → 2.1.0 (minor) (#14582)
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
2024-10-03 09:27:54 +00:00
depfu[bot]
7e9bb6833d
Update postcss 8.4.41 → 8.4.47 (patch) (#14581)
Here is everything you need to know about this upgrade. Please take a
good look at what changed and the test results before merging this pull
request.

### What changed?




#### ✳️ postcss (8.4.41 → 8.4.47) ·
[Repo](https://github.com/postcss/postcss) ·
[Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)



<details>
<summary>Release Notes</summary>
<h4><a
href="https://github.com/postcss/postcss/releases/tag/8.4.47">8.4.47</a></h4>

<blockquote><ul dir="auto">
<li>Removed debug code.</li>
</ul></blockquote>
<h4><a
href="https://github.com/postcss/postcss/releases/tag/8.4.46">8.4.46</a></h4>

<blockquote><ul dir="auto">
<li>Fixed <code class="notranslate">Cannot read properties of undefined
(reading 'before')</code>.</li>
</ul></blockquote>
<h4><a
href="https://github.com/postcss/postcss/releases/tag/8.4.45">8.4.45</a></h4>

<blockquote><ul dir="auto">
<li>Removed unnecessary fix which could lead to infinite loop.</li>
</ul></blockquote>
<h4><a
href="https://github.com/postcss/postcss/releases/tag/8.4.44">8.4.44</a></h4>

<blockquote><ul dir="auto">
<li>Another way to fix <code class="notranslate">markClean is not a
function</code> error.</li>
</ul></blockquote>
<h4><a
href="https://github.com/postcss/postcss/releases/tag/8.4.43">8.4.43</a></h4>

<blockquote><ul dir="auto">
<li>Fixed <code class="notranslate">markClean is not a function</code>
error.</li>
</ul></blockquote>
<h4><a
href="https://github.com/postcss/postcss/releases/tag/8.4.42">8.4.42</a></h4>

<blockquote><ul dir="auto">
<li>Fixed CSS syntax error on long minified files (by <a
href="https://bounce.depfu.com/github.com/varpstar">@varpstar</a>).</li>
</ul></blockquote>
<p><em>Does any of this look wrong? <a
href="https://depfu.com/packages/npm/postcss/feedback">Please let us
know.</a></em></p>
</details>

<details>
<summary>Commits</summary>
<p><a
href="57e02115e4...5e6fd1302d">See
the full diff on Github</a>. The new version differs by 33 commits:</p>
<ul>
<li><a
href="5e6fd1302d"><code>Release
8.4.47 version</code></a></li>
<li><a
href="714bc10258"><code>Typo</code></a></li>
<li><a
href="439d20e651"><code>Release
8.4.46 version</code></a></li>
<li><a
href="b93582f68e"><code>Update
dependencies</code></a></li>
<li><a
href="c51e46767d"><code>Fix
error on inserting node without raws in some cases</code></a></li>
<li><a
href="829ae47d6b"><code>Update
dependencies</code></a></li>
<li><a
href="5aaaec2214"><code>Update
remaining workflow jobs to use latest version of actions
(#1968)</code></a></li>
<li><a
href="448c4f34d6"><code>Release
8.4.45 version</code></a></li>
<li><a
href="1c77d2e333"><code>Update
unnecessary check</code></a></li>
<li><a
href="f38b329323"><code>Try
to fix CI</code></a></li>
<li><a
href="d442dc75e3"><code>Release
8.4.44 version</code></a></li>
<li><a
href="3c7cda099c"><code>Another
way to fix markClean() is undefined issue</code></a></li>
<li><a
href="b985ed1667"><code>Release
8.4.43 version</code></a></li>
<li><a
href="3025b743bf"><code>Update
dependencies</code></a></li>
<li><a
href="79ff9800c3"><code>Update
AST if it is not made by PostCSS &gt;= 8.4.41</code></a></li>
<li><a
href="0fda48a1b1"><code>Release
8.4.42 version</code></a></li>
<li><a
href="cd5b08cfa2"><code>Add
ESLint to CI</code></a></li>
<li><a
href="0975cc209d"><code>Sort
source code and fix ESLint</code></a></li>
<li><a
href="36950b4ff9"><code>Try
to fix old Node.js tests</code></a></li>
<li><a
href="fbb6d60eae"><code>Update
dependencies</code></a></li>
<li><a
href="118ebc9a9a"><code>Clean
up code</code></a></li>
<li><a
href="9e7bdca1d2"><code>Pretty
CssSyntaxError from onelined (minified) css (#1965)</code></a></li>
<li><a
href="45a24250ee"><code>Merge
pull request #1961 from nex3/readonly-array</code></a></li>
<li><a
href="0cb325a1d5"><code>Use
`ReadonlyArray` for argument types that aren&#39;t
modified</code></a></li>
<li><a
href="a886628603"><code>Merge
pull request #1957 from nex3/protected-normalize</code></a></li>
<li><a
href="13a16b0dc8"><code>Merge
pull request #1958 from nex3/typedoc</code></a></li>
<li><a
href="51022c2a42"><code>Fix
a few TypeDoc warnings</code></a></li>
<li><a
href="d6fa30b3cc"><code>Add
a protected `markDirty()` method on `Node`</code></a></li>
<li><a
href="58c50ad191"><code>Declare
`Container.normalize()` as a protected method</code></a></li>
<li><a
href="ea262f3b3f"><code>Merge
pull request #1956 from
Juneezee/refactor/replace-indexOf-with-startsWith</code></a></li>
<li><a
href="c37da3c225"><code>Replace
`indexOf === 0` with `startsWith`</code></a></li>
<li><a
href="4b96e7df14"><code>Merge
pull request #1955 from
Marukome0743/Marukome0743-patch-1</code></a></li>
<li><a
href="edcc9b13b9"><code>chore(docs):
improve visual appearance of images in README.md</code></a></li>
</ul>
</details>












---
![Depfu
Status](https://depfu.com/badges/edd6acd35d74c8d41cbb540c30442adf/stats.svg)

[Depfu](https://depfu.com) will automatically keep this PR
conflict-free, as long as you don't add any commits to this branch
yourself. You can also trigger a rebase manually by commenting with
`@depfu rebase`.

<details><summary>All Depfu comment commands</summary>
<blockquote><dl>
<dt>@​depfu rebase</dt><dd>Rebases against your default branch and
redoes this update</dd>
<dt>@​depfu recreate</dt><dd>Recreates this PR, overwriting any edits
that you've made to it</dd>
<dt>@​depfu merge</dt><dd>Merges this PR once your tests are passing and
conflicts are resolved</dd>
<dt>@​depfu cancel merge</dt><dd>Cancels automatic merging of this
PR</dd>
<dt>@​depfu close</dt><dd>Closes this PR and deletes the branch</dd>
<dt>@​depfu reopen</dt><dd>Restores the branch and reopens this PR (if
it's closed)</dd>
<dt>@​depfu pause</dt><dd>Ignores all future updates for this dependency
and closes this PR</dd>
<dt>@​depfu pause [minor|major]</dt><dd>Ignores all future minor/major
updates for this dependency and closes this PR</dd>
<dt>@​depfu resume</dt><dd>Future versions of this dependency will
create PRs again (leaves this PR as is)</dd>
</dl></blockquote>
</details>

Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
2024-10-03 11:15:18 +02:00
Adam Wathan
dae178ef6a
Add color-scheme utilities (#14567)
Replaces #11271 — the merge conflicts are killing me and it's way easier
to just do it again (added you as a co-author though @lukewarlow so
you're still credited!)

This PR adds the following new utilities for the `color-scheme`
property:

| Class               | CSS                        |
| ------------------- | -------------------------- |
| `scheme-normal`     | `color-scheme: normal`     |
| `scheme-dark`       | `color-scheme: dark`       |
| `scheme-light`      | `color-scheme: light`      |
| `scheme-light-dark` | `color-scheme: light dark` |
| `scheme-only-dark`  | `color-scheme: dark only`  |
| `scheme-only-light` | `color-scheme: light only` |

Went with `scheme-*` for the utilities because there are currently no
other CSS properties with the word `scheme` in them and
`scheme-light-dark` is going to be a common value which is three words
already even with the shortened property name.

I considered setting `color-scheme: light dark` by default as part of
Preflight for this PR but decided against it, at least for this PR. I
think that could still be a useful default but we should think about it
a bit more because if you're building a light-mode-only site it'll force
you to do some extra work.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Luke Warlow <lwarlow@igalia.com>
2024-10-02 06:07:55 -04:00
Adam Wathan
3693a71a10
Test @import "tailwindcss" prefix(tw) explicitly + move prefix tests (#14566)
I noticed our prefix tests were missing an explicit test for `@import
"tailwindcss" prefix(tw)` so this PR tweaks an existing test to test
that case.

Also noticed that `prefix.test.ts` was in the `compat` folder even
though this is a v4 feature, so moved it out to the root.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-01 13:20:18 -04:00
Philipp Spiess
65240c9240
Template migrations: Migrate v3 prefixes to v4 (#14557)
This PR adds a new migration that can migrate Tailwind CSS v3 style
prefixes into Tailwind CSS v4.

The migration is split into three separate pieces of work:

1. Firstly, we need to read the full JavaScript config to get the _old_
prefix option. This is necessary because in v4, we will not allow things
like custom-separators for the prefix. From this option we will then try
and compute a new prefix (in 90% of the cases this is going to just
remove the trailing `-` but it can also work in more complex cases).
2. Then we migrate all Candidates. The important thing here is that we
need to operate on the raw candidate string because by relying on
`parseCandidate` (which we do for all other migrations) would not work,
as the candidates are not valid in v4 syntax. More on that in a bit.
3. Lastly we also make sure to update the CSS config to include the new
prefix. This is done by prepending the prefix option like so:
    
    ```css
    @import "tailwindcss" prefix(tw);
    ```

### Migrating candidates

The main difference between v3 prefixes and v4 prefixes is that in v3,
the prefix was _part of the utility_ where as in v4 it is _always in
front of the CSS class.

So, for example, this candidate in v3: 

```
hover:-tw-mr-4
```

Would be converted to the following in v4:

```
tw:hover:-mr-4
```

Since the first example _won't parse as a valid Candidate in v4, as the
`tw-mr` utility does not exist, we have to operate on the raw candidate
string first. To do this I created a fork of the `parseCandidate`
function _without any validation of utilities or variants_. This is used
to identify part of the candidate that is the `base` and then ensuring
the `base` starts with the old prefix. We then remove this to create an
"unprefixed" candidate that we validate against a version of the
DesignSystem _with no prefixes configured_. If the variant is valid this
way, we can then print it again with the `DesignSystem` that has the new
prefix to get the migrated version.

Since we set up the `DesignSystem` to include the new prefix, we can
also be certain that migrations that happen afterwards would still
disqualify candidates that aren't valid according to the new prefix
policy. This does mean we need to have the prefix fixup be the first
step in our pipeline.

One interesting bit is that in v3, arbitrary properties did not require
prefixes where as in v4 they do. So the following candidate:

```
[color:red]
```

Will be converted to:

```
tw:[color:red]
```
2024-10-01 18:04:08 +02:00
Philipp Spiess
3f85b74611
Add integration tests for multi-root builds (#14564)
When your Vite or postcss project has multiple Tailwind CSS roots with
different configs, they should not influence each other (with the
exception of the same candidates being used).
2024-10-01 17:00:20 +02:00
Philipp Spiess
3813f03b79
Bare values: Disallow zeros in decimal places (#14562)
I noticed some more unexpected values being passed through as _bare
values_: Decimal places with zero.

These should not generate CSS but currently does:

- `from-25.%`
- `from-25.0%`
- `from-25.00%`
- etc.
2024-10-01 10:06:43 -04:00
Robin Malfait
30fbc2c707
Fix rebuilds when editing imported CSS files (#14561) 2024-10-01 11:52:12 +00:00
Philipp Spiess
78b75e4d96
Only run Ubuntu tests on feature branches (#14560)
This PR changes it so that only the Ubuntu runner starts when doing a
pull request. On a successfull `next` merge, all runners shoould start.

Furthermore this increases the retry count for integration test to 3.
This is mainly so that rare Windows flakes we still see won't become
noise when we enabled the Discord notification.
2024-10-01 13:45:52 +02:00
Philipp Spiess
c0dd000c3c
Template migrations: Add automatic var injection codemods (#14526)
In v4, we're [removing automatic var
injection](https://github.com/tailwindlabs/tailwindcss/pull/13657)
(please refer to this PR for more detail as to why).

Automatic var injection made it so that if you have a candidate like
`bg-[--my-color]`, v3 would automatically wrap the content of the
arbitrary section with a `var(…)`, resulting in the same as typing
`bg-[var(--my-color)]`.

This PR adds codemods that go over various arbitrary fields and does the
`var(…)` injection for you. To be precise, we will add `var(…)` to:

- Modifiers, e.g.: `bg-red-500/[var(--my-opacity)]`
- Variants, e.g.:  `supports-[var(--test)]:flex`
- Arbitrary candidates, e.g.: `[color:var(--my-color)]`
- Arbitrary values for functional candidates, e.g.:
`bg-[var(--my-color)]`

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-10-01 13:23:24 +02:00
Jordan Pittman
6a50e6e160
Add blocklist support from v3 config files (#14556)
This PR adds support for the `blocklist` config option when using a JS
config file in v4. You can now block certain classes from being
generated at all. This is useful in cases where scanning files sees
things that look like classes but are actually not used. For example, in
paragraphs in a markdown file:

  ```js
  // tailwind.config.js
  export default {
    blocklist: ['bg-red-500'],
  }
  ```
  
  ```html
  <!-- index.html -->
  <div class="bg-red-500 text-black/75"></div>
  ```

Output:
  
  ```css
  .text-black/75 {
    color: rgba(0, 0, 0, 0.75);
  }
  ```
2024-09-30 15:12:03 -04:00
Robin Malfait
ab82efab7d
Expose timing information in debug mode (#14553)
This PR exposes when using the the `DEBUG` environment variable. This
follows the `DEBUG` conventions where:

- `DEBUG=1`
- `DEBUG=true`
- `DEBUG=*`
- `DEBUG=tailwindcss`

Will enable the debug information, but when using:

- `DEBUG=0`
- `DEBUG=false`
- `DEBUG=-tailwindcss`

It will not.

This currently only exposes some timings related to:

1. Scanning for candidates
2. Building the CSS
3. Optimizing the CSS

We can implement a more advanced version of this where we also expose
more fine grained information such as the files we scanned, the amount
of candidates we found and so on. But I believe that this will be enough
to start triaging performance related issues.
2024-09-30 14:39:21 +00:00