Extendiendo transformadores de Style Dictionary
Adaptamos los transformadores para que trabajen con la nueva especificación
En una pasada entrega vimos como podíamos de forma más o menos sencilla, adaptar Style Dictionary a la nueva especificación de design tokens que está siendo trabajada en un grupo dentro de la w3c.
Hoy seguimos en esta misma línea y veremos como podemos adaptar los transformadores existentes de Style Dictionary (SD) que trabajan bajo la nomenclatura CTI a lo que nuevo que se viene.
Breve recordatorio
Como han pasado varias semanas desde el artículo, hacemos a continuación un resumen de los problemas que nos encontramos con SD al usar ficheros JSON escritos con las nueva especificación:
No entiende la propiedad $value que guarda el valor del token.
No entiende la propiedad $description que guarda una breve descripción del token.
Espera que los tokens se organicen en explícitamente en Categoría - Tipo - Item para poder aplicar transformadores.
Los dos primeros puntos fueron resueltos en el mencionado artículo donde creamos nuestro propio parser para adaptar lo “nuevo” a lo “antiguo”. Os recomendamos que le echéis un ojo a esa parte para seguir entendiendo todo el proceso.
Como iremos viendo a lo largo de estos artículos, la ventaja más grande de Style Dictionary es que es muy extensible y adaptable a casi cualquier caso de uso.
Anatomía de un transformador
Para poder adaptar los transformadores necesitamos entender antes que es un transformador.
Style Dictionary define un transformador como un objeto Javascript compuesto de:
Una función matcher: El filtro de tokens sobre los que aplicaremos la transformación.
Una función transformer: La función que tomará un token y lo transformará.
Un nombre: Para identificar al transformador.
Además, este objeto nos permite decirle al transformador que parte del token vamos a transformar. Las partes a transformar son: valor, atributo y nombre.
Los transformadores más comunes son los que se hacen sobre el valor del token, por ejemplo imagina que tenemos este token:
{
"button": {
"background": {
"primary": {
"$type": "color",
"$value": "#009688"
}
}
}
}
Y queremos cambiar el tipo del color de hexadecimal a RGB. Para ello usaríamos un transformador sobre el valor del token.
Aquí podríamos hacer un nuevo transformador desde 0 y usar alguna librería como tinycolor2 para transformar el color.
Sin embargo, eso sería reinventar la rueda ya que Style Dictionary pone a nuestra disposición un conjunto bastante amplio de transformadores listos para usarse. La única pega es que filtran por categoría en lugar de por $type.
Esto no es un gran problema, ya que podemos crear un wrapper (envoltura) sobre el transformador de SD y adaptarlo a usar el $type para filtrar los tokens. La clave está en saber muy bien como funcionan los objetos en Javascript y como podemos aprovecharnos de la composición para crear nuevos objetos derivando otros.
Definiendo un transformador envoltorio
Esto puede sonar muy enrevesado, pero ya vais a ver que en la práctica es mucho más sencillo de lo que parece. Al final se trata de quedarnos con la parte que nos interesa de un transformador (recuerda que es un objeto formado por una función matcher, una función transformer y el tipo de transformador).
Style Dictionary nos ofrece un transformador llamado color/rgb que se aplica sobre un valor y precisamente hace exactamente lo que queremos. El problema? pues que su función matcher filtra por tokens cuya categoría sea “color”, pero nosotros en nuestro token no tenemos categoría, sino que tenemos un $type.
La solución es crear una envoltura que extienda el transformador y le podamos proporcionar una nueva función matcher.
Primero necesitamos acceder al transformador:
const StyleDictionary = require('style-dictionary');
const colorToRgbSD = StyleDictionary.transform['color/rgb'];
Style Dictionary guarda todos los transformadores en el objeto transform y podemos acceder al que queramos por su nombre.
Ahora vamos a realizar (no os asustéis :D) una composición por concatenación para crear un nuevo transformador igualito, pero cuya función matcher sea una nueva que nosotros haremos:
const colorToRgb = Object.assign({}, colorToRgbSD, {
name: 'w3c/color/rgb',
matcher: function (token) {
return token.$type === 'color';
}
});
¡Y la lo tendríamos! Ahora solo habría que registrarlo en Style Dictionary para poder usarlo:
StyleDictionary.registerTransform(colorToRgb);
Si os profundizar sobre los tipos de composición en Javascript, os dejamos por aquí un artículo interesante.
Conclusión
Como podéis ver SD es muy extensible y con unas pocas líneas de código podemos adaptar sus transformadores a que funcionen con la nueva especificación.
Evidentemente el ejemplo que hemos visto hoy es simple, pero puede hacerse con cualquiera de los transformadores que hay pre configurados y cuya lista podéis encontrar aquí.
Muchas gracias por leernos ;)