From 0e262a13e6e88245a2bb55d892a7f3d2360d7036 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 16 Oct 2024 13:55:14 +0200 Subject: [PATCH] `@apply` is not allowed inside `@keyframes` (#14687) This PR makes sure that you cannot use `@apply` inside `@keyframes`. While some utilities can be used in `@keyframes`, the moment you introduce a variant, that's not going to work anymore because they need to operate on selectors which `@keyframes` don't have. This PR now removes all usages of `@apply` in `@keyframes`. --- packages/tailwindcss/src/apply.ts | 17 ++++++++++++++++- packages/tailwindcss/src/index.test.ts | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/tailwindcss/src/apply.ts b/packages/tailwindcss/src/apply.ts index 0cbdf4940..66a97ab40 100644 --- a/packages/tailwindcss/src/apply.ts +++ b/packages/tailwindcss/src/apply.ts @@ -1,4 +1,4 @@ -import { walk, type AstNode } from './ast' +import { walk, WalkAction, type AstNode } from './ast' import { compileCandidates } from './compile' import type { DesignSystem } from './design-system' import { escape } from './utils/escape' @@ -6,6 +6,21 @@ import { escape } from './utils/escape' export function substituteAtApply(ast: AstNode[], designSystem: DesignSystem) { walk(ast, (node, { replaceWith }) => { if (node.kind !== 'rule') return + + // Do not allow `@apply` rules inside `@keyframes` rules. + if (node.selector[0] === '@' && node.selector.startsWith('@keyframes')) { + walk(node.nodes, (child) => { + if ( + child.kind === 'rule' && + child.selector[0] === '@' && + child.selector.startsWith('@apply ') + ) { + throw new Error(`You cannot use \`@apply\` inside \`@keyframes\`.`) + } + }) + return WalkAction.Skip + } + if (!(node.selector[0] === '@' && node.selector.startsWith('@apply '))) return let candidates = node.selector diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 3eee033dd..04c0c7c4d 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -148,6 +148,20 @@ describe('arbitrary properties', () => { }) describe('@apply', () => { + it('@apply in @keyframes is not allowed', () => { + return expect(() => + compileCss(css` + @keyframes foo { + 0% { + @apply bg-red-500; + } + } + `), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: You cannot use \`@apply\` inside \`@keyframes\`.]`, + ) + }) + it('should replace @apply with the correct result', async () => { expect( await compileCss(css`