Skip to content

Commit 4ff383f

Browse files
authored
Fix malformed keyframes when using class variants (#5223)
1 parent ca6900d commit 4ff383f

7 files changed

+73
-5
lines changed

src/plugins/animation.js

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export default function () {
1111
{
1212
[`@keyframes ${prefixName(key)}`]: value,
1313
},
14-
{ respectVariants: false },
1514
],
1615
]
1716
})

src/util/isKeyframeRule.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function isKeyframeRule(rule) {
2+
return rule.parent && rule.parent.type === 'atrule' && /keyframes$/.test(rule.parent.name)
3+
}

src/util/pluginUtils.js

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import postcss from 'postcss'
33
import createColor from 'color'
44
import escapeCommas from './escapeCommas'
55
import { withAlphaValue } from './withAlphaVariable'
6+
import isKeyframeRule from './isKeyframeRule'
67

78
export function applyPseudoToMarker(selector, marker, state, join) {
89
let states = [state]
@@ -72,6 +73,9 @@ export function updateLastClasses(selectors, updateClass) {
7273
export function transformAllSelectors(transformSelector, { wrap, withRule } = {}) {
7374
return ({ container }) => {
7475
container.walkRules((rule) => {
76+
if (isKeyframeRule(rule)) {
77+
return rule
78+
}
7579
let transformed = rule.selector.split(',').map(transformSelector).join(',')
7680
rule.selector = transformed
7781
if (withRule) {

src/util/processPlugins.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import wrapWithVariants from '../util/wrapWithVariants'
1010
import cloneNodes from '../util/cloneNodes'
1111
import transformThemeValue from './transformThemeValue'
1212
import nameClass from '../util/nameClass'
13+
import isKeyframeRule from '../util/isKeyframeRule'
1314

1415
function parseStyles(styles) {
1516
if (!Array.isArray(styles)) {
@@ -28,10 +29,6 @@ function wrapWithLayer(rules, layer) {
2829
.append(cloneNodes(Array.isArray(rules) ? rules : [rules]))
2930
}
3031

31-
function isKeyframeRule(rule) {
32-
return rule.parent && rule.parent.type === 'atrule' && /keyframes$/.test(rule.parent.name)
33-
}
34-
3532
export default function (plugins, config) {
3633
const pluginBaseStyles = []
3734
const pluginComponents = []

tests/jit/animations.test.css

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@keyframes spin {
2+
to {
3+
transform: rotate(360deg);
4+
}
5+
}
6+
.animate-spin {
7+
animation: spin 1s linear infinite;
8+
}
9+
@keyframes ping {
10+
75%,
11+
100% {
12+
transform: scale(2);
13+
opacity: 0;
14+
}
15+
}
16+
.hover\:animate-ping:hover {
17+
animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
18+
}
19+
@keyframes bounce {
20+
0%,
21+
100% {
22+
transform: translateY(-25%);
23+
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
24+
}
25+
50% {
26+
transform: none;
27+
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
28+
}
29+
}
30+
.group:hover .group-hover\:animate-bounce {
31+
animation: bounce 1s infinite;
32+
}

tests/jit/animations.test.html

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="animate-spin"></div>
2+
<div class="hover:animate-ping"></div>
3+
<div class="group-hover:animate-bounce"></div>

tests/jit/animations.test.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import postcss from 'postcss'
2+
import fs from 'fs'
3+
import path from 'path'
4+
import tailwind from '../../src/jit/index.js'
5+
6+
function run(input, config = {}) {
7+
return postcss(tailwind(config)).process(input, {
8+
from: path.resolve(__filename),
9+
})
10+
}
11+
12+
test('animations', () => {
13+
let config = {
14+
darkMode: 'class',
15+
mode: 'jit',
16+
purge: [path.resolve(__dirname, './animations.test.html')],
17+
corePlugins: {},
18+
theme: {},
19+
plugins: [],
20+
}
21+
22+
let css = `@tailwind utilities`
23+
24+
return run(css, config).then((result) => {
25+
let expectedPath = path.resolve(__dirname, './animations.test.css')
26+
let expected = fs.readFileSync(expectedPath, 'utf8')
27+
28+
expect(result.css).toMatchFormattedCss(expected)
29+
})
30+
})

0 commit comments

Comments
 (0)