Fermer

juillet 23, 2020

Comment utiliser des composants stylisés dans React


À propos de l'auteur

Adebiyi Adedotun Lukman est un ingénieur UI / Frontend basé à Lagos, au Nigeria, qui adore également UI / UX Design par amour des grands logiciels. Quand …
En savoir plus sur
Adebiyi

Si l’approche axée sur les composants a ouvert une nouvelle frontière dans la manière dont nous développons des applications Web, elle n’est pas sans imperfections, l’une étant sa facilité d’utilisation et son évolutivité avec CSS. Cela a donné naissance à une nouvelle façon de construire et de gérer nos styles d'une manière spécifique au composant autrement connue sous le nom de CSS-in-JS.

Les composants stylisés sont un outil CSS-in-JS qui comble le fossé entre les composants et le style, en offrant de nombreuses fonctionnalités pour vous permettre de vous familiariser avec les composants de style de manière fonctionnelle et réutilisable. Dans cet article, vous découvrirez les bases des composants stylisés et comment les appliquer correctement à vos applications React. Vous devriez avoir déjà travaillé sur React avant de suivre ce tutoriel. Si vous recherchez diverses options pour styliser les composants React, vous pouvez consulter notre article précédent sur le sujet .

Au cœur de CSS se trouve la capacité de cibler n'importe quel élément HTML – globalement – non importe sa position dans l'arborescence DOM. Cela peut être un obstacle lorsqu'ils sont utilisés avec des composants, car les composants exigent, dans une mesure raisonnable, une colocation (c'est-à-dire garder les éléments tels que les états et le style) plus près de l'endroit où ils sont utilisés (appelée localisation).

Dans les propres termes de React , les composants stylisés sont des « primitives visuelles pour les composants », et leur objectif est de nous donner une manière flexible de styliser les composants. Le résultat est un couplage étroit entre les composants et leurs styles.

Remarque: Les composants stylisés sont disponibles à la fois pour React et React Native, et même si vous devriez absolument consulter le guide React Native, nous nous concentrerons ici sur les composants stylisés pour React .

Pourquoi des composants stylisés?

En plus de vous aider à définir des styles, les composants stylisés incluent les fonctionnalités suivantes:

  • Préfixe automatique du fournisseur
    Vous pouvez utiliser les propriétés CSS standard et les composants stylisés ajouteront des préfixes de fournisseur. ils sont nécessaires.
  • Noms de classe uniques
    Les composants stylisés sont indépendants les uns des autres, et vous n'avez pas à vous soucier de leurs noms car la bibliothèque gère cela pour vous.
  • Élimination des styles morts
    Styled les composants suppriment les styles inutilisés, même s'ils sont déclarés dans votre code.
  • et beaucoup plus .

Installation

L'installation de composants stylisés est facile. Vous pouvez le faire via un CDN ou avec un gestionnaire de packages tel que Yarn…

 yarn add styled-components 

… ou npm:

 npm i styled-components 

Notre démo utilise create-react-app .

Démarrage

La première chose que vous remarquerez peut-être à propos des composants stylisés est leur syntaxe, qui peut être décourageante si vous ne comprenez pas le magie derrière les composants stylisés . En bref, les composants stylisés utilisent les littéraux de gabarit de JavaScript pour combler le fossé entre les composants et les styles. Ainsi, lorsque vous créez un composant stylisé, vous créez en fait un composant React avec des styles. Cela ressemble à ceci:

 import styled from "styled-components";

// Composant stylé nommé StyledButton
const StyledButton = styled.button`
  couleur de fond: noir;
  taille de la police: 32px;
  Couleur blanche;
`;

function Component () {
  // Utilisez-le comme n'importe quel autre composant.
  retour  Connexion ;
} 

Ici, StyledButton est le composant stylé, et il sera rendu comme un bouton HTML avec les styles contenus. styled est une méthode utilitaire interne qui transforme le style de JavaScript en CSS réel.

