Cómo abandonamos el uso del Styled-System para crear componentes e inventamos nuestra propia bicicleta

¡Hola a todos! Mi nombre es Sasha, soy cofundador y desarrollador principal a tiempo parcial en Quarkly. En este artículo quiero hablar sobre cómo el concepto de CSS atómico, al que nos adherimos, junto con las deficiencias de la funcionalidad del sistema con estilo (y Rebass, como un caso especial de uso de esta biblioteca) nos animó a crear nuestra propia herramienta, que llamamos Atomize.

Un pequeño preámbulo. Nuestro proyecto Quarkly es una mezcla de un editor gráfico (como Figma, Sketch) y un diseñador de sitios (como Webflow) con la adición de la funcionalidad inherente al IDE clásico. Sobre Quarkly, escribiremos una publicación separada, hay algo que contar y qué mostrar, pero hoy hablaremos sobre el Atomize mencionado anteriormente.

Atomize es la base de todo el proyecto y nos permite resolver problemas que serían imposibles o difíciles de resolver utilizando Styled-System y Rebass. Como mínimo, la solución sería mucho menos elegante.

Si hay poco tiempo para dominar toda la publicación ahora, entonces puedes familiarizarte más con Atomize en nuestro GitHub .

Y para hacer que el conocimiento sea más agradable, estamos lanzando una competencia para ensamblar componentes de reacción usando Atomize. Más sobre esto al final del post.

Cómo todo empezó


Comenzando a desarrollar Quarkly, acordamos que queremos darle a nuestro usuario la capacidad de escribir en los componentes, pero sin la necesidad de usar un archivo CSS separado. Para que el código sea lo más minimalista posible, pero conserve todas las características de CSS, en contraste con los estilos en línea.

La tarea no es innovadora y, a primera vista, se resuelve completamente con la ayuda de Styled-System y Rebass. Pero esta funcionalidad no fue suficiente para nosotros, y además encontramos los siguientes problemas:

  • trabajo incómodo con puntos de interrupción;
  • falta de la capacidad de escribir estilos para el estado de desplazamiento, enfoque, etc.
  • El mecanismo de trabajar con temas no nos pareció lo suficientemente flexible.

Qué es atomizar (brevemente)


imagen

De las características clave de Atomize, podemos destacar lo siguiente:

  • la capacidad de usar variables del tema en propiedades css compuestas;
  • soporte para hover y cualquier otra pseudo-clase;
  • alias cortos para cada propiedad (como en emmet);
  • la capacidad de especificar estilos para un punto de interrupción específico, mientras se mantiene la legibilidad del marcado;
  • Interfaz minimalista.

Atomize tiene dos propósitos principales:

  • creando componentes que soporten CSS atómico y temas;
  • creando widgets para edición interactiva en el proyecto Quarkly.

Atomice las instrucciones de uso


Antes de comenzar, debe establecer las dependencias:

npm i react react-dom styled-components @quarkly/atomize @quarkly/theme

Atomize es un contenedor alrededor del componente con estilo y tiene una API similar. Es suficiente llamar al método con el nombre del elemento requerido:

import atomize from '@quarkly/atomize';
 
const MyBox = atomize.div();

En la salida, obtenemos un componente de reacción que puede aceptar cualquier CSS como accesorios.
Para facilitar su uso, se desarrolló un sistema de alias de propiedad. Por ejemplo, bgc === backgroundColor

ReactDOM.render(<MyBox bgc="red" />, root);

Puede encontrar una lista completa de propiedades y alias aquí .

El mecanismo de herencia de reacción también se proporciona:

const MySuperComponent = ({ className }) => {
   // some logic here
   return <div className={className} />;
};
 
const MyWrappedComponent = atomize(MySuperComponent);

Trabajar con temas


Sobre esto, me parece, es necesario contar más. Los temas en Quarkly se basan en variables CSS. La característica clave es la capacidad de reutilizar variables tanto de los accesorios como del tema en sí, sin la necesidad de abstracciones adicionales en forma de funciones de plantilla y posterior procesamiento adicional por parte del usuario.

Para usar variables del tema, es suficiente describir la propiedad en el tema y hacer referencia a esta propiedad usando el prefijo "-".

Las variables se pueden usar como en JSX:

import Theme from "@quarkly/theme";
 
const theme = {
   colors: {
       dark: "#04080C",
   },
};
export const MyComp = () => (
   <Theme>
       <Box bgc="--colors-dark" height="100px" width="100px" />
   </Theme>
);

