diff --git a/CHANGELOG.md b/CHANGELOG.md index f2d3edc502ff..fdad0f12d678 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! +### Fixed + +- Fix usage on Node 12.x ([b4e637e](https://github.com/tailwindlabs/tailwindcss/commit/b4e637e2e096a9d6f2210efba9541f6fd4f28e56)) +- Handle theme keys with slashes when using `theme()` in CSS ([#8831](https://github.com/tailwindlabs/tailwindcss/pull/8831)) ## [3.1.5] - 2022-07-07 @@ -15,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support configuring a default `font-weight` for each font size utility ([#8763](https://github.com/tailwindlabs/tailwindcss/pull/8763)) - Add support for alpha values in safe list ([#8774](https://github.com/tailwindlabs/tailwindcss/pull/8774)) - + ### Fixed - Improve types to support fallback values in the CSS-in-JS syntax used in plugin APIs ([#8762](https://github.com/tailwindlabs/tailwindcss/pull/8762)) diff --git a/src/lib/evaluateTailwindFunctions.js b/src/lib/evaluateTailwindFunctions.js index 4fcfa83d9f47..327581493bb2 100644 --- a/src/lib/evaluateTailwindFunctions.js +++ b/src/lib/evaluateTailwindFunctions.js @@ -157,26 +157,52 @@ let nodeTypePropertyMap = { decl: 'value', } -export default function ({ tailwindConfig: config }) { - let functions = { - theme: (node, path, ...defaultValue) => { - // Strip quotes from beginning and end of string - // This allows the alpha value to be present inside of quotes - path = path.replace(/^['"]+|['"]+$/g, '') +/** + * @param {string} path + * @returns {Iterable<[path: string, alpha: string|undefined]>} + */ +function* toPaths(path) { + // Strip quotes from beginning and end of string + // This allows the alpha value to be present inside of quotes + path = path.replace(/^['"]+|['"]+$/g, '') - let matches = path.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/) - let alpha = undefined + let matches = path.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/) + let alpha = undefined - if (matches) { - path = matches[1] - alpha = matches[2] - } + yield [path, undefined] + + if (matches) { + path = matches[1] + alpha = matches[2] + + yield [path, alpha] + } +} - let { isValid, value, error } = validatePath( +/** + * + * @param {any} config + * @param {string} path + * @param {any} defaultValue + */ +function resolvePath(config, path, defaultValue) { + const results = Array.from(toPaths(path)).map(([path, alpha]) => { + return Object.assign(validatePath(config, path, defaultValue, { opacityValue: alpha }), { + resolvedPath: path, + alpha, + }) + }) + + return results.find((result) => result.isValid) ?? results[0] +} + +export default function ({ tailwindConfig: config }) { + let functions = { + theme: (node, path, ...defaultValue) => { + let { isValid, value, error, alpha } = resolvePath( config, path, - defaultValue.length ? defaultValue : undefined, - { opacityValue: alpha } + defaultValue.length ? defaultValue : undefined ) if (!isValid) { diff --git a/tests/evaluateTailwindFunctions.test.js b/tests/evaluateTailwindFunctions.test.js index b5e97a396a72..b7e630a20bdf 100644 --- a/tests/evaluateTailwindFunctions.test.js +++ b/tests/evaluateTailwindFunctions.test.js @@ -1135,3 +1135,51 @@ test('Theme functions with alpha with quotes value around color only', () => { expect(result.warnings().length).toBe(0) }) }) + +it('can find values with slashes in the theme key while still allowing for alpha values ', () => { + let input = css` + .foo00 { + color: theme(colors.foo-5); + } + .foo01 { + color: theme(colors.foo-5/10); + } + .foo02 { + color: theme(colors.foo-5/10/25); + } + .foo03 { + color: theme(colors.foo-5 / 10); + } + .foo04 { + color: theme(colors.foo-5/10 / 25); + } + ` + + return runFull(input, { + theme: { + colors: { + 'foo-5': '#050000', + 'foo-5/10': '#051000', + 'foo-5/10/25': '#051025', + }, + }, + }).then((result) => { + expect(result.css).toMatchCss(css` + .foo00 { + color: #050000; + } + .foo01 { + color: #051000; + } + .foo02 { + color: #051025; + } + .foo03 { + color: rgb(5 0 0 / 10); + } + .foo04 { + color: rgb(5 16 0 / 25); + } + `) + }) +})