2015-12-17 53 views
6

私は誰かが私を助けてくれることを望んでいる構図について質問があります。 私はSassとreact-css-modulesを使用しています。基本的なボトムレベルのコンポーネントの1つを構成する最善の方法を知りたいと思います。ここでCSSモジュールの構成

が私たちのコンポーネントです:

import React, {PropTypes} from 'react' 
import cssModules from 'react-css-modules' 
import styles from './style.sass' 

const Button = ({children = 'Submit', ...props}) => { 
    const align = props.align ? `-${props.align}` : '' 
    const type = props.type ? `-${props.type}` : '' 
    const styleName = `button${type}${align}` 

    return (
    <button onClick={props.onClick} {...props} styleName={styleName}> 
     {children} 
    </button> 
) 
} 

Button.propTypes = { 
    align: PropTypes.string, 
    onClick: PropTypes.func.isRequired, 
    type: PropTypes.string, 
} 

export default cssModules(Button, styles) 

そしてここでは、これまでのスタイルシートです:今

@import "~components/styles/variables" 

.button 
    color: $button-default 
    background-color: transparent 
    font-family: $font-family 
    font-size: $default-font-size 
    font-weight: $font-regular 
    line-height: $default-button-height 
    margin: 0 $pad 0 0 
    outline: none 
    padding: 0 $pad*2 

.left 
    float: left 

.right 
    float: right 

.primary 
    color: $background-interaction 
    background-color: $button-default 

.button-left 
    composes: button, left 

.button-right 
    composes: button, right 

.button-primary 
    composes: button, primary 

.button-primary-left 
    composes: button, primary, left 

.button-primary-right 
    composes: button, primary, right 

、それはかなり痛いです。私たちが指数関数的に追加する構成可能な小道具は、私たちが提供しなければならない構成されたクラスの数を増加させます。現在aligntypeを設定することができ、どちらもnullになる可能性があるため、6つの組み合わせがあるため、.buttonのベースに加えて5つの作成クラスを作成します。 小道具をもう1つだけ追加した場合、ブール値boldと言うと、新しい構成クラス名を追加する必要があります:.button-bold, .button-left-bold, .button-right-bold, .button-primary-bold, .button-primary-left-bold, .button-primary-right-bold

私はreact-css-modulesと知っています。allowMultiple設定を有効にして、要素に適用する複数のモジュールを指定できるようにすることができますが、それはベストプラクティスに反するものです。私はのように感じて、には何かが不足していると感じます。私たちは何を間違っていますか?

答えて

6

私は多分、この例で懸念が混在していると思います。そのため、それは「要素ごとに1つのクラス」のルールに適合しません。要素ルールごとに1つのクラスを強制する理由の1つは、要素に実際に触れずに要素の状態の外観を簡単に変更できることです。 (基本的にはCSS自身の約束であり、最終的に実現しました)要素に複数のクラスがある場合、その要素を変更せずに外観を制御することは困難です。これは特に、意味クラスではなく外観クラスを使用する場合に当てはまります。

"button-primary-left-bold"のようなクラスはいくつかのセマンティックな意味( "button-primary")を持っていますが、レイアウトの意味( "left")とテキストの意味(bold) 。 Buttonコンポーネントには、おそらく独自のレイアウトを制御するビジネスはありません。あなたはReactコンポーネントも作成できることを覚えておいてください!

<Left><Button type="primary">Click Me!</Button></Left> 

ここで、ButtonコンポーネントのCSSモジュールでは、ボタンの種類について心配することができます。また、Buttonコンポーネントは、フロートベースのレイアウトだけでなく、あらゆるレイアウトでどこでも使用できます。

フロートをさらに意味のあるコンポーネントにプッシュすることもできます。おそらく次のようなものでしょう:

<ButtonBar> 
    <Button>Cancel</Button> 
    <Button type="primary">Save</Button> 
</ButtonBar> 

ButtonBarは、レイアウトを行う独自のCSSモジュールを持つことができます。そして、後であなたはすごいフレックスボックスレイアウトのためにそのジャンキーフロートレイアウトを交換することができます。 :-)

