This PR will fix CI on the main branch where `webpack` could not be
found on macOS (but it worked on Linux).
Going to run [ci-all] to verify the changes.
This PR is a follow-up PR for:
https://github.com/tailwindlabs/tailwindcss/pull/17433
In the other PR we allow scanning CSS files for extracting usages of CSS
variables. This is important for `.module.css` files that reference
these variables but aren't in the same big AST of the main CSS file.
This PR also makes sure to watch for changes in those registered CSS
files and re-extract the variables when they change.
This PR took a bit longer than expected because I was trying to make
sure that writing to `./dist/out.css` works without infinite-looping
(e.g.: we had issues with this in Tailwind CSS v3 with webpack).
But I couldn't reproduce the issue at all. I did had some code that
tried to detect if the CSS file contained license headers and skip in
(because then it's very likely an output CSS file) but even without it
the tests were fine.
I setup integration tests with `@tailwindcss/cli` itself, and with tools
that use webpack. Added a test for Next.js, and a dedicated webpack test
as well.
Even without tests, locally, I couldn't reproduce an infinite loop due
to changes in an output CSS file...
Eventually dropped the code that tries to detect output CSS files.
One thing to keep in mind is that if you change any of your "main" CSS
files, then we will trigger a full rebuild anyway, so this change is
only required for unrelated CSS files (like CSS module files) that use
CSS variables.
## Test plan
1. Added integration tests for the CLI and Next.js
2. Added new dedicated test for webpack
This PR reworks a unit test that created a file in the project root and
then proceeded by scanning everything in the git root for candidates.
The issue specifically is that with the `.debug/` folder, our project
root can grow quite a bit which makes this test slower the more you work
on other tests...
To fix this we now simply create a tmp folder with only that one test
file. 🚀
Closes#17346
This PR fixes an issue that caused the `--theme(…)` function to behave
differently after a legacy JS plugin or config was configured. The issue
was that the compatibility layer would patch the theme value resolver to
always inline the value. This, however, is only expected to happen if
the path does not look like a CSS variable in which case this legacy
code path should not be run.
To fix this, I'm now keeping a reference to the regular theme resolution
function and call into it if the path starts with `--`.
## Test plan
- Tested with the repro in #17346 by adding pnpm overrides and confirmed
that this fixes the issue
- Added a unit test to the `--theme(…)` resolution tests
These match the new `mask-*` and updated `bg-*` utilities.
This is the same as #17378 but for `object-position`.
| Deprecated utility | New utility |
| --------------------- | --------------------- |
| `object-left-top` | `object-top-left` |
| `object-right-top` | `object-top-right` |
| `object-left-bottom` | `object-bottom-left` |
| `object-right-bottom` | `object-bottom-right` |
This PR adds support for utilities like:
- `text-shadow-lg/25`
It uses relative color syntax to replace the alpha value of the shadow
from your theme.
When combined with a colors:
- `text-shadow-lg/25 text-shadow-red-500`
- `text-shadow-lg/25 text-shadow-red-500/75`
The alpha values are **multiplied** resulting in a shadow with the color
specified in `--color-red-500` and alpha values of 25% and 18.75%
respectively.
This PR adds new `text-shadow-*` utilities and default values courtesy
of @danhollick's.
Usage is similar to the normal `shadow-*` utilities, for example:
```html
<h1 class="text-center text-7xl tracking-tight text-white text-shadow-xl">
Some fancy <br />
headline
</h1>
```
Since this PR also adds first-class support for the `--text-shadow`
theme namespace, it also means it resolves#17047.
## Test plan
- Copied @danhollick's [demo
playground](https://play.tailwindcss.com/lbA3Y6VY8u) to the `vite` setup
and ran a production build to ensure it looks correct:
https://tailwind-text-shadows-preview-2kdnjb32b.vercel.app/
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This PR fixes an issue where CSS variables could be used in CSS modules,
but where never emitted in your final CSS.
Some backstory, when Tailwind CSS v4 came out, we _always_ emitted all
CSS variables whether they were used or not.
Later, we added an optimization where we only emit the CSS variables
that were actually used. The definition of "used" in this case is:
1. Used in your CSS file(s) — (we check the final CSS AST for this)
2. Used _somewhere_ in any of your source files (e.g.: a JavaScript file
accessing a variable)
The issue this PR tries to solve is with the very first point. If you
are using CSS modules, then every CSS file is processed separately. This
is not a choice Tailwind CSS made, but how other build tooling works
(like Vite for example).
To prevent emitting all of Tailwind's Preflight reset and all utilities
per CSS file, you can use the `@reference` directive instead of
repeating `@import "tailwindcss";`. This is explained here:
https://tailwindcss.com/docs/compatibility#explicit-context-sharing
But now we are just _referencing_ them, not emitting them. And since the
CSS module is not connected in any way to the main `index.css` file that
contains the `@import "tailwindcss";` directive, we don't even see the
CSS variables while processing the `index.css` file. (or wherever your
main CSS file is)
This is where point 2 from above comes in. This is a situation where we
rely on the extractor to find the used CSS variables so we can
internally mark them as used.
To finally get to the point of this PR, the extractor only scans
`.html`, `.js`, ... files but not `.css` files. So all the CSS variables
used inside of CSS modules will not be generated.
This PR changes that behavior to also scan `.css` files. But _only_ for
CSS variables (not any other type of class candidate). This is
important, otherwise all your custom `@utility foo {}` definitions would
always mark `foo` as a used class and include it in the CSS which is not
always the case.
On top extracting CSS variables, we will also make sure that the CSS
variables we find are in usage positions (e.g.: `var(--color-red-500)`)
and not in definition positions (e.g.: `--color-red-500: #ff0000;`).
This is important because we only want to emit the variables that are
actually used in the final CSS output.
One future improvement not implemented here, is that technically we will
also extract CSS variables that might not be used if defined in a
`@utility`.
```css
@utility never-used {
color: var(--color-red-500); /* --color-red-500 will be emitted, even if it might not be used */
}
```
Fixes: #16904Fixes: #17429
# Test plan
1. Added a test where CSS variables are defined in `.css` files (and
ignored)
2. Added a test where CSS variables are used in `.css` files (and
included)
Testing on the reproduction defined in #16904, the `.module.css` file
contains a reference to `var(--color-hot-pink)`, but generating a build
shows that the variable definition is not available:
<img width="1630" alt="image"
src="https://github.com/user-attachments/assets/a0d5c37e-6813-4cd5-a677-6c356b5a73d4"
/>
When you run the build again with the changes from this PR, then we _do_
see the definition of the `--color-hot-pink` in the root CSS file:
<img width="2876" alt="image"
src="https://github.com/user-attachments/assets/beab7c11-a31b-4ea4-8235-4849a8e92859"
/>
This PR adds `bg-{position,size}-*` utilities that support arbitrary
values. This exist as the new preferred version of something like this:
```
bg-[120px_120px]
```
Is it size or position (hint: it's the 2nd one).
To override it you'd have to provide a data type:
```
bg-[size:120px_120px]
```
Now you can be more explicit and have better intellisense by writing
these:
```
bg-position-[120px_120px]
bg-size-[120px_120px]
```
Fixes#17357
This affects the CDN and Play
Now candidates like these no longer parse and emit CSS:
- `[--foo:1rem;--bar:2rem]`
- `[&{color:red}]:flex`
- `data-[a]{color:red}foo[a]:flex`
This replaces the `scripting`, `scripting-none`, and `scripting-initial`
variants with one `noscript` variant that matches the name of the HTML
`<noscript>` element. The previous `scripting` can then be represented
as `not-noscript` e.g. `not-noscript:flex`.
This PR fixes an extraction issue in Razor files where `@@md:bg-red-500`
can't always be extracted properly. We already convert `@@md:bg-red-500`
to ` @md:bg-red-500` but in certain situations Razor will emit the
double `@@` to the DOM.
A workaround in Razor land would be to write `@("@")md:bg-red-500`
instead. See: https://github.com/dotnet/aspnetcore/issues/38595 But then
we don't extract the `@md:bg-red-500` properly anymore.
This is where this PR comes in, essentially we will pre process the
Razor contents and apply the following replacement internally:
```diff
- @("@")md:bg-red-500
+ @md:bg-red-500
```
Notice that the `)` looks like it's replaced with `@`. This will have a
small side effect later when we get to the testing part.
But this way we properly see the `@md:bg-red-500` class during class
extraction.
> [!WARNING]
> There is technically a bug here because of the replacement with `@`,
because if you now run the `npx @tailwindcss/upgrade@latest` tool, then
we would replace `)md:bg-red-500` if changes are required, not the
`@("@")md:bg-red-500` part. We can try to fix that in this PR but it
seems unlikely that we will actually run into this issue realistically
speaking. I think fixing the actual extraction here is much more
important than the upgrade tooling that could fail _if_ we ever have to
migrate `@md:…` to something else.
Fixes: #17424
## Test plan
1. Added a test to verify the fix
2. Existing tests pass
3. Verified this in the extractor tool, but it looks a tiny bit funky.
Typically we remove characters by replacing it with a space ` `. But
this time, we replace it with some spaces _and_ an `@` character that
didn't exist at that specific position. If you look at the diff above,
you will notice that `)` was replaced with `@`.
That's why in the extractor tool it is highlighted that it could extract
it, but it's just funny looking because it highlights `)md:bg-red-500`
<img width="1816" alt="image"
src="https://github.com/user-attachments/assets/57e6a3ac-bfd5-4cad-a1ce-0039b4d7d9b5"
/>
We didn't add a changelog for the PR
(https://github.com/tailwindlabs/tailwindcss/pull/17255) and there are a
few things we need to talk about. So opened this PR to get everything in
and once we're happy we can merge it in one go instead of changing on
`main` directly.
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
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?
#### ✳️ @types/react (19.0.10 → 19.0.12) ·
[Repo](https://github.com/DefinitelyTyped/DefinitelyTyped)
Sorry, we couldn't find anything useful about this release.
---

[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>
We’re using this naming for `mask-*` and `mask-radial-at-*` position
utilities and we want to be consistent. The old ones for
`background-position` will stay but are deprecated
---------
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
Was working on another issue and noticed that I wanted these but they
aren't related to any of the issues. So opening a separate PR to do some
internal cleanup.
This PR fixes some issues related to symlinks when using them in the
`@source` directive.
Fixes: #16765Fixes: #16038
## Test plan
1. Added tests to prove this works
- Added a recursive symlink test as well to make sure we don't hang
2. Existing tests still pass
[ci-all]
Fixes#17379
The preprocessor we added to detect embedded languages uses a back
reference and given a long enough file with certain byte / character
patterns it'll cause what appears to be an indefinite hang (might just
be catastrophically exponential backtracking but not sure)
This replaces the one regex w/ back references with two, anchored,
multi-line regexes
Now we search for all the starting & ending delimiters in the file. We
then loop over all the starting delimiters, find the paired ending one,
and preprocess the content inside
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
This PR adds a new source detection feature: `@source not "…"`. It can
be used to exclude files specifically from your source configuration
without having to think about creating a rule that matches all but the
requested file:
```css
@import "tailwindcss";
@source not "../src/my-tailwind-js-plugin.js";
```
While working on this feature, we noticed that there are multiple places
with different heuristics we used to scan the file system. These are:
- Auto source detection (so the default configuration or an `@source
"./my-dir"`)
- Custom sources ( e.g. `@source "./**/*.bin"` — these contain file
extensions)
- The code to detect updates on the file system
Because of the different heuristics, we were able to construct failing
cases (e.g. when you create a new file into `my-dir` that would be
thrown out by auto-source detection, it'd would actually be scanned). We
were also leaving a lot of performance on the table as the file system
is traversed multiple times for certain problems.
To resolve these issues, we're now unifying all of these systems into
one `ignore` crate walker setup. We also implemented features like
auto-source-detection and the `not` flag as additional _gitignore_ rules
only, avoid the need for a lot of custom code needed to make decisions.
High level, this is what happens after the now:
- We collect all non-negative `@source` rules into a list of _roots_
(that is the source directory for this rule) and optional _globs_ (that
is the actual rules for files in this file). For custom sources (i.e
with a custom `glob`), we add an allowlist rule to the gitignore setup,
so that we can be sure these files are always included.
- For every negative `@source` rule, we create respective ignore rules.
- Furthermore we have a custom filter that ensures files are only read
if they have been changed since the last time they were read.
So, consider the following setup:
```css
/* packages/web/src/index.css */
@import "tailwindcss";
@source "../../lib/ui/**/*.bin";
@source not "../../lib/ui/expensive.bin";
```
This creates a git ignore file that (simplified) looks like this:
```gitignore
# Auto-source rules
*.{exe,node,bin,…}
*.{css,scss,sass,…}
{node_modules,git}/
# Custom sources can overwrite auto-source rules
!lib/ui/**/*.bin
# Negative rules
lib/ui/expensive.bin
```
We then use this information _on top of your existing `.gitignore`
setup_ to resolve files (i.e so if your `.gitignore` contains rules e.g.
`dist/` this line is going to be added _before_ any of the rules lined
out in the example above. This allows negative rules to allow-list your
`.gitignore` rules.
To implement this, we're rely on the `ignore` crate but we had to make
various changes, very specific, to it so we decided to fork the crate.
All changes are prefixed with a `// CHANGED:` block but here are the
most-important ones:
- We added a way to add custom ignore rules that _extend_ (rather than
overwrite) your existing `.gitignore` rules
- We updated the order in which files are resolved and made it so that
more-specific files can allow-list more generic ignore rules.
- We resolved various issues related to adding more than one base path
to the traversal and ensured it works consistent for Linux, macOS, and
Windows.
## Behavioral changes
1. Any custom glob defined via `@source` now wins over your `.gitignore`
file and the auto-content rules.
- Resolves#16920
3. The `node_modules` and `.git` folders as well as the `.gitignore`
file are now ignored by default (but can be overridden by an explicit
`@source` rule).
- Resolves#17318
- Resolves#15882
4. Source paths into ignored-by-default folders (like `node_modules`)
now also win over your `.gitignore` configuration and auto-content
rules.
- Resolves#16669
5. Introduced `@source not "…"` to negate any previous rules.
- Resolves#17058
6. Negative `content` rules in your legacy JavaScript configuration
(e.g. `content: ['!./src']`) now work with v4.
- Resolves#15943
7. The order of `@source` definitions matter now, because you can
technically include or negate previous rules. This is similar to your
`.gitingore` file.
9. Rebuilds in watch mode now take the `@source` configuration into
account
- Resolves#15684
## Combining with other features
Note that the `not` flag is also already compatible with [`@source
inline(…)`](https://github.com/tailwindlabs/tailwindcss/pull/17147)
added in an earlier commit:
```css
@import "tailwindcss";
@source not inline("container");
```
## Test plan
- We added a bunch of oxide unit tests to ensure that the right files
are scanned
- We updated the existing integration tests with new `@source not "…"`
specific examples and updated the existing tests to match the subtle
behavior changes
- We also added a new special tag `[ci-all]` that, when added to the
description of a PR, causes the PR to run unit and integration tests on
all operating systems.
[ci-all]
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Prepare the 4.0.16 release.
~~Also added a commit to mark the `--value('…')` and `--modifier('…')`
with literals strings as an experimental feature (aka not shipped in
this PR). But we can revert that commit if we still want to ship it in
4.0.16 instead of 4.1.~~
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
See #17360
This PR updates the `marker` variant to also target the marker present
in `<summary>` elements in WebKit browsers. Chromium uses `::marker` and
is therefore already covered.
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Fixes#17332
This PR ensures that keyframes are emitted even when they are referenced
following a comma, e.g.:
```css
@theme {
--animate-test: 500ms both fade-in, 1000ms linear 500ms spin infinite;
/* ^ */
@keyframes fade-in {
from {
opacity: 0%;
}
to {
opacity: 100%;
}
}
}
```
## Test plan
Added a unit test to capture the issue from #17332
Throw an error if the input and output file for the CLI are identical.
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This PR fixes an issue where embedded Slim templates inside of Ruby
files are not pre processed because we pre process based on a file
extension.
This PR also handles embedded SLIM templates using the following syntax:
```rb
slim_template <<~SLIM
.flex
.flex-1
h1 Hello World
.flex-1
p This is a test
SLIM
```
~~As far as I can tell, this is only a Slim template thing and not a
Haml template thing but I could be wrong here. See:
https://viewcomponent.org/guide/templates.html#interpolations~~
The ViewComponent package handles anything that looks like
`{lang}_template`, so the lang here will be used as the pre processing
language for now.
Fixes: #17334
# Test plan
1. Added test for this
2. Existing tests pass
3. Made sure that the snippet from the issue works as expected:
Added an example where we have a `slim_template` and a `svelte_template`
to prove that it embeds based on the language. I also added a
`html_template` with Svelte syntax to really make sure that that
_doesn't_ work.
<img width="1816" alt="image"
src="https://github.com/user-attachments/assets/35564a32-9c46-4b51-bb1f-e02f4ffe8b01"
/>
Closes#17339
This PR fixes an issue that caused changes to `@import`-ed CSS files to
no longer rebuild the stylesheet after a change was made to a template
file.
The change in the template file causes a fast-path in the Vite plugin
now after changes in 4.0.8: _partial rebuilds_. For that branch we do
not need to re-evaluate your input CSS since we know only the candidate
list changed. However, we still need to emit all build dependencies as
via `addWatchFile(…)`, otherwise Vite will not correctly register
updates for these dependencies anymore.
## Test plan
- Updated the kitchen-sink Vite update tests to ensure that an
`@import`-ed CSS file can be updated even after a partial rebuild.
- Ensure this works in our Vite playground
This PR fixes an issue where a class shorthand in Pug followed by a `(`
is not properly extracted.
```html
<template lang="pug">
.text-sky-600.bg-neutral-900(title="A tooltip") This div has an HTML attribute.
</template>
```
The `text-sky-600` is extracted, but the `bg-neutral-900` is not.
Fixes: #17313
# Test plan
1. Added test to cover this case
2. Existing tests pass (after a few small adjustments due to _more_
extracted candidates, but definitely not _less_)
3. Verified against the original issue (top is before, bottom is this
PR)
<img width="1307" alt="image"
src="https://github.com/user-attachments/assets/68a0529f-63ad-477d-a342-e3f91c5a1690"
/>
We had this exact same bug in Slim
(https://github.com/tailwindlabs/tailwindcss/pull/17278). Since Pug,
Slim and Haml are the only pre processors we have right now with this
dot-separated class notation I also double checked the Haml
pre-processor if this is an issue or not (and it's already covered
there).
<img width="1263" alt="image"
src="https://github.com/user-attachments/assets/c658168b-d124-46c9-9ec0-9697151a57bf"
/>
This PR adds support for literal values inside the `--value('…')` and
`--modifier('…')` functions. This allows you to safelist some known
values you want to use:
E.g.:
```css
@utility tab-* {
tab-size: --value('revert', 'initial');
}
```
This allows you to use `tab-revert` and `tab-initial` for example.
<!--
👋 Hey, thanks for your interest in contributing to Tailwind!
**Please ask first before starting work on any significant new
features.**
It's never a fun experience to have your pull request declined after
investing a lot of time and effort into a new feature. To avoid this
from happening, we request that contributors create an issue to first
discuss any significant new features. This includes things like adding
new utilities, creating new at-rules, or adding new component examples
to the documentation.
https://github.com/tailwindcss/tailwindcss/blob/master/.github/CONTRIBUTING.md
-->
Closes#17194.
This reverts commit d6d913ec39e2a4cc0a70e9d21c484c6ed95d40ae.
The initial fix does breaks older versions of Chrome (where text won't
render with a color for the placeholder at all anymore) and the usage of
the _relative colors_ features also means it'll require a much newer
version of Safari/Firefox/Chrome to work correctly. The implementation
was also wrong as it always set alpha to the specific percent instead of
applying it additively (note that this can be fixed with `calc(alpha *
opacity)` though).
Instead we decided to fix this by adding a `@supports` query to
Preflight that only targets browsers that aren't affected by the crash.
We currently use the following workaround:
```css
/*
Set the default placeholder color to a semi-transparent version of the current text color in browsers that do not
crash when using `color-mix(…)` with `currentColor`. (https://github.com/tailwindlabs/tailwindcss/issues/17194)
*/
@supports (not (-webkit-appearance: -apple-pay-button)) /* Not Safari */ or
(contain-intrinsic-size: 1px) /* Safari 17+ */ {
::placeholder {
color: color-mix(in oklab, currentColor 50%, transparent);
}
}
```
## Test plan
When testing the `color-mix(currentColor)` vs `oklab(from currentColor
…)` we created the following support matrix. I'm extending it with _our
fix_ which is the fix ended up using:
| Browser | Version | `color-mix(… currentColor …)` | `oklab(from
currentColor …)` | `@supports { color-mix(…) }` |
| ------- | ------- | ----------------------------- |
---------------------------- | ------- |
| Chrome | 111 | ❌ | ❌ | ❌ |
| Chrome | 116 | ✅ | ❌ | ✅ |
| Chrome | 131+ | ✅ | ✅ | ✅ |
| Safari | 16.4 | 💥 | ❌ | ❌ |
| Safari | 16.6+ | ✅ | ❌ | ❌ |
| Safari | 18+ | ✅ | ✅ | ✅ |
| Firefox | 128 | ✅ | ❌ | ✅ |
| Firefox | 133 | ✅ | ✅ | ✅ |
Note that on Safari 16, this change makes it so that the browser does
not crash yet it still won't work either. That's because now the browser
will fall back to the default placeholder color instead. We used the
following play to test the fix: https://play.tailwindcss.com/RF1RYbZLKY
Fixes#17288
This PR fixes an issue where changes in template files that _only mark a
new CSS variable as used_ was not causing the CSS file to rebuilds.
This also fixes a flaky integration test that was caused by a missing
`await` line on the final assertion (causing it to sometimes run the
assertion in time while the test runner was still running).
## Test plan
Turns out we already had an integration test for this but it wasn't
correctly running due to the missing await.
Closes#16945
This PR changes the `--theme(…)` function now return CSS `var(…)`
definitions unless used in places where `var(…)` is not valid CSS (e.g.
in `@media (width >= theme(--breakpoint-md))`):
```css
/* input */
@theme {
--color-red: red;
}
.red {
color: --theme(--color-red);
}
/* output */
:root, :host {
--color-red: red;
}
.red {
color: var(--color-red);
}
```
Furthermore, this adds an `--theme(… inline)` option to the `--theme(…)`
function to force the resolution to be inline, e.g.:
```css
/* input */
@theme {
--color-red: red;
}
.red {
color: --theme(--color-red inline);
}
/* output */
.red {
color: red;
}
```
This PR also changes preflight and the default theme to use this new
`--theme(…)` function to ensure variables are prefixed correctly.
## Test plan
- Added unit tests and a test that pulls in the whole preflight under a
prefix theme.
Closes#17259
This PR now also updates the MacOS x64 build to use `bun-baseline`,
meaning all x64 builds now use baseline for the improved hardware
compatibility.
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This PR fixes an issue where using the class shorthand in Slim
templates, followed by an `(` results in the last class being ignored.
E.g.:
```slim
body.border-t-4.p-8(class="#{body_classes}" data-hotwire-native="#{hotwire_native_app?}" data-controller="update-time-zone")
```
This is because we will eventually extract `p-8` but it's followed by an
invalid boundary character `(`.
To solve this, we make sure to replace the `(` with a space. We already
do a similar thing when the classes are followed by an `[`.
One caveat, we _can_ have `(` in our classes, like `bg-(--my-color)`.
But in my testing this is not something that can be used in the
shorthand version.
E.g.:
```slim
div.bg-(--my-color)
```
Compiles to:
```html
<div --my-color="" class="bg-"></div>
```
So I didn't add any special handling for this. Even when trying to
escape the `(`, `-` and `)` characters, it still doesn't work. E.g.:
```slim
div.bg-\(--my-color\)
```
Compiles to:
```html
<div class="bg-">\(--my-color\)</div>
```
# Test plan
1. Added test for the issue
2. Existing tests pass
3. Verified via the extractor tool:
| Before | After |
| --- | --- |
| <img width="958" alt="image"
src="https://github.com/user-attachments/assets/f72c420e-5429-424f-a01d-12f724062bf2"
/> | <img width="958" alt="image"
src="https://github.com/user-attachments/assets/b0cc8f2f-97a8-4fca-8813-3bb1da8d99a8"
/> |
---
Fixes: #17277
This PR fixes a bug in the handling of `@utility`. Essentially if you
had a declaration where you used a `--modifier(…)` _and_ a `--value(…)`
and both caused the declaration to be removed, the declaration after the
current one would be removed as well.
This happened because 2 reasons:
1. Once we removed the declaration when we handled `--modifier(…)`, we
didn't stop the walk and kept going.
2. The `replaceWith(…)` code allows you to call the function multiple
times but immediately mutates the AST. This means that if you call it
multiple times that you are potentially removing / updating nodes
followed by the current one.
E.g.:
```css
@utility mask-r-* {
--mask-right: linear-gradient(to left, transparent, black --value(percentage));
--mask-right: linear-gradient(
to left,
transparent calc(var(--spacing) * --modifier(integer)),
black calc(var(--spacing) * --value(integer))
);
mask-image: var(--mask-linear), var(--mask-radial), var(--mask-conic);
}
```
If this is used as `mask-r-10%`, then the first definition of
`--mask-right` is kept, but the second definition of `--mask-right` is
deleted because both `--modifier(integer)` and `--value(integer)` do not
result in a valid value.
However, the `mask-image` declaration was also removed because the
`replaceWith(…)` function was called twice. Once for
`--modifier(integer)` and once for `--value(integer)`.
# Test plan
1. Added a test to cover this case.
2. Existing tests pass.
3. Added a hard error if we call `replaceWith(…)` multiple times.