Crea tu sistema de íconos SVG en React

Crea un sistema de íconos SVG personalizado en React, una de las librerías más utilizadas en el mundo del desarrollo web

Diseño web
Lectura de 8 minutos
13 jun. 2019
Crea tu sistema de íconos SVG en React

Los íconos creados con SVG son el pan de cada día dentro del mundo del diseño web. Anteriormente te hablé sobre por qué debes utilizar SVG en lugar de icon fonts y cómo crear tu paquete de íconos SVG con html y css planos, pero hoy hablaremos sobre cómo crear tu sistema de íconos SVG utilizando React. Cabe aclarar que para este ejercicio necesitarás conocimientos básicos en React, SVG y CSS.

¿Por qué React y no < use />?

En el ejercicio anterior te enseñé a crear tu paquete de íconos utilizando la etiqueta <use/>, la cual tiene como función llamar al ícono que necesitáramos mostrar. Si bien haremos algo parecido, con <use/> tenemos un pequeño problema y es que algunos navegadores no son 100% compatibles. Tal vez no serán muchos los usuarios que utilicen estos navegadores, pero si quieres asegurarte de dar compatibio sistema con React, adelante.

Guardando nuestro código SVG

Lo primero que haremos es crear un archivo donde iremos agregando nuestro código SVG, es recomendable que dicho archivo lo tengas en un ruta que sea de fácil acceso, ya que trabajarás de forma recurrente con él. Para esta ocasión nombraremos el archivo como icons.js

Una vez creado importaremos React y Fragment (puedes evitar la importación de Fragment utilizando su sintaxis corta <></>)

import React, { Fragment } from 'react'

Para un mejor orden de nuestro archivo, crearemos una clase Icon la cual recibirá como parámetros el viewBox (el atributo que contiene las coordenadas de inicio y tamaño del svg) y el código SVG de cada ícono que vayamos agregando.

class Icon {
  constructor(viewBox, svg) {
    this.viewBox = viewBox
    this.svg = <Fragment>{svg}</Fragment>
  }
}

Después crearemos otro objeto llamado svgs, en el que instaciamos la clase Icon en cada propiedad para crear los íconos. Es importante que los nombres sean descriptivos, ya que no habrá forma directa de visualizarlos desde el editor de código. Te aconsejo que minimices tu código por línea, para que sea más fácil manejarlo

const svgs = {
	// Para este ejemplo usaremos tres íconos de redes sociales
	'youtube': new Icon("0 0 512 512", <path d="M490.24,113.92c-13.888-24.704-28.96-29.248-59.648-30.976C399.936,80.864,322.848,80,256.064,80c-66.912,0-144.032,0.864-174.656,2.912c-30.624,1.76-45.728,6.272-59.744,31.008C7.36,138.592,0,181.088,0,255.904C0,255.968,0,256,0,256c0,0.064,0,0.096,0,0.096v0.064c0,74.496,7.36,117.312,21.664,141.728c14.016,24.704,29.088,29.184,59.712,31.264C112.032,430.944,189.152,432,256.064,432c66.784,0,143.872-1.056,174.56-2.816c30.688-2.08,45.76-6.56,59.648-31.264C504.704,373.504,512,330.688,512,256.192c0,0,0-0.096,0-0.16c0,0,0-0.064,0-0.096C512,181.088,504.704,138.592,490.24,113.92z M192,352V160l160,96L192,352z" />),
  'facebook': new Icon("0 0 96.124 96.123", <path d="M72.089,0.02L59.624,0C45.62,0,36.57,9.285,36.57,23.656v10.907H24.037c-1.083,0-1.96,0.878-1.96,1.961v15.803c0,1.083,0.878,1.96,1.96,1.96h12.533v39.876c0,1.083,0.877,1.96,1.96,1.96h16.352c1.083,0,1.96-0.878,1.96-1.96V54.287h14.654c1.083,0,1.96-0.877,1.96-1.96l0.006-15.803c0-0.52-0.207-1.018-0.574-1.386c-0.367-0.368-0.867-0.575-1.387-0.575H56.842v-9.246c0-4.444,1.059-6.7,6.848-6.7l8.397-0.003c1.082,0,1.959-0.878,1.959-1.96V1.98C74.046,0.899,73.17,0.022,72.089,0.02z" />),
  'twitter': new Icon("0 0 612 612", <path d="M612,116.258c-22.525,9.981-46.694,16.75-72.088,19.772c25.929-15.527,45.777-40.155,55.184-69.411c-24.322,14.379-51.169,24.82-79.775,30.48c-22.907-24.437-55.49-39.658-91.63-39.658c-69.334,0-125.551,56.217-125.551,125.513c0,9.828,1.109,19.427,3.251,28.606C197.065,206.32,104.556,156.337,42.641,80.386c-10.823,18.51-16.98,40.078-16.98,63.101c0,43.559,22.181,81.993,55.835,104.479c-20.575-0.688-39.926-6.348-56.867-15.756v1.568c0,60.806,43.291,111.554,100.693,123.104c-10.517,2.83-21.607,4.398-33.08,4.398c-8.107,0-15.947-0.803-23.634-2.333c15.985,49.907,62.336,86.199,117.253,87.194c-42.947,33.654-97.099,53.655-155.916,53.655c-10.134,0-20.116-0.612-29.944-1.721c55.567,35.681,121.536,56.485,192.438,56.485c230.948,0,357.188-191.291,357.188-357.188l-0.421-16.253C573.872,163.526,595.211,141.422,612,116.258z" />),
	// Muy importante agregar un valor por default que regrese null
	// para evitar problemas por si llegamos a escribir mal el nombre de un ícono
	'default': null
}

