From c1d0d64f8bc9636d480fb4d7aca03061fbc2d3ee Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Tue, 4 Feb 2025 11:32:12 +0100 Subject: [PATCH 1/4] add failing test --- packages/tailwindcss/src/index.test.ts | 35 ++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 67a0a3d64dab..5cee764b7ce0 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -1170,6 +1170,41 @@ describe('Parsing themes values from CSS', () => { `) }) + test('`@keyframes` in `@theme` are generated when name contains a new line', async () => { + expect( + await compileCss( + css` + @theme { + --animate-very-long-animation-name: very-long-animation-name + var( + --very-long-animation-name-configuration, + 2.5s ease-in-out 0s infinite normal none running + ); + + @keyframes very-long-animation-name { + to { + opacity: 1; + } + } + } + + @tailwind utilities; + `, + ['animate-very-long-animatino-name'], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --animate-very-long-animation-name: very-long-animation-name var(--very-long-animation-name-configuration, 2.5s ease-in-out 0s infinite normal none running); + } + + @keyframes very-long-animation-name { + to { + opacity: 1; + } + }" + `) + }) + test('`@theme` values can be unset', async () => { expect( await compileCss( From 86c83de889e3eaedc5b7984bc3cfb7d4f54c9653 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Tue, 4 Feb 2025 11:32:21 +0100 Subject: [PATCH 2/4] ensure we split on all whitespace --- packages/tailwindcss/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tailwindcss/src/index.ts b/packages/tailwindcss/src/index.ts index 2baed9acf6a5..37c19a3f3edf 100644 --- a/packages/tailwindcss/src/index.ts +++ b/packages/tailwindcss/src/index.ts @@ -545,7 +545,7 @@ async function parseCss( let keyframesRules = theme.getKeyframes() if (keyframesRules.length > 0) { let animationParts = [...theme.namespace('--animate').values()].flatMap((animation) => - animation.split(' '), + animation.split(/\s+/), ) for (let keyframesRule of keyframesRules) { From 77b6359d9db7fc467d8422c1e821ea7359043d72 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Tue, 4 Feb 2025 11:36:11 +0100 Subject: [PATCH 3/4] update changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2686352696a..7ff6cdbb6bc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! - ### Fixed - Ensure that the `containers` JS theme key is added to the `--container-*` namespace. ([#16169](https://github.com/tailwindlabs/tailwindcss/pull/16169)) +- Fix missing `@keyframes` definition ([#16237](https://github.com/tailwindlabs/tailwindcss/pull/16237)) ## [4.0.3] - 2025-02-01 From 929cfaaa2ec1de7e62c6c7e99866408163a583df Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Tue, 4 Feb 2025 12:35:47 +0100 Subject: [PATCH 4/4] fix typo --- packages/tailwindcss/src/index.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 5cee764b7ce0..497ccc034173 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -1190,13 +1190,17 @@ describe('Parsing themes values from CSS', () => { @tailwind utilities; `, - ['animate-very-long-animatino-name'], + ['animate-very-long-animation-name'], ), ).toMatchInlineSnapshot(` ":root, :host { --animate-very-long-animation-name: very-long-animation-name var(--very-long-animation-name-configuration, 2.5s ease-in-out 0s infinite normal none running); } + .animate-very-long-animation-name { + animation: var(--animate-very-long-animation-name); + } + @keyframes very-long-animation-name { to { opacity: 1;