Skip to content

Commit

Permalink
Revert "Remove automatic var(…) injection (tailwindlabs#13537)"
Browse files Browse the repository at this point in the history
This reverts commit cd4711c.
RobinMalfait committed May 8, 2024
1 parent cb17447 commit 3a59340
Showing 5 changed files with 818 additions and 749 deletions.
4 changes: 0 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -12,10 +12,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Make sure `contain-*` utility variables resolve to a valid value ([#13521](https://github.com/tailwindlabs/tailwindcss/pull/13521))
- Support unbalanced parentheses and braces in quotes in arbitrary values and variants ([#13608](https://github.com/tailwindlabs/tailwindcss/pull/13608))

### Changed

- Remove automatic `var(…)` injection ([#13537](https://github.com/tailwindlabs/tailwindcss/pull/13537))

## Changed

- Use `rem` units for breakpoints by default instead of `px` ([#13469](https://github.com/tailwindlabs/tailwindcss/pull/13469))
90 changes: 45 additions & 45 deletions packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ exports[`border-* 1`] = `
border-width: 12px;
}
.border-\\[length\\:var\\(--my-width\\)\\], .border-\\[line-width\\:var\\(--my-width\\)\\] {
.border-\\[length\\:--my-width\\], .border-\\[line-width\\:--my-width\\] {
border-style: var(--tw-border-style);
border-width: var(--my-width);
}
@@ -66,19 +66,19 @@ exports[`border-* 1`] = `
border-color: #0088cc80;
}
.border-\\[color\\:var\\(--my-color\\)\\] {
.border-\\[--my-color\\] {
border-color: var(--my-color);
}
.border-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-\\[--my-color\\]\\/50 {
border-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-\\[var\\(--my-color\\)\\] {
.border-\\[color\\:--my-color\\] {
border-color: var(--my-color);
}
.border-\\[var\\(--my-color\\)\\]\\/50 {
.border-\\[color\\:--my-color\\]\\/50 {
border-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
@@ -151,7 +151,7 @@ exports[`border-b-* 1`] = `
border-bottom-width: 12px;
}
.border-b-\\[length\\:var\\(--my-width\\)\\], .border-b-\\[line-width\\:var\\(--my-width\\)\\] {
.border-b-\\[length\\:--my-width\\], .border-b-\\[line-width\\:--my-width\\] {
border-bottom-style: var(--tw-border-style);
border-bottom-width: var(--my-width);
}
@@ -179,19 +179,19 @@ exports[`border-b-* 1`] = `
border-bottom-color: #0088cc80;
}
.border-b-\\[color\\:var\\(--my-color\\)\\] {
.border-b-\\[--my-color\\] {
border-bottom-color: var(--my-color);
}
.border-b-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-b-\\[--my-color\\]\\/50 {
border-bottom-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-b-\\[var\\(--my-color\\)\\] {
.border-b-\\[color\\:--my-color\\] {
border-bottom-color: var(--my-color);
}
.border-b-\\[var\\(--my-color\\)\\]\\/50 {
.border-b-\\[color\\:--my-color\\]\\/50 {
border-bottom-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
@@ -264,7 +264,7 @@ exports[`border-e-* 1`] = `
border-inline-end-width: 12px;
}
.border-e-\\[length\\:var\\(--my-width\\)\\], .border-e-\\[line-width\\:var\\(--my-width\\)\\] {
.border-e-\\[length\\:--my-width\\], .border-e-\\[line-width\\:--my-width\\] {
border-inline-end-style: var(--tw-border-style);
border-inline-end-width: var(--my-width);
}
@@ -292,19 +292,19 @@ exports[`border-e-* 1`] = `
border-inline-end-color: #0088cc80;
}
.border-e-\\[color\\:var\\(--my-color\\)\\] {
.border-e-\\[--my-color\\] {
border-inline-end-color: var(--my-color);
}
.border-e-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-e-\\[--my-color\\]\\/50 {
border-inline-end-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-e-\\[var\\(--my-color\\)\\] {
.border-e-\\[color\\:--my-color\\] {
border-inline-end-color: var(--my-color);
}
.border-e-\\[var\\(--my-color\\)\\]\\/50 {
.border-e-\\[color\\:--my-color\\]\\/50 {
border-inline-end-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
@@ -377,7 +377,7 @@ exports[`border-l-* 1`] = `
border-left-width: 12px;
}
.border-l-\\[length\\:var\\(--my-width\\)\\], .border-l-\\[line-width\\:var\\(--my-width\\)\\] {
.border-l-\\[length\\:--my-width\\], .border-l-\\[line-width\\:--my-width\\] {
border-left-style: var(--tw-border-style);
border-left-width: var(--my-width);
}
@@ -405,19 +405,19 @@ exports[`border-l-* 1`] = `
border-left-color: #0088cc80;
}
.border-l-\\[color\\:var\\(--my-color\\)\\] {
.border-l-\\[--my-color\\] {
border-left-color: var(--my-color);
}
.border-l-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-l-\\[--my-color\\]\\/50 {
border-left-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-l-\\[var\\(--my-color\\)\\] {
.border-l-\\[color\\:--my-color\\] {
border-left-color: var(--my-color);
}
.border-l-\\[var\\(--my-color\\)\\]\\/50 {
.border-l-\\[color\\:--my-color\\]\\/50 {
border-left-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
@@ -490,7 +490,7 @@ exports[`border-r-* 1`] = `
border-right-width: 12px;
}
.border-r-\\[length\\:var\\(--my-width\\)\\], .border-r-\\[line-width\\:var\\(--my-width\\)\\] {
.border-r-\\[length\\:--my-width\\], .border-r-\\[line-width\\:--my-width\\] {
border-right-style: var(--tw-border-style);
border-right-width: var(--my-width);
}
@@ -518,19 +518,19 @@ exports[`border-r-* 1`] = `
border-right-color: #0088cc80;
}
.border-r-\\[color\\:var\\(--my-color\\)\\] {
.border-r-\\[--my-color\\] {
border-right-color: var(--my-color);
}
.border-r-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-r-\\[--my-color\\]\\/50 {
border-right-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-r-\\[var\\(--my-color\\)\\] {
.border-r-\\[color\\:--my-color\\] {
border-right-color: var(--my-color);
}
.border-r-\\[var\\(--my-color\\)\\]\\/50 {
.border-r-\\[color\\:--my-color\\]\\/50 {
border-right-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
@@ -603,7 +603,7 @@ exports[`border-s-* 1`] = `
border-inline-start-width: 12px;
}
.border-s-\\[length\\:var\\(--my-width\\)\\], .border-s-\\[line-width\\:var\\(--my-width\\)\\] {
.border-s-\\[length\\:--my-width\\], .border-s-\\[line-width\\:--my-width\\] {
border-inline-start-style: var(--tw-border-style);
border-inline-start-width: var(--my-width);
}
@@ -631,19 +631,19 @@ exports[`border-s-* 1`] = `
border-inline-start-color: #0088cc80;
}
.border-s-\\[color\\:var\\(--my-color\\)\\] {
.border-s-\\[--my-color\\] {
border-inline-start-color: var(--my-color);
}
.border-s-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-s-\\[--my-color\\]\\/50 {
border-inline-start-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-s-\\[var\\(--my-color\\)\\] {
.border-s-\\[color\\:--my-color\\] {
border-inline-start-color: var(--my-color);
}
.border-s-\\[var\\(--my-color\\)\\]\\/50 {
.border-s-\\[color\\:--my-color\\]\\/50 {
border-inline-start-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
@@ -716,7 +716,7 @@ exports[`border-t-* 1`] = `
border-top-width: 12px;
}
.border-t-\\[length\\:var\\(--my-width\\)\\], .border-t-\\[line-width\\:var\\(--my-width\\)\\] {
.border-t-\\[length\\:--my-width\\], .border-t-\\[line-width\\:--my-width\\] {
border-top-style: var(--tw-border-style);
border-top-width: var(--my-width);
}
@@ -744,19 +744,19 @@ exports[`border-t-* 1`] = `
border-top-color: #0088cc80;
}
.border-t-\\[color\\:var\\(--my-color\\)\\] {
.border-t-\\[--my-color\\] {
border-top-color: var(--my-color);
}
.border-t-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-t-\\[--my-color\\]\\/50 {
border-top-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-t-\\[var\\(--my-color\\)\\] {
.border-t-\\[color\\:--my-color\\] {
border-top-color: var(--my-color);
}
.border-t-\\[var\\(--my-color\\)\\]\\/50 {
.border-t-\\[color\\:--my-color\\]\\/50 {
border-top-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
@@ -841,7 +841,7 @@ exports[`border-x-* 1`] = `
border-right-width: 12px;
}
.border-x-\\[length\\:var\\(--my-width\\)\\], .border-x-\\[line-width\\:var\\(--my-width\\)\\] {
.border-x-\\[length\\:--my-width\\], .border-x-\\[line-width\\:--my-width\\] {
border-left-style: var(--tw-border-style);
border-right-style: var(--tw-border-style);
border-left-width: var(--my-width);
@@ -879,22 +879,22 @@ exports[`border-x-* 1`] = `
border-right-color: #0088cc80;
}
.border-x-\\[color\\:var\\(--my-color\\)\\] {
.border-x-\\[--my-color\\] {
border-left-color: var(--my-color);
border-right-color: var(--my-color);
}
.border-x-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-x-\\[--my-color\\]\\/50 {
border-left-color: color-mix(in srgb, var(--my-color) 50%, transparent);
border-right-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-x-\\[var\\(--my-color\\)\\] {
.border-x-\\[color\\:--my-color\\] {
border-left-color: var(--my-color);
border-right-color: var(--my-color);
}
.border-x-\\[var\\(--my-color\\)\\]\\/50 {
.border-x-\\[color\\:--my-color\\]\\/50 {
border-left-color: color-mix(in srgb, var(--my-color) 50%, transparent);
border-right-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
@@ -986,7 +986,7 @@ exports[`border-y-* 1`] = `
border-bottom-width: 12px;
}
.border-y-\\[length\\:var\\(--my-width\\)\\], .border-y-\\[line-width\\:var\\(--my-width\\)\\] {
.border-y-\\[length\\:--my-width\\], .border-y-\\[line-width\\:--my-width\\] {
border-top-style: var(--tw-border-style);
border-bottom-style: var(--tw-border-style);
border-top-width: var(--my-width);
@@ -1024,22 +1024,22 @@ exports[`border-y-* 1`] = `
border-bottom-color: #0088cc80;
}
.border-y-\\[color\\:var\\(--my-color\\)\\] {
.border-y-\\[--my-color\\] {
border-top-color: var(--my-color);
border-bottom-color: var(--my-color);
}
.border-y-\\[color\\:var\\(--my-color\\)\\]\\/50 {
.border-y-\\[--my-color\\]\\/50 {
border-top-color: color-mix(in srgb, var(--my-color) 50%, transparent);
border-bottom-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
.border-y-\\[var\\(--my-color\\)\\] {
.border-y-\\[color\\:--my-color\\] {
border-top-color: var(--my-color);
border-bottom-color: var(--my-color);
}
.border-y-\\[var\\(--my-color\\)\\]\\/50 {
.border-y-\\[color\\:--my-color\\]\\/50 {
border-top-color: color-mix(in srgb, var(--my-color) 50%, transparent);
border-bottom-color: color-mix(in srgb, var(--my-color) 50%, transparent);
}
482 changes: 250 additions & 232 deletions packages/tailwindcss/src/candidate.test.ts
Original file line number Diff line number Diff line change
@@ -359,23 +359,24 @@ it('should parse a utility with an arbitrary modifier', () => {
utilities.functional('bg', () => [])

expect(run('bg-red-500/[50%]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": {
"kind": "arbitrary",
"value": "50%",
},
"negative": false,
"root": "bg",
"value": {
"fraction": null,
"kind": "named",
"value": "red-500",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": {
"dashedIdent": null,
"kind": "arbitrary",
"value": "50%",
},
"negative": false,
"root": "bg",
"value": {
"fraction": null,
"kind": "named",
"value": "red-500",
},
"variants": [],
}
`)
})

it('should parse a utility with a modifier that is important', () => {
@@ -440,266 +441,279 @@ it('should parse a utility with an arbitrary value', () => {
utilities.functional('bg', () => [])

expect(run('bg-[#0088cc]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": "#0088cc",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": "#0088cc",
},
"variants": [],
}
`)
})

it('should parse a utility with an arbitrary value including a typehint', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-[color:var(--value)]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dataType": "color",
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dashedIdent": null,
"dataType": "color",
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
})

it('should parse a utility with an arbitrary value with a modifier', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-[#0088cc]/50', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": {
"kind": "named",
"value": "50",
},
"negative": false,
"root": "bg",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": "#0088cc",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": {
"kind": "named",
"value": "50",
},
"negative": false,
"root": "bg",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": "#0088cc",
},
"variants": [],
}
`)
})

it('should parse a utility with an arbitrary value with an arbitrary modifier', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-[#0088cc]/[50%]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": {
"kind": "arbitrary",
"value": "50%",
},
"negative": false,
"root": "bg",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": "#0088cc",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": {
"dashedIdent": null,
"kind": "arbitrary",
"value": "50%",
},
"negative": false,
"root": "bg",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": "#0088cc",
},
"variants": [],
}
`)
})

it('should parse a utility with an arbitrary value that is important', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-[#0088cc]!', { utilities })).toMatchInlineSnapshot(`
{
"important": true,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": "#0088cc",
},
"variants": [],
}
`)
{
"important": true,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": "#0088cc",
},
"variants": [],
}
`)
})

it('should parse a utility with an implicit variable as the arbitrary value', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-[var(--value)]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
expect(run('bg-[--value]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dashedIdent": "--value",
"dataType": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
})

it('should parse a utility with an implicit variable as the arbitrary value that is important', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-[var(--value)]!', { utilities })).toMatchInlineSnapshot(`
{
"important": true,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
expect(run('bg-[--value]!', { utilities })).toMatchInlineSnapshot(`
{
"important": true,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dashedIdent": "--value",
"dataType": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
})

it('should parse a utility with an explicit variable as the arbitrary value', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-[var(--value)]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
})

it('should parse a utility with an explicit variable as the arbitrary value that is important', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-[var(--value)]!', { utilities })).toMatchInlineSnapshot(`
{
"important": true,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
{
"important": true,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "bg",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"variants": [],
}
`)
})

it('should parse a utility with an implicit variable as the modifier', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-red-500/[var(--value)]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": {
"kind": "arbitrary",
"value": "var(--value)",
},
"negative": false,
"root": "bg",
"value": {
"fraction": null,
"kind": "named",
"value": "red-500",
},
"variants": [],
}
`)
expect(run('bg-red-500/[--value]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": {
"dashedIdent": "--value",
"kind": "arbitrary",
"value": "var(--value)",
},
"negative": false,
"root": "bg",
"value": {
"fraction": null,
"kind": "named",
"value": "red-500",
},
"variants": [],
}
`)
})

it('should parse a utility with an implicit variable as the modifier that is important', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-red-500/[var(--value)]!', { utilities })).toMatchInlineSnapshot(`
{
"important": true,
"kind": "functional",
"modifier": {
"kind": "arbitrary",
"value": "var(--value)",
},
"negative": false,
"root": "bg",
"value": {
"fraction": null,
"kind": "named",
"value": "red-500",
},
"variants": [],
}
`)
expect(run('bg-red-500/[--value]!', { utilities })).toMatchInlineSnapshot(`
{
"important": true,
"kind": "functional",
"modifier": {
"dashedIdent": "--value",
"kind": "arbitrary",
"value": "var(--value)",
},
"negative": false,
"root": "bg",
"value": {
"fraction": null,
"kind": "named",
"value": "red-500",
},
"variants": [],
}
`)
})

it('should parse a utility with an explicit variable as the modifier', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-red-500/[var(--value)]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": {
"kind": "arbitrary",
"value": "var(--value)",
},
"negative": false,
"root": "bg",
"value": {
"fraction": null,
"kind": "named",
"value": "red-500",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": {
"dashedIdent": null,
"kind": "arbitrary",
"value": "var(--value)",
},
"negative": false,
"root": "bg",
"value": {
"fraction": null,
"kind": "named",
"value": "red-500",
},
"variants": [],
}
`)
})

it('should parse a utility with an explicit variable as the modifier that is important', () => {
@@ -711,6 +725,7 @@ it('should parse a utility with an explicit variable as the modifier that is imp
"important": true,
"kind": "functional",
"modifier": {
"dashedIdent": null,
"kind": "arbitrary",
"value": "var(--value)",
},
@@ -848,41 +863,43 @@ it('should replace `_` with ` `', () => {
utilities.functional('content', () => [])

expect(run('content-["hello_world"]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "content",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": ""hello world"",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "content",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": ""hello world"",
},
"variants": [],
}
`)
})

it('should not replace `\\_` with ` ` (when it is escaped)', () => {
let utilities = new Utilities()
utilities.functional('content', () => [])

expect(run('content-["hello\\_world"]', { utilities })).toMatchInlineSnapshot(`
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "content",
"value": {
"dataType": null,
"kind": "arbitrary",
"value": ""hello_world"",
},
"variants": [],
}
`)
{
"important": false,
"kind": "functional",
"modifier": null,
"negative": false,
"root": "content",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": ""hello_world"",
},
"variants": [],
}
`)
})

it('should not replace `_` inside of `url()`', () => {
@@ -897,6 +914,7 @@ it('should not replace `_` inside of `url()`', () => {
"negative": false,
"root": "bg",
"value": {
"dashedIdent": null,
"dataType": null,
"kind": "arbitrary",
"value": "url(https://example.com/some_page)",
52 changes: 49 additions & 3 deletions packages/tailwindcss/src/candidate.ts
Original file line number Diff line number Diff line change
@@ -11,16 +11,24 @@ type ArbitraryUtilityValue = {
kind: 'arbitrary'

/**
* bg-[color:var(--my-color)]
* bg-[color:--my-color]
* ^^^^^
*/
dataType: string | null

/**
* bg-[#0088cc]
* ^^^^^^^
* bg-[--my_variable]
* var(^^^^^^^^^^^^^)
*/
value: string

/**
* bg-[--my_variable]
* ^^^^^^^^^^^^^
*/
dashedIdent: string | null
}

export type NamedUtilityValue = {
@@ -50,6 +58,12 @@ type ArbitraryModifier = {
* ^^^
*/
value: string

/**
* bg-red-500/[--my_variable]
* ^^^^^^^^^^^^^
*/
dashedIdent: string | null
}

type NamedModifier = {
@@ -366,10 +380,26 @@ export function parseCandidate(input: string, designSystem: DesignSystem): Candi
break
}

// If an arbitrary value looks like a CSS variable, we automatically wrap
// it with `var(...)`.
//
// But since some CSS properties accept a `<dashed-ident>` as a value
// directly (e.g. `scroll-timeline-name`), we also store the original
// value in case the utility matcher is interested in it without
// `var(...)`.
let dashedIdent: string | null = null
if (arbitraryValue[0] === '-' && arbitraryValue[1] === '-') {
dashedIdent = arbitraryValue
arbitraryValue = `var(${arbitraryValue})`
} else {
arbitraryValue = decodeArbitraryValue(arbitraryValue)
}

candidate.value = {
kind: 'arbitrary',
dataType: typehint || null,
value: decodeArbitraryValue(arbitraryValue),
value: arbitraryValue,
dashedIdent,
}
} else {
// Some utilities support fractions as values, e.g. `w-1/2`. Since it's
@@ -402,9 +432,25 @@ function parseModifier(modifier: string): CandidateModifier {
if (modifier[0] === '[' && modifier[modifier.length - 1] === ']') {
let arbitraryValue = modifier.slice(1, -1)

// If an arbitrary value looks like a CSS variable, we automatically wrap
// it with `var(...)`.
//
// But since some CSS properties accept a `<dashed-ident>` as a value
// directly (e.g. `scroll-timeline-name`), we also store the original
// value in case the utility matcher is interested in it without
// `var(...)`.
let dashedIdent: string | null = null
if (arbitraryValue[0] === '-' && arbitraryValue[1] === '-') {
dashedIdent = arbitraryValue
arbitraryValue = `var(${arbitraryValue})`
} else {
arbitraryValue = decodeArbitraryValue(arbitraryValue)
}

return {
kind: 'arbitrary',
value: decodeArbitraryValue(arbitraryValue),
value: arbitraryValue,
dashedIdent,
}
}

939 changes: 474 additions & 465 deletions packages/tailwindcss/src/utilities.test.ts

Large diffs are not rendered by default.

0 comments on commit 3a59340

Please sign in to comment.