(El color # 04080C está disponible a través de la propiedad --colors-dark)

Entonces, en el tema en sí:

import Theme from "@quarkly/theme";
 
const theme = {
   colors: {
       dark: "#04080C",
   },
   borders: {
       dark: "5px solid --colors-dark",
   },
};
export const MyComp = () => (
   <Theme>
       <Box border="--borders-dark" height="100px" width="100px" />
   </Theme>
);

(Reutilizamos la variable de los colores, conectándola al tema de los bordes)

Para los colores en el marcado JSX, se proporciona una sintaxis simplificada:

import Theme from "@quarkly/theme";
 
const theme = {
   colors: {
       dark: "#04080C",
   },
};
export const MyComp = () => (
   <Theme>
       <Box bgc="--dark" height="100px" width="100px" />
   </Theme>
);

Para trabajar con expresiones de medios, los temas tienen un punto de interrupción.
Puede agregar un prefijo a cualquier propiedad en forma de un nombre clave de punto de interrupción.

import Theme from "@quarkly/theme";
 
const theme = {
   breakpoints: {
       sm: [{ type: "max-width", value: 576 }],
       md: [{ type: "max-width", value: 768 }],
       lg: [{ type: "max-width", value: 992 }],
   },
   colors: {
       dark: "#04080C",
   },
   borders: {
       dark: "5px solid --colors-dark",
   },
};
export const MyComp = () => (
   <Theme>
       <Box
           md-bgc="--dark"
           border="--borders-dark"
           height="100px"
           width="100px"
       />
   </Theme>
);

El código fuente de los temas se puede encontrar aquí .

Efectos


La principal diferencia entre Atomize y Styled-System son los "efectos". ¿Qué es y por qué es necesario?
Imaginemos que crea un componente Button, cambia su color y borde, pero ¿cómo asignar estilos para desplazarse, enfocar, etc.? Aquí los efectos vienen al rescate.

Al crear un componente, simplemente transfiera el objeto con la configuración:

const MySuperButton = atomize.button({
 effects: {
   hover: ":hover",
   focus: ":focus",
   active: ":active",
   disabled: ":disabled",
 },
});

La clave es el prefijo en el nombre de los accesorios, y el valor es el selector CSS. Por lo tanto, cerramos la necesidad de todas las pseudo-clases.

Ahora, si especificamos el prefijo de desplazamiento a cualquier propiedad CSS, se aplicará con cierto efecto. Por ejemplo, cuando pasas el cursor sobre:

ReactDOM.render(<MySuperButton hover-bgc="blue" />, root);

También puede combinar efectos con expresiones multimedia:

ReactDOM.render(<MySuperButton md-hover-bgc="blue" />, root);

Algunos ejemplos


Para visualizar la información anterior, ahora reunamos algún componente interesante. Hemos preparado dos ejemplos:


En el segundo ejemplo, utilizamos la mayor parte de la funcionalidad, así como una API externa.

Pero eso no es todo


El segundo propósito de Atomize, como mencionó anteriormente, es crear widgets en Quarkly basados ​​en componentes de reacción personalizados.

Para hacer esto, simplemente envuelva su componente en Atomize y describa su configuración para que Quarkly pueda comprender qué propiedades se pueden editar de forma interactiva:

export default atomize(PokemonCard)(
 {
   name: "PokeCard",
   effects: {
     hover: ":hover",
   },
   description: {
     // past here description for your component
     en: "PokeCard — my awesome component",
   },
   propInfo: {
     // past here props description for your component
     name: {
       control: "input",
     },
   },
 },
 { name: "pikachu" }
);

Los campos de configuración para el componente se ven así:

  • efectos - define pseudo-clases del navegador (hover, focus, etc.);
  • descripción : una descripción del componente que aparecerá cuando el cursor se desplace sobre su nombre;
  • propInfo : configuración de controles que se mostrarán en el panel derecho (pestaña accesorios).

Cómo determinar los accesorios que se mostrarán en el panel derecho (pestaña accesorios):

propInfo: {
   yourCustomProps: { //  
       description: { en: "test" }, //    
       control: "input" //  
   }
}

Posibles opciones de control:

  • entrada
  • Seleccione
  • color
  • fuente
  • sombra
  • transición
  • transformar
  • filtrar,
  • antecedentes
  • icono de casilla de verificación,
  • icono de radio
  • grupo de radio
  • caja.

Un ejemplo mas. Aquí agregamos nuestro componente al sistema y ahora podemos editarlo interactivamente:


¡Gracias a quienes dominaron el material hasta el final! Pido disculpas de antemano por la confusión, esta es la primera experiencia en escribir tales artículos. Agradecería las críticas.

Y ahora la competencia!


Con el fin de calentar un poco el interés de la comunidad en un conocimiento más cercano de Atomize, decidimos seguir el camino simple y comprensible (como el propio Atomize): ¡estamos lanzando un concurso!

Toda la información sobre los términos, reglas y premios está disponible en el sitio web oficial del concurso.

En resumen: para participar y ganar, debe encontrar (o encontrar un componente listo) interesante y útil en React y adaptarlo a los requisitos de Atomize. Seleccionaremos y premiaremos a los ganadores en varias categorías a la vez. Se garantizan premios adicionales de nuestro equipo en caso de agregar su componente a Quarkly.

All Articles