cover

Cómo aplicar formato de moneda y fecha en Javascript


Cuando trabajamos en una aplicación, en particular de lado de la UI, el cómo mostramos la información es un punto importante para que nuestra interfaz sea entendible, estética y, por supuesto, funcional. En muchos casos esta información es texto plano que basta con mostrar tal como lo tenemos, pero en otros casos trabajamos con valores númericos, booleanos o cadenas de texto (strings) que necesitamos mostrar con formatos específicos.

En esta ocasión quiero centrarme en 2 de los más comunes, fechas y valores que querramos mostrar como moneda (e.j. $10.00).

Para estos casos seguramente has pensado que lo mejor sea utilizar una librería tipo date-fns o momentJS para el formato de fechas y dinero.js para el formato de moneda, pero puede no ser la mejor idea, ¿a qué me refiero? en muchos casos simplemente necesitamos cambiar Thu Aug 04 2022 16:42:27 GMT-0500 (hora de verano central) por 04/08/2022 o agregar un $ al valor númerico 10.00, e instalar una librería para solo hacer esto parece excesivo, ¿no crees?.

Las alternativas

Clase Date

Date.toLocaleDateString

Lo más simple es utilizar el método toLocaleDateString que nos proporciona la clase Date

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Si buscas utilizar el formato de diferentes regiones del mundo (locale):

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Y también puedes cambiar el formato en que se muestra el día o mes por ejemplo:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Las keys más utilizadas que podemos agregar al objeto de options son:

  • weekday, valores posibles => "narrow", "short", "long"
  • era, valores posibles => "narrow", "short", "long"
  • year, valores posibles => "numeric", "2-digit"
  • month, valores posibles => "narrow", "short", "long", "numeric", "2-digit"
  • day, valores posibles => "numeric", "2-digit"
  • hour, valores posibles => "numeric", "2-digit"
  • minute, valores posibles => "numeric", "2-digit"
  • second, valores posibles => "numeric", "2-digit"
  • timeZoneName, valores posibles => "narrow", "short", "long"
  • hour12, selecciona si usar horario de 12 horas o 24 horas y depende del locale, valores posibles => "true", "false"

Hay otras opciones que podemos agregar que son menos comunes, si quieres explorarlas te comparto este artículo donde las puedes explorar.

Por último, este método nos permite añadir un locale de respaldo en caso de que el que hayamos solicitado no esté soportado:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Muy útil, ¿no te parece?. Esta alternativa es perfecta para cuando las operaciones que necesitamos hacer con las fechas no son complicadas. Sin embargo, te quiero compartir otra alternativa, perfecta para casos donde necesitas un poco más de opciones para formatear las fechas y (aquí va la sorpresa) que también nos permite dar formato a listas de valores (arrays) y números (además de formato a fechas, claro), ¡Una verdadera maravilla de JavaScript!

Objeto Intl

El objeto Intl nos permite acceder a la API de internacionalización de ECMAScript, que proporciona comparación de cadenas sensible al idioma, formato de números y formato de fecha y hora. El objeto Intl proporciona acceso a varios métodos útiles para internacionalización y a otras funciones sensibles al lenguaje.

Intl.DateTimeFormat

Siguiendo la línea de formato de fechas, veamos cómo es que haríamos lo mismo que hicimos con Date, pero ahora con Intl:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Al igual que con el método toLocaleDateString, podemos pasar un objeto de opciones para modificar el formato con que se muestran algunas secciones de la fecha:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Las keys que vimos previamente también aplican para DateTimeFormat. Sin embargo, tenemos la posibilidad de añadir algunas otras para configurar aún más cómo es que queremos mostrar nuestras fechas, te dejo la referencia para que las puedas revisar por aquí.

A este punto no hay mucha diferencia o una razón en particular para usar una forma o la otra, más allá de tu preferencia personal, si la implementación que buscas es tan simple como lo anterior, pero ahora te voy a mostrar un método de Intl que me parece increible.

Intl.RelativeTimeFormat

Si lo que necesitas es mostrar una fecha en formato relativo, es decir, algo como "dentro de 3 días" o "el año pasado", entonces este método es perfecto.

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Nota: Para expresar fechas pasadas, el valor que colocamos es negativo

Si lo que quieres es cambiar el formato del mensaje, puedes pasar un objeto de options.

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Puedes revisar el resto de las opciones posibles aquí.

