mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Remove dependency on postcss-functions (#4317)
* Write postcss-functions ourselves * Add test for nested theme calls * Remove unused import
This commit is contained in:
parent
522787ac41
commit
5ebe5e8309
@ -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",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import _ from 'lodash'
|
||||
import functions from 'postcss-functions'
|
||||
import didYouMean from 'didyoumean'
|
||||
import transformThemeValue from '../util/transformThemeValue'
|
||||
import parseValue from 'postcss-value-parser'
|
||||
|
||||
function findClosestExistingPath(theme, path) {
|
||||
const parts = _.toPath(path)
|
||||
@ -109,23 +109,70 @@ function validatePath(config, path, defaultValue) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function (config) {
|
||||
return (root) =>
|
||||
functions({
|
||||
functions: {
|
||||
theme: (path, ...defaultValue) => {
|
||||
const { isValid, value, error } = validatePath(
|
||||
config,
|
||||
path,
|
||||
defaultValue.length ? defaultValue : undefined
|
||||
)
|
||||
function extractArgs(node, vNodes, functions) {
|
||||
vNodes = vNodes.map((vNode) => resolveVNode(node, vNode, functions))
|
||||
|
||||
if (!isValid) {
|
||||
throw root.error(error)
|
||||
}
|
||||
let args = ['']
|
||||
|
||||
return value
|
||||
},
|
||||
},
|
||||
})(root)
|
||||
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) {
|
||||
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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"); }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user