3 votes

Approche de la création de variantes avec des composants stylisés

Quelle est la meilleure façon de créer des variantes à l'aide de composants stylisés ? Voici ce que je fais actuellement.

  const ButtonStyle = styled.button`
  padding:8px 20px;
  border:none;
  outline:none;
  font-weight:${props => props.theme.font.headerFontWeight};
  font-size:${props => props.theme.font.headerFontSize};
  display:block;
  &:hover{
    cursor:pointer;
  }
  ${({ variant }) =>
    variant == 'header' && css`
    background-color:${props => props.theme.colors.lightblue};
    color:${({ theme }) => theme.colors.white};
    &:active{
      background-color:${props => props.theme.colors.blue}
    }
    `
  }
  ${({ variant }) =>
    variant == 'white' && css`
    background-color:white;
    color:${({ theme }) => theme.colors.lightblue};
    &:active{
      color:${props => props.theme.colors.blue}
    }
    `
  }
`;

Je ne peux pas dire si c'est la manière standard de procéder. J'ai également utilisé d'autres composants comme bases pour créer d'autres composants à partir d'eux, tout en modifiant quelques éléments.

par exemple

  const InnerDiv = styled(otherComponent)`
  position: unset;
  background-color: red;
  overflow-x: hidden;
  display: flex;
`;

Quelle est la meilleure approche ? Existe-t-il de meilleures alternatives ?

3voto

Luis Paulo Pinto Points 2661

Ce n'est que mon opinion :

Je ne pense pas que nous puissions faire quelque chose de très différent de ce que vous avez fait.

Une autre façon de faire, à laquelle j'ai pensé, serait de créer un objet d'options pour cartographier les possibilités de la variante, comme ceci :

const variantOptions = {
  header: {
    backgroundColor: theme.colors.lightblue,
    color: theme.colors.white,
    active: theme.colors.blue,
  },
  white: {
    backgroundColor: "white",
    color: theme.colors.lightblue,
    active: theme.colors.blue,
  },
};

Et utilisez-le dans votre composant de style comme ceci :

const ButtonStyle = styled.button`
  padding: 8px 20px;
  border: none;
  outline: none;
  font-weight: ${(props) => props.theme.font.headerFontWeight};
  font-size: ${(props) => props.theme.font.headerFontSize};
  display: block;
  &:hover {
    cursor: pointer;
  }

  ${({ variant }) =>
    variant &&
    variantOptions[variant] &&
    css`
       background-color: ${variantOptions[variant].backgroundColor};
       color: ${variantOptions[variant].color};
       &:active {
          color: ${variantOptions[variant].active};
       }
   `}
`;

Et tous ces boutons vont fonctionner :

<ButtonStyle variant="*wrong*">Button</ButtonStyle>
<ButtonStyle variant="header">Button</ButtonStyle>
<ButtonStyle variant="white">Button</ButtonStyle>
<ButtonStyle>Button</ButtonStyle>

1voto

AbdessamadEL Points 11

Inspiré par les solutions précédentes, je veux partager ce que j'ai trouvé :

import styled, { css, DefaultTheme } from 'styled-components';

const variantStyles = (theme: DefaultTheme, variant = 'primary') =>
  ({
    primary: css`
      color: ${theme.colors.light};
      background: ${theme.colors.primary};
      border: 1px solid ${theme.colors.primary};
    `,
  }[variant]);

const Button = styled.button<{ variant: string }>`
  padding: 1rem;
  font-size: 0.875rem;
  transition: all 0.3s;
  cursor: pointer;

  ${({ theme, variant }) => variantStyles(theme, variant)}

  &:active {
    transform: translateY(1.5px);
  }
`;

export default Button;

Pour l'instant il ne contient que le primaire et c'est celui par défaut, mais vous pouvez ajouter plus de variantes en ajoutant un nouvel objet à variantStyles objet

Vous pouvez ensuite l'utiliser en passant la variante en tant que prop ou garder la valeur par défaut en ne passant aucune variante.

import { Button } from './HeroSection.styles';

<Button variant="primary">Start Learning</Button>

0voto

MrWashinton Points 168

Lorsque je traite des variantes de composants stylisés, voici ce que j'aime faire pour que les choses restent organisées et évolutives.

Si les variantes sont stockées dans le même fichier, j'utilise les propriétés d'héritage :

const DefaultButton = styled.button`
    color: ${(props) => props.theme.primary};
`;

const ButtonFlashy = styled(DefaultButton)`
    color: fuchsia;
`;

const ButtonDisabled = styled(DefaultButton)`
    color: ${(props) => props.theme.grey};
`;

Si nous parlons de composants réutilisables, j'utiliserais cette technique :

import styled from 'styled-components';

// Note that having a default class is important
const StyledCTA = ({ className = 'default', children }) => {
    return <Wrapper className={className}>{children}</Wrapper>;
};

/*
 * Default Button styles
 */
const Wrapper = styled.button`
    color: #000;
`;

/*
 * Custom Button Variant 1
 */
export const StyledCTAFushia = styled(StyledCTA)`
    && {
        color: fuchsia;
    }
`;

/*
 * Custom Button Variant 2
 */
export const StyledCTADisabled = styled(StyledCTA)`
    && {
        color: ${(props) => props.theme.colors.grey.light};
    }
`;

export default StyledCTA;

Utilisation :

import StyledCTA, { StyledCTADisabled, StyledCTAFushia } from 'components/StyledCTA';

const Page = () => {
    return (
        <>
            <StyledCTA>Default CTA</StyledCTA>
            <StyledCTADisabled>Disable CTA</StyledCTADisabled>
            <StyledCTAFushia>Fuchsia CTA</StyledCTAFushia>
        </>
    )
};

Pour en savoir plus, lisez les articles de blog que j'ai créés sur le sujet. aquí y .

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