[ @sdxc/u/animation ]
keyframes
Emits an @keyframes rule under name at the top level, where the serializer reads stop keys (from, to, 50%) as stop selectors.
import { keyframes } from "@sdxc/u/animation";Examples
Basic example
Use keyframes(name, frames) to declare a @keyframes rule with from and to stops, and run it by name with animationHost():
fade
<div mix={[...]}>
<div
mix={[
keyframes("fade", { from: { opacity: 1 }, to: { opacity: 0.2 } }),
animationHost("fade", {
duration: "1s",
iterationCount: "infinite",
direction: "alternate",
}),
...,
]}
>
fade
</div>
</div>Using percentage stops
Key the frames by percentage, like "50%", to place stops anywhere on the timeline; a stop may set its own easing:
bounce
<div mix={[...]}>
<div
mix={[
keyframes("bounce", {
"0%, 100%": {
translate: "0 -25%",
animationTimingFunction: "cubic-bezier(0.8, 0, 1, 1)",
},
"50%": { translate: "0 0", animationTimingFunction: "cubic-bezier(0, 0, 0.2, 1)" },
}),
animationHost("bounce", { duration: "1s", iterationCount: "infinite" }),
...,
]}
>
bounce
</div>
</div>Animating several properties
A stop can set several properties, like scale and opacity together for a ping:
ping
<div mix={[...]}>
<div mix={[relative(), ...]}>
<span
mix={[
keyframes("ping", { "75%, 100%": { scale: "2", opacity: 0 } }),
animationHost("ping", {
duration: "1s",
easing: "cubic-bezier(0, 0, 0.2, 1)",
iterationCount: "infinite",
}),
absolute(),
inset(0),
...,
]}
/>
ping
</div>
</div><div
mix={[
u.keyframes("fade-in", {
from: { opacity: 0 },
to: { opacity: 1 },
}),
css({
animationName: "fade-in",
animationDuration: "150ms",
}),
]}
/>// Equivalent at the top level of a `css()` call.
css({ "@keyframes fade-in": { from: { opacity: 0 }, to: { opacity: 1 } } })Applying on a state
Wrap the call in a state utility to scope it to one selector.
u.hover(<div
mix={[
u.keyframes("fade-in", {
from: { opacity: 0 },
to: { opacity: 1 },
}),
css({
animationName: "fade-in",
animationDuration: "150ms",
}),
]}
/>)Responsive design
Wrap the call in a container query to scope it to one width.
u.at("md", <div
mix={[
u.keyframes("fade-in", {
from: { opacity: 0 },
to: { opacity: 1 },
}),
css({
animationName: "fade-in",
animationDuration: "150ms",
}),
]}
/>)Signature
u.keyframes(name: string, frames: Record<string, CSSStyles>)