Temas de componentes de react com variáveis ​​CSS

Este artigo mostra minha maneira pessoal de usar variáveis CSS para temas. Existem outras maneiras de implementar temas com CSS vars, alguns deles podem ser mais preferíveis a você.

Até recentemente, sempre que pensávamos em alterar temas em tempo de execução, buscávamos imediatamente algum tipo de solução JS / JSX. Isso pode ser tema através de componentes de ordem superior, passando temas como acessórios (geralmente com a ajuda de React.Context) ou usando bibliotecas populares como componentes estilizados.

Hoje, graças às 'propriedades personalizadas do CSS', também conhecidas como 'variáveis do CSS', mudamos o peso para o CSS simples. Ou seja, ainda é necessário um pouco de JavaScript, mas como você verá, ele desempenha um papel muito menor.

Por que usar propriedades personalizadas de CSS para temas

Otimização de performance

Outro motivo seria tornar os componentes da interface do usuário o mais universal possível. Isso significa usar tecnologias universais (JS, CSS, HTML), em oposição ao código específico da biblioteca / estrutura (por exemplo, 'componentes com estilo' ou até mesmo incorporar seu estilo nos componentes do React).

Isso é importante para manutenção e escala. É muito mais fácil “traduzir” os componentes da interface do usuário de uma tecnologia para outra quando a maior parte do estilo é feita usando CSS simples. Portanto, esteja migrando sua base de código para outra tecnologia ou mesmo criando outro aplicativo usando tecnologias diferentes, você achará muito mais fácil fazê-lo quando a maior parte do estilo for feita usando CSS simples.

Como uma observação importante, a manutenção e a escalabilidade também são uma função do uso das ferramentas certas. Eu pessoalmente uso o Bit para compartilhar e organizar todos os meus componentes de interface do usuário. Essa é a minha maneira de, essencialmente, construir um sistema de design para minha equipe sem perder um tempo precioso com isso. Diferentemente de outras ferramentas e metodologias, o Bit oferece a liberdade de enviar continuamente novos componentes de interface do usuário, de qualquer base de código para sua própria coleção de componentes no Bit.dev . A alternativa seria trabalhar em um projeto totalmente novo (um projeto de biblioteca da interface do usuário) apenas para documentar e compartilhar os componentes da interface do usuário.

https://bit.dev/

Um resumo desta metodologia

Antes de começarmos, pode ser mais fácil descrever as etapas dessa metodologia:

  1. Use dois tipos de variáveis CSS, 'propriedades selecionadas' e 'propriedades armazenadas': O primeiro grupo seria as variáveis que são realmente usadas como valores para todos os seus componentes de interface do usuário. O segundo grupo serviria como uma maneira de armazenar valores, um conjunto de valores para cada tema.

  2. O primeiro tipo de variáveis CSS, as 'propriedades selecionadas', não terão seus próprios valores constantes, mas apenas terá outras variáveis CSS, as 'propriedades armazenadas'. É assim que definimos um tema padrão.

  3. Vamos utilizar JS para substituir todas as variáveis que servem como valores para nossas 'propriedades sel cionadas' por outro conjunto de variáveis das 'propriedades armazenadas'.

Definir variáveis globais de CSS

Variáveis CSS (e o suporte total que eles têm em todos os navegadores populares) são algo que todos esperávamos. Eles não são apenas uma solução para armazenar paletas de cores e tamanhos padronizados (algo que estamos acostumados a resolver por pré-processadores como o SASS), mas na verdade transformam o CSS de ser completamente estático em ter algum tipo de dinâmica (algo que os pré-processadores não conseguem entregar, pelo menos não em tempo de execução).

A sintaxe para declarar uma variável CSS é bastante simples: é adicionada ao nome da variável. Observe que os nomes das variáveis diferenciam maiúsculas de minúsculas.

Para usar uma variável, envolva o nome da variável com var().

No exemplo abaixo, eu também configurei meus valores selecionados para o tema padrão 'light' usando as variáveis para o meu tema light, como valores.

Observe como eu defini minhas variáveis no nível raiz. Essa não é a única maneira de fazê-lo. As variáveis podem ser definidas em todos os seletores de CSS e até mesmo em consultas de mídia CSS - que, é claro, as tornariam mais específicas; esse é um recurso muito útil que não explorar neste artigo.

:root {
  /* Set the deafult values */
  --selected-primary-color: var(--light-primary-color);
  --selected-disabled-color: var(--light-disabled-color);

  /* Set the 'light' theme */
  --light-primary-color: #007bff;
  --light-disabled-color: #6c757d;

  /* Set the 'dark' theme */
  --dark-primary-color: #000000;
  --dark-disabled-color: #4a4a4b;
}

Abaixo, um exemplo de CSS para um componente Button. Observe como eu defini as propriedades relevantes para --selected- e não diretamente para um valor temático. Então, por exemplo, em vez de usar --dark-primary-color, estou usando --selected-primary-color.

.primary-btn {
    color: #fff;
    position: relative;
    font-size: 16px;
    padding: 10px;
    min-width: 120px;
    border-radius: 5px;
    background-color: var(--selected-primary-color);
    outline: unset;
    transition: background-color 0.3s ease, box-shadow 0.7s ease;
  }

  .primary-btn:disabled{
    background-color: var(--selected-disabled-color);
  }

Criar uma função 'setTheme'

A função abaixo coleta todas as --selected variáveis CSS usadas ( ). E define seus valores para as variáveis de tema selecionadas. Aqui, JS é usado apenas para substituir os valores de um conjunto limitado de variáveis CSS, para outro conjunto de valores.

 setTheme = (themeName) => {

// Get all 'selected' custom CSS properties from the ':root'.
// These are the variables that are actually used (as oppose to vars to store the alternatives from different themes)
const selectedCssProps = Array.from(document.styleSheets)
  .reduce(
    (acc, sheet) =>
      (acc = [
        ...acc,
        ...Array.from(sheet.cssRules).reduce(
          (def, rule) =>
            (def =
              rule.selectorText === ":root"
                ? [
                    ...def,
                    ...Array.from(rule.style).filter(name =>
                      name.startsWith("--selected")
                    )
                  ]
                : def),
          []
        )
      ]),
    []
  );

// Set the selected values to values of a different theme
selectedCssProps.forEach(prop => {
    // set each selected variable with its analog variable from the new theme
    document.documentElement.style.setProperty(prop, `var(--${themeName}${prop.substring(10)})`);
});

}

export default setTheme;

O método-chave aqui é o setProperty método que nos permite selecionar uma variável CSS / propriedade customizada e definir um novo valor.

document.documentElement.style.setProperty (<Variável CSS>, <Value>)

Deixe uma resposta
You May Also Like