Como abandonamos o uso do Styled-System para criar componentes e inventamos nossa própria bicicleta

Olá a todos! Meu nome é Sasha, sou co-fundador e desenvolvedor chefe em tempo parcial da Quarkly. Neste artigo, quero falar sobre como o conceito de CSS atômico, ao qual aderimos, juntamente com as deficiências da funcionalidade do Styled-System (e Rebass, como um caso especial do uso desta biblioteca) nos incentivaram a criar nossa própria ferramenta, que chamamos de Atomize.

Um pequeno preâmbulo. Nosso projeto Quarkly é uma mistura de um editor gráfico (como Figma, Sketch) e um designer de site (como Webflow) com a adição da funcionalidade inerente ao IDE clássico. Sobre a Quarkly, escreveremos um post separado, há algo a dizer e o que mostrar, mas hoje falaremos sobre o Atomize mencionado acima.

Atomize é a base de todo o projeto e nos permite resolver problemas que seriam impossíveis ou difíceis de resolver usando o Styled-System e Rebass. No mínimo, a solução seria muito menos elegante.

Se houver pouco tempo para dominar toda a postagem agora, você poderá se familiarizar com o Atomize em nosso GitHub .

E para tornar o conhecimento mais agradável, estamos lançando uma competição para a montagem de componentes de reação usando o Atomize. Mais sobre isso no final do post.

Como tudo começou


Começando a desenvolver o Quarkly, concordamos que queremos dar ao usuário a capacidade de digitar componentes, mas sem a necessidade de usar um arquivo CSS separado. Para tornar o código o mais minimalista possível, mas mantenha todos os recursos CSS, em contraste com os estilos embutidos.

A tarefa não é inovadora e, à primeira vista, é completamente resolvida com a ajuda do Styled-System e Rebass. Mas essa funcionalidade não foi suficiente para nós e, além disso, encontramos os seguintes problemas:

  • trabalho desconfortável com pontos de interrupção;
  • falta de capacidade de escrever estilos para o foco do estado, foco etc;
  • O mecanismo de trabalhar com tópicos nos pareceu não ser flexível o suficiente.

O que é o Atomize (brevemente)


imagem

Dentre os principais recursos do Atomize, podemos destacar o seguinte:

  • a capacidade de usar variáveis ​​do tópico em propriedades css compostas;
  • suporte para pairar e quaisquer outras pseudo-classes;
  • aliases curtos para cada propriedade (como emmet);
  • a capacidade de especificar estilos para um ponto de interrupção específico, mantendo a legibilidade da marcação;
  • interface minimalista.

O Atomize tem dois objetivos principais:

  • criar componentes que suportem CSS e temas atômicos;
  • criando widgets para edição interativa no projeto Quarkly.

Atomize as instruções de uso


Antes de iniciar o trabalho, é necessário estabelecer as dependências:

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

Atomize é um wrapper em torno do componente com estilo e tem uma API semelhante. Basta chamar o método com o nome do elemento necessário:

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

Na saída, obtemos um componente de reação que pode aceitar qualquer CSS como suporte.
Para facilitar o uso, foi desenvolvido um sistema de alias de propriedade. Por exemplo, bgc === backgroundColor

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

Uma lista completa de propriedades e aliases pode ser encontrada aqui .

O mecanismo de herança de reação também é fornecido:

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

Trabalhar com temas


Sobre isso, parece-me, é necessário contar com mais detalhes. Os temas no Quarkly são baseados em variáveis ​​CSS. O principal recurso é a capacidade de reutilizar variáveis ​​dos adereços e do próprio tópico, sem a necessidade de abstrações adicionais na forma de funções de modelo e subsequente processamento adicional pelo usuário.

Para usar variáveis ​​do tópico, basta descrever a propriedade no tópico e fazer referência a essa propriedade usando o prefixo "-".

Variáveis ​​podem ser usadas como em JSX:

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

(A cor # 04080C está disponível na propriedade --colors-dark).

Portanto, no próprio assunto:

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 a variável das cores, conectando-a ao tema de bordas)

Para cores na marcação JSX, é fornecida uma sintaxe simplificada:

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

Para trabalhar com expressões de mídia, os temas têm um ponto de interrupção.
Você pode adicionar um prefixo a qualquer propriedade na forma de um nome de chave de ponto de interrupção.

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>
);

O código fonte dos tópicos pode ser encontrado aqui .

Efeitos


A principal diferença entre o Atomize e o Styled-System são os "efeitos". O que é e por que é necessário?
Vamos imaginar que você crie um componente Button, altere sua cor e borda, mas como atribuir estilos a pairar, focar etc? Aqui os efeitos vêm para o resgate.

Ao criar um componente, basta transferir o objeto com a configuração:

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

A chave é o prefixo no nome dos objetos e o valor é o seletor CSS. Assim, encerramos a necessidade de todas as pseudo-classes.

Agora, se especificarmos o prefixo do cursor para qualquer propriedade CSS, ele será aplicado com um certo efeito. Por exemplo, quando você passa o mouse sobre:

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

Você também pode combinar efeitos com expressões de mídia:

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

Alguns exemplos


Para visualizar as informações acima, vamos agora montar um componente interessante. Nós preparamos dois exemplos:


No segundo exemplo, usamos a maior parte da funcionalidade, além de uma API externa.

Mas isso não é tudo


O segundo objetivo do Atomize, como você mencionou acima, é criar widgets no Quarkly com base em componentes de reação personalizados.

Para fazer isso, basta agrupar seu componente no Atomize e descrever sua configuração para que o Quarkly possa entender quais propriedades podem ser editadas interativamente:

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" }
);

Os campos de configuração para o componente têm esta aparência:

  • efeitos - define pseudo-classes do navegador (foco, foco, etc);
  • descrição - uma descrição do componente que aparecerá quando o cursor passar o mouse sobre seu nome;
  • propInfo - configuração dos controles que serão exibidos no painel direito (guia props).

Como determinar os acessórios que serão exibidos no painel direito (guia acessórios):

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

Possíveis opções de controle:

  • entrada
  • selecionar
  • cor
  • Fonte
  • sombra
  • transição
  • transformar
  • filtro,
  • fundo
  • ícone da caixa de seleção,
  • ícone de rádio,
  • grupo de rádio
  • caixa de seleção.

Mais um exemplo. Aqui, adicionamos nosso componente ao sistema e agora podemos editá-lo interativamente:


Obrigado a quem dominou o material até o fim! Peço desculpas antecipadamente pela confusão, esta é a primeira experiência ao escrever esses artigos. Eu ficaria grato pelas críticas.

E agora a competição!


Para aquecer um pouco o interesse da comunidade em conhecer melhor o Atomize, decidimos seguir o caminho simples e compreensível (como o próprio Atomize) - estamos lançando um concurso!

Todas as informações sobre os termos, regras e prêmios estão disponíveis no site oficial do concurso.

Resumindo: para participar e vencer, você precisa criar (ou encontrar um componente interessante e útil pronto para o React) e adaptá-lo aos requisitos do Atomize. Selecionaremos e premiaremos os vencedores em várias categorias ao mesmo tempo. Prêmios adicionais de nossa equipe no caso de adicionar seu componente ao Quarkly são garantidos.

All Articles