Importante: Observa que este método no recibe un objeto de fecha, solo recibe un valor númerico y un identificador temporal (day o month) que sirve para el formato internacionalizado. El cálculo para sacar el valor númerico lo tenemos que hacer nosotros, pero no te preocupes, más adelante de digo cómo.

¡Basta de fechas!

Como te mencioné al principio de este artículo, el formato de moneda es otro de los que posiblemente ocupes más y que también veremos aquí y sí, Intl también nos cubre con esto.

Intl.NumberFormat

Este método permite formatear los números en función del idioma, siendo el formato de moneda al que le daremos prioridad, pero igual te comentaré un poco los demás, ya sabes, por no dejar.

El uso es simple y muy similar a lo que hemos visto hasta el momento.

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Genial, ¿no?, vamos a mejorarlo.

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Importante: En los ejemplos anteriores el primer valor (es-ES o en-US) corresponde al locale y es el que determina realmente cómo es que se mostrará nuestro valor por lo que aunque estemos mostrando pesos mexicanos (MXN) el formato en que se muestra puede variar segun el locale, veamos un ejemplo:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

A pesar de que en los 2 casos estamos mostrando pesos mexicanos (MXN) indicado en la llave currency de las options, la forma en la que se muestra el valor es distinto debido a que los locales, son distintos, uno es formato europeo (es-ES o español de españa) y el otro es formato mexicano (es-MX).

Por último, hay otra propiedad de las options que podemos pasar que me parece interesante y que me gustaría compartirte, currencyDisplay.

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Puedes revisar el resto de las opciones posibles aquí.

Finalmente, quiero mencionar otras opciones que tiene NumberFormat, las unidades y los porcentajes

Unidades

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Puedes revisar el resto de las unidades posibles aquí.

Porcentaje

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Bonus

Adicional a lo que hemos visto quiero platicarte de otros métodos que tiene Intl que también son interesantes:

Intl.ListFormat

Este método es en realidad muy simple, nos permite mostrar una lista legible de valores para cada idioma partiendo de una array de valores

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Puedes cambiar la forma en la que se muestra la lista agregando la llave type al objeto de options:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Los valores posibles son:

  • conjunction, para listas de tipo "y"
  • disjunction para listas de tipo "o"
  • unit si la lista es de unidades de medida, que se suelen poner en forma de lista de modo diferente.

Intl.PluralRules

Este método lo podemos describir como algo más avanzado y está pensado para ser una ayuda cuando necesitamos pluralizar valores o palabras, pero ojo, no funciona pasando una cadena y que nos devuelva el valor pluralizado, el funcionamiento es de más bajo nivel.

Por ejemplo, en español, inglés u otros idiomas occidentales una viga mide 1 metro (singular), 3 metros (plural) o, curiosamente, 0 metros (plural aunque sea cero). Sin embargo, en árabe tiene otras acepciones para ciertos números.

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Como puedes observar, para los idiomas occidentales generalmente hay dos posibilidades: 'one' (singular) o 'other' (plural), y con eso podemos decidir si se le pone una "s" al final o no, por ejemplo:

Si hablamos de pez (singular) y peces (plural), no es simplemente agregar una s. Sin embargo, para casos más simples puede ser de mucha ayuda.

Ahora sí, para terminar...

Si llegaste hasta aquí, agradezco que te hayas tomado el tiempo de leer este post y quiero cerrar con lo que prometí antes: un par de algoritmos que nos ayuden a completementar y sacar el mayor provecho de lo que acabamos de ver.

Cambiar el estilo de cómo mostramos la fecha

Si queremos cambiar el caracter con el que mostramos la fecha, directamente con estos métodos no es posible, pero si hacemos un poco de algoritmia podemos lograrlo:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

Sacar los días entre 2 fechas para usarlos con RelativeTimeFormat

En realidad es muy simple ya que con JavaScript podes operar fechas de forma que podamos sacar como entero los días, años o meses entre 2 fechas.

Ejemplo con días:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
meta cover

Efectos secundarios con useEffect

Checa este otro Post

meta cover

Cómo Publicar tu proyecto Vite en Github Pages con el método más fácil

Checa este otro Post

¡Nuevo curso!

Animaciones web con React + Motion 🧙🏻