Catégories
Plugin et site web

Construire une bibliothèque de composants avec React and Emotion – Smashing Magazine

A propos de l'auteur

Ingénieur front-end passionné par la performance et les technologies de pointe.
Plus à propos
Ademola

Une bibliothèque de composants permet de maintenir une conception cohérente sur plusieurs projets. Cela garantit la cohérence, car toutes les modifications apportées se propageront dans les projets qui l'utilisent. Dans ce didacticiel, nous allons apprendre à créer une bibliothèque de composants en utilisant Emotion dans React pour résoudre les incohérences.

Selon Clearleft, une bibliothèque de composants est:

"Un ensemble de composants, organisé de manière significative et offrant souvent (mais pas nécessairement) un moyen de parcourir et de prévisualiser ces composants et leurs ressources associées."

– «Lors de la création de bibliothèques de composants», à gauche

Nous allons apprendre à créer une bibliothèque de composants en en créant une qui comprend quatre composants:

  1. Button
    Un wrapper autour du bouton HTML par défaut
  2. Box
    Un conteneur (HTML div) avec des propriétés personnalisées
  3. Columns
    Un conteneur dont les enfants sont espacés uniformément sur l'axe des x
  4. Stack
    Un conteneur dont les enfants sont espacés uniformément sur l'axe y

Ces composants pourraient ensuite être utilisés dans n'importe quelle application sur laquelle nous travaillons. Nous allons créer la bibliothèque de composants en utilisant React et Emotion.

À la fin de cet article, vous devriez être en mesure de créer une bibliothèque de composants qui convient à tout cas d'utilisation que vous avez à l'esprit. Ces connaissances vous seront utiles lorsque vous travaillerez avec une équipe qui doit utiliser des composants réutilisables.

Commençons par définir ce qu'est la bibliothèque Emotion. La documentation explique:

«Emotion est une bibliothèque conçue pour écrire des styles CSS avec JavaScript. Il offre une composition de style puissante et prévisible en plus d'une excellente expérience de développement avec des fonctionnalités telles que les cartes sources, les étiquettes et les utilitaires de test. »

– «Introduction», Emotion Docs

Essentiellement, Emotion est une bibliothèque CSS-in-JavaScript, et une chose intéressante à propos des bibliothèques CSS-in-JavaScript est qu'elles vous permettent de colocaliser des composants avec des styles. Être capable de les lier ensemble dans une étendue garantit que certains styles de composants n'interfèrent pas avec d'autres, ce qui est crucial pour notre bibliothèque de composants.

Emotion expose deux API pour React:

  • @emotion/core
  • @emotion/styled

Avant de nous plonger dans le fonctionnement de ces API, notez qu'elles prennent toutes les deux en charge le style des composants avec des chaînes de modèle et des objets.

le API principale est en fait comme le régulier style propriété que nous utilisons actuellement lors de la création d'applications avec React, avec l'ajout d'un préfixe de fournisseur, de sélecteurs imbriqués, de requêtes multimédias, etc.

L'utilisation de l'approche objet avec l'API principale ressemblerait généralement à ceci:

import { jsx } from '@emotion/core'

let Box = props => {
  return (
    
) }

Ceci est un exemple plutôt artificiel qui montre comment nous pourrions styliser un Box composant avec Emotion. C’est comme remplacer le style propriété pour un css propriété, puis nous sommes prêts à partir.

Voyons maintenant comment nous pourrions utiliser l'approche de chaîne de modèle avec la même API principale:

import { jsx, css } from '@emotion/core'

let Box = props => {
  return (
    
) }

Tout ce que nous avons fait, c'est envelopper la chaîne de modèle avec le css tag, et Emotion s'occupe du reste.

le API stylisée, qui est construit sur l'API principale, adopte une approche légèrement différente pour styliser les composants. Cette API est appelée avec un élément HTML ou un composant React particulier, et cet élément est appelé avec un objet ou une chaîne de modèle contenant les styles de cet élément.

Voyons comment nous pourrions utiliser l'approche objet avec l'API stylisée:

import styled from '@emotion/styled'

const Box = styled.div({
        backgroundColor: 'grey'
});

Voici une façon d'utiliser l'API stylisée, qui est une alternative à l'utilisation de l'API principale. Les sorties rendues sont les mêmes.

Voyons maintenant comment nous pourrions utiliser l'approche de chaîne de modèle à l'aide de l'API stylisée:

