diff --git a/CHANGELOG.md b/CHANGELOG.md index ae28119ce22e..981553e8083a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improve types for `resolveConfig` ([#12272](https://github.com/tailwindlabs/tailwindcss/pull/12272)) - Ensure configured `font-feature-settings` for `mono` are included in Preflight ([#12342](https://github.com/tailwindlabs/tailwindcss/pull/12342)) - Don't crash when given applying a variant to a negated version of a simple utility ([#12514](https://github.com/tailwindlabs/tailwindcss/pull/12514)) +- Fix support for slashes in arbitrary modifiers ([#12515](https://github.com/tailwindlabs/tailwindcss/pull/12515)) ## [3.3.5] - 2023-10-25 diff --git a/src/util/pluginUtils.js b/src/util/pluginUtils.js index bef9fc1658e7..256d891a2150 100644 --- a/src/util/pluginUtils.js +++ b/src/util/pluginUtils.js @@ -88,6 +88,22 @@ function isArbitraryValue(input) { function splitUtilityModifier(modifier) { let slashIdx = modifier.lastIndexOf('/') + // If the `/` is inside an arbitrary, we want to find the previous one if any + // This logic probably isn't perfect but it should work for most cases + let arbitraryStartIdx = modifier.lastIndexOf('[', slashIdx) + let arbitraryEndIdx = modifier.indexOf(']', slashIdx) + + let isNextToArbitrary = modifier[slashIdx - 1] === ']' || modifier[slashIdx + 1] === '[' + + // Backtrack to the previous `/` if the one we found was inside an arbitrary + if (!isNextToArbitrary) { + if (arbitraryStartIdx !== -1 && arbitraryEndIdx !== -1) { + if (arbitraryStartIdx < slashIdx && slashIdx < arbitraryEndIdx) { + slashIdx = modifier.lastIndexOf('/', arbitraryStartIdx) + } + } + } + if (slashIdx === -1 || slashIdx === modifier.length - 1) { return [modifier, undefined] } diff --git a/tests/arbitrary-values.test.js b/tests/arbitrary-values.test.js index ff7abcd84fdc..b9400ef55f6f 100644 --- a/tests/arbitrary-values.test.js +++ b/tests/arbitrary-values.test.js @@ -654,6 +654,21 @@ crosscheck(({ stable, oxide }) => { }) }) +it('should support slashes in arbitrary modifiers', () => { + let config = { + content: [{ raw: html`
` }], + } + + return run('@tailwind utilities', config).then((result) => { + return expect(result.css).toMatchFormattedCss(css` + .text-lg\/\[calc\(50px\/1rem\)\] { + font-size: 1.125rem; + line-height: calc(50px / 1rem); + } + `) + }) +}) + it('should not insert spaces around operators inside `env()`', () => { let config = { content: [{ raw: html`
` }],