In order to properly migrate your Tailwind CSS v3 project to v4, we need access to the JavaScript configuration object. This was previously only required for template migrations, but in this PR we're making it so that this is also a prerequisite of the CSS migrations. This is because some migrations, like `@apply`, also need to convert candidates that to the v4 syntax and we need the full config in order to properly validate them. In addition to requiring a JS config, we also now attempt to automatically find the right configuration file inside the current working directory. This is now matching the behavior of the Tailwind CSS v3 CLI where it will find the config automatically if it's in the current directory and called `tailwind.conf.js`. --------- Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
50 lines
1.5 KiB
TypeScript
50 lines
1.5 KiB
TypeScript
import type { AtRule, Plugin } from 'postcss'
|
|
import type { Config } from 'tailwindcss'
|
|
import type { DesignSystem } from '../../../tailwindcss/src/design-system'
|
|
import { segment } from '../../../tailwindcss/src/utils/segment'
|
|
import { migrateCandidate } from '../template/migrate'
|
|
|
|
export function migrateAtApply({
|
|
designSystem,
|
|
userConfig,
|
|
}: {
|
|
designSystem: DesignSystem
|
|
userConfig: Config
|
|
}): Plugin {
|
|
function migrate(atRule: AtRule) {
|
|
let utilities = atRule.params.split(/(\s+)/)
|
|
let important =
|
|
utilities[utilities.length - 1] === '!important' ||
|
|
utilities[utilities.length - 1] === '#{!important}' // Sass/SCSS
|
|
|
|
if (important) utilities.pop() // Remove `!important`
|
|
|
|
let params = utilities.map((part) => {
|
|
// Keep whitespace
|
|
if (part.trim() === '') return part
|
|
let variants = segment(part, ':')
|
|
let utility = variants.pop()!
|
|
|
|
// Apply the important modifier to all the rules if necessary
|
|
if (important && utility[0] !== '!' && utility[utility.length - 1] !== '!') {
|
|
utility += '!'
|
|
}
|
|
|
|
// Reconstruct the utility with the variants
|
|
return [...variants, utility].join(':')
|
|
})
|
|
|
|
// If we have a valid designSystem and config setup, we can run all
|
|
// candidate migrations on each utility
|
|
params = params.map((param) => migrateCandidate(designSystem, userConfig, param))
|
|
|
|
atRule.params = params.join('').trim()
|
|
}
|
|
|
|
return {
|
|
postcssPlugin: '@tailwindcss/upgrade/migrate-at-apply',
|
|
OnceExit(root) {
|
|
root.walkAtRules('apply', migrate)
|
|
},
|
|
}
|
|
}
|