import styled from '@emotion/styled'

const Box = styled.div`
        background-color: grey
`

Cela réalise la même chose que l'approche objet, uniquement avec une chaîne de modèle cette fois.

Nous pourrions utiliser l'API principale ou l'API stylisée lors de la création de composants ou d'une application. Je préfère l'approche stylisée pour une bibliothèque de composants pour plusieurs raisons:

  • Il accomplit beaucoup avec quelques frappes.
  • Il faut un as prop, qui permet de modifier dynamiquement l'élément HTML du site d'appel. Disons que nous utilisons par défaut un élément de paragraphe et que nous avons besoin d'un élément d'en-tête à cause de la sémantique; nous pouvons passer l'élément d'en-tête comme valeur au as propriété.

Commencer

Pour commencer, clonons les scripts de configuration sur GitHub, ce que nous pouvons faire sur la ligne de commande:

git clone git@github.com:smashingmagazine/component-library.git

Cette commande copie le code de ce référentiel dans le component-libraryDossier de. Il contient le code requis pour configurer une bibliothèque de composants, qui comprend Rollup pour aider à regrouper notre bibliothèque.

Nous avons actuellement un components dossier avec un index.js fichier, qui ne fait rien. Nous allons créer de nouveaux dossiers sous components dossier pour chaque composant que nous construisons dans notre bibliothèque. Le dossier de chaque composant exposera les fichiers suivants:

  • Component.js
    C'est le composant que nous construisons.
  • index.js
    Cela exporte le composant de Component.js et facilite le référencement des composants à partir d'un emplacement différent.
  • Component.story.js
    Cela rend essentiellement notre composant dans ses multiples états à l'aide de Storybook.

Il est également livré avec un utils dossier, qui définit certaines propriétés qui seraient utilisées dans nos composants. Le dossier contient plusieurs fichiers:

  • helpers.js
    Cela contient des fonctions d'assistance que nous allons utiliser dans notre application.
  • units.js
    Cela définit les unités d'espacement et de taille de police, que nous utiliserons plus tard.
  • theme.js
    Cela définit la palette, les ombres, la typographie et la forme de notre bibliothèque de composants.

Regardons ce que nous avons défini dans le units.js fichier:

export const spacing = {
  none: 0,
  xxsmall: '4px',
  xsmall: '8px',
  small: '12px',
  medium: '20px',
  gutter: '24px',
  large: '32px',
  xlarge: '48px',
  xxlarge: '96px',
};

export const fontSizes = {
  xsmall: '0.79rem',
  small: '0.889rem',
  medium: '1rem',
  large: '1.125rem',
  xlarge: '1.266rem',
  xxlarge: '1.424rem',
};

Cela définit le spacing et fontSizes règles. La règle d'espacement a été inspirée par le système de conception Braid, qui est basé sur des multiples de quatre. le fontSizes sont dérivées de la deuxième grande échelle de type (1,125), qui est une bonne échelle pour les sites Web de produits. Si vous souhaitez en savoir plus sur l'échelle de type, "Exploration des échelles de type réactif" explique l'intérêt de connaître les échelles appropriées pour différents sites Web.

Ensuite, passons en revue theme.js fichier!

import { spacing } from './units';

const white = '#fff';
const black = '#111';

const palette = {
  common: {
    black,
    white,
  },
  primary: {
    main: '#0070F3',
    light: '#146DD6',
    contrastText: white,
  },
  error: {
    main: '#A51C30',
    light: '#A7333F',
    contrastText: white,
  },
  grey: {
    100: '#EAEAEA',
    200: '#C9C5C5',
    300: '#888',
    400: '#666',
  },
};

const shadows = {
  0: 'none',
  1: '0px 5px 10px rgba(0, 0, 0, 0.12)',
  2: '0px 8px 30px rgba(0, 0, 0, 0.24)',
};

const typography = {
  fontFamily:
    "Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Ubuntu, 'Helvetica Neue', sans-serif",
};

const shape = {
  borderRadius: spacing('xxsmall'),
};

export const theme = {
  palette,
  shadows,
  typography,
  shape,
};

Dans le fichier de thème, nous avons défini notre palette, qui sont essentiellement les couleurs que nous allons utiliser dans tous les composants de notre bibliothèque. Nous avons également un shadows objet, où nous définissons notre box-shadow valeurs. Il y a aussi le typography objet, qui définit actuellement simplement notre fontFamily. Finalement, shape est utilisé pour des propriétés telles que border-radius. La structure de ce thème est inspirée de Material-UI.

