Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only expose used CSS variables #16211

Merged
merged 44 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7ebc4ed
track if CSS variable is used
RobinMalfait Feb 3, 2025
87de2a5
move `:root` population to `build(…)` step
RobinMalfait Feb 3, 2025
3472e7c
do not emit unused theme variables
RobinMalfait Feb 3, 2025
44367e5
update tests
RobinMalfait Feb 3, 2025
b777ba3
mark variables as used when used in your CSS
RobinMalfait Feb 3, 2025
ad68639
update tests
RobinMalfait Feb 3, 2025
b3b693f
do not mark CSS variables in `@utility` and `@custom-variant` as used
RobinMalfait Feb 3, 2025
1d6d4fa
add method to track CSS variables in an AST
RobinMalfait Feb 3, 2025
470f493
update tests
RobinMalfait Feb 3, 2025
a285222
fast path: only scan if `var()` is used in the raw candidate
RobinMalfait Feb 3, 2025
5b7f315
add failing tests for `@utility`
RobinMalfait Feb 4, 2025
2e88937
track CSS variables in `@utility`
RobinMalfait Feb 4, 2025
2f2faa0
add Oxide tests to ensure we find CSS variables
RobinMalfait Feb 4, 2025
7e61d5e
add integration test
RobinMalfait Feb 4, 2025
34f16e4
emit CSS variables when new CSS variables are found
RobinMalfait Feb 4, 2025
bdfbaeb
only emit `--foo-bar` if preceded by `var(`
RobinMalfait Feb 4, 2025
9212ca2
run cargo clippy
RobinMalfait Feb 4, 2025
fc736a1
use `fs.expectFileToContain`
RobinMalfait Feb 4, 2025
5b2f975
implement different approach
RobinMalfait Feb 4, 2025
9b1920e
update tests to reflect changes
RobinMalfait Feb 4, 2025
34a1fac
handle escaped CSS variables
RobinMalfait Feb 4, 2025
d29bb7f
update tests
RobinMalfait Feb 4, 2025
60335d0
improve ValueParser, handle escaped characters
RobinMalfait Feb 4, 2025
4cc3ab2
cleanup unnecessary code
RobinMalfait Feb 5, 2025
e5a7071
cleanup unnecessary check
RobinMalfait Feb 5, 2025
07a20b9
cache tracking of variables
RobinMalfait Feb 5, 2025
8748021
detect all variables that start with `--`
RobinMalfait Feb 5, 2025
63f3917
update changelog
RobinMalfait Feb 6, 2025
64ddc5f
rename `USED` to `STATIC`
RobinMalfait Feb 6, 2025
da33751
allow `theme(static)`
RobinMalfait Feb 6, 2025
1420e9f
add test for `@theme static`
RobinMalfait Feb 6, 2025
8f3eb8a
allow accessing `context` in the `optimizeAst` step
RobinMalfait Feb 7, 2025
2e7c8dc
track usage of `@keyframes`
RobinMalfait Feb 7, 2025
64cd24a
remove unnecessary logic
RobinMalfait Feb 7, 2025
557406b
reflect removal of unused `@keyframes` in tests
RobinMalfait Feb 7, 2025
f3439f3
update CHANGELOG
RobinMalfait Feb 7, 2025
b735291
remove unnecessary check
RobinMalfait Feb 7, 2025
dc7aee8
add test for `@theme static`
RobinMalfait Feb 7, 2025
a00210a
Test that non-theme keyframes are always preserved
adamwathan Feb 7, 2025
7cd2443
improve naming
RobinMalfait Feb 7, 2025
b132705
move tracking of variables up
RobinMalfait Feb 7, 2025
bf428dd
keep `static` and `used` separate
RobinMalfait Feb 7, 2025
680d72d
remove unnecessary code
RobinMalfait Feb 7, 2025
aafc1d6
remove unnecessary reset
RobinMalfait Feb 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Nothing yet!
### Fixed