En HTML et CSS bruts, nous aurions ceci:

 button {
  couleur de fond: noir;
  taille de la police: 32px;
  Couleur blanche;
}

 

Si les composants stylisés sont des composants React, pouvons-nous utiliser des accessoires? Oui, nous pouvons.

Adaptation basée sur des accessoires

Les composants stylisés sont fonctionnels donc nous pouvons facilement styliser les éléments de manière dynamique. Supposons que notre page comporte deux types de boutons, l’un avec un arrière-plan noir et l’autre bleu. Nous n'avons pas besoin de créer deux composants stylisés pour eux; nous pouvons adapter leur style en fonction de leurs accessoires.

 import styled from "styled-components";

const StyledButton = styled.button`
  largeur min: 200px;
  bordure: aucune;
  taille de la police: 18px;
  rembourrage: 7px 10px;
  / * La couleur d'arrière-plan résultante sera basée sur les accessoires bg. * /
  background-color: $ {props => props.bg === "noir"? "noir": "bleu";
`;

Profil de fonction () {
  revenir (
    
Bouton A Bouton B
) }

Comme StyledButton est un composant React qui accepte les accessoires, nous pouvons attribuer une couleur d'arrière-plan différente en fonction de l'existence ou de la valeur de bg prop.

Vous notez cependant que nous n'avons pas donné à notre bouton le type . Faisons cela:

 function Profile () {
  revenir (
    <>
      
        Bouton A
      
        alerte ("cliqué")}>
        Bouton B
      
    
  );
} 

Les composants stylisés peuvent différencier les types d'accessoires qu'ils reçoivent. Ils savent que type est un attribut HTML, donc ils rendent réellement tout en utilisant l'accessoire bg dans leur propre traitement. Remarquez comment nous avons attaché un gestionnaire d'événements?

En parlant d'attributs, une syntaxe étendue nous permet de gérer les accessoires en utilisant le constructeur attrs . Vérifiez ceci:

 const StyledContainer = styled.section.attrs ((props) => ({
  largeur: props.width || "100%",
  hasPadding: props.hasPadding || faux,
})) `
  - rembourrage du conteneur: 20px;
  width: $ {(props) => props.width}; // Retombe à 100%
  remplissage: $ {(props) =>
    (props.hasPadding && "var (- container-padding)") || "aucun"};
`; 

Remarquez comment nous n'avons pas besoin d'un ternaire lors du réglage de la largeur? C’est parce que nous lui avons déjà défini une valeur par défaut avec width: props.width || "100%", . De plus, nous avons utilisé propriétés personnalisées CSS parce que nous le pouvons!

Remarque: Si les composants stylisés sont des composants React et que nous pouvons passer des accessoires, pouvons-nous également utiliser des états? Le compte GitHub de la bibliothèque a un problème pour résoudre ce très important.

Extension des styles

Supposons que vous travaillez sur une page de destination et que vous avez défini votre conteneur sur un certain max-width pour garder les choses centrées. Vous avez un StyledContainer pour cela:

 const StyledContainer = styled.section`
  largeur maximale: 1024px;
  rembourrage: 0 20px;
  marge: 0 auto;
`; 

Ensuite, vous découvrez que vous avez besoin d'un conteneur plus petit, avec un remplissage de 10 pixels des deux côtés, au lieu de 20 pixels. Votre première pensée pourrait être de créer un autre composant de style, et vous avez raison, mais cela ne prendrait pas de temps avant de vous rendre compte que vous dupliquez des styles.

 const StyledContainer = styled.section`
  largeur maximale: 1024px;
  rembourrage: 0 20px;
  marge: 0 auto;
`;

const StyledSmallContainer = styled.section`
  largeur maximale: 1024px;
  rembourrage: 0 10px;
  marge: 0 auto;
`; 

