I'm trying to pass props to keyframe
element & do some conditional animation. Here's my code:
import styled, { keyframes } from "styled-components";
import {
PRIMARY,
SECONDARY,
DANGER,
TEXT,
OUTLINE,
} from "../../constans";
interface PropTypes {
color?: string;
variant?: string;
size?: string;
shadow?: boolean;
disabled?: boolean;
hoverAnimation?: boolean;
}
const StyledButton = styled.button<PropTypes>`
// [... SOME CODE ...]
animation: ${(props) => hoverAnimate(props)} 2s infinite;
`;
const hoverAnimate = (props: PropTypes) => keyframes`
100%{
color: ${() => {
console.log(props);
if (props.variant) {
if (props.color) {
return `var(--color-${props.color})`;
}
return "#444";
}
return "#fff";
}};
background: ${() => {
if (props.variant === TEXT || props.variant === OUTLINE)
return "#f00";
console.log("object");
if (props.color === PRIMARY) return "var(--color-primary)";
if (props.color === SECONDARY) return "var(--color-secondary)";
if (props.color === DANGER) return "var(--color-danger)";
return "var(--color-default)";
}};
}
`;
What am I doing wrong?
TS complains:
Argument of type '() => string' is not assignable to parameter of type 'SimpleInterpolation'. Type '() => string' is missing the following properties from type 'readonly SimpleInterpolation[]': concat, join, slice, indexOf, and 17 more.
And, console.log(props)
prints:
object
It's like a string. I can't expand this object
in dev tools (even if try destructure).
It appears like you are trying to use an IIFE (immediately invoked function expression) to return a "string" that would be used inside template strings.
But you are getting TypeScript error:
Argument of type '() => string' is not assignable to parameter of type 'SimpleInterpolation'.
because your current code:
const hoverAnimate = (props: PropTypes) => keyframes`
100%{
color: ${() => {
if (props.variant) {
if (props.color) {
return `var(--color-${props.color})`;
}
return "#444";
}
return "#fff";
}};
...
doesn't properly call the IIFE.
Here is how to fix it by calling (note the additional ()
s) the IIFE:
const hoverAnimate = (props: PropTypes) => keyframes`
100%{
color: ${(() => { // Here, at start
if (props.variant) {
if (props.color) {
return `var(--color-${props.color})`;
}
return "#444";
}
return "#fff";
})()}; // And, here
...
You need to do the same for background
as well.