- Only expose used CSS variables ([#16211](https://github.com/tailwindlabs/tailwindcss/pull/16211))
- Only expose used `@keyframes` ([#16211](https://github.com/tailwindlabs/tailwindcss/pull/16211))

## [4.0.4] - 2025-02-06

Expand Down
59 changes: 53 additions & 6 deletions crates/oxide/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,12 @@ impl<'a> Extractor<'a> {
let start_brace_index = utility.find(b"[");
let end_brace_index = utility.find(b"]");

match (start_brace_index, end_brace_index) {
(Some(start_brace_index), Some(end_brace_index)) => {
if start_brace_index < index && end_brace_index > index {
skip_parens_check = true;
}
if let (Some(start_brace_index), Some(end_brace_index)) =
(start_brace_index, end_brace_index)
{
if start_brace_index < index && end_brace_index > index {
skip_parens_check = true;
}
_ => {}
}

if !skip_parens_check && !utility[index + 1..].starts_with(b"--") {
Expand Down Expand Up @@ -1679,6 +1678,54 @@ mod test {
);
}

#[test]
fn test_find_css_variables() {
let candidates = run("var(--color-red-500)", false);
assert_eq!(candidates, vec!["var", "--color-red-500"]);

let candidates = run("<div style={{ 'color': 'var(--color-red-500)' }}/>", false);
assert_eq!(
candidates,
vec!["div", "style", "color", "var", "--color-red-500"]
);
}

#[test]
fn test_find_css_variables_with_fallback_values() {
let candidates = run("var(--color-red-500, red)", false);
assert_eq!(candidates, vec!["var", "--color-red-500", "red"]);

let candidates = run("var(--color-red-500,red)", false);
assert_eq!(candidates, vec!["var", "--color-red-500", "red"]);

let candidates = run(
"<div style={{ 'color': 'var(--color-red-500, red)' }}/>",
false,
);
assert_eq!(
candidates,
vec!["div", "style", "color", "var", "--color-red-500", "red"]
);

let candidates = run(
"<div style={{ 'color': 'var(--color-red-500,red)' }}/>",
false,
);
assert_eq!(
candidates,
vec!["div", "style", "color", "var", "--color-red-500", "red"]
);
}

#[test]
fn test_find_css_variables_with_fallback_css_variable_values() {
let candidates = run("var(--color-red-500, var(--color-blue-500))", false);
assert_eq!(
candidates,
vec!["var", "--color-red-500", "--color-blue-500"]
);
}

#[test]
fn test_is_valid_candidate_string() {
assert_eq!(
Expand Down
62 changes: 62 additions & 0 deletions integrations/cli/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1253,3 +1253,65 @@ test(
`)
},
)

test(
'emit CSS variables if used outside of utilities',
{
fs: {
'package.json': json`
{
"dependencies": {
"tailwindcss": "workspace:^",
"@tailwindcss/cli": "workspace:^"
}
}
`,
'src/index.css': css`
@import 'tailwindcss/utilities';
@theme {
--*: initial;
Copy link
Member

Choose a reason for hiding this comment

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

don't really need this line in the code since you're not importing from tailwindcss right?

--color-blue-500: blue;
}
`,
'src/index.ts': ts`
function MyComponent() {
return <motion.div />
}
`,
},
},
async ({ fs, spawn, expect }) => {
let process = await spawn(
'pnpm tailwindcss --input src/index.css --output dist/out.css --watch',
)
await process.onStderr((m) => m.includes('Done in'))

// No CSS variables are used, so nothing should be generated yet.
expect(await fs.dumpFiles('./dist/*.css')).toMatchInlineSnapshot(`
"
--- ./dist/out.css ---
<EMPTY>
"
`)

// Use a CSS variable in JS/TS land, now it should be generated.
await fs.write(
'./src/index.ts',
ts`
function MyComponent() {
return <motion.div animate={{ backgroundColor: 'var(--color-blue-500)' }} />
}
`,
)

fs.expectFileToContain(
'./dist/out.css',
css`
:root,
:host {
--color-blue-500: blue;
}
`,
)
},
)
Loading