反応用の最小CSS-in-JSスタイルのコンポーネントソリューション。
また、非ゴールであるものもいくつかあります。
as 、 .withComponent()メソッド).attrs()メソッド)defaultPropsを使用します。 import { styled } from '@minstack/styled' ;タグ名を使用して、あらゆるHTML要素タイプをスタイルします。スタイル化されたコンポーネントは、HTML要素がサポートするのと同じすべてのプロップ(転送される参照を含む)をサポートします。
const StyledComponent = styled ( 'div' ) `
color: black;
` ;タグ名メソッドスタイルもサポートされています。
const StyledComponent = styled . div `
color: black;
` ; classNameプロパティを受け入れるReactコンポーネントをスタイルするか、すでにスタイルのあるコンポーネントのスタイルを拡張します。
const StyledComponent = styled ( Component ) `
color: black;
` ; テンプレート文字列の汎用パラメーターを設定することにより、追加のプロパティをスタイルのコンポーネントに追加できます。一般的に、スタイルのプロパティには、スタイリングにのみ使用されることを示すために、 $をプレフィックスする必要があります。 $文字から始まるプロパティ名は、属性として基礎となるHTML要素に渡されません。
interface ComponentStyleProps {
$font ?: string ;
}
const StyledComponent = styled ( 'div' ) < ComponentStyleProps > `
font-family: ${ ( props ) => props . $font } ;
` ; styled.globalユーティリティを使用して、グローバルスタイルのコンポーネントを作成します。
const GlobalStyle = styled . global `
body,
html {
margin: 0;
padding: 0;
}
` ;スタイルのプロパティもグローバルスタイルに追加できます。
interface GlobalStyleProps {
$font ?: string ;
}
const GlobalStyle = styled . global < GlobalStyleProps > `
body,
html {
font-family: ${ ( props ) => props . $font } ;
}
` ;キーフレームまたはフォントフレースを定義することは、他のスタイルを定義するのと同じです。それらは特定のコンポーネントにスコープされていないため、おそらくグローバルスタイルでのみ使用する必要があります。名前の衝突を防ぐために、含まれているgetIdユーティリティを使用して、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 } ;
` ; テーマをcreateStyledユーティリティに返すテーマフック(または任意の関数)を渡します。次に、2番目の引数が任意のスタイルのテンプレート文字列機能値に渡されると、テーマ値が利用可能になります。
// File: styled-with-theme.ts
import { createStyled } from '@minstack/styled' ;
export const styled = createStyled ( useTheme ) ;これにより、強くタイプされたstyledインスタンスが作成されます。組み込みインスタンスの代わりにこのインスタンスを使用します。
import { styled } from './styled-with-theme' ;
const ThemedComponent = styled ( 'div' ) `
color: ${ ( props , theme ) => theme . fgColor } ;
background-color: ${ ( props , theme ) => theme . bgColor } ;
` ; すべてのCSSとネスティングがサポートされています。
スタイルをスタイルに直接適用するには、スタイルに導かれているコンポーネントに直接適用するには、タグ付きテンプレートのトップレベル(周囲のブロックなし)でCSSプロパティを使用します。
const StyledComponent = styled ( 'div' ) `
color: red;
` ;トップレベルのCSSプロパティは、動的なスタイルのクラスセレクターにラップされます
. _rmsds7y13d_ {
color : red;
}CSSルールブロックを使用して、スタイルのコンポーネントの子供をスタイリングします。
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
}
` ;スタイルのダイナミッククラスは、すべてのセレクターに自動的に準備され、それらを「スコープ」します。
. _rmsds7y13d_ . child {
color : blue;
}すべてのスタイルのコンポーネント(グローバルスタイルを除く)は、セレクターとして使用できます。
const StyledComponentA = styled ( 'div' ) `
color: blue;
` ;
const StyledComponentB = styled ( 'div' ) `
${ StyledComponentA } {
background-color: yellow;
}
` ;各スタイルのコンポーネントには、作成時に生成される一意の静的クラスがあります。スタイルのコンポーネントのtoString()メソッドは、その静的クラスのセレクター文字列( "._rmsss7y13d_" )を返します。
. _rmsds7y13d_ . _rmsss7y13d_ {
color : red;
}静的クラスは、コンポーネントのディスプレイ名、スタイルテンプレートの静的部分(別のスタイルのコンポーネントを拡張するとき)を継承する静的部分、および同じ「サムプリント」を共有する以前に作成したコンポーネントの数から生成されます。ほとんどの場合、これにより、SSRおよびクライアントレンダリング全体で静的クラスが安定するはずです。静的クラスSSRの問題が発生した場合、それはおそらく、不安定な作成順序を持つ同じ指紋を持つコンポーネントによるものです。問題のあるコンポーネントの指紋をユニークにするために.withConfig()メソッドを使用してdisplayName変更してみてください。
const StyledComponent = styled . div . withConfig ( { displayName : 'StyledComponent' } ) `
color: red;
` ;ネストルールブロックは、より複雑なセレクターを作成します。
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
.grandchild {
color: green;
}
}
` ;スタイルのダイナミッククラスがトップレベルのセレクターに加入しているように、子どもセレクターも子どもセレクターに加えられているように。
. _rmsds7y13d_ . child {
color : blue;
}
. _rmsds7y13d_ . child . grandchild {
color : green;
}親セレクター参照( & )は、SCSS/SASSで行うのと同じように動作します。特別な詳細は、親セレクターがスタイルルート(親ブロック内にネストされていない)で使用される場合、スタイルの暗黙的/仮想親ブロックセレクターである現在のスタイルのユニークなスタイルのクラスを指すことです。
const StyledComponent = styled ( 'div' ) `
&& {
color: red;
}
&:hover {
color: blue;
}
.parent & {
color: green;
}
` ;すべてのCSS AT-Ruleはサポートされています( @charsetは<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;
}
}
}
}
` ;必要に応じて、アットレールは巻き上げられ、親の選択者は、介在するアートルールなしで同じように処理されます。
@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;
}
}CSSプロパティ値が「空」(空の文字列、 false 、 null 、 undefined 、または"" )の場合、プロパティ全体がスタイルから省略されます。
const StyledComponent = styled ( 'div' ) `
color: ${ null } ;
background-color: red;
` ;カラープロパティには価値がないため、含まれていません。
. _rmsds7y13d_ {
background-color : red;
}スタイルには、ブロック( /* */ )とラインコメント( // )の両方を含めることができます。レンダリングされたスタイルシートにコメントが含まれることはありません。
const StyledComponent = styled ( 'div' ) `
// This is a comment.
/* And so...
...is this. */
` ; styled.stringタグ付きテンプレート機能は、すべての値が補間されたシンプルなスタイルの文字列を返します。静的値のみが許可されます(関数なし)。空のプロパティ値( null 、 undefined 、 false 、および"" )は、スタイルのコンポーネントで行うのと同じように機能し、プロパティを省略します。
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;
` ; 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;
` ; StyledTestラッパーを使用して、安定したクラス名とスタイル情報を含むスナップショットを作成します。
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は、デフォルトのcache 、 manager 、およびrendererをオーバーライドできます。デフォルト操作にはプロバイダーは必要ありません。
const cache = createStyledCache ( ) ;
const manager = createStyledManager ( ) ;
const renderer = createStyledRenderer ( ) ;
render (
< StyledProvider cache = { cache } manager = { manager } renderer = { renderer } >
< App />
</ StyledProvider > ,
) ; StyledTestコンポーネントは、3つすべてのリソースのテストバージョンを注入してクラス名を置き換えてキャプチャスタイルを注入する、事前に構成されたStyledProviderです。
注:提供されたキャッシュ、マネージャー、およびレンダラーは、スタイルのコンポーネントの寿命にわたって変更してはなりません。エラーが変異すると、エラーがスローされます(または生産に記録されます)。
サーバー上のアプリケーションをレンダリングするときに、 createSsrStyledManagerとStyledProviderを使用してスタイルをキャプチャします。
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>
` ; SSRマネージャーのgetStyleTags()メソッドは、 <style>タグのみを含む単一のHTML文字列を返します。 getStyleElement() (React Elements Array)およびgetCss() (CSS文字列アレイ)メソッドもあります。
createStyledManager (またはcreateSsrStyledManager )とStyledProviderを使用して、すべての挿入スタイルにnonceを設定します。
const manager = createStyledManager ( nonce ) ;
render (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ; | 特徴 | Minstackスタイル | グーバー | スタイルのコンポーネント | 感情 | |
|---|---|---|---|---|---|
| 図書館 | |||||
| バンドルサイズ(約kb)[1] | 2.8 | 1.2 | 13.3 | 9.1 | |
| ゼロ依存関係 | ? | ? | ? | ? | |
| タイプスクリプトネイティブ | ? | ? | ? | ? | |
| API | |||||
| タグ付きテンプレートスタイル | ? | ? | ? | ? | |
| ダイナミックスタイル | ? | ? | ? | ? | |
| オブジェクトスタイル | ? | ? | ? | ? | |
| グローバルスタイル | ? | ? | ? | ? | |
多型( as ) | ? | ? | ? | ? | |
プロパティマッピング( attrs ) | ? | ? | ? | ? | |
| テーマ[2] | ? | ? | ? | ? | |
| SSR | ? | ? | ? | ? | |
| スナップショットテスト | ? | ? | ? | ? | |
| スタイル | |||||
| 基本的なCSS構文[3] | ? | ? | ? | ? | |
CSS @media | ? | ? | ? | ? | |
CSS @keyframes | ? | ? | ? | ? | |
css @font-face | ? | ⭕ | ⭕ | ? | |
CSS @import | ? | ⭕ | ? | ? | |
他のCSS @ルール | ? | ⭕ | ⭕ | ⭕ | |
| ベンダープレフィックス[4] | ? | ? | ? | ? | |
| ネストを支配します | ? | ? | ? | ? | |
親セレクター( & ) | ? | ? | ? | ? | |
| スタイルのコンポーネントセレクター[5] | ? | ? | ? | ? |
styledのエクスポート(ツリーシェーキング、マイニフィス、およびGZIPの後)です。グーバーはこのソリューションに非常に似ています。それは同じくらい速く、小さく、いくつかの追加機能(オブジェクトスタイル、 asプロパティ)をサポートしています。では、グーバーの欠点は何ですか、そしてなぜ私は代わりにこれを使用するのでしょうか?
StyledTestテストラッパーコンポーネントを提供します。setup()関数を使用しますが、これはテーマタイプを変更しません。テーマタイプを拡張することは宣言の合併で実現できますが、これもグローバルであり、あまり安全ではありません。このライブラリは、新しいAPIインスタンスを返すcreateStyled()ファクトリーを提供します。styled.div styled('div') )を有効にするためにバベルプラグインが必要です。このライブラリは、タイムサポートをコンパイルせずにstyled.<tag>をサポートしています。setup()を呼び出す必要があります。このライブラリは、反応をターゲットにしており、Preact/ preact/compatを必要とします。このライブラリは意見を述べており、Gooberがサポートするいくつかの機能を除外しています。これは、スタイルのコンポーネントを設計できる代替方法の数を減らすためです。これにより、コードの一貫性が向上し、全体的に優れた開発者エクスペリエンス(DX)を提供します。同じことを達成するための2つの異なる方法のサポートを削除することは、ライブラリのサイズとランタイムオーバーヘッドがコア機能の改善に縮小および/または割り当てられ、ライブラリが全体的に維持可能であることを意味します。
asプロパティをサポートしています。このライブラリは、本質的にタイプの安全ではないためではなく、スタイルヘルパー(たとえばstyled.stringユーティリティなど)を使用すると、スタイルを再利用するより良い方法があります。ベンチマーク実装については、benchmark.jsスクリプトを参照してください。
| 図書館 | op/s |
|---|---|
| Minstackスタイル | 144,970 |
| グーバー | 142,028 |
| 感情 | 124,681 |
| スタイルのコンポーネント | 118,072 |
getIdオプションの名前空間引数を受け入れます(再添加).withConfig()追加しましたgetIdおよびダイナミッククラスのハッシュでメジャーバージョンを使用しますstyled.divサポート(例: styled('div') ))useInsertionEffectを使用しますstyled.stringヘルパーを追加しましたStyledProviderを追加しましたcreateSsrStyledManager )StyledTest )getIdもう議論を受け入れませんstyled.mixinを削除しましたrenderStylesToString