From f8d7623ea515a00002731992aa623f8bb31616e0 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Fri, 21 Feb 2025 04:55:30 -0500 Subject: [PATCH] Preserve custom properties in keyframes (#16376) Closes #16374 Ensure we don't remove custom properties from within `@keyframe` declarations. --------- Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com> Co-authored-by: Jordan Pittman Co-authored-by: Philipp Spiess --- packages/tailwindcss/src/ast.ts | 8 +++++- packages/tailwindcss/src/index.test.ts | 38 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/tailwindcss/src/ast.ts b/packages/tailwindcss/src/ast.ts index 36194d9f41fc..5a23f4e48fb2 100644 --- a/packages/tailwindcss/src/ast.ts +++ b/packages/tailwindcss/src/ast.ts @@ -286,7 +286,9 @@ export function optimizeAst( // Track variables defined in `@theme` if (context.theme && node.property[0] === '-' && node.property[1] === '-') { - cssThemeVariables.get(parent).add(node) + if (!context.keyframes) { + cssThemeVariables.get(parent).add(node) + } } // Track used CSS variables @@ -354,6 +356,10 @@ export function optimizeAst( // AtRule else if (node.kind === 'at-rule') { + if (node.name === '@keyframes') { + context = { ...context, keyframes: true } + } + let copy = { ...node, nodes: [] } for (let child of node.nodes) { transform(child, copy.nodes, context, depth + 1) diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 67b6c3c53770..d5b71c6b6a5c 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -1613,6 +1613,44 @@ describe('Parsing theme values from CSS', () => { `) }) + // https://github.com/tailwindlabs/tailwindcss/issues/16374 + test('custom properties in keyframes preserved', async () => { + expect( + await compileCss( + css` + @theme { + --animate-foo: used 1s infinite; + + @keyframes used { + to { + --other: var(--angle); + --angle: 360deg; + } + } + } + + @tailwind utilities; + `, + ['animate-foo'], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --animate-foo: used 1s infinite; + } + + .animate-foo { + animation: var(--animate-foo); + } + + @keyframes used { + to { + --other: var(--angle); + --angle: 360deg; + } + }" + `) + }) + test('keyframes are generated when used in an animation using `@theme inline`', async () => { expect( await compileCss(