Commit graph

6274 commits

Author SHA1 Message Date
Jordan Pittman
83e2cd296d Clarify perf comment
The actual unoptimized bytecode contains one additional instruction but this is definitely a bit faster in benchmarks
2025-05-07 16:04:45 -04:00
Jordan Pittman
f3fc8137f2 Add line table benchmark 2025-05-07 15:49:45 -04:00
Jordan Pittman
347d9e2971 Remove unncessary settings from test 2025-05-07 15:49:03 -04:00
Jordan Pittman
e3561fba8e Update type 2025-05-06 11:29:11 -04:00
Jordan Pittman
58932d5a25 Inline function to push mappings 2025-05-06 11:28:17 -04:00
Jordan Pittman
1992ba55ab Add comment clarifying magic number 2025-05-06 11:27:12 -04:00
Jordan Pittman
8fdb8baaa1 Increment unknown source ID when generating maps 2025-05-06 11:26:44 -04:00
Jordan Pittman
db5d97403e Fix typo 2025-05-06 11:26:06 -04:00
Jordan Pittman
78915dc156 Remove leftover logs 2025-05-06 11:25:29 -04:00
Jordan Pittman
2e8d099475 Move walk into map fn 2025-05-06 11:23:27 -04:00
Jordan Pittman
5e2fd98f60 Don’t double clone nodes 2025-05-06 11:14:07 -04:00
Jordan Pittman
65e2c17627 Optimize LineTable#find implementation 2025-05-06 10:36:15 -04:00
Jordan Pittman
c9cb8a7deb Fix UI tests 2025-05-05 17:56:23 -04:00
Jordan Pittman
502bda71b8 Update lockfile 2025-05-05 14:06:10 -04:00
Jordan Pittman
00358d0686 Add source map support to PostCSS 2025-05-05 14:05:36 -04:00
Jordan Pittman
bb78c59770 Add source map support to Vite 2025-05-05 14:05:36 -04:00
Jordan Pittman
2f25e3ec3a Add source map support to the CLI 2025-05-05 14:05:36 -04:00
Jordan Pittman
acf5f3182e Update source maps when optimizing output CSS 2025-05-05 14:05:31 -04:00
Jordan Pittman
2302668b48 Add integration test helpers for source maps 2025-05-05 14:05:31 -04:00
Jordan Pittman
b191165f44 Prep for source maps in build tools 2025-05-05 14:05:31 -04:00
Jordan Pittman
a0a9a33952 Use offset information to generate source maps 2025-05-05 14:05:31 -04:00
Jordan Pittman
9a9b47a1fa Track utilities per-candidate in @apply 2025-05-05 13:47:25 -04:00
Jordan Pittman
6b9ace2679 Track utilities generated by @apply 2025-05-05 13:47:25 -04:00
Jordan Pittman
6febfd966a Track locations when printing 2025-05-05 13:47:25 -04:00
Jordan Pittman
fcd4e2d2bc Track locations when optimizing 2025-05-05 13:47:25 -04:00
Jordan Pittman
386e72158c Track generated utilities 2025-05-05 13:47:25 -04:00
Jordan Pittman
3143eb6e7a Track theme variables 2025-05-05 13:47:25 -04:00
Jordan Pittman
3bc80cda67 Track wrapping at-rules created by imports 2025-05-05 13:47:25 -04:00
Jordan Pittman
c129f48cae Track locations inside @import 2025-05-05 13:47:25 -04:00
Jordan Pittman
e95e6e239f Track locations when parsing 2025-05-05 13:47:25 -04:00
Jordan Pittman
f08f89d7ba Track source locations in the AST
These are stored as character offsets for the original input (`src`) as well as the printed output (`dst`)
2025-05-05 13:47:25 -04:00
Jordan Pittman
8319bd83b3 Update CSS parser tests to preserve CRLF where needed 2025-05-05 13:47:25 -04:00
Jordan Pittman
65409a98d9 Don’t replace CRLF with LF before parsing CSS
Now that we can handle CRLF correctly in the parser this is no longer necessary
2025-05-05 13:47:25 -04:00
Jordan Pittman
da86e231d4 Handle CRLF in strings 2025-05-05 13:47:25 -04:00
Jordan Pittman
e7652b7a71 Check for CRLF when scanning consecutive whitespace 2025-05-05 13:47:25 -04:00
Jordan Pittman
c53f344871 Skip over the CR in CRLF when parsing CSS 2025-05-05 13:47:25 -04:00
Jordan Pittman
68ce361ef4 Return resolved path in loadStylesheet and loadModule
Source map support needs this in loadStylesheet but it makes more sense to be consistent and require it for both.
2025-05-05 13:47:25 -04:00
Jordan Pittman
a4cd44d426 Cleanup code a bit 2025-05-05 13:47:25 -04:00
Robin Malfait
5c5ae04db6
Fix Windows CI build (#17878)
This PR fixes a Windows CI issue due to the recently merged #17846

There might be better ways to solve this, but essentially we want to
make sure we are always dealing with `\n` and not `\r\n`. This PR fixes
that by replacing all `\r\n` with `\n` in the tests.
2025-05-05 17:38:53 +02:00
Jordan Pittman
6a1df6acf6
Ignore @tailwind utilities inside @reference (#17836)
You can use `@reference "tailwindcss"` or `@reference
"../path/to/your/css/file.css"` to reference your theme for use in
`@apply`, `theme(…)`, etc…

Unfortunatley, because the imported file still contains `@tailwind
utilities` it would trigger a re-scan of the filesystem — even though
the use of `@reference` ensures that no CSS can actually be output by
the import itself.

This PR does two things:
- Adds some explicit feature detection tests for what features we pick
up in a stylesheet based on the CSS written and how things are imported
- Explicitly ignores `@tailwind utilities` inside of `@reference` so it
isn't a trigger for file scanning

Because of how Vite itself handles dependencies editing files on disk
will still trigger a rebuild of any file using `@reference`. This is
because Vite rebuilds files when _any_ of its transitive dependencies
change.

For example, given this Vue file:
```vue
<style>
@reference "./styles.css";
</style>
<template> <!-- ... --> </template>
```

And this stylesheet:
```css
@import "tailwindcss";
```

The dependency chain looks like this: `file.vue -> styles.css -> {all
the sources in your project}`

Vite sees that a file (e.g. `index.html`) has changed, thus `styles.css`
needs change, which means `file.vue` needs to be compiled again as well.
Now in reality we depend on the _on disk_ version of styles.css not the
compiled version but Vite itself doesn't know that (or have a way to
indicate this afaik).

Coming up with a solution to that problem will have to be a separate PR
— but there is a workaround:

### 1. Inline the imports from `@import "tailwindcss";`

Replace this in your main stylesheet:
```css
@import "tailwindcss";
```

with this (this is basically what `node_modules/tailwindcss/index.css`
is):
```css
@layer theme, base, components, utilities;

@import 'tailwindcss/theme' layer(theme);
@import 'tailwindcss/preflight' layer(base);
@import 'tailwindcss/utilities' layer(utilities);

/* the rest of your styles imports, styles, etc… */
```

### 2. Split your stylesheet into "main" and "theme" parts

Your "theme" is comprised of the `@import 'tailwindcss/theme'
layer(theme);` import, any custom `@theme` blocks, any `@config`
directives, and any `@plugin` directives. Move all of these into their
own file.

For example, replace this with two files:

```css
@layer theme, base, components, utilities;
@import 'tailwindcss/theme' layer(theme);
@import 'tailwindcss/preflight' layer(base);
@import 'tailwindcss/utilities' layer(utilities);

@theme {
  --color-primary: #c0ffee;
}

@plugin "./my-plugin.js";

/* the rest of your styles imports, styles, etc… */
```

with a theme file:
```css
@import 'tailwindcss/theme' layer(theme);

/* all your `@theme` stuff goes in this file */
@theme {
  --color-primary: #c0ffee;
}

/* additionally any @config or @plugin does too */
@plugin "./my-plugin.js";
```

and your main CSS file:
```css
@layer theme, base, components, utilities;
@import './my-theme.css'; /* I replaced this import */
@import 'tailwindcss/preflight' layer(base);
@import 'tailwindcss/utilities' layer(utilities);

/* the rest of your styles imports, styles, etc… */
```

### 3. Import only your "theme" file in your Vue components / CSS
modules / etc…

```vue
<style>
@reference "./my-theme.css";
</style>
<template> <!-- ... --> </template>
```

Fixes #17693
2025-05-05 11:21:55 -04:00
Robin Malfait
d38554d110
Fix HAML extraction with embedded Ruby (#17846)
This PR fixes and improves the HAML extractor by ensuring that whenever
we detect lines or blocks of Ruby code (`-`, `=` and `~`) characters at
the beginning of the line, we treat them as Ruby code.

Fixes: #17813

## Test Plan

1. Existing tests pass
2. Changed 1 existing test which embedded Ruby syntax
3. Added a dedicated test to ensure the HAML file in the linked issue is
parsed correctly

Running this in the internal extractor tool you can see that the
`w-[12px]`, `w-[16px]`, `h-[12px]`, and `h-[16px]` are properly
extracted.

Note: the `mr-12px` is also extracted, but not highlighted because this
is not a valid Tailwind CSS class.

<img width="1816" alt="image"
src="https://github.com/user-attachments/assets/fc5929ca-bc71-47d2-b21b-7abeec86f54d"
/>
2025-05-05 10:26:17 -04:00
depfu[bot]
473f0241bf
Update h3 1.15.1 → 1.15.3 (patch) (#17873) 2025-05-05 10:30:10 +00:00
depfu[bot]
e00d0926eb
Update @vitejs/plugin-react 4.3.4 → 4.4.1 (minor) (#17862) 2025-05-04 19:28:46 +02:00
depfu[bot]
dd5ec49606
Update eslint 9.24.0 → 9.25.1 (minor) (#17850)
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?




#### ✳️ eslint (9.24.0 → 9.25.1) ·
[Repo](https://github.com/eslint/eslint) ·
[Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)



<details>
<summary>Release Notes</summary>
<h4><a
href="https://github.com/eslint/eslint/releases/tag/v9.25.1">9.25.1</a></h4>

<blockquote><h2 dir="auto">Bug Fixes</h2>
<ul dir="auto">
<li>
<a
href="cdc8e8c950"><code
class="notranslate">cdc8e8c</code></a> fix: revert directive detection
in no-unused-expressions (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19639">#19639</a>)
(sethamus)</li>
</ul>
<h2 dir="auto">Chores</h2>
<ul dir="auto">
<li>
<a
href="1f2b057ddc"><code
class="notranslate">1f2b057</code></a> chore: upgrade @eslint/js@9.25.1
(<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19642">#19642</a>)
(Milos Djermanovic)</li>
<li>
<a
href="771317fa93"><code
class="notranslate">771317f</code></a> chore: package.json update for
@eslint/js release (Jenkins)</li>
</ul></blockquote>
<h4><a
href="https://github.com/eslint/eslint/releases/tag/v9.25.0">9.25.0</a></h4>

<blockquote><h2 dir="auto">Features</h2>
<ul dir="auto">
<li>
<a
href="dcd95aafa3"><code
class="notranslate">dcd95aa</code></a> feat: support TypeScript syntax
in no-empty-function rule (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19551">#19551</a>)
(sethamus)</li>
<li>
<a
href="77d6d5bc49"><code
class="notranslate">77d6d5b</code></a> feat: support TS syntax in <code
class="notranslate">no-unused-expressions</code> (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19564">#19564</a>)
(Sweta Tanwar)</li>
<li>
<a
href="90228e5d57"><code
class="notranslate">90228e5</code></a> feat: support <code
class="notranslate">JSRuleDefinition</code> type (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19604">#19604</a>)
(루밀LuMir)</li>
<li>
<a
href="59ba6b7378"><code
class="notranslate">59ba6b7</code></a> feat: add allowObjects option to
no-restricted-properties (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19607">#19607</a>)
(sethamus)</li>
<li>
<a
href="db650a036b"><code
class="notranslate">db650a0</code></a> feat: support TypeScript syntax
in <code class="notranslate">no-invalid-this</code> rule (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19532">#19532</a>)
(Tanuj Kanti)</li>
<li>
<a
href="9535cffe7b"><code
class="notranslate">9535cff</code></a> feat: support TS syntax in <code
class="notranslate">no-loop-func</code> (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19559">#19559</a>)
(Nitin Kumar)</li>
</ul>
<h2 dir="auto">Bug Fixes</h2>
<ul dir="auto">
<li>
<a
href="910bd13c4c"><code
class="notranslate">910bd13</code></a> fix: <code
class="notranslate">nodeTypeKey</code> not being used in <code
class="notranslate">NodeEventGenerator</code> (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19631">#19631</a>)
(StyleShit)</li>
</ul>
<h2 dir="auto">Documentation</h2>
<ul dir="auto">
<li>
<a
href="ca7a735dde"><code
class="notranslate">ca7a735</code></a> docs: update <code
class="notranslate">no-undef-init</code> when not to use section (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19624">#19624</a>)
(Tanuj Kanti)</li>
<li>
<a
href="1b870c9da4"><code
class="notranslate">1b870c9</code></a> docs: use <code
class="notranslate">eslint-config-xo</code> in the getting started guide
(<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19629">#19629</a>)
(Nitin Kumar)</li>
<li>
<a
href="5d4af16ab1"><code
class="notranslate">5d4af16</code></a> docs: add types for multiple rule
options (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19616">#19616</a>)
(Tanuj Kanti)</li>
<li>
<a
href="e8f8d57bd6"><code
class="notranslate">e8f8d57</code></a> docs: Update README (GitHub
Actions Bot)</li>
<li>
<a
href="a40348f1f6"><code
class="notranslate">a40348f</code></a> docs: no-use-before-define tweaks
(<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19622">#19622</a>)
(Kirk Waiblinger)</li>
<li>
<a
href="0ba3ae3e5a"><code
class="notranslate">0ba3ae3</code></a> docs: Update README (GitHub
Actions Bot)</li>
<li>
<a
href="865dbfed6c"><code
class="notranslate">865dbfe</code></a> docs: ensure "learn more"
deprecation links point to useful resource (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19590">#19590</a>)
(Kirk Waiblinger)</li>
<li>
<a
href="f80b746d85"><code
class="notranslate">f80b746</code></a> docs: add known limitations for
no-self-compare (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19612">#19612</a>)
(Nitin Kumar)</li>
<li>
<a
href="865aed6293"><code
class="notranslate">865aed6</code></a> docs: Update README (GitHub
Actions Bot)</li>
</ul>
<h2 dir="auto">Chores</h2>
<ul dir="auto">
<li>
<a
href="88dc1965a4"><code
class="notranslate">88dc196</code></a> chore: upgrade @eslint/js@9.25.0
(<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19636">#19636</a>)
(Milos Djermanovic)</li>
<li>
<a
href="345288d7b2"><code
class="notranslate">345288d</code></a> chore: package.json update for
@eslint/js release (Jenkins)</li>
<li>
<a
href="affe6be018"><code
class="notranslate">affe6be</code></a> chore: upgrade trunk (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19628">#19628</a>)
(sethamus)</li>
<li>
<a
href="dd20cf274e"><code
class="notranslate">dd20cf2</code></a> test: fix <code
class="notranslate">no-loop-func</code> test with duplicate variable
reports (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19610">#19610</a>)
(Milos Djermanovic)</li>
<li>
<a
href="bd05397ef6"><code
class="notranslate">bd05397</code></a> chore: upgrade <code
class="notranslate">@eslint/*</code> dependencies (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19606">#19606</a>)
(Milos Djermanovic)</li>
<li>
<a
href="22ea18b8ba"><code
class="notranslate">22ea18b</code></a> chore: replace invalid <code
class="notranslate">int</code> type with <code
class="notranslate">number</code> inside JSDocs. (<a
href="https://bounce.depfu.com/github.com/eslint/eslint/pull/19597">#19597</a>)
(Arya Emami)</li>
</ul></blockquote>
<p><em>Does any of this look wrong? <a
href="feedback">Please let us
know.</a></em></p>
</details>

<details>
<summary>Commits</summary>
<p><a
href="d49f5b7333...3ed4b3652d">See
the full diff on Github</a>. The new version differs by 29 commits:</p>
<ul>
<li><a
href="3ed4b3652d"><code>9.25.1</code></a></li>
<li><a
href="7a19ccd052"><code>Build:
changelog update for 9.25.1</code></a></li>
<li><a
href="1f2b057ddc"><code>chore:
upgrade @eslint/js@9.25.1 (#19642)</code></a></li>
<li><a
href="771317fa93"><code>chore:
package.json update for @eslint/js release</code></a></li>
<li><a
href="cdc8e8c950"><code>fix:
revert directive detection in no-unused-expressions
(#19639)</code></a></li>
<li><a
href="e62e267615"><code>9.25.0</code></a></li>
<li><a
href="bc2c3e6acc"><code>Build:
changelog update for 9.25.0</code></a></li>
<li><a
href="88dc1965a4"><code>chore:
upgrade @eslint/js@9.25.0 (#19636)</code></a></li>
<li><a
href="345288d7b2"><code>chore:
package.json update for @eslint/js release</code></a></li>
<li><a
href="910bd13c4c"><code>fix:
`nodeTypeKey` not being used in `NodeEventGenerator`
(#19631)</code></a></li>
<li><a
href="ca7a735dde"><code>docs:
update `no-undef-init` when not to use section (#19624)</code></a></li>
<li><a
href="affe6be018"><code>chore:
upgrade trunk (#19628)</code></a></li>
<li><a
href="1b870c9da4"><code>docs:
use `eslint-config-xo` in the getting started guide
(#19629)</code></a></li>
<li><a
href="5d4af16ab1"><code>docs:
add types for multiple rule options (#19616)</code></a></li>
<li><a
href="e8f8d57bd6"><code>docs:
Update README</code></a></li>
<li><a
href="a40348f1f6"><code>docs:
no-use-before-define tweaks (#19622)</code></a></li>
<li><a
href="0ba3ae3e5a"><code>docs:
Update README</code></a></li>
<li><a
href="865dbfed6c"><code>docs:
ensure &quot;learn more&quot; deprecation links point to useful resource
(#19590)</code></a></li>
<li><a
href="dcd95aafa3"><code>feat:
support TypeScript syntax in no-empty-function rule
(#19551)</code></a></li>
<li><a
href="77d6d5bc49"><code>feat:
support TS syntax in `no-unused-expressions` (#19564)</code></a></li>
<li><a
href="90228e5d57"><code>feat:
support `JSRuleDefinition` type (#19604)</code></a></li>
<li><a
href="f80b746d85"><code>docs:
add known limitations for no-self-compare (#19612)</code></a></li>
<li><a
href="59ba6b7378"><code>feat:
add allowObjects option to no-restricted-properties
(#19607)</code></a></li>
<li><a
href="db650a036b"><code>feat:
support TypeScript syntax in `no-invalid-this` rule
(#19532)</code></a></li>
<li><a
href="dd20cf274e"><code>test:
fix `no-loop-func` test with duplicate variable reports
(#19610)</code></a></li>
<li><a
href="9535cffe7b"><code>feat:
support TS syntax in `no-loop-func` (#19559)</code></a></li>
<li><a
href="bd05397ef6"><code>chore:
upgrade `@eslint/*` dependencies (#19606)</code></a></li>
<li><a
href="22ea18b8ba"><code>chore:
replace invalid `int` type with `number` inside JSDocs.
(#19597)</code></a></li>
<li><a
href="865aed6293"><code>docs:
Update README</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>
2025-05-03 01:04:36 +02:00
Robin Malfait
c095071f22
Skip .css files when migrating templates (#17854)
This PR fixes an issue where the upgrade tool also migrates `.css` files
as-if they are content files. This is not the intended behavior.

## Test plan

Ran this on my personal website. 

Before:
<img width="1316" alt="image"
src="https://github.com/user-attachments/assets/2b7337c6-7b88-4811-911f-139ab2e31b3b"
/>

After: 
<img width="1046" alt="image"
src="https://github.com/user-attachments/assets/55f09355-37cb-419b-9924-973cf2681c1d"
/>
2025-05-03 00:48:45 +02:00
Robin Malfait
4e4275638f
Design system driven upgrade migrations (#17831)
This PR introduces a vastly improved upgrade migrations system, to
migrate your codebase and modernize your utilities to make use of the
latest variants and utilities.

It all started when I saw this PR the other day:
https://github.com/tailwindlabs/tailwindcss/pull/17790

I was about to comment "Don't forget to add a migration". But I've been
thinking about a system where we can automate this process away. This PR
introduces this system.

This PR introduces upgrade migrations based on the internal Design
System, and it mainly updates arbitrary variants, arbitrary properties
and arbitrary values.

## The problem

Whenever we ship new utilities, or you make changes to your CSS file by
introducing new `@theme` values, or adding new `@utility` rules. It
could be that the rest of your codebase isn't aware of that, but you
could be using these values.

For example, it could be that you have a lot of arbitrary properties in
your codebase, they look something like this:

```html
<div class="[color-scheme:dark] [text-wrap:balance]"></div>
```

Whenever we introduce new features in Tailwind CSS, you probably don't
keep an eye on the release notes and update all of these arbitrary
properties to the newly introduced utilities.

But with this PR, we can run the upgrade tool:

```console
npx -y @tailwindcss/upgrade@latest
```

...and it will upgrade your project to use the new utilities:

```html
<div class="scheme-dark text-balance"></div>
```

It also works for arbitrary values, for example imagine you have classes
like this:

```html
<!-- Arbitrary property -->
<div class="[max-height:1lh]"></div>

<!-- Arbitrary value -->
<div class="max-h-[1lh]"></div>
```

Running the upgrade tool again:

```console
npx -y @tailwindcss/upgrade@latest
```

... gives you the following output:

```html
<!-- Arbitrary property -->
<div class="max-h-lh"></div>

<!-- Arbitrary value -->
<div class="max-h-lh"></div>
```

This is because of the original PR I mentioned, which introduced the
`max-h-lh` utilities.

A nice benefit is that this output only has 1 unique class instead of 2,
which also potentially reduces the size of your CSS file.

It could also be that you are using arbitrary values where you (or a
team member) didn't even know an alternative solution existed.

E.g.:

```html
<div class="w-[48rem]"></div>
```

After running the upgrade tool you will get this:

```html
<div class="w-3xl"></div>
```

We can go further though. Since the release of Tailwind CSS v4, we
introduced the concept of "bare values". Essentially allowing you to
type a number on utilities where it makes sense, and we produce a value
based on that number.

So an input like this:

```html
<div class="border-[123px]"></div>
```

Will be optimized to just:

```html
<div class="border-123"></div>
```

This can be very useful for complex utilities, for example, how many
times have you written something like this:

```html
<div class="grid-cols-[repeat(16,minmax(0,1fr))]"></div>
```

Because up until Tailwind CSS v4, we only generated 12 columns by
default. But since v4, we can generate any number of columns
automatically.

Running the migration tool will give you this:

```html
<div class="grid-cols-16"></div>
```

### User CSS

But, what if I told you that we can keep going...

In [Catalyst](https://tailwindcss.com/plus/ui-kit) we often use classes
that look like this for accessibility reasons:

```html
<div class="text-[CanvasText] bg-[Highlight]"></div>
```

What if you want to move the `CanvasText` and `Highlight` colors to your
CSS:

```css
@import "tailwincdss";

@theme {
  --color-canvas: CanvasText;
  --color-highlight: Highlight;
}
```

If you now run the upgrade tool again, this will be the result:

```html
<div class="text-canvas bg-highlight"></div>
```

We never shipped a `text-canvas` or `bg-highlight` utility, but the
upgrade tool uses your own CSS configuration to migrate your codebase.

This will keep your codebase clean, consistent and modern and you are in
control.

Let's look at one more example, what if you have this in a lot of
places:

```html
<div class="[scrollbar-gutter:stable]"></div>
```

And you don't want to wait for the Tailwind CSS team to ship a
`scrollbar-stable` (or similar) feature. You can add your own utility:

```css
@import "tailwincdss";

@utility scrollbar-stable {
  scrollbar-gutter: stable;
}
```

```html
<div class="scrollbar-stable"></div>
```

## The solution — how it works

There are 2 big things happening here:

1. Instead of us (the Tailwind CSS team) hardcoding certain migrations,
we will make use of the internal `DesignSystem` which is the source of
truth for all this information. This is also what Tailwind CSS itself
uses to generate the CSS file.

   The internal `DesignSystem` is essentially a list of all:

   1. The internal utilities
   2. The internal variants
   3. The default theme we ship
   4. The user CSS
      1. With custom `@theme` values
      2. With custom `@custom-variant` implementations
      3. With custom `@utility` implementations
2. The upgrade tool now has a concept of `signatures`

The signatures part is the most interesting one, and it allows us to be
100% sure that we can migrate your codebase without breaking anything.

A signature is some unique identifier that represents a utility. But 2
utilities that do the exact same thing will have the same signature.

To make this work, we have to make sure that we normalize values. One
such value is the selector. I think a little visualization will help
here:

| UTILITY          | GENERATED SIGNATURE     |
| ---------------- | ----------------------- |
| `[display:flex]` | `.x { display: flex; }` |
| `flex`           | `.x { display: flex; }` |

They have the exact same signature and therefore the upgrade tool can
safely migrate them to the same utility.

For this we will prefer the following order:

1. Static utilities — essentially no brackets. E.g.: `flex`,
`grid-cols-2`
2. Arbitrary values — e.g.: `max-h-[1lh]`, `border-[2px]`
3. Arbitrary properties — e.g.: `[color-scheme:dark]`, `[display:flex]`

We also have to canonicalize utilities to there minimal form.
Essentially making sure we increase the chance of finding a match.

```
[display:_flex_] → [display:flex] → flex
[display:_flex]  → [display:flex] → flex
[display:flex_]  → [display:flex] → flex
[display:flex]   → [display:flex] → flex
```

If we don't do this, then the signatures will be slightly different, due
to the whitespace:

| UTILITY            | GENERATED SIGNATURE       |
| ------------------ | ------------------------- |
| `[display:_flex_]` | `.x { display:  flex ; }` |
| `[display:_flex]`  | `.x { display:  flex; }`  |
| `[display:flex_]`  | `.x { display: flex ; }`  |
| `[display:flex]`   | `.x { display: flex; }`   |

### Other small improvements

A few other improvements are for optimizing existing utilities:

1. Remove unnecessary data types. E.g.:

   - `bg-[color:red]` -> `bg-[red]`
- `shadow-[shadow:inset_0_1px_--theme(--color-white/15%)]` ->
`shadow-[inset_0_1px_--theme(--color-white/15%)]`

This also makes use of these signatures and if dropping the data type
results in the same signature then we can safely drop it.

Additionally, if a more specific utility exists, we will prefer that
one. This reduced ambiguity and the need for data types.

   - `bg-[position:123px]` → `bg-position-[123px]`
   - `bg-[123px]` → `bg-position-[123px]`
   - `bg-[size:123px]` → `bg-size-[123px]`


2. Optimizing modifiers. E.g.:
   - `bg-red-500/[25%]` → `bg-red-500/25`
   - `bg-red-500/[100%]` → `bg-red-500`
   - `bg-red-500/100` → `bg-red-500`

3. Hoist `not` in arbitrary variants

- `[@media_not_(prefers-color-scheme:dark)]:flex` →
`not-[@media_(prefers-color-scheme:dark)]:flex` → `not-dark:flex` (in
case you are using the default `dark` mode implementation

4. Optimize raw values that could be converted to bare values. This uses
the `--spacing` variable to ensure it is safe.

   - `w-[64rem]` → `w-256`

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
2025-05-02 23:18:06 +02:00
Philipp Spiess
45cd32eed7
Prepare v4.1.5 release (#17830)
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2025-04-30 16:57:44 +02:00
Philipp Spiess
a636933cd4
Add discrete properties to the default list of transition properties (#17812)
This PR changes the `transition` utility to include five new properties:

- `display`
- `visibility`
- `content-visibility`
- `overlay`
- `pointer-eventes`

On its own, this change does nothing since these properties will apply
their change _immediately_. However, in combination with
`transition-discrete` this will ensure that you can now transition these
types without requiering `transition-all` or arbitrary transition
properties.

## Test plan

- Ensured this works in the Vite playground with native `<dialog>`
components


https://github.com/user-attachments/assets/89bf4a75-b681-4574-8bb4-845fffdec43b

Notice how:

- the backdrop stays open until the transition is over (that's because
of `overlay` in the property list)
- the dialog is displayed until the transition is over

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2025-04-30 14:30:58 +02:00
depfu[bot]
ab4eb18bab
Update @types/react-dom 19.1.1 → 19.1.2 (patch) (#17829) 2025-04-30 11:50:44 +02:00
Robin Malfait
dbc8023a08
Do not sort and format stylesheets that didn't change (#17824)
This PR improves the upgrade tooling at tiny bit to make sure that as
long as we didn't change any of the stylesheets, that we also don't sort
internal nodes and/or format the stylesheet at all.

This is important in case the Prettier rules are different or if a
totally different formatter is used.

Essentially, if we didn't have to change the stylesheets because of a
migration, we don't want to change it due to a formatter either.
2025-04-29 17:07:35 +00:00