export default svgs

Creando nuestro componente < Icon />

Ya tenemos listo nuestro archivo con los códigos de nuestros íconos, el siguiente paso es crear el componente <Icon/> donde los iremos llamando. En este componente debemos importar nuestro archivo de íconos y como propiedades recibirá el nombre del ícono que renderizará. Como un extra también le pasaremos unlick. Nunca sabes cuándo se vayan a necesitar y mejor agregarlos de una vez.

import React from "react";
// Importamos nuestro objeto desde el archivo de íconos
import svgs from "./icons";


const Icon = ({ svg, classes, click, title }) => {
  // Ingresaremos el nombre del ícono con la propiedad svg
  // de nuestro ícono en el objeto de íconos
  // Junto con una condicional para buscar el valor por
  // default que retornará null en caso de no encontrar coin svgs['default']
  // Estructura de un elemento SVG utilizando los datos de nuestro
  // archivo de íconos y las propiedades que le pasamos
  const svgRender = svgs[svg] || svgs.default;
  return (
    <svg
      viewBox={svgRender.viewBox}
      className={classes}
      title={title}
      xmlns="http://www.w3.org/2000/svg"
    >
      {svgRender.svg}
    </svg>
  );
};

export default Icon;

Dando estilos a nuestros íconos

Es hora de darle estilos a nuestros íconos al puro estilo de EDteam. Haremos que cada ícono tome el contexto de color y tamaño de donde se esté utilizando, te recomiendo no añadir estilos específicos como márgenes, porque nunca sabes en qué lugar terminarás usando tu componente de íconos y lo que menos deseas es tener un archivo donde se sobreescriban estilos.

.svg-icon {
	height  : 1em;
   fill    : currentcolor;
  /* currentColor actua como una variable tomando 
     el color el nodo padre. 
     Si estás utilizando vectores que poseen distintos 
     rellenos, no serán afectados por esta línea
  */
}

Usando nuestro componente

Y listo, ya tenemos todo configurado en nuestro sistema de íconos creado en React, lo único que nos hace falta es empezar a utilizarlo. He aquí un pequeño ejemplo:

<p><Icon svg="facebook" classes="svg-icon" title="Facebook"/><span>Danos like en facebook</span></p>

<!-- Como recordarás no agregamos un ícono para linkedin, por lo que el componente no renderizará nada
     pero eso no afectará al resto de los íconos -->
<p><Icon svg="linkedin" classes="svg-icon" title="Linkedin"/><span>Conéctate en linkedin</span></p>

Después de leer este artículo, tu ki en el manejo de íconos está por los cielos gracias a EDteam. 🔥

Si tienes alguna duda o sugerencia, recuerda que contamos con una comunidad donde estaré encantado de responder cualquier publicación.

Avatar

Alexis Mora Angulo

@jopzikVer perfil

Técnico en programación. Estudiante de diseño gráfico. Diseñador UX en EDteam. #NoTeDetengas #tambienSoyEDteam 🌊

Comentarios de los usuarios

TM
Tirone Mota

@tironemota82720

Recomiendo revisar código ya que no funciona a partir de la linea donde dice // Ingresaremos el nombre del ícono con la propiedad svg He intentado crear mi archivo de iconos SVG y no logro mostrar los iconos, podrás ayudarme

BR
benjamin rosario

@benjaminrosario94021

Saludos, Gracias por la ayuda. Tengo una duda, que tal que quiera agregar mas de un '<path />
'?

Recuerda iniciar sesión para comentar este articulo