From 4f80b986824be4a699f2501b8fcfe9e5c9b3d769 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Tue, 11 May 2021 12:56:38 -0400 Subject: [PATCH 1/3] Write postcss-functions ourselves --- package.json | 1 - src/lib/evaluateTailwindFunctions.js | 86 ++++++++++++++++++++++------ 2 files changed, 67 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 3be760450ba1..771ab3b89230 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,6 @@ "normalize-path": "^3.0.0", "object-hash": "^2.1.1", "parse-glob": "^3.0.4", - "postcss-functions": "^3", "postcss-js": "^3.0.3", "postcss-nested": "5.0.5", "postcss-selector-parser": "^6.0.5", diff --git a/src/lib/evaluateTailwindFunctions.js b/src/lib/evaluateTailwindFunctions.js index 033ceca379d2..a5998accce52 100644 --- a/src/lib/evaluateTailwindFunctions.js +++ b/src/lib/evaluateTailwindFunctions.js @@ -1,7 +1,8 @@ import _ from 'lodash' -import functions from 'postcss-functions' import didYouMean from 'didyoumean' import transformThemeValue from '../util/transformThemeValue' +import buildMediaQuery from '../util/buildMediaQuery' +import parseValue from 'postcss-value-parser' function findClosestExistingPath(theme, path) { const parts = _.toPath(path) @@ -109,23 +110,70 @@ function validatePath(config, path, defaultValue) { } } +function extractArgs(node, vNodes, functions) { + vNodes = vNodes.map((vNode) => resolveVNode(node, vNode, functions)) + + let args = [''] + + for (let vNode of vNodes) { + if (vNode.type === 'div' && vNode.value === ',') { + args.push('') + } else { + args[args.length - 1] += parseValue.stringify(vNode) + } + } + + return args +} + +function resolveVNode(node, vNode, functions) { + if (vNode.type === 'function' && functions[vNode.value] !== undefined) { + let args = extractArgs(node, vNode.nodes, functions) + vNode.type = 'word' + vNode.value = functions[vNode.value](node, ...args) + } + + return vNode +} + +function resolveFunctions(node, input, functions) { + return parseValue(input) + .walk((vNode) => { + resolveVNode(node, vNode, functions) + }) + .toString() +} + +let nodeTypePropertyMap = { + atrule: 'params', + decl: 'value', +} + export default function (config) { - return (root) => - functions({ - functions: { - theme: (path, ...defaultValue) => { - const { isValid, value, error } = validatePath( - config, - path, - defaultValue.length ? defaultValue : undefined - ) - - if (!isValid) { - throw root.error(error) - } - - return value - }, - }, - })(root) + let functions = { + theme: (node, path, ...defaultValue) => { + const { isValid, value, error } = validatePath( + config, + path, + defaultValue.length ? defaultValue : undefined + ) + + if (!isValid) { + throw node.error(error) + } + + return value + }, + } + return (root) => { + root.walk((node) => { + let property = nodeTypePropertyMap[node.type] + + if (property === undefined) { + return + } + + node[property] = resolveFunctions(node, node[property], functions) + }) + } } From 032cfb45278ba8570a342c4945378412709fa4a8 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Tue, 11 May 2021 13:35:42 -0400 Subject: [PATCH 2/3] Add test for nested theme calls --- tests/themeFunction.test.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/themeFunction.test.js b/tests/themeFunction.test.js index f2027ae8e26b..ae4eea4619be 100644 --- a/tests/themeFunction.test.js +++ b/tests/themeFunction.test.js @@ -68,6 +68,27 @@ test('a default value can be provided', () => { }) }) +test('the default value can use the theme function', () => { + const input = ` + .cookieMonster { color: theme('colors.blue', theme('colors.yellow')); } + ` + + const output = ` + .cookieMonster { color: #f7cc50; } + ` + + return run(input, { + theme: { + colors: { + yellow: '#f7cc50', + }, + }, + }).then((result) => { + expect(result.css).toEqual(output) + expect(result.warnings().length).toBe(0) + }) +}) + test('quotes are preserved around default values', () => { const input = ` .heading { font-family: theme('fontFamily.sans', "Helvetica Neue"); } From 94cca197f9a7881fa8be4a9ae49ebeb836f4059c Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Tue, 11 May 2021 13:54:37 -0400 Subject: [PATCH 3/3] Remove unused import --- src/lib/evaluateTailwindFunctions.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/evaluateTailwindFunctions.js b/src/lib/evaluateTailwindFunctions.js index a5998accce52..dc991b38bf33 100644 --- a/src/lib/evaluateTailwindFunctions.js +++ b/src/lib/evaluateTailwindFunctions.js @@ -1,7 +1,6 @@ import _ from 'lodash' import didYouMean from 'didyoumean' import transformThemeValue from '../util/transformThemeValue' -import buildMediaQuery from '../util/buildMediaQuery' import parseValue from 'postcss-value-parser' function findClosestExistingPath(theme, path) {