Solução mínima de componentes estilizados CSS-in-JS para reação.
Há também algumas coisas que não são de gols.
as propriedade, .withComponent() método).attrs()defaultProps . import { styled } from '@minstack/styled' ;Estilo qualquer tipo de elemento HTML usando o nome da tag. O componente estilizado suporta todos os mesmos adereços (incluídos referidos, que são encaminhados) que o elemento HTML suporta.
const StyledComponent = styled ( 'div' ) `
color: black;
` ;O estilo do método do nome da tag também é suportado.
const StyledComponent = styled . div `
color: black;
` ; Estilo qualquer componente de reação que aceite uma propriedade className ou estenda os estilos de um componente já com estilo.
const StyledComponent = styled ( Component ) `
color: black;
` ; Propriedades extras podem ser adicionadas ao componente estilizado, definindo o parâmetro genérico da sequência de modelos. Geralmente, as propriedades de estilo devem ser prefixadas com $ para indicar que elas são usadas apenas para estilo. Qualquer nome de propriedade que começa com o caractere $ não será passado para o elemento HTML subjacente como um atributo.
interface ComponentStyleProps {
$font ?: string ;
}
const StyledComponent = styled ( 'div' ) < ComponentStyleProps > `
font-family: ${ ( props ) => props . $font } ;
` ; Use o utilitário styled.global para criar componentes de estilo global.
const GlobalStyle = styled . global `
body,
html {
margin: 0;
padding: 0;
}
` ;As propriedades de estilo também podem ser adicionadas aos estilos globais.
interface GlobalStyleProps {
$font ?: string ;
}
const GlobalStyle = styled . global < GlobalStyleProps > `
body,
html {
font-family: ${ ( props ) => props . $font } ;
}
` ; Definir quadros-chave ou fontes é o mesmo que definir qualquer outro estilo. Como eles não são escoposos a nenhum componente em particular, eles provavelmente devem ser usados apenas em estilos globais. Para evitar colisões de nomes, use o utilitário getId incluído para gerar nomes exclusivos para CSS.
const openSansFont = getId ( 'font/open-sans' ) ;
const slideInAnimation = getId ( 'keyframes/slide-in' ) ;
const GlobalStyle = styled . global `
@font-face {
font-family: ${ openSansFont } ;
src: url('/fonts/OpenSans-Regular-webfont.woff') format('woff');
}
@keyframes ${ slideInAnimation } {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
` ;
const StyledComponent = styled ( 'div' ) `
font-family: ${ openSansFont } ;
animation-name: ${ slideInAnimation } ;
` ; Passe um gancho de tema (ou qualquer função) que retorne um tema ao utilitário createStyled . O valor do tema estará disponível, pois o segundo argumento foi transmitido para qualquer modelo de sequência de modelos estilizados.
// File: styled-with-theme.ts
import { createStyled } from '@minstack/styled' ;
export const styled = createStyled ( useTheme ) ; Isso cria uma instância styled fortemente digitada. Use esta instância em vez da instância interna.
import { styled } from './styled-with-theme' ;
const ThemedComponent = styled ( 'div' ) `
color: ${ ( props , theme ) => theme . fgColor } ;
background-color: ${ ( props , theme ) => theme . bgColor } ;
` ; Todo o CSS mais o ninho é suportado.
Para aplicar estilos diretamente ao elemento ou componente HTML sendo estilizado, use propriedades CSS no nível superior do modelo marcado (sem bloco circundante).
const StyledComponent = styled ( 'div' ) `
color: red;
` ;As propriedades CSS de nível superior serão embrulhadas em um seletor de classe de estilo dinâmico
. _rmsds7y13d_ {
color : red;
}Use blocos de regras CSS para estilizar crianças do componente com estilo.
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
}
` ;A classe dinâmica estilizada será automaticamente presa a todos os seletores para torná -los "escopo".
. _rmsds7y13d_ . child {
color : blue;
}Todo componente com estilo (exceto estilos globais) pode ser usado como seletor.
const StyledComponentA = styled ( 'div' ) `
color: blue;
` ;
const StyledComponentB = styled ( 'div' ) `
${ StyledComponentA } {
background-color: yellow;
}
` ; Cada componente com estilo possui uma classe estática exclusiva que é gerada na criação. O método toString() do componente estilizado retorna uma seleção (por exemplo. "._rmsss7y13d_" ) para essa classe estática.
. _rmsds7y13d_ . _rmsss7y13d_ {
color : red;
} A classe estática é gerada a partir do nome de exibição do componente, a parte estática do modelo de estilo, classes estáticas herdadas (ao estender outro componente com estilo) e o número de componentes criados anteriormente que compartilham a mesma "impressão thumb -impressão". Na maioria dos casos, isso deve tornar as classes estáticas estáveis entre as renderizações SSR e do cliente. Se ocorrer problemas de SSR da classe estática, provavelmente será devido a componentes com a mesma impressão digital com uma ordem de criação instável. Tente alterar o displayName usando o método .withConfig() para tornar a impressão digital do componente problemática exclusiva.
const StyledComponent = styled . div . withConfig ( { displayName : 'StyledComponent' } ) `
color: red;
` ;Blocos de regras de ninho para criar seletores mais complexos.
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
.grandchild {
color: green;
}
}
` ;Assim como a classe dinâmica estilizada é presa aos seletores de nível superior, os seletores de pais também são presos aos seletores infantis.
. _rmsds7y13d_ . child {
color : blue;
}
. _rmsds7y13d_ . child . grandchild {
color : green;
} Referências de seletor de pais ( & ) funcionam da mesma maneira que fazem no SCSS/SASS. O único detalhe extra é que, quando um seletor de pais é usado na raiz do estilo (não aninhada dentro de um bloco pai), ele se refere à classe de estilo exclusiva do estilo atual, que é o seletor de blocos pai implícito/virtual para o estilo.
const StyledComponent = styled ( 'div' ) `
&& {
color: red;
}
&:hover {
color: blue;
}
.parent & {
color: green;
}
` ; Todos os CSS AT-RULES são suportados (exceto @charset que não é permitido dentro <style> elementos).
const StyledComponent = styled ( 'div' ) `
@media screen and (min-width: 900px) {
color: red;
}
.child {
@media screen and (min-width: 600px) {
.grandchild {
color: blue;
.adopted & {
color: green;
}
}
}
}
` ;O AT-RULES será içado conforme necessário, e os seletores de pais serão tratados da mesma maneira que seriam sem o intervalo de regra.
@media screen and ( min-width : 900 px ) {
. _rmsds7y13d_ {
color : red;
}
}
@media screen and ( min-width : 600 px ) {
. _rmsds7y13d_ . child . grandchild {
color : blue;
}
. adopted . _rmsds7y13d_ . child . grandchild {
color : green;
}
} Se um valor da propriedade CSS estiver "vazio" (string vazia, false , null , undefined ou "" ), toda a propriedade será omitida do estilo.
const StyledComponent = styled ( 'div' ) `
color: ${ null } ;
background-color: red;
` ;A propriedade Color não está incluída porque não tem valor.
. _rmsds7y13d_ {
background-color : red;
} Os estilos podem conter comentários de bloco ( /* */ ) e linha ( // ). Os comentários nunca são incluídos nas folhas de estilo renderizadas.
const StyledComponent = styled ( 'div' ) `
// This is a comment.
/* And so...
...is this. */
` ; A função Modelo Tagded styled.string Retorna uma string de estilo simples com todos os valores interpolados. Somente valores estáticos são permitidos (sem funções). Os valores de propriedade vazia ( null , undefined , false e "" ) funcionam da mesma maneira que fazem em componentes estilizados e fazem com que a propriedade seja omitida.
const fontHelper = styled . string `
font-family: Arial, sans-serif;
font-weight: 400;
font-size: ${ size } ;
` ;
// Then use in a styled component or another helper.
const StyledComponent = styled ( 'div' ) `
${ fontHelper }
color: red;
` ; O ajudante styled.string não tem efeitos colaterais e faz muito pouco trabalho, por isso também é seguro usar em funções.
const shadow = ( depth : number ) => {
return styled . string `
-moz-box-shadow: 0 ${ depth } px ${ depth } px black;
-webkit-box-shadow: 0 ${ depth } px ${ depth } px black;
box-shadow: 0 ${ depth } px ${ depth } px black;
` ;
} ;
// Then use in a styled component or another helper.
const StyledComponent = styled ( 'div' ) < { $shadowDepth : number } > `
${ ( props ) => shadow ( props . $shadowDepth ) }
color: red;
` ; Use o wrapper StyledTest para produzir instantâneos com nomes de classes e informações de estilo estável.
const container = render ( < MyStyledComponent /> , { wrapper : StyledTest } ) ;
expect ( container ) . toMatchSnapshot ( ) ; // Snapshot
<div>
<div
class="_test-dynamic-0_ _test-static-0_"
>
Hello, world!
</div>
<style>
._test-dynamic-0_ {
padding: 1rem;
}
</style>
</div>
Um StyledProvider pode substituir o cache , manager e renderer padrão. Nenhum provedor é necessário para a operação padrão.
const cache = createStyledCache ( ) ;
const manager = createStyledManager ( ) ;
const renderer = createStyledRenderer ( ) ;
render (
< StyledProvider cache = { cache } manager = { manager } renderer = { renderer } >
< App />
</ StyledProvider > ,
) ; O componente StyledTest é um StyledProvider pré-configurado que injeta versões de teste dos três recursos para substituir os nomes das classes e capturar estilos.
NOTA: O cache, gerente e renderizador fornecidos não devem mudar ao longo da vida de um componente com estilo. Um erro será lançado (ou logado na produção) se eles sofrerem.
Use createSsrStyledManager e o StyledProvider para capturar estilos ao renderizar o aplicativo no servidor.
const manager = createSsrStyledManager ( ) ;
const html = renderToString (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ;
const html = `
<!doctype HTML>
<html>
<head>
${ manager . getStyleTags ( ) }
</head>
<body>
<div id="root">
${ html }
</div>
</body>
</html>
` ; O método getStyleTags() do SSR Manager retorna uma única string html que contém apenas tags <style> . Também existem métodos getStyleElement() (React Elements Array) e getCss() (CSS Strings Array).
Use createStyledManager (ou createSsrStyledManager ) e o StyledProvider para definir um nonce em todos os estilos injetados.
const manager = createStyledManager ( nonce ) ;
render (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ; | Recurso | Montos com estilo | Goober | Componentes estilizados | Emoção | |
|---|---|---|---|---|---|
| Biblioteca | |||||
| Tamanho do pacote (aprox. Kb) [1] | 2.8 | 1.2 | 13.3 | 9.1 | |
| Zero dependências | ? | ? | ? | ? | |
| TypeScript Native | ? | ? | ? | ? | |
| API | |||||
| Estilos de modelo marcados | ? | ? | ? | ? | |
| Estilos dinâmicos | ? | ? | ? | ? | |
| Estilos de objeto | ? | ? | ? | ? | |
| Estilos globais | ? | ? | ? | ? | |
Polimorfismo ( as ) | ? | ? | ? | ? | |
Mapeamento de propriedades ( attrs ) | ? | ? | ? | ? | |
| Tempo [2] | ? | ? | ? | ? | |
| Ssr | ? | ? | ? | ? | |
| Teste de instantâneo | ? | ? | ? | ? | |
| Estilo | |||||
| Sintaxe básica CSS [3] | ? | ? | ? | ? | |
CSS @media | ? | ? | ? | ? | |
CSS @keyframes | ? | ? | ? | ? | |
CSS @font-face | ? | ⭕ | ⭕ | ? | |
CSS @import | ? | ⭕ | ? | ? | |
Outras regras CSS @ | ? | ⭕ | ⭕ | ⭕ | |
| Prefixando do fornecedor [4] | ? | ? | ? | ? | |
| Regra nidificação | ? | ? | ? | ? | |
Seletores de pais ( & ) | ? | ? | ? | ? | |
| Seletores de componentes com estilo [5] | ? | ? | ? | ? |
styled (após troca de árvores, minificação e GZIP) calculada usando o Webpack Bundle Analyzer. Goober é muito semelhante a esta solução. É tão rápido, menor e tem suporte para alguns recursos extras (estilos de objetos e propriedades as ). Então, quais são as desvantagens de Goober e por que eu usaria isso?
StyledTest , que não apenas permite testes de instantâneo, mas também faz de uma maneira que seja a estrutura de teste agnóstica.setup() que configura a única instância global da API , e isso não altera o tipo de tema. Estender o tipo de tema pode ser realizado com a fusão da declaração, mas isso é novamente global e não é muito seguro. Esta biblioteca fornece à fábrica createStyled() que retorna uma nova instância da API , que tem um tema fortemente digitado.styled.div em vez de styled('div') ). Esta biblioteca suporta styled.<tag> sem suporte de tempo de compilação.setup() ao usar o React. Essa biblioteca segira reagem e requer preact/compat ao usar o PreAct.Esta biblioteca é opinativa e deixa de fora alguns recursos que o Goober suporta. Isso é para reduzir o número de maneiras alternativas que os componentes estilizados podem ser projetados, o que aumenta a consistência do código e fornece uma melhor experiência geral do desenvolvedor (DX). Remover o suporte para duas maneiras diferentes de realizar a mesma coisa também significa que o tamanho da biblioteca e a sobrecarga de tempo de execução são reduzidos e/ou alocados para melhorar os recursos principais, e que a biblioteca é mais mantida em geral.
as para alterar o tipo de componente subjacente do componente com estilo. Esta biblioteca não é porque é inerentemente digitar inseguro e usar auxiliares de estilo (por exemplo, o utilitário styled.string ) fornece uma maneira melhor de reutilizar os estilos.Consulte o script benchmark.js para a implementação de referência.
| Biblioteca | Op/s |
|---|---|
| Montos com estilo | 144.970 |
| Goober | 142.028 |
| Emoção | 124.681 |
| Componentes estilizados | 118.072 |
getId aceita um argumento de namespace opcional (re-add).withConfig() aos modelos estilizadosgetId e de classe dinâmicastyled.div Alternative to styled('div') )useInsertionEffect do React, quando disponívelstyled.string Helper para construir cordas de estilo estáticoStyledProvidercreateSsrStyledManager )StyledTest )getId não aceita mais um argumentostyled.mixinrenderStylesToString