Solution minimale de composants de style CSS-in-JS pour réagir.
Il y a aussi certaines choses qui ne sont pas des Goals.
as propriété, .withComponent() ).attrs() Méthode)defaultProps . import { styled } from '@minstack/styled' ;Style tout type d'élément HTML en utilisant le nom de balise. Le composant stylé prend en charge tous les mêmes accessoires (références incluses, qui sont transmises) que l'élément HTML prend en charge.
const StyledComponent = styled ( 'div' ) `
color: black;
` ;Le style de méthode du nom de balise est également pris en charge.
const StyledComponent = styled . div `
color: black;
` ; Style tout composant React qui accepte une propriété className , ou étendez les styles d'un composant déjà stylé.
const StyledComponent = styled ( Component ) `
color: black;
` ; Des propriétés supplémentaires peuvent être ajoutées au composant stylé en définissant le paramètre générique de la chaîne de modèle. Généralement, les propriétés de style doivent être préfixées avec $ pour indiquer qu'elles ne sont utilisées que pour le style. Tout nom de propriété qui commence par le caractère $ ne sera pas transmis à l'élément HTML sous-jacent en tant qu'attribut.
interface ComponentStyleProps {
$font ?: string ;
}
const StyledComponent = styled ( 'div' ) < ComponentStyleProps > `
font-family: ${ ( props ) => props . $font } ;
` ; Utilisez l'utilitaire styled.global pour créer des composants de style global.
const GlobalStyle = styled . global `
body,
html {
margin: 0;
padding: 0;
}
` ;Des propriétés de style peuvent également être ajoutées aux styles mondiaux.
interface GlobalStyleProps {
$font ?: string ;
}
const GlobalStyle = styled . global < GlobalStyleProps > `
body,
html {
font-family: ${ ( props ) => props . $font } ;
}
` ; Définir des images clés ou des portes de police est la même que la définition de tout autre style. Puisqu'ils ne sont pas étendus vers un composant particulier, ils ne devraient probablement être utilisés que dans les styles mondiaux. Pour éviter les collisions de noms, utilisez l'utilitaire getId inclus pour générer des noms uniques CSS-SAFE.
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 } ;
` ; Passez un crochet à thème (ou toute fonction) qui renvoie un thème à l'utilitaire createStyled . La valeur du thème sera ensuite disponible car le deuxième argument transmis à n'importe quel modèle de modèle de modèle de modèle stylé.
// File: styled-with-theme.ts
import { createStyled } from '@minstack/styled' ;
export const styled = createStyled ( useTheme ) ; Cela crée une instance styled fortement tapée. Utilisez cette instance au lieu de l'instance intégrée.
import { styled } from './styled-with-theme' ;
const ThemedComponent = styled ( 'div' ) `
color: ${ ( props , theme ) => theme . fgColor } ;
background-color: ${ ( props , theme ) => theme . bgColor } ;
` ; Tous les nidification CSS Plus sont pris en charge.
Pour appliquer des styles directement sur l'élément ou le composant HTML en cours de style, utilisez les propriétés CSS au niveau supérieur du modèle marqué (pas de bloc environnant).
const StyledComponent = styled ( 'div' ) `
color: red;
` ;Les propriétés CSS de niveau supérieur seront enveloppées dans un sélecteur de classe de style dynamique
. _rmsds7y13d_ {
color : red;
}Utilisez des blocs de règles CSS pour styliser les enfants du composant stylé.
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
}
` ;La classe dynamique stylée sera automatiquement adaptée à tous les sélecteurs pour les rendre "de portée".
. _rmsds7y13d_ . child {
color : blue;
}Chaque composant stylé (sauf les styles globaux) peut être utilisé comme sélecteur.
const StyledComponentA = styled ( 'div' ) `
color: blue;
` ;
const StyledComponentB = styled ( 'div' ) `
${ StyledComponentA } {
background-color: yellow;
}
` ; Chaque composant stylé a une classe statique unique qui est générée sur la création. La méthode toString() du composant stylé renvoie une chaîne de sélecteur (par exemple. "._rmsss7y13d_" ) pour cette classe statique.
. _rmsds7y13d_ . _rmsss7y13d_ {
color : red;
} La classe statique est générée à partir du nom d'affichage du composant, de la partie statique du modèle de style, des classes statiques héritées (lors de l'extension d'un autre composant stylé) et du nombre de composants créés précédemment qui partagent la même "empreinte de pouce". Dans la plupart des cas, cela devrait rendre les classes statiques stables à travers les rendus SSR et clients. Si des problèmes SSR de classe statique se produisent, cela est probablement dû à des composants avec la même empreinte digitale ayant un ordre de création instable. Essayez de modifier le displayName à l'aide de la méthode .withConfig() pour rendre l'empreinte digitale du composant problématique unique.
const StyledComponent = styled . div . withConfig ( { displayName : 'StyledComponent' } ) `
color: red;
` ;NEST Blocs de règle pour créer des sélecteurs plus complexes.
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
.grandchild {
color: green;
}
}
` ;Tout comme la classe dynamique stylée est appliquée aux sélecteurs de niveau supérieur, il en va de même pour les sélecteurs de parents adjoints aux sélecteurs d'enfants.
. _rmsds7y13d_ . child {
color : blue;
}
. _rmsds7y13d_ . child . grandchild {
color : green;
} Les références du sélecteur parent ( & ) fonctionnent de la même manière que dans SCSS / SASS. Le seul détail supplémentaire est que lorsqu'un sélecteur parent est utilisé à la racine de style (non imbriquée à l'intérieur d'un bloc parent), il fait référence à la classe de style unique du style actuel, qui est le sélecteur de blocs parent implicite / virtuel pour le style.
const StyledComponent = styled ( 'div' ) `
&& {
color: red;
}
&:hover {
color: blue;
}
.parent & {
color: green;
}
` ; Tous les RUS CSS sont pris en charge (sauf @charset qui n'est pas autorisé à l'intérieur <style> Éléments).
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;
}
}
}
}
` ;Les rubriques seront hissées si nécessaire, et les sélecteurs de parents seront traités de la même manière qu'ils seraient sans l'intermédiaire en règle.
@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 une valeur de propriété CSS est "vide" (chaîne vide, false , null , undefined ou "" ), la propriété entière sera omise du style.
const StyledComponent = styled ( 'div' ) `
color: ${ null } ;
background-color: red;
` ;La propriété Color n'est pas incluse car elle n'a aucune valeur.
. _rmsds7y13d_ {
background-color : red;
} Les styles peuvent contenir à la fois des commentaires Block ( /* */ ) et en ligne ( // ). Les commentaires ne sont jamais inclus dans les feuilles de style rendues.
const StyledComponent = styled ( 'div' ) `
// This is a comment.
/* And so...
...is this. */
` ; La fonction de modèle taguée styled.string renvoie une chaîne de style simple avec toutes les valeurs interpolées. Seules les valeurs statiques sont autorisées (aucune fonction). Les valeurs de propriété vides ( null , undefined , false et "" ) fonctionnent de la même manière que dans les composants stylisés et provoquent l'omission de la propriété.
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;
` ; L'assistance styled.string n'a pas d'effets secondaires et fait très peu de travail, il est donc également sûr à utiliser dans les fonctions.
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;
` ; Utilisez l'emballage StyledTest pour produire des instantanés avec des noms de classe stables et des informations de style.
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 peut remplacer le cache , manager et renderer par défaut. Aucun fournisseur n'est requis pour le fonctionnement par défaut.
const cache = createStyledCache ( ) ;
const manager = createStyledManager ( ) ;
const renderer = createStyledRenderer ( ) ;
render (
< StyledProvider cache = { cache } manager = { manager } renderer = { renderer } >
< App />
</ StyledProvider > ,
) ; Le composant StyledTest est un StyledProvider préconfiguré qui injecte des versions de test des trois ressources pour remplacer les noms de classe et les styles de capture.
Remarque: Le cache fourni, le gestionnaire et le rendu ne doivent pas changer au cours de la durée de vie d'un composant stylé. Une erreur sera lancée (ou connectée en production) si elles mutent.
Utilisez createSsrStyledManager et le StyledProvider pour capturer des styles lors de la rendu de l'application sur le serveur.
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>
` ; La méthode getStyleTags() du gestionnaire SSR renvoie une seule chaîne HTML contenant uniquement des balises <style> . Il existe également des méthodes getStyleElement() (React Elements Array) et getCss() (CSS Strings Array).
Utilisez createStyledManager (ou createSsrStyledManager ) et le StyledProvider pour définir un nonce sur tous les styles injectés.
const manager = createStyledManager ( nonce ) ;
render (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ; | Fonctionnalité | Styled Minstack | Goober | Composants stylisés | Émotion | |
|---|---|---|---|---|---|
| Bibliothèque | |||||
| Taille du faisceau (environ KB) [1] | 2.8 | 1.2 | 13.3 | 9.1 | |
| Zéro dépendances | ? | ? | ? | ? | |
| Natif de dactylographie | ? | ? | ? | ? | |
| API | |||||
| Styles de modèle tagués | ? | ? | ? | ? | |
| Styles dynamiques | ? | ? | ? | ? | |
| Styles d'objet | ? | ? | ? | ? | |
| Styles mondiaux | ? | ? | ? | ? | |
Polymorphisme ( as ) | ? | ? | ? | ? | |
Mappage des propriétés ( attrs ) | ? | ? | ? | ? | |
| THEMING [2] | ? | ? | ? | ? | |
| RSE | ? | ? | ? | ? | |
| Tests instantanés | ? | ? | ? | ? | |
| Style | |||||
| Syntaxe CSS de base [3] | ? | ? | ? | ? | |
CSS @media | ? | ? | ? | ? | |
Css @keyframes | ? | ? | ? | ? | |
CSS @font-face | ? | ⭕ | ⭕ | ? | |
Css @import | ? | ⭕ | ? | ? | |
Autres règles CSS @ | ? | ⭕ | ⭕ | ⭕ | |
| Prefixing du vendeur [4] | ? | ? | ? | ? | |
| Règle de nidification | ? | ? | ? | ? | |
Sélectionneurs de parents ( & ) | ? | ? | ? | ? | |
| Sélecteurs de composants stylisés [5] | ? | ? | ? | ? |
styled (après la casting des arbres, la minification et le GZIP) calculées à l'aide de l'analyseur de bundle WebPack. Goober est très similaire à cette solution. Il est tout aussi rapide, plus petit et a une prise en charge de quelques fonctionnalités supplémentaires (styles d'objets et la propriété as ). Alors, quels sont les inconvénients de Goober, et pourquoi je l'utiliserais à la place?
StyledTest qui permet non seulement les tests d'instantanés, mais le fait d'une manière qui est un framework Agnostic.setup() qui configure la seule instance globale de l'API , et cela ne modifie pas le type de thème. L'extension du type de thème peut être accomplie avec la fusion de la déclaration, mais cela est à nouveau global et pas très sûr. Cette bibliothèque fournit l'usine createStyled() qui renvoie une nouvelle instance API , qui a un thème fortement dactylographié.styled.div au lieu de styled('div') ). Cette bibliothèque prend en charge styled.<tag> sans compiler le support temporel.setup() lors de l'utilisation de React. Cette bibliothèque cible réagit et nécessite preact/compat lors de l'utilisation du préact.Cette bibliothèque est opinionnée et laisse de côté certaines fonctionnalités que Goober prend en charge. Il s'agit de réduire le nombre de façons alternatives pour lesquelles les composants stylisés peuvent être conçus, ce qui augmente la cohérence du code, et offre une meilleure expérience de développeur globale (DX). La suppression du support pour deux façons différentes pour accomplir la même chose signifie également que la taille de la bibliothèque et les frais généraux d'exécution sont réduits et / ou alloués aux fonctionnalités de base améliorées, et que la bibliothèque est plus maintenable dans l'ensemble.
as pour modifier le type de composant sous-jacent du composant stylé. Cette bibliothèque ne le fait pas parce qu'elle est intrinsèquement dangereuse, et l'utilisation des aides de style (par exemple, l'utilitaire styled.string ) offre un meilleur moyen de réutiliser les styles.Voir le script Benchmark.js pour l'implémentation de benchmark.
| Bibliothèque | OP / S |
|---|---|
| Styled Minstack | 144 970 |
| Goober | 142 028 |
| Émotion | 124 681 |
| Composants stylisés | 118 072 |
getId accepte un argument d'espace de noms facultatif (remis).withConfig()getId et Dynamicstyled.div à styled('div') )useInsertionEffect de reactstyled.string pour construire des cordes de style statiqueStyledProvidercreateSsrStyledManager )StyledTest )getId n'accepte plus un argumentstyled.mixinrenderStylesToString