2017-11-27 31 views
2

私は、Emotionでスタイルされたコンポーネントを持っていたいと思います。最終的にはスタイリングをコントロールする小道具が必要です。たとえば、パッドと幅を変更するさまざまな小道具を持つGridColコンポーネントを考えてみましょう(幅はさまざまなビューポート幅で変更できます)。Emotion CSS-in-JS - コンポーネントの小道具に基づいて条件付きCSSを追加する方法は?

私はこのようなAPIを使用したい:

<GridCol gutter size="2> 

// or alternatively, like this: 

<GridCol gutter size={{ 
    m: 2, 
    l: 4 
}}> 

ここで起こって三つのことがあります。

  • gutterをカラムに、いくつかの水平方向のパディングを追加ブール小道具ですが
  • size propは文字列またはオブジェクトです。文字列の場合は、CSSを数行追加するだけですが、オブジェクトであれば、別の場所に設定されているブレークポイントオブジェクトに基づいてメディアクエリを挿入する必要があります。

Emotion's docsこの種のスタイリングをどのように処理するかは不明ですが、少なくとも私はそれを見たことがないので、共通の解決策が見つかると思っていました。 gutter小道具のために

、それは簡単です:size小道具のために

const GridCol = props => styled('div')` 
    display: block; 
    box-sizing: border-box; 
    flex: 1 0 0; 
    min-width: 0; 
    padding: ${props.gutter ? `0 10px` : '0'}; 
` 

、それは私がこのような何かを探すように得られたCSSが欲しい、もっと複雑になる:

const GridCol = props => styled('div')` 
    display: block; 
    box-sizing: border-box; 
    flex: 1 0 0; 
    min-width: 0; 
    padding: ${props.gutter ? `0 10px` : '0'}; 

    /* styles here if `size` is a string */ 
    width: 10%; 

    /* styles here if `size` is an object */ 
    @media screen and (min-width: 500px) { 
     width: 20%; 
    } 


    @media screen and (min-width: 800px) { 
     width: 30%; 
    } 


    @media screen and (min-width: 1100px) { 
     width: 40%; 
    } 
` 

widthの値はbreakpointsオブジェクトの値に対応する小道具のキーによって決定されますが、この部分は自明ではありませんが、必要なCSSを動的に生成する方法はわかりません。

私は追加できる情報があると確信していますが、私はいくつかの試みを行いましたが、現時点では何も作業していません。私の気持ちは、各条件ごとにCSSを生成するステートレス機能コンポーネントを作成し、最後にCSSに参加するということです。

答えて

5

これは大きな質問です。まず、このパターンを避けてください。

const GridCol = props => styled('div')` 
    display: block; 
    box-sizing: border-box; 
    flex: 1 0 0; 
    min-width: 0; 
    padding: ${props.gutter ? `0 10px` : '0'}; 
` 

この例では、パフォーマンスの面で恐ろしいすべてのレンダリングで新しいスタイリングコンポーネントが作成されます。

任意の式または補間が関数になります。この関数は、2つの引数を受け取ります:propsとあなたの例ではsize小道具については

const GridCol = styled('div')` 
    display: block; 
    box-sizing: border-box; 
    flex: 1 0 0; 
    min-width: 0; 
    padding: ${props => props.gutter ? `0 10px` : '0'}; 
` 

contextが、私は次のパターンを使用します。

import { css } from 'emotion' 

const sizePartial = (props) => typeof props.size === 'string' ? 
    css`width: 10%;` : 
    css` 
    @media screen and (min-width: 500px) { 
     width: 20%; 
    } 


    @media screen and (min-width: 800px) { 
     width: 30%; 
    } 


    @media screen and (min-width: 1100px) { 
     width: 40%; 
    } 
` 

部分的には、式に含まれる他の関数と同様に使用できます。

const GridCol = styled('div')` 
    display: block; 
    box-sizing: border-box; 
    flex: 1 0 0; 
    min-width: 0; 
    padding: ${props => props.gutter ? `0 10px` : '0'}; 
    ${sizePartial}; 
` 

これは、プロジェクト全体で再利用可能な動的スタイルを構成するために使用できる非常に強力なパターンです。

あなたはこのパターンが https://github.com/emotion-js/facepainthttps://github.com/jxnblk/styled-system

をチェックアウト活用し、他のライブラリに興味がある場合
関連する問題