Solusi komponen gaya CSS-in-JS minimal untuk bereaksi.
Ada juga beberapa hal yang bukan tujuan.
as properti, .withComponent() metode).attrs() metode)defaultProps . import { styled } from '@minstack/styled' ;Gaya jenis elemen HTML apa pun dengan menggunakan nama tag. Komponen gaya mendukung semua alat peraga yang sama (termasuk referensi, yang diteruskan) yang didukung elemen HTML.
const StyledComponent = styled ( 'div' ) `
color: black;
` ;Gaya metode nama tag juga didukung.
const StyledComponent = styled . div `
color: black;
` ; Gaya setiap komponen bereaksi yang menerima properti className , atau memperluas gaya komponen yang sudah ditata.
const StyledComponent = styled ( Component ) `
color: black;
` ; Properti tambahan dapat ditambahkan ke komponen gaya dengan mengatur parameter generik dari string template. Secara umum, properti gaya harus diawali dengan $ untuk menunjukkan bahwa mereka hanya digunakan untuk gaya. Nama properti apa pun yang dimulai dengan karakter $ tidak akan diteruskan ke elemen HTML yang mendasari sebagai atribut.
interface ComponentStyleProps {
$font ?: string ;
}
const StyledComponent = styled ( 'div' ) < ComponentStyleProps > `
font-family: ${ ( props ) => props . $font } ;
` ; Gunakan utilitas styled.global Global untuk membuat komponen gaya global.
const GlobalStyle = styled . global `
body,
html {
margin: 0;
padding: 0;
}
` ;Properti gaya dapat ditambahkan ke gaya global juga.
interface GlobalStyleProps {
$font ?: string ;
}
const GlobalStyle = styled . global < GlobalStyleProps > `
body,
html {
font-family: ${ ( props ) => props . $font } ;
}
` ; Mendefinisikan key kerangka atau font-font sama dengan mendefinisikan gaya lain. Karena mereka tidak terselubung ke komponen tertentu, mereka mungkin hanya boleh digunakan dalam gaya global. Untuk mencegah tabrakan nama, gunakan utilitas getId yang disertakan untuk menghasilkan nama unik 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 } ;
` ; Lulus kait tema (atau fungsi apa pun) yang mengembalikan tema ke utilitas createStyled . Nilai tema kemudian akan tersedia sebagai argumen kedua yang diteruskan ke nilai fungsional string templat gaya apa pun.
// File: styled-with-theme.ts
import { createStyled } from '@minstack/styled' ;
export const styled = createStyled ( useTheme ) ; Ini menciptakan instance styled yang sangat diketik. Gunakan instance ini alih-alih instance bawaan.
import { styled } from './styled-with-theme' ;
const ThemedComponent = styled ( 'div' ) `
color: ${ ( props , theme ) => theme . fgColor } ;
background-color: ${ ( props , theme ) => theme . bgColor } ;
` ; Semua CSS Plus Nesting didukung.
Untuk menerapkan gaya langsung ke elemen HTML atau komponen yang ditata, gunakan properti CSS di tingkat atas dari templat yang ditandai (tidak ada blok di sekitarnya).
const StyledComponent = styled ( 'div' ) `
color: red;
` ;Properti CSS tingkat atas akan dibungkus dengan pemilih kelas gaya dinamis
. _rmsds7y13d_ {
color : red;
}Gunakan blok aturan CSS untuk menata anak -anak dari komponen gaya.
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
}
` ;Kelas dinamis bergaya akan secara otomatis disiapkan untuk semua pemilih untuk membuat mereka "berjudul".
. _rmsds7y13d_ . child {
color : blue;
}Setiap komponen gaya (kecuali gaya global) dapat digunakan sebagai pemilih.
const StyledComponentA = styled ( 'div' ) `
color: blue;
` ;
const StyledComponentB = styled ( 'div' ) `
${ StyledComponentA } {
background-color: yellow;
}
` ; Setiap komponen gaya memiliki kelas statis unik yang dihasilkan pada penciptaan. Metode toString() komponen bergaya mengembalikan string pemilih (mis. "._rmsss7y13d_" ) untuk kelas statis itu.
. _rmsds7y13d_ . _rmsss7y13d_ {
color : red;
} Kelas statis dihasilkan dari nama tampilan komponen, bagian statis dari templat gaya, kelas statis yang diwariskan (ketika memperluas komponen bergaya lain), dan jumlah komponen yang dibuat sebelumnya yang memiliki "jempol" yang sama. Dalam kebanyakan kasus, ini harus membuat kelas statis stabil di seluruh SSR dan render klien. Jika masalah SSR kelas statis terjadi, itu mungkin karena komponen dengan sidik jari yang sama memiliki urutan kreasi yang tidak stabil. Coba ubah displayName menggunakan metode .withConfig() untuk membuat sidik jari komponen bermasalah unik.
const StyledComponent = styled . div . withConfig ( { displayName : 'StyledComponent' } ) `
color: red;
` ;Blok aturan sarang untuk membuat pemilih yang lebih kompleks.
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
.grandchild {
color: green;
}
}
` ;Sama seperti kelas dinamis yang ditata disiapkan untuk pemilih tingkat atas, demikian juga pemilih orang tua yang diisi untuk pemilih anak.
. _rmsds7y13d_ . child {
color : blue;
}
. _rmsds7y13d_ . child . grandchild {
color : green;
} Referensi Pemilih Orangtua ( & ) bekerja dengan cara yang sama seperti di SCSS/SASS. Satu detail ekstra adalah bahwa ketika pemilih induk digunakan pada root gaya (tidak bersarang di dalam blok induk), itu mengacu pada kelas gaya unik dari gaya saat ini, yang merupakan pemilih blok induk implisit/virtual untuk gaya tersebut.
const StyledComponent = styled ( 'div' ) `
&& {
color: red;
}
&:hover {
color: blue;
}
.parent & {
color: green;
}
` ; Semua aturan CSS didukung (kecuali @charset yang tidak diperbolehkan di dalam elemen <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;
}
}
}
}
` ;AT-RULES akan diangkat seperlunya, dan pemilih orang tua akan ditangani dengan cara yang sama seperti tanpa aturan intervensi.
@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;
}
} Jika nilai properti CSS "kosong" (string kosong, false , null , undefined , atau "" ), maka seluruh properti akan dihilangkan dari gaya.
const StyledComponent = styled ( 'div' ) `
color: ${ null } ;
background-color: red;
` ;Properti warna tidak termasuk karena tidak memiliki nilai.
. _rmsds7y13d_ {
background-color : red;
} Gaya dapat berisi kedua blok ( /* */ ) dan komentar baris ( // ). Komentar tidak pernah termasuk dalam stylesheet yang diberikan.
const StyledComponent = styled ( 'div' ) `
// This is a comment.
/* And so...
...is this. */
` ; Fungsi template tag styled.string mengembalikan string gaya sederhana dengan semua nilai yang diinterpolasi. Hanya nilai statis yang diizinkan (tidak ada fungsi). Nilai properti kosong ( null , undefined , false , dan "" ) bekerja dengan cara yang sama seperti yang mereka lakukan dalam komponen gaya, dan menyebabkan properti dihilangkan.
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;
` ; Helper styled.string
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;
` ; Gunakan pembungkus StyledTest untuk menghasilkan snapshot dengan nama kelas yang stabil dan informasi gaya.
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>
StyledProvider dapat mengesampingkan cache default, manager , dan renderer . Tidak diperlukan penyedia untuk operasi default.
const cache = createStyledCache ( ) ;
const manager = createStyledManager ( ) ;
const renderer = createStyledRenderer ( ) ;
render (
< StyledProvider cache = { cache } manager = { manager } renderer = { renderer } >
< App />
</ StyledProvider > ,
) ; Komponen StyledTest adalah StyledProvider yang telah dikonfigurasi sebelumnya yang menyuntikkan versi uji ketiga sumber daya untuk menggantikan nama kelas dan menangkap gaya.
Catatan: Cache, manajer, dan renderer yang disediakan tidak boleh berubah selama masa pakai komponen gaya. Kesalahan akan dilemparkan (atau dicatat dalam produksi) jika mereka bermutasi.
Gunakan createSsrStyledManager dan StyledProvider untuk menangkap gaya saat merender aplikasi di server.
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>
` ; Metode getStyleTags() SSR Manager mengembalikan satu string HTML tunggal yang hanya berisi tag <style> . Ada juga metode getStyleElement() (React Elements) dan getCss() (CSS Strings Array).
Gunakan createStyledManager (atau createSsrStyledManager ) dan StyledProvider untuk menetapkan nonce pada semua gaya yang disuntikkan.
const manager = createStyledManager ( nonce ) ;
render (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ; | Fitur | MinStack ditata | Goober | Komponen gaya | Emosi | |
|---|---|---|---|---|---|
| Perpustakaan | |||||
| Ukuran bundel (sekitar kb) [1] | 2.8 | 1.2 | 13.3 | 9.1 | |
| Nol dependensi | ? | ? | ? | ? | |
| Naskah naskah | ? | ? | ? | ? | |
| API | |||||
| Tagged Template Styles | ? | ? | ? | ? | |
| Gaya dinamis | ? | ? | ? | ? | |
| Gaya objek | ? | ? | ? | ? | |
| Gaya global | ? | ? | ? | ? | |
Polimorfisme ( as ) | ? | ? | ? | ? | |
Pemetaan properti ( attrs ) | ? | ? | ? | ? | |
| Tema [2] | ? | ? | ? | ? | |
| SSR | ? | ? | ? | ? | |
| Pengujian Snapshot | ? | ? | ? | ? | |
| Gaya | |||||
| Sintaks CSS Dasar [3] | ? | ? | ? | ? | |
CSS @media | ? | ? | ? | ? | |
CSS @keyframes | ? | ? | ? | ? | |
Css @font-face | ? | ⭕ | ⭕ | ? | |
CSS @import | ? | ⭕ | ? | ? | |
Aturan CSS @ lainnya | ? | ⭕ | ⭕ | ⭕ | |
| Awalan vendor [4] | ? | ? | ? | ? | |
| Aturan bersarang | ? | ? | ? | ? | |
Pemilih Orang Tua ( & ) | ? | ? | ? | ? | |
| Selektor komponen gaya [5] | ? | ? | ? | ? |
styled (setelah pengocok pohon, minifikasi, dan GZIP) dihitung menggunakan analisis bundel webpack. Goober sangat mirip dengan solusi ini. Ini sama cepat, lebih kecil, dan memiliki dukungan untuk beberapa fitur tambahan (gaya objek, dan as properti). Jadi apa kelemahan Goober, dan mengapa saya harus menggunakan ini?
StyledTest yang tidak hanya memungkinkan pengujian snapshot, tetapi melakukannya dengan cara yang merupakan kerangka kerja uji agnostik.setup() yang mengonfigurasi instance global tunggal API , dan ini tidak mengubah jenis tema. Memperluas jenis tema dapat dicapai dengan penggabungan deklarasi, tetapi ini sekali lagi global dan tidak terlalu aman. Perpustakaan ini menyediakan pabrik createStyled() yang mengembalikan instance API baru , yang memiliki tema yang sangat diketik.styled.div bukannya styled('div') ). Perpustakaan ini mendukung styled.<tag> tanpa dukungan waktu kompilasi.setup() saat menggunakan React. Target pustaka ini bereaksi dan membutuhkan preact/compat saat menggunakan preact.Perpustakaan ini memiliki pendapat dan meninggalkan beberapa fitur yang didukung Goober. Ini untuk mengurangi jumlah cara alternatif yang dapat dirancang oleh komponen gaya, yang meningkatkan konsistensi kode, dan memberikan pengalaman pengembang yang lebih baik secara keseluruhan (DX). Menghapus dukungan untuk dua cara berbeda untuk mencapai hal yang sama juga berarti ukuran perpustakaan dan overhead runtime dikurangi dan/atau dialokasikan untuk meningkatkan fitur inti, dan bahwa perpustakaan lebih dapat dipelihara secara keseluruhan.
as untuk mengubah jenis komponen yang mendasari dari komponen gaya. Perpustakaan ini bukan karena secara inheren mengetik tidak aman, dan menggunakan penolong gaya (mis. Utilitas styled.string ) memberikan cara yang lebih baik untuk menggunakan kembali gaya.Lihat skrip Benchmark.js untuk implementasi Benchmark.
| Perpustakaan | Op/s |
|---|---|
| MinStack ditata | 144.970 |
| Goober | 142.028 |
| Emosi | 124.681 |
| Komponen gaya | 118.072 |
getId menerima argumen namespace opsional (ditambahkan kembali).withConfig() Metode statis ke template gayagetId dan dinamisstyled.div Alternative to styled('div') )useInsertionEffect bila tersediastyled.string helper untuk membangun string gaya statisStyledProvidercreateSsrStyledManager )StyledTest )getId tidak lagi menerima argumenstyled.mixinrenderStylesToString yang dihapus