2 votes

Comment échapper correctement les fonctions css pour les composants stylisés ?

Contexte : Je souhaite animer deux composants différents en utilisant les mêmes styles css. Les animations dépendent de certains accessoires passés à la fonction AnimatedBox alors, par exemple, si seulement props.right est vrai, n'anime que le bord droit. Je pensais qu'une fonction css ferait l'affaire, donc pour ne pas répéter le code, je crée seulement l'élément et j'appelle la fonction. Cependant, j'obtiens l'erreur suivante, quoi que je fasse, et les composants ne se comportent pas comme prévu :

Functions that are interpolated in css calls will be stringified.

Voici un extrait de mon code (il est tronqué).

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}
`
(...)

largeur d'expansion , expandHeight , couleur de la bordure inférieure etc. sont toutes des animations d'images clés. J'ai juste besoin de savoir comment écrire ces fonctions et les passer au composant stylé que je veux sans obtenir cette erreur.

SOLVÉ

Comme @jsejcksn l'a suggéré, j'ai dû placer les divs stylisées dans la portée du composant. Ensuite, j'ai fait en sorte que les fonctions css prennent explicitement des paramètres et fassent quelques changements syntaxiques, puis je leur ai passé les props nécessaires.

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;
                `
            )
        )    
    }
`

0voto

pattern86 Points 214

Je pense que vous vous attendez à ce que vos fonctions soient évaluées, mais ce n'est pas ce qui se passe lors de l'interpolation. Comme dans l'exemple ci-dessous, vos fonctions sont tout simplement transformées en chaîne de caractères dans le littéral du modèle.

// where is name defined?
const str = `hello ${(name) => `${name}`}!`;
console.log(str); //=> "hello (name) => `${name}`!"

Vous devrez définir les styles dans le cadre des variables que vous souhaitez pouvoir utiliser (par exemple, à l'intérieur du composant si elles proviennent des accessoires du composant) :

const name = 'Earth';

const str = `hello ${name}!`;
console.log(str); //=> "hello Earth!"

const Component = (props) => {
  const divStyle = css`
    background-color: ${props.bgColor};
    color: white;
  `;

  const VariableColorDiv = styled.div`${divStyle}`;

  return <VariableColorDiv>hello world</VariableColorDiv>;
};

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X