Context: I want to animate two different components using the same css styles. Animations depend on some props being passed to the AnimatedBox component, then for example, if only props.right is true, then animate only the right border. I thought a css function would do the job, so for not repeating the code, I only create the element and call the function. However, I'm getting the following error, no matter what I do, and the components don't behave as expected:
Functions that are interpolated in css calls will be stringified.
Here is a bit of my code (it's truncated).
const AnimatedBox = props => (
<>
{props.absolute
?
<MaskWrapper>
<BeforeMask {...props}/>
<AfterMask {...props}/>
</MaskWrapper>
:
<AnimatedDiv {...props}></AnimatedDiv>}
</>
)
export default AnimatedBox
const commonConfig = css`
box-sizing: inherit;
position: absolute;
content: '';
border: 1px solid transparent;
border-radius: 3px;
`
const beforeConfig = css`
top: 0;
left: 0;
border-top-color: ${({top}) => `${top && "#60d75a"}`};
border-right-color: ${({right}) => `${right && "#60d75a"}`};
animation: ${expandWidth} 0.25s ease-out forwards,
${expandHeight} 0.25s ease-out 0.25s forwards;
`
const afterConfig = css`
right: 0;
bottom: 0;
animation: ${({bottom, left}) => `${
(bottom && left)
?
`
${bottomBorderColor} 0s ease-out 0.5s forwards,
${leftBorderColor} 0s ease-out 0.5s forwards,
${expandWidth} 0.25s ease-out 0.5s forwards,
${expandHeight} 0.25s ease-out 0.75s forwards;
`
: (
bottom
?
`
${bottomBorderColor} 0s ease-out 0.5s forwards,
${expandWidth} 0.25s ease-out 0.5s forwards,
${expandHeight} 0.25s ease-out 0.75s forwards;
`
: (
left
&&
`
${leftBorderColor} 0s ease-out 0.5s forwards,
${expandWidth} 0.25s ease-out 0.5s forwards,
${expandHeight} 0.25s ease-out 0.75s forwards;
`
)
)
}`
};
`
const BeforeMask = styled.div`
${beforeConfig}
`
(...)
expandWidth, expandHeight, bottomBorderColor, etc, are all keyframe animations. I just need to know how to write those functions and pass them to the styled component I want without getting that error.
SOLVED
As @jsejcksn suggested, I had to put the styled divs into the component's scope. Then I made the css functions explicitly take parameters and make some syntactical changes, and then pass the required props to them.
const AnimatedBox = props => {
(...)
const BeforeMask = styled.div`
${beforeConfig(props.top, props.right)}
`
(...)
return (
<>
{props.absolute
?
<MaskWrapper>
<BeforeMask {...props}/>
<AfterMask {...props}/>
</MaskWrapper>
:
<AnimatedDiv {...props}></AnimatedDiv>}
</>
)}
const beforeConfig = (top, right) => css`
top: 0;
left: 0;
border-top-color: ${top && "#60d75a"};
border-right-color: ${right && "#60d75a"};
animation: ${expandWidth} 0.25s ease-out forwards,
${expandHeight} 0.25s ease-out 0.25s forwards;
`
const afterConfig = (bottom, left) => css`
right: 0;
bottom: 0;
animation: ${
(bottom && left)
?
css`
${bottomBorderColor} 0s ease-out 0.5s forwards,
${leftBorderColor} 0s ease-out 0.5s forwards,
${expandWidth} 0.25s ease-out 0.5s forwards,
${expandHeight} 0.25s ease-out 0.75s forwards;
`
:
(
bottom
?
css`
${bottomBorderColor} 0s ease-out 0.5s forwards,
${expandWidth} 0.25s ease-out 0.5s forwards,
${expandHeight} 0.25s ease-out 0.75s forwards;
`
:
(
left
&&
css`
${leftBorderColor} 0s ease-out 0.5s forwards,
${expandWidth} 0.25s ease-out 0.5s forwards,
${expandHeight} 0.25s ease-out 0.75s forwards;
`
)
)
}
`