3. Ajouter une propriété calculée pour les types

Nous allons mettre en place une deuxième propriété calculée, pour les types d’un pokémon. Chaque pokémon peut avoir entre un et trois types différents. Ce que nous aimerions faire, c’est associer une couleur à chaque type possible, comme ceci :

Le pokémon Roucool a deux types : Normal et Vol.

Comme vous pouvez le voir, on a ajouté les types d’un pokémon sur sa carte. Nous avons déjà à notre disposition les valeurs de ces types (« Normal » et « Vol ») au niveau de notre objet pokémon. La principale difficulté va être d’associer pour chaque type une couleur spécifique. Par exemple, le type « Normal » est associé à la couleur grise, et le type « Vol » est associé à la couleur bleu. Mais commençons tout doucement, en ajoutant dans un premier temps les types d’un pokémon sur sa carte. Modifiez donc le composant pokemon-card.tsx comme ceci :

// ...

const PokemonCard: FunctionComponent<Props> = ({pokemon, borderColor = '#009688'}) => {
  // ...

  return (
    <div className="col s6 m4" onMouseEnter={showBorder} onMouseLeave={hideBorder}>
      <div className="card horizontal" style={{ borderColor: color }}>
        <div className="card-image"> 
          <img src={pokemon.picture} alt={pokemon.name}/>
        </div>
        <div className="card-stacked">
          <div className="card-content">
            <p>{pokemon.name}</p>
            <p><small>{formatDate(pokemon.created)}</small></p>
            {pokemon.types.map(type => (
              <span key={type}>{type}</span>
            ))}
          </div>
        </div>
      </div> 
    </div>
  );
}

export default PokemonCard;

Comme vous pouvez le voir, on a ajouté la liste des types d’un pokémon, les uns à la suite des autres. Pour l’utilisateur, cela ressemble à ça :

Les types du pokémon ne sont pas bien mis en forme !

Bon, c’est une première étape, mais ce n’est pas encore ce que nous souhaitons obtenir. Il nous manque le petit bloc de couleur autour des types. Pour cela, nous allons utiliser des classes CSS de la librairie Materialize que nous avons ajouté précédemment. En appliquant quelques classes, nous allons mettre en place chaque type avec la bonne couleur, pour tous les pokémons. Nous allons donc créer une fonction formatType dans notre composant PokemonCard. Cette fonction prendra en paramètre un type de pokémon, et renverra les classes CSS correspondant à la couleur attendue pour chaque type. Je vous invite donc à ajouter cette méthode, toujours dans le fichier pokemon-card.tsx :

// ...

const PokemonCard: FunctionComponent<Props> = ({pokemon, borderColor = '#009688'}) => {

  // ...

  const formatDate = (date: Date): string => {
    return `${date.getDate()}/${date.getMonth()+1}/${date.getFullYear()}`;
  }

  const formatType = (type: string): string => {
    let color: string;

    switch (type) {
      case 'Feu': 
        color = 'red lighten-1'; 
        break; 
      case 'Eau': 
        color = 'blue lighten-1'; 
        break; 
      case 'Plante': 
        color = 'green lighten-1'; 
        break; 
      case 'Insecte': 
        color = 'brown lighten-1'; 
        break; 
      case 'Normal': 
        color = 'grey lighten-3'; 
        break; 
      case 'Vol': 
        color = 'blue lighten-3'; 
        break; 
      case 'Poison': 
        color = 'deep-purple accent-1'; 
        break; 
      case 'Fée': 
        color = 'pink lighten-4'; 
        break; 
      case 'Psy': 
        color = 'deep-purple darken-2'; 
        break; 
      case 'Electrik': 
        color = 'lime accent-1'; 
        break; 
      case 'Combat': 
        color = 'deep-orange'; 
        break; 
      default: 
        color = 'grey'; 
        break; 
    }

    return `chip ${color}`;
  }

  return (
    <div className="col s6 m4" onMouseEnter={showBorder} onMouseLeave={hideBorder}>
      <div className="card horizontal" style={{ borderColor: color }}>
        <div className="card-image"> 
          <img src={pokemon.picture} alt={pokemon.name}/>
        </div>
        <div className="card-stacked">
          <div className="card-content">
            <p>{pokemon.name}</p>
            <p><small>{formatDate(pokemon.created)}</small></p>
            {pokemon.types.map(type => (
              <span key={type} className={formatType(type)}>{type}</span>
            ))}
          </div>
        </div>
      </div> 
    </div>
  );
}

export default PokemonCard;

Comme vous pouvez le constater, nous avons ajouté une trèèès longue méthode formatType. Pourtant, même si cette méthode est longue, elle est plutôt simple. Elle prend en paramètre le type d’un pokémon, et pour chaque type existant, on associe le nom d’une classe de Materialize. On combine ensuite cette classe avec une autre classe « chip« , à la ligne 53, qui permet de définir un petit bloc avec Materialize. En combinant ces deux classes, on obtiens donc un petit bloc d’une certaine couleur. 😇

Du coup, à la ligne 67, on applique cette classe sur chacun des types du pokémon, et on obtiens de petits bloc avec la bonne couleur !