mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
6259 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
498f9ff003
|
Migrate bare values to named values (#18000)
This PR improves the upgrade tool by also migrating bare values to named values defined in the `@theme`. Recently we shipped some updates dat allowed us to migrate arbitrary values (with square brackets), but we didn't migrate bare values yet. That means that in this example: ```html <div class="aspect-[16/9]"></div> <div class="aspect-16/9"></div> ``` We migrated this to: ```html <div class="aspect-video"></div> <div class="aspect-16/9"></div> ``` With this change, we will also try and migrate the bare value to a named value. So this example: ```html <div class="aspect-[16/9]"></div> <div class="aspect-16/9"></div> ``` Now becomes: ```html <div class="aspect-video"></div> <div class="aspect-video"></div> ``` ## Test plan 1. Added unit tests for the new functionality. 2. Ran this on a local project Before: <img width="432" alt="image" src="https://github.com/user-attachments/assets/ce1adfbd-7be1-4062-bea5-66368f748e44" /> After: <img width="382" alt="image" src="https://github.com/user-attachments/assets/a385c94c-4e4c-4e1c-ac73-680c56ac4081" /> |
||
|
|
ef2e6c71fe
|
Upgrade: Migrate outline class (#17996)
This PR adds a migration from `outline` to `outline-solid` for the v3 -> v4 upgrade tool. ## Test plan - Added integration test |
||
|
|
4fba87bc90
|
Upgrade lightningcss to 1.30.0 (#17979)
|
||
|
|
ba944ca3b1
|
Upgrade bun to 1.2.13 (#17981)
|
||
|
|
5688f0a7ae
|
Add ignore pattern for node_modules in globby search in upgrade cli (#17969)
When passing `gitignore: true` to globby it will start a search for all .gitignore files, this initial search includes node_modules making it hang forever for large monorepos with many files inside node_modules |
||
|
|
19e2b29c68
|
Update @types/react-dom 19.1.2 → 19.1.3 (patch) (#17976) | ||
|
|
0d975f5f06
|
Update dedent 1.5.3 → 1.6.0 (minor) (#17965)
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? #### ✳️ dedent (1.5.3 → 1.6.0) · [Repo](https://github.com/dmnd/dedent) · [Changelog](https://github.com/dmnd/dedent/blob/main/CHANGELOG.md) <details> <summary>Release Notes</summary> <h4><a href="https://github.com/dmnd/dedent/releases/tag/v1.6.0">1.6.0</a></h4> <blockquote><h2 dir="auto">What's Changed</h2> <ul dir="auto"> <li>feat: add <code class="notranslate">trimWhitespace</code> option by <a href="https://bounce.depfu.com/github.com/43081j">@43081j</a> in <a href="https://bounce.depfu.com/github.com/dmnd/dedent/pull/97">#97</a> </li> </ul> <h2 dir="auto">New Contributors</h2> <ul dir="auto"> <li> <a href="https://bounce.depfu.com/github.com/43081j">@43081j</a> made their first contribution in <a href="https://bounce.depfu.com/github.com/dmnd/dedent/pull/97">#97</a> </li> </ul> <p dir="auto"><strong>Full Changelog</strong>: <a href="https://bounce.depfu.com/github.com/dmnd/dedent/compare/v1.5.3...v1.6.0"><tt>v1.5.3...v1.6.0</tt></a></p></blockquote> <p><em>Does any of this look wrong? <a href="https://depfu.com/packages/npm/dedent/feedback">Please let us know.</a></em></p> </details> <details> <summary>Commits</summary> <p><a href=" |
||
|
|
f0986ce127
|
Prevent duplicate suggestions when using @theme and @utility together (#17675)
Fixes https://github.com/tailwindlabs/tailwindcss-intellisense/issues/1313 Right now given this CSS: ```css @theme reference { --text-header: 1.5rem; } @utility text-header { text-transform: uppercase; } ``` You'll see two entries for `text-header` in IntelliSense completions but we only want you to see one. This PR solves this by merging their modifier lists and de-duping by class name. |
||
|
|
3386049b7b
|
Fix upgrade error when using @import … source(…) (#17963)
This PR fixes an issue when running the upgrade tool and if any of the
CSS files has an import that looks like this:
```css
@import "tailwindcss" source("…");
```
This was trying to resolve `tailwindcss" source("…` instead of
`tailwindcss`.
This PR fixes that.
## Test plan
1. Ran it locally on a project
Before:
<img width="1158" alt="image"
src="https://github.com/user-attachments/assets/09bf5d69-797c-4330-ade1-edc213f7ce5c"
/>
After:
<img width="1029" alt="image"
src="https://github.com/user-attachments/assets/d1c9e194-30e2-4564-83c5-d9a259a67e90"
/>
|
||
|
|
737994b7aa
|
Allow _ before numbers during candidate extraction (#17961)
This PR fixes a bug where a class like `header_1` wasn't properly extracted because we didn't allow an `_` before a number. This PR fixes that by allowing an `_` before a number. Fixes: #17960 ## Test plan 1. Added a test to verify this works 2. Existing tests work Used the visualizer tool for this to verify that the `header_1` class is being extracted: <img width="1816" alt="image" src="https://github.com/user-attachments/assets/fdc21602-0e2b-4e4e-92a1-19c4f4f5393f" /> |
||
|
|
2d139984da
|
Prepare v4.1.6 release (#17951)
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>v4.1.6 |
||
|
|
47bb007eae
|
Download platform specific package if optionalDependencies are skipped (#17929)
Closes #15806 This PR adds a new `postinstall` script to `@tailwindcss/oxide` that will attempt to download the platform-specific optional dependency to avoid issues when the package manager does not do that automatically (see #15806). The implementation for this is fairly simple: The npm package is downloaded from the official npm servers and extracted into the `node_modules` directory of the `@tailwidncss/oxide` installation. ## Test plan Since we still lack a solid repro of #15806, the way I tested this change was to manually remove all automatically-installed optional dependencies and then running the postinstall script manually. The script then downloads the right version package which makes the import to `@tailwidncss/oxide` work. An appropriate integration test was added too. I furthermore also validated that: - This works across CI platforms [ci-all] - The postinstall script bails out when running `pnpm install` in the dev setup. This is necessary since doing the initial install won't have any binary dependencies yet so it would download invalid versions from npm (as the version numbers locally refer to the last released version). We can safely bail out here though since this was never an issue with local development. - The postinstall script does not do anything when the `@tailwindcss/oxide` library is added _unless_ the issue is detected. [ci-all] --------- Co-authored-by: Robin Malfait <malfait.robin@gmail.com> |
||
|
|
2f6679abfe
|
Print sources when DEBUG=* is set (#17952)
This PR improves the debug logging by also adding the provided `@source`
to the log file. It will also print the optimized sources (the ones we
expand and mark as `Auto` or `Pattern`).
In the logs, this will look like this:
```
2025-05-09T11:03:32.906478Z INFO tailwindcss_oxide::scanner: Provided sources:
2025-05-09T11:03:32.906544Z INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/Users/robin/github.com/RobinMalfait/spreadsheet", pattern: "**/*", negated: false }
2025-05-09T11:03:32.906589Z INFO tailwindcss_oxide::scanner: Optimized sources:
2025-05-09T11:03:32.906595Z INFO tailwindcss_oxide::scanner: Source: Auto { base: "/Users/robin/github.com/RobinMalfait/spreadsheet" }
```
Or if you have more sources:
```
2025-05-09T11:06:54.767546Z INFO tailwindcss_oxide::scanner: Provided sources:
2025-05-09T11:06:54.767660Z INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/Users/robin/github.com/RobinMalfait/spreadsheet", pattern: "**/*", negated: false }
2025-05-09T11:06:54.767987Z INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/Users/robin/github.com/RobinMalfait/spreadsheet/app", pattern: "./routes/*.{jsx,tsx}", negated: false }
2025-05-09T11:06:54.767992Z INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/Users/robin/github.com/RobinMalfait/spreadsheet/app", pattern: "./utils/*.ts", negated: false }
2025-05-09T11:06:54.768450Z INFO tailwindcss_oxide::scanner: Optimized sources:
2025-05-09T11:06:54.768455Z INFO tailwindcss_oxide::scanner: Source: Auto { base: "/Users/robin/github.com/RobinMalfait/spreadsheet" }
2025-05-09T11:06:54.768459Z INFO tailwindcss_oxide::scanner: Source: Pattern { base: "/Users/robin/github.com/RobinMalfait/spreadsheet/app/routes", pattern: "*.jsx" }
2025-05-09T11:06:54.768462Z INFO tailwindcss_oxide::scanner: Source: Pattern { base: "/Users/robin/github.com/RobinMalfait/spreadsheet/app/routes", pattern: "*.tsx" }
2025-05-09T11:06:54.768466Z INFO tailwindcss_oxide::scanner: Source: Pattern { base: "/Users/robin/github.com/RobinMalfait/spreadsheet/app/utils", pattern: "*.ts" }
```
|
||
|
|
ae57d26852
|
Update contribution docs (#17911)
This PR updates the contribution docs to make it easier for anyone contributing to Tailwind CSS. |
||
|
|
ff9f183368
|
Fix source map paths in CI (#17938) | ||
|
|
56b22bb1d3
|
Add support for source maps (#17775)
Closes #13694 Closes #13591 # Source Maps Support for Tailwind CSS This PR adds support for source maps to Tailwind CSS v4 allowing us to track where styles come from whether that be user CSS, imported stylesheets, or generated utilities. This will improve debuggability in browser dev tools and gives us a good foundation for producing better error messages. I'll go over the details on how end users can enable source maps, any limitations in our implementation, changes to the internal `compile(…)` API, and some details and reasoning around the implementation we chose. ## Usage ### CLI Source maps can be enabled in the CLI by using the command line argument `--map` which will generate an inline source map comment at the bottom of your CSS. A separate file may be generated by passing a file name to `--map`: ```bash # Generates an inline source map npx tailwindcss -i input.css -o output.css --map # Generates a separate source map file npx tailwindcss -i input.css -o output.css --map output.css.map ``` ### PostCSS Source maps are supported when using Tailwind as a PostCSS plugin *in development mode only*. They may or may not be enabled by default depending on your build tool. If they are not you may be able to configure them within your PostCSS config: ```jsonc // package.json { // … "postcss": { "map": { "inline": true }, "plugins": { "@tailwindcss/postcss": {}, }, } } ``` ### Vite Source maps are supported when using the Tailwind CSS Vite plugin in *development mode only* by enabling the `css.devSourcemap` setting: ```js import tailwindcss from "@tailwindcss/vite"; import { defineConfig } from "vite"; export default defineConfig({ plugins: [tailwindcss()], css: { devSourcemap: true, }, }) ``` Now when a CSS file is requested by the browser it'll have an inline source map comment that the browser can use. ## Limitations - Production build source maps are currently disabled due to a bug in Lightning CSS. See https://github.com/parcel-bundler/lightningcss/pull/971 for more details. - In Vite, minified CSS build source maps are not supported at all. See https://github.com/vitejs/vite/issues/2830 for more details. - In PostCSS, minified CSS source maps are not supported. This is due to the complexity required around re-associating every AST node with a location in the generated, optimized CSS. This complexity would also have a non-trivial performance impact. ## Testing Here's how to test the source map functionality in different environments: ### Testing the CLI 1. Setup typical project that the CLI can use and with sources to scan. ```css @import "tailwindcss"; @utilty my-custom-utility { color: red; } /* to test `@apply` */ .card { @apply bg-white text-center shadow-md; } ``` 2. Build with source maps: ```bash bun /path/to/tailwindcss/packages/@tailwindcss-cli/src/index.ts --input input.css -o output.css --map ``` 3. Open Chrome DevTools, inspect an element with utility classes, and you should see rules pointing to `input.css` or `node_modules/tailwindcss/index.css` ### Testing with Vite Testing in Vite will require building and installing necessary files under `dist/*.tgz`. 1. Create a Vite project and enable source maps in `vite.config.js`: ```js import tailwindcss from "@tailwindcss/vite"; import { defineConfig } from "vite"; export default defineConfig({ plugins: [tailwindcss()], css: { // This line is required for them to work devSourcemap: true, }, }) ``` 2. Add a component that uses Tailwind classes and custom CSS: ```jsx // ./src/app.jsx export default function App() { return ( <div className="bg-blue-500 my-custom-class"> Hello World </div> ) } ``` ```css /* ./src/styles.css */ @import "tailwindcss"; @utilty my-custom-utility { color: red; } /* to test `@apply` */ .card { @apply bg-white text-center shadow-md; } ``` 3. Run `npm run dev`, open DevTools, and inspect elements to verify source mapping works for both utility classes and custom CSS. ### Testing with PostCSS CLI 1. Create a test file and update your PostCSS config: ```css /* input.css */ @import "tailwindcss"; @layer components { .card { @apply p-6 rounded-lg shadow-lg; } } ``` ```jsonc // package.json { // … "postcss": { "map": { "inline": true }, "plugins": { "/path/to/tailwindcss/packages/packages/@tailwindcss-postcss/src/index.ts": {} } } } ``` 2. Run PostCSS through Bun: ```bash bunx --bun postcss ./src/index.css -o out.css ``` 3. Inspect the output CSS - it should include an inline source map comment at the bottom. ### Testing with PostCSS + Next.js Testing in Next.js will require building and installing necessary files under `dist/*.tgz`. However, I've not been able to get CSS source maps to work in Next.js without this hack: ```js const nextConfig: NextConfig = { // next.js overwrites config.devtool so we prevent it from doing so // please don't actually do this… webpack: (config) => Object.defineProperty(config, "devtool", { get: () => "inline-source-map", set: () => {}, }), }; ``` This is definitely not supported and also doesn't work with turbopack. This can be used to test them temporarily but I suspect that they just don't work there. ### Manual source map analysis You can analyze source maps using Evan Wallace's [Source Map Visualization](https://evanw.github.io/source-map-visualization/) tool which will help to verify the accuracy and quality of source maps. This is what I used extensively while developing this implementation. It'll help verify that custom, user CSS maps back to itself in the input, that generated utilities all map back to `@tailwind utilities;`, that source locations from imported files are also handled correctly, etc… It also highlights the ranges of stuff so it's easy to see if there are off-by-one errors. It's easiest to use inline source maps with this tool because you can take the CSS file and drop it on the page and it'll analyze it while showing the file content. If you're using Vite you'll want to access the CSS file with `?direct` at the end so you don't get a JS module back. ## Implementation The source map implementation follows the ECMA-426 specification and includes several key components to aid in that goal: ### Source Location Tracking Each emittable AST node in the compilation pipeline tracks two types of source locations: - `src`: Original source location - [source file, start offset, end offset] - `dst`: Generated source location - [output file, start offset, end offset] This dual tracking allows us to maintain mappings between the original source and generated output for things like user CSS, generated utilities, uses of `@apply`, and tracking theme variables. It is important to note that source locations for nodes _never overlap_ within a file which helps simplify source map generation. As such each type of node tracks a specific piece of itself rather than its entire "block": | Node | What a `SourceLocation` represents | | ----------- | ---------------------------------------------------------------- | | Style Rule | The selector | | At Rule | Rule name and params, includes the `@` | | Declaration | Property name and value, excludes the semicolon | | Comment | The entire comment, includes the start `/*` and end `*/` markers | ### Windows line endings when parsing CSS Because our AST tracks nodes through offsets we must ensure that any mutations to the file do *not* change the lenth of the string. We were previously replacing `\r\n` with `\n` (see [filter code points](https://drafts.csswg.org/css-syntax/#css-filter-code-points) from the spec) — which changes the length of the string and all offsets may end up incorrect. The CSS parser was updated to handle the CRLF token directly by skipping over the `\r` and letting remaining code handle `\n` as it did previously. Some additional tweaks were required when "peeking" the input but those changes were fairly small. ### Tracking of imports Source maps need paths to the actual imported stylesheets but the resolve step for stylesheets happens inside the call to `loadStylesheet` which make the file path unavailable to us. Because of this the `loadStylesheet` API was augmented such that it has to return a `path` property that we can then use to identify imported sources. I've also made the same change to the `loadModule` API for consistency but nothing currently uses this property. The `path` property likely makes `base` redundant but elminating that (if we even want to) is a future task. ### Optimizing the AST Our optimization pass may intoduce some nodes, for example, fallbacks we create for `@property`. These nodes are linked back to `@tailwind utilities` as ultimately that is what is responsible for creating them. ### Line Offset Tables A key component to our source map generation is the line offset table, which was inspired by some ESBuild internals. It stores a sorted list of offsets for the start of each line allowing us to translate offsets to line/column `Position`s in `O(log N)` time and from `Position`s to offsets in `O(1)` time. Creation of the table takes `O(N)` time. This means that we can store code point offsets for source locations and not have to worry about computing or tracking line/column numbers during parsing and serialization. Only when a source map is generated do these offsets need to be computed. This ensures the performance penalty when not using source maps is minimal. ### Source Map Generation The source map returned by `buildSourceMap()` is designed to follow the [ECMA-426 spec](https://tc39.es/ecma426). Because that spec is not completely finalized we consider the result of `buildSourceMap()` to be internal API that may change as the spec chamges. The produces source map is a "decoded" map such that all sources and mappings are in an object graph. A library like `source-map-js` must be used to convert this to an encoded source map of the right version where mappings are encoded with base 64 VLQs. Any specific integration (Vite, PostCSS, etc…) can then use `toSourceMap()` from `@tailwindcss/node` to convert from the internal source map to an spec-compliant encoded source map that can be understood by other tools. ### Handling minification in Lightning Since we use Lightning CSS for optimization, and it takes in an input map, we generate an encoded source map that we then pass to lightning. The output source map *from lighting itself* is then passed back in during the second optimization pass. The final map is then passed from lightning to the CLI (but not Vite or PostCSS — see the limitations section for details). In some cases we have to "fix up" the output CSS. When this happens we use `magic-string` to do the replacement in a way that is trackable and `@amppproject/remapping` to map that change back onto the original source map. Once the need for these fix ups disappear these dependencies can go away. Notes: - The accuracy of source maps run though lightning is reduced as it only tracks on a per-rule level. This is sufficient enough for browser dev tools so should be fine. - Source maps during optimization do not function properly at this time because of a bug in Lightning CSS regarding license comments. Once this bug is fixed they will start working as expected. ### How source locations flow through the system 1. During initial CSS parsing, source locations are preserved. 2. During parsing these source locations are also mapped to the destinations which supports an optimization for when no utilities are generated. 3. Throughout the compilation process, transformations maintain source location data 4. Generated utilities are explicitly pointed to `@tailwind utilities` unless generated by `@apply`. 5. When optimization is enabled, source maps are remapped through lightningcss 6. Final source maps are written in the requested format (inline or separate file) |
||
|
|
62706dccb0
|
Trigger updates to the internal upgrades repo (#17928)
This PR updates will now trigger the new internal `upgrades` repo instead of the Tailwind Play repo directly. We will be updating more internal repos when a new version is published. We will also use that new repo to update our other repos for other published packages in the future. |
||
|
|
17ca56d386
|
Fix bug with nested @apply rules in utility classes (#17924) (#17925)
Fixes #17924 When an `@apply` pointed to utility that nested usages of `@apply`, these nested usages were not properly carried through the dependency chain. This was because we were only tracking dependencies on the immediate parent rather than all parents. To fix this, this PR: - Modifies the dependency resolution to track dependencies through the entire parent path - Uses a `walk(…)` for the node replacement logic so that all nested `@apply` usages are also resolved (as these are now tracked in the dependency list anyways ## Test Plan - Added a regression test for #17924 to the unit tests and ensure existing tests don't break |
||
|
|
179e5ddd7c
|
Add more folders to the list of ignored content dirs (#17892)
Closes #15452 This PR adds more directories to the list of ignored content dirs. These are now handled the same as `node_modules`: - Contents of this directory are ignored by default to avoid scanning dependency trees - Explicit `@import`s inside these folders are now treated as _external_, bypassing any `.gitignore` files. The new extensions are: - Version control systems: `.hg`, `.svn` - Bundler caches: `.venv`, `venv`, `.yarn` - Framework caches: `.next`, `.turbo`, `.parcel-cache`, `__pycache__`, `.svelte-kit` ## Test plan Verified with the repro of #15452 by renaming the ignored directory to `.venv` and installing a local tarball: <img width="1283" alt="Screenshot 2025-05-06 at 13 14 55" src="https://github.com/user-attachments/assets/3265acbb-e121-47b3-ac6c-e174770f8234" /> |
||
|
|
d8c4df8001
|
Write to log file when using DEBUG=* (#17906)
This PR improves the debugability of the scanner when using `DEBUG=*` by
writing to a `tailwindcss-{pid}.log` file in the current working
directory.
It will include all the tracing information from the scanner. This PR
also introduces `Discovering {path}` and `Reading {path}` logs.
- `Discovering {path}` — this is logged when we are traversing the file
system looking for files. We use the `ignore` crate, and log this
information in the `filter_entry` callback. If a file was already
ignored by `.gitignore` files, this won't show up, but it also means
that we will not read it.
- `Reading {path}` — this is when we are actually reading the file so we
can start extracting potential Tailwind CSS classes.
These will give you some insights in what paths are being scanned, and
if we get stuck, where we get stuck.
Also, we are appending to the file. In the log below, you can already
see that a `tailwindcss-<number>.log` file exists already even though it
didn't exist before running the command. This should make it easier to
debug if we get stuck on a specific file/folder because the file will be
populated with information.
There are a few reasons for appending to a file:
1. There is a lot of output, so spamming the stdout/stderr is not ideal
2. If you run the same command again, after changing your `@source`
directives, you could diff the outputs. (although, the timestamps will
be different)
3. When using `DEBUG=*`, a lot of other tools also output debug
information, so writing to a file should make this better.
<details>
<summary>Example log</summary>
```log
2025-05-06T23:13:45.912292Z INFO scan_sources: tailwindcss_oxide::scanner: enter
2025-05-06T23:13:45.912697Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/out.css"
2025-05-06T23:13:45.912716Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/tailwindcss-61347.log"
2025-05-06T23:13:45.912748Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app"
2025-05-06T23:13:45.912786Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/test"
2025-05-06T23:13:45.912814Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/test/utils.ts"
2025-05-06T23:13:45.912851Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/utils"
2025-05-06T23:13:45.912873Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/utils/flatten.ts"
2025-05-06T23:13:45.912884Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/utils/matrix.ts"
2025-05-06T23:13:45.912893Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/utils/default-map.ts"
2025-05-06T23:13:45.912904Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/tailwind.css"
2025-05-06T23:13:45.912914Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/root.tsx"
2025-05-06T23:13:45.912936Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain"
2025-05-06T23:13:45.912962Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/expression.ts"
2025-05-06T23:13:45.912972Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/walk-ast.ts"
2025-05-06T23:13:45.912995Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature"
2025-05-06T23:13:45.913019Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/parser.test.ts"
2025-05-06T23:13:45.913029Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/validate.test.ts"
2025-05-06T23:13:45.913039Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/tokenizer.ts"
2025-05-06T23:13:45.913048Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/validate.ts"
2025-05-06T23:13:45.913058Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/parser.ts"
2025-05-06T23:13:45.913067Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/tokenizer.test.ts"
2025-05-06T23:13:45.913077Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/ast.ts"
2025-05-06T23:13:45.913086Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/version-control.ts"
2025-05-06T23:13:45.913095Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/tokenizer.ts"
2025-05-06T23:13:45.913105Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/type-checker.test.ts"
2025-05-06T23:13:45.913121Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/evaluation-result.ts"
2025-05-06T23:13:45.913505Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/tmp.test.ts"
2025-05-06T23:13:45.913514Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/version-control.test.ts"
2025-05-06T23:13:45.913523Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/tokenizer.test.ts"
2025-05-06T23:13:45.913531Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/evaluation.ts"
2025-05-06T23:13:45.913554Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions"
2025-05-06T23:13:45.913583Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/sequence.test.ts"
2025-05-06T23:13:45.913592Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/date.ts"
2025-05-06T23:13:45.913601Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/lookup.test.ts"
2025-05-06T23:13:45.913613Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/statistics.ts"
2025-05-06T23:13:45.913622Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/intrinsics.test.ts"
2025-05-06T23:13:45.913631Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/math.ts"
2025-05-06T23:13:45.913640Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/engineering.ts"
2025-05-06T23:13:45.913648Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/types.test.ts"
2025-05-06T23:13:45.913656Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/text.ts"
2025-05-06T23:13:45.913665Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/text.test.ts"
2025-05-06T23:13:45.913673Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/intrinsics.ts"
2025-05-06T23:13:45.913681Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/logic.ts"
2025-05-06T23:13:45.913689Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/date.test.ts"
2025-05-06T23:13:45.913697Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/types.ts"
2025-05-06T23:13:45.913705Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/logic.test.ts"
2025-05-06T23:13:45.913713Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/lookup.ts"
2025-05-06T23:13:45.913720Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/sequence.ts"
2025-05-06T23:13:45.913728Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/engineering.test.ts"
2025-05-06T23:13:45.913741Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/index.ts"
2025-05-06T23:13:45.913749Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/math.test.ts"
2025-05-06T23:13:45.913757Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/statistics.test.ts"
2025-05-06T23:13:45.913783Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/__snapshots__"
2025-05-06T23:13:45.913817Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/spreadsheet.test.ts"
2025-05-06T23:13:45.913826Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/type-checker.ts"
2025-05-06T23:13:45.913833Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/function-utils.ts"
2025-05-06T23:13:45.913841Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/spreadsheet.ts"
2025-05-06T23:13:45.913849Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/expression.test.ts"
2025-05-06T23:13:45.913857Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/evaluation.test.ts"
2025-05-06T23:13:45.913879Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/routes"
2025-05-06T23:13:45.913896Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/app/routes/_index.tsx"
2025-05-06T23:13:45.914172Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/README.md"
2025-05-06T23:13:45.914197Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/public"
2025-05-06T23:13:45.914228Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/public/fonts"
2025-05-06T23:13:45.914268Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/package.json"
2025-05-06T23:13:45.914289Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/scripts"
2025-05-06T23:13:45.914310Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/scripts/generate-documentation.ts"
2025-05-06T23:13:45.914332Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/.github"
2025-05-06T23:13:45.914383Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/.github/workflows"
2025-05-06T23:13:45.914410Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/.github/workflows/ci.yml"
2025-05-06T23:13:45.914420Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/tsconfig.json"
2025-05-06T23:13:45.914455Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/vite.config.ts"
2025-05-06T23:13:45.914486Z INFO scan_sources: tailwindcss_oxide::scanner: Discovering "/Users/robin/github.com/RobinMalfait/spreadsheet/biome.json"
2025-05-06T23:13:45.914512Z INFO scan_sources: tailwindcss_oxide::scanner: exit
2025-05-06T23:13:45.914515Z INFO extract_candidates: tailwindcss_oxide::scanner: enter
2025-05-06T23:13:45.914518Z INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: enter
2025-05-06T23:13:45.914524Z INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: Reading 58 file(s)
2025-05-06T23:13:45.914808Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/tailwindcss-61347.log"
2025-05-06T23:13:45.914990Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/routes/_index.tsx"
2025-05-06T23:13:45.915138Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/.github/workflows/ci.yml"
2025-05-06T23:13:45.915140Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/statistics.test.ts"
2025-05-06T23:13:45.915145Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/tokenizer.ts"
2025-05-06T23:13:45.915163Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/tsconfig.json"
2025-05-06T23:13:45.915153Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/engineering.ts"
2025-05-06T23:13:45.915226Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/utils/matrix.ts"
2025-05-06T23:13:45.915229Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/walk-ast.ts"
2025-05-06T23:13:45.915372Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/test/utils.ts"
2025-05-06T23:13:45.915578Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/ast.ts"
2025-05-06T23:13:45.915599Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/validate.ts"
2025-05-06T23:13:45.915637Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/version-control.ts"
2025-05-06T23:13:45.915647Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/parser.ts"
2025-05-06T23:13:45.915657Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/vite.config.ts"
2025-05-06T23:13:45.915680Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/types.test.ts"
2025-05-06T23:13:45.915681Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/utils/flatten.ts"
2025-05-06T23:13:45.915701Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/parser.test.ts"
2025-05-06T23:13:45.915706Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/README.md"
2025-05-06T23:13:45.915691Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/utils/default-map.ts"
2025-05-06T23:13:45.915701Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/spreadsheet.test.ts"
2025-05-06T23:13:45.915730Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/package.json"
2025-05-06T23:13:45.915753Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/tokenizer.ts"
2025-05-06T23:13:45.915731Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/biome.json"
2025-05-06T23:13:45.915787Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/validate.test.ts"
2025-05-06T23:13:45.915822Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/signature/tokenizer.test.ts"
2025-05-06T23:13:45.915826Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/text.ts"
2025-05-06T23:13:45.915885Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/root.tsx"
2025-05-06T23:13:45.915885Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/types.ts"
2025-05-06T23:13:45.915886Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/type-checker.ts"
2025-05-06T23:13:45.915990Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/type-checker.test.ts"
2025-05-06T23:13:45.915995Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/text.test.ts"
2025-05-06T23:13:45.915998Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/logic.ts"
2025-05-06T23:13:45.916000Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/intrinsics.ts"
2025-05-06T23:13:45.916024Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/sequence.ts"
2025-05-06T23:13:45.916056Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/function-utils.ts"
2025-05-06T23:13:45.916058Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/scripts/generate-documentation.ts"
2025-05-06T23:13:45.916070Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/expression.ts"
2025-05-06T23:13:45.916075Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/logic.test.ts"
2025-05-06T23:13:45.916063Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/date.test.ts"
2025-05-06T23:13:45.916119Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/evaluation-result.ts"
2025-05-06T23:13:45.916120Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/index.ts"
2025-05-06T23:13:45.916148Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/expression.test.ts"
2025-05-06T23:13:45.916152Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/engineering.test.ts"
2025-05-06T23:13:45.916193Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/lookup.ts"
2025-05-06T23:13:45.916219Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/tmp.test.ts"
2025-05-06T23:13:45.916228Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/tokenizer.test.ts"
2025-05-06T23:13:45.916245Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/evaluation.test.ts"
2025-05-06T23:13:45.916256Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/spreadsheet.ts"
2025-05-06T23:13:45.916253Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/lookup.test.ts"
2025-05-06T23:13:45.916267Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/sequence.test.ts"
2025-05-06T23:13:45.916287Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/math.test.ts"
2025-05-06T23:13:45.916286Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/version-control.test.ts"
2025-05-06T23:13:45.916317Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/intrinsics.test.ts"
2025-05-06T23:13:45.916323Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/evaluation.ts"
2025-05-06T23:13:45.916354Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/statistics.ts"
2025-05-06T23:13:45.916562Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/date.ts"
2025-05-06T23:13:45.916609Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/domain/functions/math.ts"
2025-05-06T23:13:45.916676Z INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: exit
2025-05-06T23:13:45.916682Z INFO extract_candidates:parse_all_blobs: tailwindcss_oxide::scanner: enter
2025-05-06T23:13:45.916688Z INFO extract_candidates:parse_all_blobs:extract: tailwindcss_oxide::scanner: enter
2025-05-06T23:13:45.918271Z INFO extract_candidates:parse_all_blobs:extract: tailwindcss_oxide::scanner: exit
2025-05-06T23:13:45.918282Z INFO extract_candidates:parse_all_blobs: tailwindcss_oxide::scanner: exit
2025-05-06T23:13:45.918286Z INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: enter
2025-05-06T23:13:45.918288Z INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: Reading 2 file(s)
2025-05-06T23:13:45.918315Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/app/tailwind.css"
2025-05-06T23:13:45.918504Z INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/RobinMalfait/spreadsheet/out.css"
2025-05-06T23:13:45.918512Z INFO extract_candidates:read_all_files: tailwindcss_oxide::scanner: exit
2025-05-06T23:13:45.918519Z INFO extract_candidates:extract_css_variables: tailwindcss_oxide::scanner: enter
2025-05-06T23:13:45.918522Z INFO extract_candidates:extract_css_variables:extract: tailwindcss_oxide::scanner: enter
2025-05-06T23:13:45.918635Z INFO extract_candidates:extract_css_variables:extract: tailwindcss_oxide::scanner: exit
2025-05-06T23:13:45.918640Z INFO extract_candidates:extract_css_variables: tailwindcss_oxide::scanner: exit
2025-05-06T23:13:45.919059Z INFO extract_candidates: tailwindcss_oxide::scanner: exit
```
</details>
We also output where we are writing the file to. This looks like this
when using the CLI:
<img width="1462" alt="image"
src="https://github.com/user-attachments/assets/79c2cc95-adea-4bbd-a4f1-101de45726f5"
/>
Last but not least, this also ignores `.log` files by default
## Test plan
Ran the CLI (but you can use any tool real, since this is implemented in
Oxide) with the `DEBUG=*` flag.
The file generated, looks like the example I shared above.
|
||
|
|
449dfcf00d
|
Make upgrades faster (#17898)
This PR fixes an issue where the upgrade tests were taking too long. This PR fixes that. Essentially when updating dependencies we did this: ```sh npm install tailwindcss@latest npm install @tailwindcss/postcss@latest npm install prettier-plugin-tailwindcss@latest ``` But this is not ideal, because we are calling out to `npm` and run each dependency in isolation. With this PR, we essentially do it all in one go: ```sh npm install tailwindcss@latest @tailwindcss/postcss@latest prettier-plugin-tailwindcss@latest ``` ## Test plan Testing this locally, the results look like this: | Before | After | |--------|-------| | <img width="590" alt="image" src="https://github.com/user-attachments/assets/c899d432-78c3-4945-af73-3ef4fffa08da" /> | <img width="656" alt="image" src="https://github.com/user-attachments/assets/a448d711-dd74-44cf-9790-c8a14fc6964f" /> | In CI: | Before (with a failure) | After | | --- | --- | | <img width="224" alt="image" src="https://github.com/user-attachments/assets/f58a6bf6-fdbe-4474-aa1f-444ab51a53c9" /> | <img width="224" alt="image" src="https://github.com/user-attachments/assets/54606df5-4f69-444b-8d4c-5ce27c5d6b41" /> | [ci-all] |
||
|
|
4f8539c063
|
Fix bug replacing modifier variable shorthand syntax underscores (#17889)
Resolves #17888 **Reproduction URL:** https://play.tailwindcss.com/YvIekuzVRd Changes: * Don't use `decodeArbitraryValue` when parsing variable shorthand syntax in modifiers * replace `decodeArbitraryValue(modifier.slice(1, -1))` with `modifier.slice(1, -1)` * added test case, passing ✅ --------- Co-authored-by: Robin Malfait <malfait.robin@gmail.com> |
||
|
|
ed45952d15
|
Update turbo 2.5.0 → 2.5.2 (patch) (#17887) | ||
|
|
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. |
||
|
|
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
|
||
|
|
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" /> |
||
|
|
473f0241bf
|
Update h3 1.15.1 → 1.15.3 (patch) (#17873) | ||
|
|
e00d0926eb
|
Update @vitejs/plugin-react 4.3.4 → 4.4.1 (minor) (#17862) | ||
|
|
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=" |
||
|
|
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" /> |
||
|
|
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> |
||
|
|
45cd32eed7
|
Prepare v4.1.5 release (#17830)
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>v4.1.5 |
||
|
|
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> |
||
|
|
ab4eb18bab
|
Update @types/react-dom 19.1.1 → 19.1.2 (patch) (#17829) | ||
|
|
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. |
||
|
|
d3846a4570
|
Update test to retry assertion on empty file and don't include forward-slash in the assertion (#17821)
To fix the CI issues we have, it turns out there are two issues: 1. The file-read was not retried, making it possible for all platforms (but mostly Windows because it's the slowest) to sometimes not have the file created yet before making the assertion. 2. A forward-slash in the assertion message path would always be a backslash when run on Windows, thus the Windows test would never pass. ## Test plan - [ci-all] and have the test pass two times. |
||
|
|
9fec4ef60b
|
Update bun 1.2.8 → 1.2.11 (patch) (#17816) | ||
|
|
d2daf59524
|
Skip color-mix(…) when opacity is 100% (#17815)
This PR improves colors with alpha values where the alpha value results
in 100%.
Before this change, a class like `bg-red-500/100` would be generated as:
```css
.bg-red-500\/100 {
background-color: #ef4444;
}
@supports (color: color-mix(in lab, red, red)) {
.bg-red-500\/100 {
background-color: color-mix(in oklab, var(--color-red-500) 100%, transparent);
}
}
```
But we don't need the `color-mix`, or the fallback styles at all in case
the alpha value is 100%.
After this change the `bg-red-500/100` class will generate as:
```css
.bg-red-500\/100 {
background-color: var(--color-red-500);
}
```
Which is essentially the same as `bg-red-500`, but we can migrate that
away in the future. At least the generated CSS is smaller.
## Test plan
1. Added a test to ensure the generated value doesn't include color-mix
at all.
|
||
|
|
3a1b27e3f8
|
Pretty print variants starting with @ (#17814)
While working on another PR I noticed that some variants were re-printed in an odd way. Specifically, this PR fixes an issue where variants using the `@`-root were incorrectly printed. - `@lg` was printed as `@-lg` - `@[400px]` was printed as `@-[400px]` This is now special cased where the `-` is not inserted for `@`-root variants. ## Test plan 1. Added a test to ensure the `@`-root variants are printed correctly. |
||
|
|
af1d4aa683 | Temporarily disable broken Windows test | ||
|
|
ba103799f7
|
Add h-lh/min-h-lh/max-h-lh utilities to match an elements line height (#17790)
This PR adds the following utilities that can be used to match an elements line height: - `h-lh` - `min-h-lh` - `max-h-lh` These are all equivalent to providing `1lh` as an arbitrary value. e.g. `h-[1lh]` |
||
|
|
62ca1ec42d | Fix Windows tests | ||
|
|
52000a30f0
|
PostCSS: Improve error recovery (#17754)
Closes #17295 This commit addresses an issue where the PostCSS plugin would get stuck in an error state when processing files with e.g. invalid @apply directives. This change prevents the PostCSS plugin from getting stuck in an error states particularly when the error happened inside an `@import`ed CSS files (as these were not registered as dependencies correctly before). ## Error overlays Some frameworks (e.g. Angular 19 or Next.js) handle errors inside PostCSS transforms to render a nice error overlay. This works well and gives immediate feedback that something went wrong. However, even when dependencies are registered before an error is thrown, these frameworks _will not consider changes to these dependencies anymore_ when an error occurs, as you can see in this Next.js example: https://github.com/user-attachments/assets/985c9dd7-daf8-4628-b4ad-6543ef220954 To avoid conditions where errors are not recoverable, this PR makes it so that these overlays will no longer show up in the app and only be logged to the output console. This will need follow-up upstream work before we can revisit this. ## Test plan - Tested with the repro in #17295. The error can now be recovered from. - Tested with a Next.js app where the issue in the screencast above is now no longer happening. - Added an integration test for errors in `@import`-ed files - Added a unit test for the changed `@apply` behavior. |
||
|
|
231cdddb94 | Update all of nextjs to version 15.3.1 | ||
|
|
d780a55e65
|
Update @playwright/test 1.51.1 → 1.52.0 (minor) (#17780) | ||
|
|
2bf2b4db98
|
update changelog | ||
|
|
46758f7c29
|
Bump all Tailwind CSS related dependencies during upgrade (#17763)
This PR bumps all Tailwind CSS related dependencies when running the upgrade tool _if_ the dependency exists in your package.json file. E.g.: if you have `tailwindcss` and `@tailwindcss/vite` in your package.json, then both will be updated to the latest version. This PR is not trying to be smart and skip updating if you are already on the latest version. It will just try and update the dependencies and your package manager will do nothing in case it was already the latest version. ## Test plan Ran this on one of my personal projects and this was the output: <img width="1023" alt="image" src="https://github.com/user-attachments/assets/a189fe7a-a58a-44aa-9246-b720e7a2a892" /> Notice that I don't have `@tailwindcss/vite` logs because I am using `@tailwindcss/postcss`. |
||
|
|
a7f4a4d3b8
|
Upgrade wasm related dependencies (#17753)
Closes #17752 Closes #17748 Closes #17747 Closes #17746 Closes #17745 |
||
|
|
8e826b18f3
|
Ensure @tailwindcss/upgrade runs on Tailwind CSS v4 projects and is idempotent (#17717)
This PR ensures that the `@tailwindcss/upgrade` tool works on existing Tailwind CSS v4 projects. This PR also ensures that the upgrade tool is idempotent, meaning that it can be run multiple times and it should result in the same output. One awesome feature this unlocks is that you can run the upgrade tool on your codebase at any time and upgrade classes if you still have some legacy syntaxes, such as `bg-[var(--my-color)]`, in your muscle memory. One small note: If something changed in the first run, re-running will not work immediately because your git repository will not be clean and the upgrade tool requires your git repo to be clean. But once you verified and committed your changes, the upgrade tool will be idempotent. Idempotency is guaranteed by ensuring that some migrations are skipped by checking what version of Tailwind CSS you are on _before_ the version is upgraded. For the Tailwind CSS version: We will resolve `tailwindcss` itself to know the _actual_ version that is installed (the one resolved from `node_modules`). Not the one available in your package.json. Your `package.json` could be out of sync if you reverted changes but didn't run `npm install` yet. Back to Idempotency: For example, we have migrations where we change the variant order of stacked variants. If we would run these migrations every time you run the upgrade tool then we would be flip-flopping the order every run. See: https://tailwindcss.com/docs/upgrade-guide#variant-stacking-order Another example is where we rename some utilities. For example, we rename: | Before | After | | ----------- | ----------- | | `shadow` | `shadow-sm` | | `shadow-sm` | `shadow-xs` | Notice how we have `shadow-sm` in both the `before` and `after` column. If we would run the upgrade tool again, then we would eventually migrate your original `shadow` to `shadow-sm` (first run) and then to `shadow-xs` (second run). Which would result in the wrong shadow. See: https://tailwindcss.com/docs/upgrade-guide#renamed-utilities --- The order of upgrade steps changed a bit as well to make the internals are easier to work with and reason about. 1. Find CSS files 2. Link JS config files (if you are in a Tailwind CSS v3 project) 3. Migrate the JS config files (if you are in a Tailwind CSS v3 project) 4. Upgrade Tailwind CSS to v4 (or the latest version at that point) 5. Migrate the stylesheets (we used to migrate the source files first) 6. Migrate the source files This is done so that step 5 and 6 will always operate on a Tailwind CSS v4 project and we don't need to check the version number again. This is also necessary because your CSS file will now very likely contain `@import "tailwindcss";` which doesn't exist in Tailwind CSS v3. This also means that we can rely on the same internals that Tailwind CSS actually uses for locating the source files. We will use `@tailwindcss/oxide`'s scanner to find the source files (and it also keeps your custom `@source` directives into account). This PR also introduces a few actual migrations related to recent features and changes we shipped. 1. We migrate deprecated classes to their new names: | Before | After | | --------------------- | --------------------- | | `bg-left-top` | `bg-top-left` | | `bg-left-bottom` | `bg-bottom-left` | | `bg-right-top` | `bg-top-right` | | `bg-right-bottom` | `bg-bottom-right` | | `object-left-top` | `object-top-left` | | `object-left-bottom` | `object-bottom-left` | | `object-right-top` | `object-top-right` | | `object-right-bottom` | `object-bottom-right` | Introduced in: - https://github.com/tailwindlabs/tailwindcss/pull/17378 - https://github.com/tailwindlabs/tailwindcss/pull/17437 2. We migrate simple arbitrary variants to their dedicated variant: | Before | After | | ----------------------- | ------------------- | | `[&:user-valid]:flex` | `user-valid:flex` | | `[&:user-invalid]:flex` | `user-invalid:flex` | Introduced in: - https://github.com/tailwindlabs/tailwindcss/pull/12370 3. We migrate `@media` variants to their dedicated variant: | Before | After | | ----------------------------------------------------- | ------------------------- | | `[@media_print]:flex` | `print:flex` | | `[@media(prefers-reduced-motion:no-preference)]:flex` | `motion-safe:flex` | | `[@media(prefers-reduced-motion:reduce)]:flex` | `motion-reduce:flex` | | `[@media(prefers-contrast:more)]:flex` | `contrast-more:flex` | | `[@media(prefers-contrast:less)]:flex` | `contrast-less:flex` | | `[@media(orientation:portrait)]:flex` | `portrait:flex` | | `[@media(orientation:landscape)]:flex` | `landscape:flex` | | `[@media(forced-colors:active)]:flex` | `forced-colors:flex` | | `[@media(inverted-colors:inverted)]:flex` | `inverted-colors:flex` | | `[@media(pointer:none)]:flex` | `pointer-none:flex` | | `[@media(pointer:coarse)]:flex` | `pointer-coarse:flex` | | `[@media(pointer:fine)]:flex` | `pointer-fine:flex` | | `[@media(any-pointer:none)]:flex` | `any-pointer-none:flex` | | `[@media(any-pointer:coarse)]:flex` | `any-pointer-coarse:flex` | | `[@media(any-pointer:fine)]:flex` | `any-pointer-fine:flex` | | `[@media(scripting:none)]:flex` | `noscript:flex` | The new variants related to `inverted-colors`, `pointer`, `any-pointer` and `scripting` were introduced in: - https://github.com/tailwindlabs/tailwindcss/pull/11693 - https://github.com/tailwindlabs/tailwindcss/pull/16946 - https://github.com/tailwindlabs/tailwindcss/pull/11929 - https://github.com/tailwindlabs/tailwindcss/pull/17431 This also applies to the `not` case, e.g.: | Before | After | | --------------------------------------------------------- | ----------------------------- | | `[@media_not_print]:flex` | `not-print:flex` | | `[@media_not(prefers-reduced-motion:no-preference)]:flex` | `not-motion-safe:flex` | | `[@media_not(prefers-reduced-motion:reduce)]:flex` | `not-motion-reduce:flex` | | `[@media_not(prefers-contrast:more)]:flex` | `not-contrast-more:flex` | | `[@media_not(prefers-contrast:less)]:flex` | `not-contrast-less:flex` | | `[@media_not(orientation:portrait)]:flex` | `not-portrait:flex` | | `[@media_not(orientation:landscape)]:flex` | `not-landscape:flex` | | `[@media_not(forced-colors:active)]:flex` | `not-forced-colors:flex` | | `[@media_not(inverted-colors:inverted)]:flex` | `not-inverted-colors:flex` | | `[@media_not(pointer:none)]:flex` | `not-pointer-none:flex` | | `[@media_not(pointer:coarse)]:flex` | `not-pointer-coarse:flex` | | `[@media_not(pointer:fine)]:flex` | `not-pointer-fine:flex` | | `[@media_not(any-pointer:none)]:flex` | `not-any-pointer-none:flex` | | `[@media_not(any-pointer:coarse)]:flex` | `not-any-pointer-coarse:flex` | | `[@media_not(any-pointer:fine)]:flex` | `not-any-pointer-fine:flex` | | `[@media_not(scripting:none)]:flex` | `not-noscript:flex` | For each candidate, we run a set of upgrade migrations. If at the end of the migrations the original candidate is still the same as the new candidate, then we will parse & print the candidate one more time to pretty print into consistent classes. Luckily parsing is cached so there is no real downside overhead. Consistency (especially with arbitrary variants and values) will reduce your CSS file because there will be fewer "versions" of your class. Concretely, the pretty printing will apply changes such as: | Before | After | | ---------------------- | ----------------- | | `bg-[var(--my-color)]` | `bg-(--my-color)` | | `bg-[rgb(0,_0,_0)]` | `bg-[rgb(0,0,0)]` | Another big important reason for this change is that these classes on their own would have been migrated _if_ another migration was relevant for this candidate. This means that there are were some inconsistencies. E.g.: | Before | After | Reason | | ----------------------- | ---------------------- | ------------------------------------ | | `!bg-[var(--my-color)]` | `bg-(--my-color)!` | Because the `!` is in the wrong spot | | `bg-[var(--my-color)]` | `bg-[var(--my-color)]` | Because no migrations rand | As you can see, the way the `--my-color` variable is used, is different. This changes will make sure it will now always be consistent: | Before | After | | ----------------------- | ---------------------- | | `!bg-[var(--my-color)]` | `bg-(--my-color)!` | | `bg-[var(--my-color)]` | `bg-(--my-color)` | Yay! Of course, if you don't want these more cosmetic changes, you can always ignore the upgrade and revert these changes and only commit the changes you want. # Test plan - All existing tests still pass. - But I had to delete 1 test (we tested that Tailwind CSS v3 was required). - And had to mock the `version.isMajor` call to ensure we run the individual migration tests correctly. - Added new tests to test: 1. Migrating Tailwind CSS v4 projects works 1. Idempotency of the upgrade tool [ci-all] |
||
|
|
25ec6a3b7d
|
Ignore .db files by default (#17711)
This PR ignores `.db` files by default. We already ignored `.sqlite` and `.sqlite3` files but we didn't ignore `.db` files which is a common extension for database files as well. Due to the binary nature of `.db` files, scanning these could result in hard to debug errors such as:  |