Avant de créer StyledSmallContainer comme dans l'extrait de code ci-dessus, apprenons comment réutiliser et hériter des styles. Cela ressemble plus ou moins au fonctionnement de l’opérateur spread :

 const StyledContainer = styled.section`
  largeur maximale: 1024px;
  rembourrage: 0 20px;
  marge: 0 auto;
`;

// Hériter de StyledContainer dans StyledSmallConatiner
const StyledSmallContainer = styled (StyledContainer) `
  rembourrage: 0 10px;
`;

function Accueil () {
  revenir (
    
      

Le secret est d'être heureux

); } function Contact () { revenir (

La route continue

); }

Dans votre StyledSmallContainer vous obtiendrez tous les styles de StyledContainer mais le rembourrage sera remplacé. Gardez à l’esprit que, d’ordinaire, vous obtiendrez un élément de section pour StyledSmallContainer car c’est ce que StyledContainer rend. Mais cela ne veut pas dire qu'il est taillé dans la pierre ou immuable.

Le "as" Polymorphic Prop

Avec le as polymorphic prop vous pouvez permuter l'extrémité ] élément qui est rendu. Un cas d'utilisation est celui où vous héritez des styles (comme dans le dernier exemple). Si, par exemple, vous préférez un div à une section pour StyledSmallContainer vous pouvez passer le comme accessoire à votre style composant avec la valeur de votre élément préféré, comme ceci:

 function Home () {
  revenir (
    
      

C’est une affaire, pas personnelle

); } function Contact () { revenir (

Ne dribblez jamais quand vous pouvez passer

); }

Maintenant, StyledSmallContainer sera rendu en tant que div . Vous pouvez même avoir un composant personnalisé comme valeur:

 function Home () {
  revenir (
    
      

C’est une affaire, pas personnelle

); } function Contact () { revenir (

Ne dribblez jamais quand vous pouvez passer

); }

Ne le prenez pas pour acquis.

Syntaxe de type SCSS

Le préprocesseur CSS Stylis permet aux composants stylisés de prendre en charge la syntaxe de type SCSS, telle que l'imbrication:

 const StyledProfileCard = styled.div`
  bordure: 1px noir uni;

  > .username {
    taille de la police: 20px;
    la couleur noire;
    transition: 0,2 s;

    &: hover {
      La couleur rouge;
    }

    + .dob {
      couleur: gris;
    }
  }
`;

function ProfileCard () {
  revenir (
    
      

John Doe

Date: 12 octobre 2013

Homme

); }

Animation

Les composants stylisés ont un assistant images clés qui aide à créer des images clés d'animation (réutilisables). L'avantage ici est que les images clés seront détachées des composants stylisés et pourront être exportées et réutilisées là où c'est nécessaire.

 import styled, {keyframes} from "styled-components";

const slideIn = images clés`
  de {
    opacité: 0;
  }

  à {
    opacité: 1;
  }
`;

const Toast = styled.div`
  animation: $ {slideIn} 0.5s cubic-bezier (0.4, 0, 0.2, 1) les deux;
  rayon de la bordure: 5px;
  rembourrage: 20px;
  position: fixe;
`; 

Global Styling

Alors que l'objectif initial de CSS-in-JS et, par extension, des composants stylisés est la portée des styles, nous pouvons également exploiter le style global des composants stylisés. Étant donné que nous travaillons principalement avec des styles étendus, vous pourriez penser que c'est un paramètre d'usine invariable, mais vous vous trompez. Pensez-y: qu'est-ce que le cadrage? Il est techniquement possible pour nous – au nom du style global – de faire quelque chose de similaire à ceci:

 ReactDOM.render (
  
    
  ,
  document.getElementById ("racine")
); 

Mais nous avons déjà une fonction d'assistance – createGlobalStyle – dont la seule raison d'être est le style global. Alors, pourquoi lui nier sa responsabilité?

Une chose pour laquelle nous pouvons utiliser createGlobalStyle est de normaliser le CSS :

 import {createGlobalStyle} de "styled-components";

