Fix malformed keyframes when using class variants (#5223)
This commit is contained in:
parent
ca6900dc35
commit
4ff383fbbe
7 changed files with 73 additions and 5 deletions
|
|
@ -11,7 +11,6 @@ export default function () {
|
|||
{
|
||||
[`@keyframes ${prefixName(key)}`]: value,
|
||||
},
|
||||
{ respectVariants: false },
|
||||
],
|
||||
]
|
||||
})
|
||||
|
|
|
|||
3
src/util/isKeyframeRule.js
Normal file
3
src/util/isKeyframeRule.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export default function isKeyframeRule(rule) {
|
||||
return rule.parent && rule.parent.type === 'atrule' && /keyframes$/.test(rule.parent.name)
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import postcss from 'postcss'
|
|||
import createColor from 'color'
|
||||
import escapeCommas from './escapeCommas'
|
||||
import { withAlphaValue } from './withAlphaVariable'
|
||||
import isKeyframeRule from './isKeyframeRule'
|
||||
|
||||
export function applyPseudoToMarker(selector, marker, state, join) {
|
||||
let states = [state]
|
||||
|
|
@ -72,6 +73,9 @@ export function updateLastClasses(selectors, updateClass) {
|
|||
export function transformAllSelectors(transformSelector, { wrap, withRule } = {}) {
|
||||
return ({ container }) => {
|
||||
container.walkRules((rule) => {
|
||||
if (isKeyframeRule(rule)) {
|
||||
return rule
|
||||
}
|
||||
let transformed = rule.selector.split(',').map(transformSelector).join(',')
|
||||
rule.selector = transformed
|
||||
if (withRule) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import wrapWithVariants from '../util/wrapWithVariants'
|
|||
import cloneNodes from '../util/cloneNodes'
|
||||
import transformThemeValue from './transformThemeValue'
|
||||
import nameClass from '../util/nameClass'
|
||||
import isKeyframeRule from '../util/isKeyframeRule'
|
||||
|
||||
function parseStyles(styles) {
|
||||
if (!Array.isArray(styles)) {
|
||||
|
|
@ -28,10 +29,6 @@ function wrapWithLayer(rules, layer) {
|
|||
.append(cloneNodes(Array.isArray(rules) ? rules : [rules]))
|
||||
}
|
||||
|
||||
function isKeyframeRule(rule) {
|
||||
return rule.parent && rule.parent.type === 'atrule' && /keyframes$/.test(rule.parent.name)
|
||||
}
|
||||
|
||||
export default function (plugins, config) {
|
||||
const pluginBaseStyles = []
|
||||
const pluginComponents = []
|
||||
|
|
|
|||
32
tests/jit/animations.test.css
Normal file
32
tests/jit/animations.test.css
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.animate-spin {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes ping {
|
||||
75%,
|
||||
100% {
|
||||
transform: scale(2);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.hover\:animate-ping:hover {
|
||||
animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
|
||||
}
|
||||
@keyframes bounce {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(-25%);
|
||||
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
|
||||
}
|
||||
50% {
|
||||
transform: none;
|
||||
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
}
|
||||
.group:hover .group-hover\:animate-bounce {
|
||||
animation: bounce 1s infinite;
|
||||
}
|
||||
3
tests/jit/animations.test.html
Normal file
3
tests/jit/animations.test.html
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<div class="animate-spin"></div>
|
||||
<div class="hover:animate-ping"></div>
|
||||
<div class="group-hover:animate-bounce"></div>
|
||||
30
tests/jit/animations.test.js
Normal file
30
tests/jit/animations.test.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import postcss from 'postcss'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import tailwind from '../../src/jit/index.js'
|
||||
|
||||
function run(input, config = {}) {
|
||||
return postcss(tailwind(config)).process(input, {
|
||||
from: path.resolve(__filename),
|
||||
})
|
||||
}
|
||||
|
||||
test('animations', () => {
|
||||
let config = {
|
||||
darkMode: 'class',
|
||||
mode: 'jit',
|
||||
purge: [path.resolve(__dirname, './animations.test.html')],
|
||||
corePlugins: {},
|
||||
theme: {},
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
let css = `@tailwind utilities`
|
||||
|
||||
return run(css, config).then((result) => {
|
||||
let expectedPath = path.resolve(__dirname, './animations.test.css')
|
||||
let expected = fs.readFileSync(expectedPath, 'utf8')
|
||||
|
||||
expect(result.css).toMatchFormattedCss(expected)
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue