diff --git a/CHANGELOG.md b/CHANGELOG.md index 90d5b4b3301d..00562767e4e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Types: allow for arbitrary theme values (for 3rd party plugins) ([#7926](https://github.com/tailwindlabs/tailwindcss/pull/7926)) +- Don’t split vars with numbers in them inside arbitrary values ([#8091](https://github.com/tailwindlabs/tailwindcss/pull/8091)) ### Added diff --git a/src/util/dataTypes.js b/src/util/dataTypes.js index a9a1c7b584e8..61b4ed732695 100644 --- a/src/util/dataTypes.js +++ b/src/util/dataTypes.js @@ -42,10 +42,16 @@ export function normalize(value, isRoot = true) { // Add spaces around operators inside calc() that do not follow an operator // or '('. - return value.replace( - /(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, - '$1 $2 ' - ) + value = value.replace(/calc\(.+\)/g, (match) => { + return match.replace( + /(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, + '$1 $2 ' + ) + }) + + // Add spaces around some operators not inside calc() that do not follow an operator + // or '('. + return value.replace(/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([\/])/g, '$1 $2 ') } export function url(value) { diff --git a/tests/normalize-data-types.test.js b/tests/normalize-data-types.test.js new file mode 100644 index 000000000000..d223f92eebe8 --- /dev/null +++ b/tests/normalize-data-types.test.js @@ -0,0 +1,42 @@ +import { normalize } from '../src/util/dataTypes' + +let table = [ + ['foo', 'foo'], + ['foo-bar', 'foo-bar'], + ['16/9', '16 / 9'], + + // '_'s are converted to spaces except when escaped + ['foo_bar', 'foo bar'], + ['foo__bar', 'foo bar'], + ['foo\\_bar', 'foo_bar'], + + // Urls are preserved as-is + [ + 'url("https://example.com/abc+def/some-path/2022-01-01-abc/some_underscoered_path")', + 'url("https://example.com/abc+def/some-path/2022-01-01-abc/some_underscoered_path")', + ], + + // var(…) is preserved as is + ['var(--foo)', 'var(--foo)'], + ['var(--headings-h1-size)', 'var(--headings-h1-size)'], + + // calc(…) get's spaces around operators + ['calc(1+2)', 'calc(1 + 2)'], + ['calc(100%+1rem)', 'calc(100% + 1rem)'], + ['calc(1+calc(100%-20px))', 'calc(1 + calc(100% - 20px))'], + ['calc(var(--headings-h1-size)*100)', 'calc(var(--headings-h1-size) * 100)'], + [ + 'calc(var(--headings-h1-size)*calc(100%+50%))', + 'calc(var(--headings-h1-size) * calc(100% + 50%))', + ], + ['var(--heading-h1-font-size)', 'var(--heading-h1-font-size)'], + ['var(--my-var-with-more-than-3-words)', 'var(--my-var-with-more-than-3-words)'], + ['var(--width, calc(100%+1rem))', 'var(--width, calc(100% + 1rem))'], + + // Misc + ['color(0_0_0/1.0)', 'color(0 0 0 / 1.0)'], +] + +it.each(table)('normalize data: %s', (input, output) => { + expect(normalize(input)).toBe(output) +})