const GlobalStyle = createGlobalStyle`
    / * Votre css est réinitialisé ici * /
`;

// Utilisez votre GlobalStyle
function App () {
  revenir (
    
); }

Remarque: Les styles créés avec createGlobalStyle n'acceptent aucun enfant. Pour en savoir plus consultez la documentation .

À ce stade, vous vous demandez peut-être pourquoi nous devrions utiliser createGlobalStlye . Voici quelques raisons:

  • Nous ne pouvons rien cibler en dehors du rendu racine sans lui (par exemple, html body etc.).
  • createGlobalStyle injecte des styles mais ne restitue aucun élément réel. Si vous regardez attentivement le dernier exemple, vous remarquerez que nous n'avons spécifié aucun élément HTML à afficher. C'est cool car nous n'avons peut-être pas besoin de l'élément. Après tout, nous sommes préoccupés par les styles globaux. Nous ciblons les sélecteurs en général, et non des éléments spécifiques.
  • createGlobalStyle n'est pas défini et peut être affiché n'importe où dans notre application et sera applicable tant qu'il se trouve dans le DOM. Pensez au concept pas à la structure .
 import {createGlobalStyle} de "styled-components";

const GlobalStyle = createGlobalStyle`
  / * Votre css est réinitialisé ici * /

  .app-title {
    taille de la police: 40px;
  }
`;

const StyledNav = styled.nav`
    / * Vos styles ici * /
`;

function Nav ({enfants}) {
  revenir (
    
      
       {enfants}
    
  );
}

function App () {
  revenir (
    
); }

Si vous pensez à la structure, alors app-title ne doit pas avoir le style défini dans GlobalStyle . Mais cela ne fonctionne pas de cette façon. Où que vous choisissiez de rendre votre GlobalStyle il sera injecté lorsque votre composant sera rendu .

Attention : createGlobalStyles sera seulement être rendu si et quand il est dans le DOM.

CSS Helper

Nous avons déjà vu comment adapter des styles basés sur des accessoires. Et si on voulait aller un peu plus loin? La fonction d'assistance CSS permet d'y parvenir. Supposons que nous ayons deux champs de saisie de texte avec des états: vide et actif, chacun avec une couleur différente. Nous pouvons faire ceci:

 const StyledTextField = styled.input`
  couleur: $ {(props) => (props.isEmpty? "none": "black")};
«; 

Tout va bien. Par la suite, si nous devons ajouter un autre état de rempli, nous devrons modifier nos styles:

 const StyledTextField = styled.input`
  couleur: $ {(accessoires) =>
    props.isEmpty? "aucun": accessoires actifs? "bleu violet"};
»

Or l'opération ternaire devient de plus en plus complexe. Et si nous ajoutions un autre état à nos champs de saisie de texte ultérieurement? Ou que faire si nous voulons donner à chaque état des styles supplémentaires, autres que la couleur? Pouvez-vous imaginer resserrer les styles dans l'opération ternaire? L'assistant css est très pratique.

 const StyledTextField = styled.input`
  largeur: 100%;
  hauteur: 40px;

  $ {(accessoires) =>
    (accessoires vides &&
      css`
        couleur: aucune;
        couleur de fond: blanc;
      `) ||
    (accessoires actifs &&
      css`
        la couleur noire;
        backgroundcolor: whitemoke;
      `)}
`; 

Ce que nous avons fait, c'est en quelque sorte élargi notre syntaxe ternaire pour accueillir plus de styles, et avec une syntaxe plus compréhensible et organisée. Si la déclaration précédente semble erronée, c'est parce que le code essaie d'en faire trop. Alors, revenons en arrière et affinons:

 const StyledTextField = styled.input`
largeur: 100%;
hauteur: 40px;

// 1. État vide
$ {(accessoires) =>
  accessoires vides &&
  css`
    couleur: aucune;
    couleur de fond: blanc;
  `}

// 2. État actif
$ {(accessoires) =>
  accessoires actifs &&
  css`
    la couleur noire;
    backgroundcolor: whitemoke;
  `}

// 3. État rempli
$ {(accessoires) =>
  accessoires remplis &&
  css`
    la couleur noire;
    couleur de fond: blanc;
    bordure: 1px vert uni;
  `}
`; 