「太字」の修飾子の例では、Buttonコンポーネント内には配置されていません。 について考えてみると、なぜ何かが太字であり、コンポーネントまたはセマンティックプロパティを作成することをお勧めします。そうでなければ、デザインが "太字"ボタンを "イタリックグリーン"ボタンに変更する必要がある場合は、一連の要素を変更する必要があります。

意味コンポーネントのビジュアル/レイアウトクラスを交換し、コンポーネントとCSSモジュールを分割すると、 "指数関数的な増加"が少なくなります。あなたが本当に複数の意味論的特性が結合されている必要がある状況になった場合、それらの状態を綴ることにいくらかの価値があります。良い例は "primary-disabled"です。これは、いくつかの理由から、「プライマリディスエーブル」より優れています。まず、CSSモジュールを見て、明示的な状態を表示するのは簡単です。第二に、あいまいな用途やそれらのクラスの関係はありません。 「プライマリディスエーブル」は実際にこれらのクラスを有効に使用していますか?それは誰かが使用していることが書かれている場合にのみ知ることができます。 「無効」クラスは、「プライマリ」クラスの何かをオーバーライドする可能性があります。つまり、暗黙的な順序依存関係があります。将来の意味のある編集では、これらのクラス間の関係が明白でないため、簡単に内容を破ることができます。よくあることですが、キーストロークを保存するために何かを暗黙的に選択すると、微妙なエラーが発生する可能性があります。キーストローク税のそのビットを支払うことは、物事をロックし、何がうまくいくのか、何ができないのかを明白にします。

いくつかのキーストロークを節約するもう1つの小さなポイント:「ボタン」プレフィックスの理由はありません。それはまさにCSSモジュールのためのものです。これを代わりに:

.normal 
    color: $button-default 
    background-color: transparent 
    font-family: $font-family 
    font-size: $default-font-size 
    font-weight: $font-regular 
    line-height: $default-button-height 
    margin: 0 $pad 0 0 
    outline: none 
    padding: 0 $pad*2 

.primary 
    composes: normal 
    color: $background-interaction 
    background-color: $button-default 

ファイル名自体は基本的に "ボタン"プレフィックスです。

+0

このような素晴らしい答えはありがとう!私は実際にあなたの答えのようなCSSモジュールについての貴重なガイドラインやベストプラクティスを見つけるのに苦労しています。お勧めするリソースがありますか? – Azuli42

2

私はこの場合は作成から離れ、クラスを入れ子にすると思います。 SASS

import React, {PropTypes} from 'react' 
import cssModules from 'react-css-modules' 
import styles from './style.sass' 

const Button = ({children = 'Submit', ...props}) => { 
    const align = props.align ? `${props.align}` : '' 
    const type = props.type ? `${props.type}` : '' 
    const styleName = `button ${type} ${align}` 

    return (
    <button onClick={props.onClick} {...props} styleName={styleName}> 
     {children} 
    </button> 
) 
} 

Button.propTypes = { 
    align: PropTypes.string, 
    onClick: PropTypes.func.isRequired, 
    type: PropTypes.string, 
} 

export default cssModules(Button, styles) 

そして:ここに私の提案は(私のJSXは少しオフになっているなら、私はご容赦)です

@import "~components/styles/variables" 

.button 
    color: $button-default 
    background-color: transparent 
    font-family: $font-family 
    font-size: $default-font-size 
    font-weight: $font-regular 
    line-height: $default-button-height 
    margin: 0 $pad 0 0 
    outline: none 
    padding: 0 $pad*2 

    &.left 
    float: left 

    &.right 
    float: right 

    &.primary 
    color: $background-interaction 
    background-color: $button-default 

完全で他のクラス名と競合する可能性があり、「プライマリ」、「左」とすることを認めますあなたのアプリ。だから、若干良い(よりスコープの)名前を考え出すのは悪い考えではないかもしれません。

+0

私は間違いなくあなたのところを見ていますが、「他のクラス名と衝突する可能性があります」という問題は、CSSモジュールが解決する問題とまったく同じです。それは私が離れたい悪夢のようなものです! :-)少なくともこれでトップレベルのクラス ".button"は、cssモジュールローダーから一意の名前を取得するので、衝突する可能性があります。私は実際には完全にクリーンでカプセル化されたスタイルの約束を果たすソリューションを期待していました。 –

関連する問題