diff --git a/CHANGELOG.md b/CHANGELOG.md index 288d72a2762a..a17210a22c97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow plugins from a parent document to be used in an iframe ([#12208](https://github.com/tailwindlabs/tailwindcss/pull/12208)) - Add types for `tailwindcss/nesting` ([#12269](https://github.com/tailwindlabs/tailwindcss/pull/12269)) - Bump `jiti`, `fast-glob`, and `browserlist` dependencies ([#11550](https://github.com/tailwindlabs/tailwindcss/pull/11550)) +- Improve automatic `var` injection for properties that accept a `` ([#12236](https://github.com/tailwindlabs/tailwindcss/pull/12236)) ## [3.3.3] - 2023-07-13 diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index 5fb6bfe0212d..69b6827733e7 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -496,7 +496,7 @@ function extractArbitraryProperty(classCandidate, context) { return null } - let normalized = normalize(value) + let normalized = normalize(value, { property }) if (!isParsableCssValue(property, normalized)) { return null diff --git a/src/util/dataTypes.js b/src/util/dataTypes.js index 6a7f067a0d06..b427a1631ae9 100644 --- a/src/util/dataTypes.js +++ b/src/util/dataTypes.js @@ -10,10 +10,34 @@ function isCSSFunction(value) { return cssFunctions.some((fn) => new RegExp(`^${fn}\\(.*\\)`).test(value)) } +// These properties accept a `` as one of the values. This means that you can use them +// as: `timeline-scope: --tl;` +// +// Without the `var(--tl)`, in these cases we don't want to normalize the value, and you should add +// the `var()` yourself. +// +// More info: +// - https://drafts.csswg.org/scroll-animations/#propdef-timeline-scope +// - https://developer.mozilla.org/en-US/docs/Web/CSS/timeline-scope#dashed-ident +// +const AUTO_VAR_INJECTION_EXCEPTIONS = new Set([ + // Concrete properties + 'scroll-timeline-name', + 'timeline-scope', + 'view-timeline-name', + 'font-palette', + + // Shorthand properties + 'scroll-timeline', + 'animation-timeline', + 'view-timeline', +]) + // This is not a data type, but rather a function that can normalize the // correct values. -export function normalize(value, isRoot = true) { - if (value.startsWith('--')) { +export function normalize(value, context = null, isRoot = true) { + let isVarException = context && AUTO_VAR_INJECTION_EXCEPTIONS.has(context.property) + if (value.startsWith('--') && !isVarException) { return `var(${value})` } @@ -27,7 +51,7 @@ export function normalize(value, isRoot = true) { return part } - return normalize(part, false) + return normalize(part, context, false) }) .join('') } diff --git a/tests/normalize-data-types.test.js b/tests/normalize-data-types.test.js index fa4267b45645..d3b52cfe726e 100644 --- a/tests/normalize-data-types.test.js +++ b/tests/normalize-data-types.test.js @@ -1,3 +1,4 @@ +import { css, run } from './util/run' import { normalize } from '../src/util/dataTypes' import { crosscheck } from './util/run' @@ -78,3 +79,31 @@ crosscheck(() => { expect(normalize(input)).toBe(output) }) }) + +it('should not automatically inject the `var()` for properties that accept `` as the value', () => { + let config = { + content: [ + // Automatic var injection + { raw: '[color:--foo]' }, + + // Automatic var injection is skipped + { raw: '[timeline-scope:--foo]' }, + ], + } + + let input = css` + @tailwind utilities; + ` + + return run(input, config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .\[color\:--foo\] { + color: var(--foo); + } + + .\[timeline-scope\:--foo\] { + timeline-scope: --foo; + } + `) + }) +})