Ensuite, notre helpers.js fichier!

export const isObjectEmpty = (obj) => {
  return Object.keys(obj).length === 0;
};

Ici, nous exposons uniquement le isObjectEmpty fonction, qui prend un objet et retourne true si l'objet est vide. Il retourne false s'il a des valeurs. Nous allons utiliser cette fonction plus tard.

Maintenant que nous avons parcouru tous les fichiers du utils dossier, il est grand temps de commencer à créer nos composants!

Boutons

Les boutons sont l'un des composants les plus utilisés sur le Web. Ils sont utilisés partout et peuvent prendre différentes formes, formes, tailles, etc.

Voici les boutons que nous allons créer dans Figma.

Une illustration qui montre à quoi ressemble le composant Button
Conception de composant de bouton de Figma (Grand aperçu)

Ces variations subtiles vont être appliquées en tant que propriétés à notre bouton. Nous aimerions que les boutons de notre bibliothèque de composants acceptent des propriétés telles que variant, size, enableElevation (c'est à dire. box-shadow), et color.

En commençant par le composant bouton, créons un Button dossier, où nous définirons tout ce qui concerne les boutons, comme indiqué précédemment.

Créons notre composant bouton:

import styled from '@emotion/styled';
import isPropValid from '@emotion/is-prop-valid';

const StyledButton = () => {};

const IGNORED_PROPS = ('color');

const buttonConfig = {
  shouldForwardProp: (prop) =>
    isPropValid(prop) && !IGNORED_PROPS.includes(prop),
};

export const Button = styled('button', buttonConfig)(StyledButton);

Ici, nous avons commencé par configurer notre composant de bouton avec un buttonConfig. le buttonConfig contient shouldForwardProp, qui est utilisé pour contrôler les propriétés qui doivent être transmises au DOM, car des propriétés telles que color apparaissent sur l'élément rendu par défaut.

Ensuite, définissons nos tailles de boutons, que nous allons utiliser dans le composant bouton!

const buttonSizeProps = {
  small: {
    fontSize: fontSizes('xsmall'),
    padding: `${spacing('xsmall')} ${spacing('small')}`,
  },
  medium: {
    fontSize: fontSizes('small'),
    padding: `${spacing('small')} ${spacing('medium')}`,
  },
  large: {
    fontSize: fontSizes('medium'),
    padding: `${spacing('medium')} ${spacing('large')}`,
  },
};

buttonSizeProps est une carte de nos valeurs de taille (small, medium, et large), et il renvoie fontSize et padding valeurs basées sur les tailles. Pour un petit bouton, nous aurions besoin d'une petite police avec un petit remplissage. Il en va de même pour les tailles moyennes et grandes pour les mettre à l'échelle de manière appropriée.

Ensuite, définissons une fonction qui fournit des propriétés CSS valides en fonction de la variante transmise:

const getPropsByVariant = ({ variant, color, theme }) => {

  const colorInPalette = theme.palette(color);

  const variants = {
    outline: colorInPalette
      ? outlineVariantPropsByPalette
      : defaultOutlineVariantProps,
    solid: colorInPalette
      ? solidVariantPropsByPalette
      : defaultSolidVariantProps,
  };

  return variants(variant) || variants.solid;
};

Ici le getPropsByVariant la fonction prend en variant, color, et theme properties et renvoie les propriétés du variant spécifié; si aucune variante n'est spécifiée, la valeur par défaut est solid. colorInPalette récupère la palette affectée à la couleur spécifiée si elle est trouvée, et undefined sinon trouvé dans notre theme objet.

Dans chaque variante, nous vérifions si une palette existe réellement pour la couleur spécifiée; si ce n'est pas le cas, nous utilisons les couleurs du common et grey objets de notre thème, que nous appliquerons dans defaultOutlineVariantProps et defaultSolidVariantProps.

Ensuite, définissons nos propriétés de variante!

const defaultSolidVariantProps = {
  main: {
    border: `1px solid ${theme.palette.grey(100)}`,
    backgroundColor: theme.palette.grey(100),
    color: theme.palette.common.black,
  },
  hover: {
    border: `1px solid ${theme.palette.grey(200)}`,
    backgroundColor: theme.palette.grey(200),
  },
};

const defaultOutlineVariantProps = {
  main: {
    border: `1px solid ${theme.palette.common.black}`,
    backgroundColor: theme.palette.common.white,
    color: theme.palette.common.black,
  },
  hover: {
    border: `1px solid ${theme.palette.common.black}`,
    backgroundColor: theme.palette.common.white,
    color: theme.palette.common.black,
  },
};

const solidVariantPropsByPalette = colorInPalette && {
  main: {
    border: `1px solid ${colorInPalette.main}`,
    backgroundColor: colorInPalette.main,
    color: colorInPalette.contrastText,
  },
  hover: {
    border: `1px solid ${colorInPalette.light}`,
    backgroundColor: colorInPalette.light,
  },
};

const outlineVariantPropsByPalette = colorInPalette && {
  main: {
    border: `1px solid ${colorInPalette.main}`,
    backgroundColor: theme.palette.common.white,
    color: colorInPalette.main,
  },
  hover: {
    border: `1px solid ${colorInPalette.light}`,
    backgroundColor: theme.palette.common.white,
    color: colorInPalette.light,
  },
};

Ici, nous définissons les propriétés qui vont être appliquées à notre bouton en fonction des variantes sélectionnées. Et, comme indiqué précédemment, defaultSolidVariantProps et defaultOutlineVariantProps utilisez les couleurs de notre common et grey objets comme solution de secours lorsque la couleur spécifiée n'est pas dans notre palette ou lorsqu'aucune couleur n'est spécifiée pour ce que nous mettons en place.

Au fait, le solidVariantPropsByPalette et outlineVariantPropsByPalette les objets utilisent la couleur de notre palette comme spécifié par le bouton. Ils ont tous les deux main et hover propriétés qui différencient respectivement les styles par défaut et de survol du bouton.

La conception des boutons que nous avons utilisée représente deux variantes, que nous pouvons vérifier dans la conception de notre bibliothèque de composants.

Ensuite, créons notre StyledButton fonction, qui combine tout ce que nous avons fait jusqu'à présent.

const StyledButton = ({
  color,
  size,
  variant,
  enableElevation,
  disabled,
  theme,
}) => {
  if (isObjectEmpty(theme)) {
    theme = defaultTheme;
  }

  const fontSizeBySize = buttonSizeProps(size)?.fontSize;
  const paddingBySize = buttonSizeProps(size)?.padding;
  const propsByVariant = getPropsByVariant({ variant, theme, color });

  return {
    fontWeight: 500,
    cursor: 'pointer',
    opacity: disabled && 0.7,
    transition: 'all 0.3s linear',
    padding: buttonSizeProps.medium.padding,
    fontSize: buttonSizeProps.medium.fontSize,
    borderRadius: theme.shape.borderRadius,
    fontFamily: theme.typography.fontFamily,
    boxShadow: enableElevation && theme.shadows(1),
    ...(propsByVariant && propsByVariant.main),
    ...(paddingBySize && { padding: paddingBySize }),
    ...(fontSizeBySize && { fontSize: fontSizeBySize }),
    '&:hover': !disabled && {
      boxShadow: enableElevation && theme.shadows(2),
      ...(propsByVariant && propsByVariant.hover),
    },
  };
};

dans le StyledButton fonction, nous attribuons defaultTheme au thème si le theme L’objet est vide, ce qui rend facultatif pour les utilisateurs de notre bibliothèque d’utiliser le ThemeProvider d’Emotion afin d’utiliser la bibliothèque. Nous avons attribué fontSize et padding basé sur buttonSizeProps objet. Nous avons défini plusieurs propriétés de bouton par défaut, telles que fontWeight et cursor, qui ne sont liés à aucune propriété, et nous avons également dérivé color, backgroundColor, et border valeurs basées sur le résultat de propsByVariant.

Maintenant que nous avons créé notre Button composant, voyons comment nous pouvons l’utiliser:


Nous pouvons vérifier à quoi cela ressemble sur CodeSandbox:

Voilà comment utiliser le Button composant. Nous définissons les propriétés suivantes:

  • Nous définissons une variante avec un solid valeur. Nous aurions pu spécifier outline au lieu. Si la variant prop n'est pas fourni, nous utiliserions également par défaut solid.
  • Nous définissons color, avec une valeur de primary. Nous soutenons également error comme valeur de couleur ou couleur d'un theme objet. Si la color n'est pas spécifiée, nous reviendrions à notre état de couleur par défaut.
  • Nous définissons size, avec une valeur de small. Il pourrait être medium (la valeur par défaut) ou large.
  • Nous définissons EnableElevation parce que nous en voulons box-shadow sur notre bouton. Nous aurions pu choisir de ne pas l'utiliser.
  • Enfin, nous définissons disabled parce que nous voulons que notre bouton soit désactivé. La chose supplémentaire que nous faisons à un bouton désactivé est de réduire son opacité.

Le bouton n'a pas besoin de prendre de propriété. Par défaut, il s'agit d'un bouton solide de taille moyenne.

Composant de boîte

Un composant boîte est un conteneur qui peut contenir n'importe quel composant ou élément HTML. Il accepte mais n'est pas limité à des propriétés telles que padding, margin, display, et width. Il peut également être utilisé comme composant de base pour certains des autres composants que nous aborderons plus tard.

Voici à quoi cela ressemble sur Figma:

Une illustration qui montre à quoi ressemble le composant Box
Conception de composants de boîte à partir de Figma (grand aperçu)

Avant de plonger dans le code, n’oublions pas de créer un nouveau dossier pour ce composant.

Maintenant, créons notre Box composant:


import styled from '@emotion/styled';
import isPropValid from '@emotion/is-prop-valid';
import { spacing, theme as defaultTheme } from '../../utils';

const StyledBox = ({
  paddingX,
  paddingY,
  marginX,
  marginY,
  width,
  display,
  theme,
  ...props
}) => {

  if (isObjectEmpty(theme)) {
    theme = defaultTheme;
  }

  const padding = spacing(props.padding);
  let paddingTop = spacing(props.paddingTop);
  let paddingRight = spacing(props.paddingRight);
  let paddingBottom = spacing(props.paddingBottom);
  let paddingLeft = spacing(props.paddingLeft);
  if (paddingX) {
    paddingLeft = spacing(paddingX);
    paddingRight = spacing(paddingX);
  }
  if (paddingY) {
    paddingTop = spacing(paddingY);
    paddingBottom = spacing(paddingY);
  }
  let margin = spacing(props.margin);
  let marginTop = spacing(props.marginTop);
  let marginRight = spacing(props.marginRight);
  let marginBottom = spacing(props.marginBottom);
  let marginLeft = spacing(props.marginLeft);
  if (marginX) {
    marginLeft = spacing(marginX);
    marginRight = spacing(marginX);
  }
  if (marginY) {
    marginTop = spacing(marginY);
    marginBottom = spacing(marginY);
  }
  return {
    padding,
    paddingTop,
    paddingRight,
    paddingBottom,
    paddingLeft,
    margin,
    marginTop,
    marginRight,
    marginBottom,
    marginLeft,
    width,
    display,
    fontFamily: theme.typography.fontFamily,
  };
};

const IGNORED_PROPS = ('display', 'width');

const boxConfig = {
  shouldForwardProp: (prop) =>
    isPropValid(prop) && !IGNORED_PROPS.includes(prop),
};

export const Box = styled('div', boxConfig)(StyledBox);

le spacing la règle que nous avons définie précédemment est appliquée à la fois au remplissage et à la marge, comme nous pouvons le voir dans le Box composant. Nous recevons des valeurs contextuelles pour le remplissage et la marge, et nous recherchons leurs valeurs réelles à partir du spacing objet.

Nous acceptons paddingX et paddingY accessoires pour mettre à jour le remplissage sur l'axe horizontal et vertical, respectivement. Nous faisons de même pour marginX et marginY ainsi que.

De plus, nous ne voulons pas display et width props pour être transmis au DOM car nous n'en avons besoin que dans CSS. Donc, nous les ajoutons à notre liste d'accessoires à ignorer, et les transmettons à notre configuration.

Voici comment nous pourrions utiliser Box composant:


  Simple Box Component

Nous pouvons voir à quoi cela ressemble sur CodeSandbox.

Dans ce Box composant, nous avons attribué small comme valeur de notre padding propriété, et medium à la paddingTop et paddingBottom Propriétés. Une fois rendu, le Box composant aura son padding-left et padding-right propriétés définies sur 12px chacun, et son padding-top et padding-bottom propriétés définies sur 20px. Nous aurions pu remplacer paddingTop et paddingBottom avec paddingY et obtenu le même résultat.

Composant Colonnes

le Columns composant est une variante de notre Box composant, avec un display Type de flex et avec les enfants espacés uniformément sur l'axe des x.

Voici une représentation du Columns composant dans Figma:

Une illustration qui montre à quoi ressemble le composant Button
Conception de composants de colonnes à partir de Figma (Grand aperçu)

Construisons notre Columns composant!

import React from 'react';
import { Box } from '../Box';

export const Columns = ({ children, space, ...props }) => {
  return (
    
      {React.Children.map(children, (child, index) => {
        if (child.type !== Box) {
          console.warn(
            'Each child in a Columns component should be a Box component'
          );
        }

        if (index > 0) {
          return React.cloneElement(child, {
            marginLeft: space,
            width: '100%',
          });
        }

        return React.cloneElement(child, { width: '100%' });
      })}
    
  );
};

Nous utilisons React.Children pour cartographier le Columns les enfants du composant. Et nous ajoutons marginLeft et width propriétés à chacun des enfants, à l'exception du premier enfant, qui n'a pas besoin d'un marginLeft propriété car il s'agit de l'enfant le plus à gauche de la colonne. Nous nous attendons à ce que chaque enfant soit un Box élément pour s'assurer que les styles nécessaires lui sont appliqués.

Voici comment nous pourrions utiliser Columns composant:


   Item 1
   Item 2
   Item 3

Nous pouvons voir à quoi cela ressemble sur CodeSandbox.

le Columns les enfants ici sont espacés uniformément sur l'axe des x de 12 pixels, car c'est la valeur de small résout, comme nous l'avons défini précédemment. Parce que le Columns composant est littéralement un Box composant, il peut prendre d'autres Box propriétés des composants, et nous pouvons les personnaliser autant que nous le voulons.

Composant de pile

C'est aussi une variante de notre Box composant qui occupe toute la largeur de l'élément parent et dont les enfants sont régulièrement espacés sur l'axe y.

Voici une représentation du Stack composant dans Figma:

Une illustration qui montre à quoi ressemble le composant Stack
Conception de composants de pile à partir de Figma (Grand aperçu)

Construisons notre Stack composant:

import React from 'react';
import { Box } from '../Box';
import { Columns } from '../Columns';

const StackChildrenTypes = (Box, Columns);
const UnsupportedChildTypeWarning =
  'Each child in a Stack component should be one of the types: Box, Columns';

export const Stack = ({ children, space, ...props }) => {
  return (
    
      {React.Children.map(children, (child, index) => {
        if (!StackChildrenTypes.includes(child.type)) {
          console.warn(UnsupportedChildTypeWarning);
        }

        if (index > 0) {
          return React.cloneElement(child, { marginTop: space });
        }

        return child;
      })}
    
  );
};

Ici, nous cartographions chaque enfant avec React.Children et appliquer un paddingTop propriété à lui avec la valeur de la space argument. Quant au premier enfant, nous avons besoin qu'il prenne sa position d'origine, donc nous sautons l'ajout d'un marginTop propriété à elle. Nous acceptons également que chaque enfant soit un Box afin que nous puissions lui appliquer les propriétés nécessaires.

Voici comment nous pourrions utiliser Stack composant:


   Item 1
   Item 2
   Item 3

Nous pouvons voir à quoi cela ressemble sur CodeSandbox.

Ici le Box les éléments sont espacés uniformément avec le small unité, et le premier Box prend un séparé marginTop propriété. Cela montre que vous pouvez personnaliser les composants comme vous le souhaitez.

Conclusion

Nous avons passé en revue les bases de l'utilisation d'Emotion pour créer des composants dans React à l'aide des API qu'elle fournit. Il ne s'agit que de l'une des nombreuses façons de créer une bibliothèque de composants. Il y a quelques nuances à le construire pour une marque, car vous n'aurez peut-être pas à prendre en compte le thème et d'autres éléments. Mais si vous prévoyez de rendre la bibliothèque publique un jour, vous devrez alors traiter les demandes pour ces pièces manquantes, alors considérez cette possibilité et rendez la bibliothèque un peu flexible à l'avance.

Si vous avez des questions, n'hésitez pas à les laisser sous forme de commentaires.

Le référentiel de cet article se trouve sur GitHub et les conceptions de boutons que nous avons utilisées se trouvent sur Figma.

Références

Éditorial fracassant(ks, ra, al, il)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *