Skip to content

Commit e8715d0

Browse files
Extract keyframe name when followed by comma (#17352)
Fixes #17332 This PR ensures that keyframes are emitted even when they are referenced following a comma, e.g.: ```css @theme { --animate-test: 500ms both fade-in, 1000ms linear 500ms spin infinite; /* ^ */ @Keyframes fade-in { from { opacity: 0%; } to { opacity: 100%; } } } ``` ## Test plan Added a unit test to capture the issue from #17332
1 parent baa016a commit e8715d0

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2525
### Fixed
2626

2727
- Fix class extraction followed by `(` in Pug ([#17320](https://github.com/tailwindlabs/tailwindcss/pull/17320))
28+
- Ensure `@keyframes` for theme animations are emitted if they are referenced following a comma
2829
- Vite: Ensure that updates to an imported CSS file are properly propagated after updating templates ([#17347](https://github.com/tailwindlabs/tailwindcss/pull/17347))
2930
- Pre process `Slim` templates embedded in Ruby files ([#17336](https://github.com/tailwindlabs/tailwindcss/pull/17336))
3031
- Error when input and output files resolve to the same file when using the CLI ([#17311](https://github.com/tailwindlabs/tailwindcss/pull/17311))

Diff for: packages/tailwindcss/src/ast.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ export function optimizeAst(ast: AstNode[], designSystem: DesignSystem) {
310310

311311
// Track used animation names
312312
if (node.property === 'animation') {
313-
let parts = node.value.split(/\s+/)
314-
for (let part of parts) usedKeyframeNames.add(part)
313+
for (let keyframeName of extractKeyframeNames(node.value))
314+
usedKeyframeNames.add(keyframeName)
315315
}
316316

317317
parent.push(node)
@@ -438,8 +438,8 @@ export function optimizeAst(ast: AstNode[], designSystem: DesignSystem) {
438438
)
439439
if (variableUsed) {
440440
if (declaration.property.startsWith(designSystem.theme.prefixKey('--animate-'))) {
441-
let parts = declaration.value!.split(/\s+/)
442-
for (let part of parts) usedKeyframeNames.add(part)
441+
for (let keyframeName of extractKeyframeNames(declaration.value!))
442+
usedKeyframeNames.add(keyframeName)
443443
}
444444

445445
continue
@@ -605,3 +605,7 @@ function isVariableUsed(
605605

606606
return false
607607
}
608+
609+
function extractKeyframeNames(value: string): string[] {
610+
return value.split(/[\s,]+/)
611+
}

Diff for: packages/tailwindcss/src/index.test.ts

+43
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,49 @@ describe('Parsing theme values from CSS', () => {
19391939
`)
19401940
})
19411941

1942+
// https://github.com/tailwindlabs/tailwindcss/issues/17332
1943+
test('extracts keyframe names followed by comma', async () => {
1944+
expect(
1945+
await compileCss(
1946+
css`
1947+
@theme {
1948+
--animate-test: 500ms both fade-in, 1000ms linear 500ms spin infinite;
1949+
1950+
@keyframes fade-in {
1951+
from {
1952+
opacity: 0%;
1953+
}
1954+
to {
1955+
opacity: 100%;
1956+
}
1957+
}
1958+
}
1959+
1960+
@tailwind utilities;
1961+
`,
1962+
['animate-test'],
1963+
),
1964+
).toMatchInlineSnapshot(`
1965+
":root, :host {
1966+
--animate-test: .5s both fade-in, 1s linear .5s spin infinite;
1967+
}
1968+
1969+
.animate-test {
1970+
animation: var(--animate-test);
1971+
}
1972+
1973+
@keyframes fade-in {
1974+
from {
1975+
opacity: 0;
1976+
}
1977+
1978+
to {
1979+
opacity: 1;
1980+
}
1981+
}"
1982+
`)
1983+
})
1984+
19421985
test('keyframes outside of `@theme are always preserved', async () => {
19431986
expect(
19441987
await compileCss(

0 commit comments

Comments
 (0)