Notre raffinement divise le style en trois morceaux différents gérables et faciles à comprendre. C’est une victoire.

StyleSheetManager

Comme l’assistant CSS, StyleSheetManager est une méthode d’aide permettant de modifier le traitement des styles. Il faut certains accessoires – comme disableVendorPrefixes (vous pouvez consulter la liste complète ) – qui vous aident à désactiver les préfixes de fournisseur de son sous-arbre.

 import styled, {StyleSheetManager} depuis "styled-components";

const StyledCard = styled.div`
  largeur: 200px;
  couleur de fond: blanc;
`;

const StyledNav = styled.div`
  largeur: calc (100% - var (- side-nav-width));
`;

Profil de fonction () {
  revenir (
    
Ceci est une carte
); }

disableVendorPrefixes est passé comme accessoire à . Ainsi, les composants stylisés enveloppés par seraient désactivés, mais pas ceux de .

Débogage plus facile

Lors de l'introduction de composants stylisés à l'un de mes collègues, une de leurs plaintes était qu'il était difficile de localiser un élément rendu dans le DOM – ou dans React Developer Tools, d'ailleurs. C'est l'un des inconvénients des composants stylisés: en essayant de fournir des noms de classe uniques, il attribue des hachages uniques aux éléments, qui se trouvent être cryptiques, mais il rend le displayName lisible pour un débogage plus facile.

 importer React depuis "react";
import stylisé à partir de "styled-components";
import "./App.css";

const LoginButton = styled.button`
  couleur de fond: blanc;
  la couleur noire;
  bordure: 1px rouge uni;
`;

function App () {
  revenir (
    
Connexion
); }

Par défaut, les composants stylisés affichent LoginButton comme dans le DOM et comme LoginButton dans React Developer Tools, ce qui facilite le débogage. Nous pouvons activer le booléen displayName si nous ne voulons pas de ce comportement. Cela nécessite une configuration Babel.

Note : Dans la documentation, le package babel-plugin-styled-components est spécifié, ainsi qu'un .babelrc ] fichier de configuration. Le problème avec ceci est que, comme nous utilisons create-react-app nous ne pouvons pas configurer beaucoup de choses si nous ne les éjectons pas. C'est ici qu'interviennent les macros Babel.

Nous devrons installer babel-plugin-macros avec npm ou Yarn, puis créer un babel-plugin-macros.config.js à la racine de notre application, avec le contenu:

 module.exports = {
  styledComponents: {
    displayName: vrai,
    fileName: faux,
  },
}; 

Avec la valeur fileName inversée, le displayName sera précédé du nom de fichier pour une précision encore plus unique.

Nous devons également maintenant importer depuis le macro :

 // Avant
import stylisé à partir de "styled-components";

// Après
import styled from "styled-components / macro"; 

Conclusion

Maintenant que vous pouvez composer votre CSS par programmation, n'abusez pas de la liberté. Pour ce que cela vaut, faites de votre mieux pour maintenir la cohérence de vos composants stylisés. N'essayez pas de composer des conditionnels lourds, et ne supposez pas que tout doit être un composant stylisé. Aussi, n'abstenez pas trop en créant des composants de style naissant pour des cas d'utilisation que vous devinez seulement quelque part.

Autres ressources

  1. Documentation Styled Components
  2. " Building a Système de composants réutilisables avec React.js et styled-components », Lukas Gisder-Dubé
  3. Utilisation avec Next.js
  4. Utilisation avec Gatsby
 Smashing Editorial ] (ks, ra, yk, al, il)




Source link