Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add substituteAtVariant utility
  • Loading branch information
RobinMalfait committed Sep 4, 2025
commit 19949cc413027de3f5204d68f9e03245f7a3bb1d
30 changes: 30 additions & 0 deletions packages/tailwindcss/src/variants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Features } from '.'
import {
WalkAction,
atRoot,
Expand All @@ -12,6 +13,8 @@ import {
type StyleRule,
} from './ast'
import { type Variant } from './candidate'
import { applyVariant } from './compile'
import type { DesignSystem } from './design-system'
import type { Theme } from './theme'
import { compareBreakpoints } from './utils/compare-breakpoints'
import { DefaultMap } from './utils/default-map'
Expand Down Expand Up @@ -1198,3 +1201,30 @@ export function substituteAtSlot(ast: AstNode[], nodes: AstNode[]) {
}
})
}

export function substituteAtVariant(ast: AstNode[], designSystem: DesignSystem): Features {
let features = Features.None
walk(ast, (variantNode, { replaceWith }) => {
if (variantNode.kind !== 'at-rule' || variantNode.name !== '@variant') return

// Starting with the `&` rule node
let node = styleRule('&', variantNode.nodes)

let variant = variantNode.params

let variantAst = designSystem.parseVariant(variant)
if (variantAst === null) {
throw new Error(`Cannot use \`@variant\` with unknown variant: ${variant}`)
}

let result = applyVariant(node, variantAst, designSystem.variants)
if (result === null) {
throw new Error(`Cannot use \`@variant\` with variant: ${variant}`)
}

// Update the variant at-rule node, to be the `&` rule node
replaceWith(node)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we never mutate the selector of the & node, then we could skip some layers by using:

Suggested change
replaceWith(node)
replaceWith(node.nodes)

But the final result should be the same. This is also the same behavior we had before so I think we can keep it like this.

features |= Features.Variants
})
return features
}