Solución mínima de componentes de estilo CSS-in-JS para React.
También hay algunas cosas que no son goles.
as propiedad, .withComponent() Método).attrs() )defaultProps . import { styled } from '@minstack/styled' ;Estilizar cualquier tipo de elemento HTML usando el nombre de la etiqueta. El componente de estilo admite todos los mismos accesorios (referencias incluidas, que se envían) que admite el elemento HTML.
const StyledComponent = styled ( 'div' ) `
color: black;
` ;El estilo del método del nombre de la etiqueta también es compatible.
const StyledComponent = styled . div `
color: black;
` ; Estilizar cualquier componente React que acepte una propiedad className , o extienda los estilos de un componente ya con estilo.
const StyledComponent = styled ( Component ) `
color: black;
` ; Se pueden agregar propiedades adicionales al componente de estilo configurando el parámetro genérico de la cadena de plantilla. En general, las propiedades de estilo deben estar prefijadas con $ para indicar que solo se usan para el estilo. Cualquier nombre de propiedad que comience con el personaje $ no se pasará al elemento HTML subyacente como un atributo.
interface ComponentStyleProps {
$font ?: string ;
}
const StyledComponent = styled ( 'div' ) < ComponentStyleProps > `
font-family: ${ ( props ) => props . $font } ;
` ; Use la utilidad styled.global Global para crear componentes de estilo global.
const GlobalStyle = styled . global `
body,
html {
margin: 0;
padding: 0;
}
` ;Las propiedades de estilo también se pueden agregar a los estilos globales.
interface GlobalStyleProps {
$font ?: string ;
}
const GlobalStyle = styled . global < GlobalStyleProps > `
body,
html {
font-family: ${ ( props ) => props . $font } ;
}
` ; Definir pañuelos clave o caras de fuentes es lo mismo que definir cualquier otro estilo. Dado que no están alcanzados a ningún componente en particular, probablemente solo deberían usarse en los estilos globales. Para evitar colisiones de nombres, use la utilidad getId incluida para generar nombres únicos seguros a 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 } ;
` ; Pase un gancho de tema (o cualquier función) que devuelva un tema a la utilidad createStyled . El valor del tema estará disponible a medida que el segundo argumento pase a cualquier valor funcional de cadena de plantilla de estilo.
// File: styled-with-theme.ts
import { createStyled } from '@minstack/styled' ;
export const styled = createStyled ( useTheme ) ; Esto crea una instancia styled fuertemente escrita. Use esta instancia en lugar de la instancia incorporada.
import { styled } from './styled-with-theme' ;
const ThemedComponent = styled ( 'div' ) `
color: ${ ( props , theme ) => theme . fgColor } ;
background-color: ${ ( props , theme ) => theme . bgColor } ;
` ; Todos los CSS Plus Nesting son compatibles.
Para aplicar estilos directamente al elemento HTML o componente que se está diseñando, use propiedades CSS en el nivel superior de la plantilla etiquetada (sin bloque circundante).
const StyledComponent = styled ( 'div' ) `
color: red;
` ;Las propiedades de CSS de nivel superior se envolverán en un selector de clases de estilo dinámico
. _rmsds7y13d_ {
color : red;
}Use bloques de reglas CSS para estilo niños del componente de estilo.
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
}
` ;La clase Dynamic Styled se preparará automáticamente a todos los selectores para que se "alcancen".
. _rmsds7y13d_ . child {
color : blue;
}Cada componente de estilo (excepto los estilos globales) se puede usar como selector.
const StyledComponentA = styled ( 'div' ) `
color: blue;
` ;
const StyledComponentB = styled ( 'div' ) `
${ StyledComponentA } {
background-color: yellow;
}
` ; Cada componente de estilo tiene una clase estática única que se genera en la creación. El método toString() del componente de estilo devuelve una cadena selectora (por ejemplo, "._rmsss7y13d_" ) para esa clase estática.
. _rmsds7y13d_ . _rmsss7y13d_ {
color : red;
} La clase estática se genera a partir del nombre de la pantalla del componente, la parte estática de la plantilla de estilo, clases estáticas heredadas (al extender otro componente de estilo) y el número de componentes creados anteriormente que comparten la misma "huella de pulgar". En la mayoría de los casos, esto debería hacer que las clases estáticas estables en la RSS y los renders de clientes. Si se producen problemas de SSR de clase estática, probablemente se deba a componentes con la misma huella digital que tiene una orden de creación inestable. Intente cambiar el displayName usando el método .withConfig() para que la huella digital del componente problemático sea única.
const StyledComponent = styled . div . withConfig ( { displayName : 'StyledComponent' } ) `
color: red;
` ;Bloques de reglas de nido para crear selectores más complejos.
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
.grandchild {
color: green;
}
}
` ;Al igual que la clase Dynamic Styled se prepara a los selectores de nivel superior, también los selectores de los padres se preparan para los selectores infantiles.
. _rmsds7y13d_ . child {
color : blue;
}
. _rmsds7y13d_ . child . grandchild {
color : green;
} Las referencias del selector de padres ( & ) funcionan de la misma manera que lo hacen en SCSS/SASS. El único detalle adicional es que cuando se usa un selector de padres en la raíz de estilo (no anidada dentro de un bloque principal), se refiere a la clase de estilo única del estilo actual, que es el selector de bloque parado implícito/virtual para el estilo.
const StyledComponent = styled ( 'div' ) `
&& {
color: red;
}
&:hover {
color: blue;
}
.parent & {
color: green;
}
` ; Todas las reglas AT CSS son compatibles (excepto @charset , que no está permitido dentro de los elementos <style> ).
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;
}
}
}
}
` ;Las reglas se izarán según sea necesario, y los selectores de los padres se manejarán de la misma manera que lo serían sin la interferencia intermedia.
@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;
}
} Si un valor de propiedad CSS está "vacío" (cadena vacía, false , null , undefined o "" ), entonces toda la propiedad se omitirá desde el estilo.
const StyledComponent = styled ( 'div' ) `
color: ${ null } ;
background-color: red;
` ;La propiedad de color no está incluida porque no tiene valor.
. _rmsds7y13d_ {
background-color : red;
} Los estilos pueden contener comentarios de bloque ( /* */ ) y línea de línea ( // ). Los comentarios nunca se incluyen en las hojas de estilo renderizadas.
const StyledComponent = styled ( 'div' ) `
// This is a comment.
/* And so...
...is this. */
` ; La función de plantilla etiquetada de styled.string devuelve una cadena de estilo simple con todos los valores interpolados. Solo se permiten valores estáticos (sin funciones). Los valores vacíos de la propiedad ( null , undefined , false y "" ) funcionan de la misma manera que lo hacen en los componentes de estilo, y hacen que la propiedad se omite.
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;
` ; El estilo ayudante styled.string no tiene efectos secundarios y hace muy poco trabajo, por lo que también es seguro usarlo en funciones.
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 el envoltorio StyledTest para producir instantáneas con nombres de clases estables e información de estilo.
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>
Un StyledProvider puede anular el cache , manager y renderer predeterminado. No se requiere ningún proveedor para la operación predeterminada.
const cache = createStyledCache ( ) ;
const manager = createStyledManager ( ) ;
const renderer = createStyledRenderer ( ) ;
render (
< StyledProvider cache = { cache } manager = { manager } renderer = { renderer } >
< App />
</ StyledProvider > ,
) ; El componente StyledTest es un StyledProvider preconfigurado que inyecta versiones de prueba de los tres recursos para reemplazar los nombres de clases y los estilos de captura.
Nota: El caché, el gerente y el renderizado proporcionados no deben cambiar durante la vida útil de un componente de estilo. Se lanzará un error (o se registrará en producción) si mutan.
Use createSsrStyledManager y StyledProvider para capturar estilos al representar la aplicación en el 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>
` ; El método getStyleTags() del administrador SSR devuelve una única cadena HTML que contiene solo etiquetas <style> . También hay getStyleElement() (React Elements Array) y getCss() (matriz CSS Strings).
Use createStyledManager (o createSsrStyledManager ) y el StyledProvider para establecer un nonce en todos los estilos inyectados.
const manager = createStyledManager ( nonce ) ;
render (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ; | Característica | Estilo minstack | Goober | Componentes de estilo | Emoción | |
|---|---|---|---|---|---|
| Biblioteca | |||||
| Tamaño del paquete (aprox. Kb) [1] | 2.8 | 1.2 | 13.3 | 9.1 | |
| Cero dependencias | ? | ? | ? | ? | |
| Nativo de mecanografiado | ? | ? | ? | ? | |
| API | |||||
| Estilos de plantilla etiquetados | ? | ? | ? | ? | |
| Estilos dinámicos | ? | ? | ? | ? | |
| Estilos de objeto | ? | ? | ? | ? | |
| Estilos globales | ? | ? | ? | ? | |
Polimorfismo ( as ) | ? | ? | ? | ? | |
Mapeo de propiedades ( attrs ) | ? | ? | ? | ? | |
| Temas [2] | ? | ? | ? | ? | |
| SSR | ? | ? | ? | ? | |
| Prueba de instantánea | ? | ? | ? | ? | |
| Estilo | |||||
| Sintaxis básica de CSS [3] | ? | ? | ? | ? | |
CSS @media | ? | ? | ? | ? | |
CSS @keyframes | ? | ? | ? | ? | |
CSS @font-face | ? | ⭕ | ⭕ | ? | |
CSS @import | ? | ⭕ | ? | ? | |
Otras reglas CSS @ | ? | ⭕ | ⭕ | ⭕ | |
| Prefijo de proveedores [4] | ? | ? | ? | ? | |
| Anidación de reglas | ? | ? | ? | ? | |
Selectores de padres ( & ) | ? | ? | ? | ? | |
| Selectores de componentes de estilo [5] | ? | ? | ? | ? |
styled (después de la sacudida de los árboles, la minificación y el GZIP) calculado utilizando el analizador de paquetes Webpack. Goober es muy similar a esta solución. Es igual de rápido, más pequeño y tiene soporte para algunas características adicionales (estilos de objetos y la propiedad as ). Entonces, ¿qué son las desventajas de Goober y por qué usaría esto en su lugar?
StyledTest que no solo habilita las pruebas de instantáneas, sino que lo hace de una manera que es el marco de prueba agnóstico.setup() que configura la única instancia global de la API , y esto no cambia el tipo de tema. Extender el tipo de tema se puede lograr con la fusión de la declaración, pero esto nuevamente es global y no es muy seguro. Esta biblioteca proporciona la fábrica createStyled() que devuelve una nueva instancia de API , que tiene un tema fuertemente escrito.styled.div en lugar de styled('div') ). Esta biblioteca es compatible con styled.<tag> sin soporte de tiempo de compilación.setup() cuando se usa React. Esta biblioteca se dirige a reaccionar y requiere preact/compat cuando se usa PREACT.Esta biblioteca es obstinada y deja de lado algunas características que Goober admite. Esto es para reducir la cantidad de formas alternativas en que se pueden diseñar componentes de estilo, lo que aumenta la consistencia del código, y proporciona una mejor experiencia de desarrollador (DX) general. Eliminar el soporte para dos formas diferentes de lograr lo mismo también significa que el tamaño de la biblioteca y la sobrecarga de tiempo de ejecución se reducen y/o se asignan a características centrales mejoradas, y que la biblioteca es más mantenible en general.
as para cambiar el tipo de componente subyacente del componente de estilo. Esta biblioteca no se debe a que sea inherentemente inseguro, y el uso de ayudantes de estilo (por ejemplo, la utilidad styled.string ) proporciona una mejor manera de reutilizar los estilos.Vea el script Benchmark.js para la implementación de referencia.
| Biblioteca | OP/S |
|---|---|
| Estilo minstack | 144,970 |
| Goober | 142,028 |
| Emoción | 124,681 |
| Componentes de estilo | 118,072 |
getId acepta un argumento opcional del espacio de nombres (reenviado).withConfig() a las plantillas de estilogetId y Dynamic Class Hashesstyled.div Alternative to styled('div') )useInsertionEffect de React cuando esté disponiblestyled.string agregado para construir cuerdas de estilo estáticoStyledProvidercreateSsrStyledManager )StyledTest )getId ya no acepta una discusiónstyled.mixinrenderStylesToString eliminado