react-with-styles

React でテーマを使用して CSS-in-JavaScript を利用できます。特定の実装に強く依存することはありません。
1,659
作成者Joe Lencioni

React コンポーネントで CSS-in-JavaScript を使用できます。特定の実装 (例:AphroditeRadiumReact Native) に強く依存することはありません。スタイルを定義する際に、共有テーマ情報 (例: 色、フォント) に簡単にアクセスできます。

インターフェース

その他のリソース

使用方法

色などの共有テーマ情報を持つオブジェクトをエクスポートするモジュールを作成します。

export default {
  color: {
    primary: '#FF5A5F',
    secondary: '#00A699',
  },
};

テーマとインターフェースを登録します。たとえば、テーマが MyTheme.js によってエクスポートされ、Aphrodite を使用したい場合は、独自の withStyles.js ファイルでこれを設定できます。

import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet';
import aphroditeInterface from 'react-with-styles-interface-aphrodite';
import { css, withStyles } from 'react-with-styles';

import MyTheme from './MyTheme';

ThemedStyleSheet.registerTheme(MyTheme);
ThemedStyleSheet.registerInterface(aphroditeInterface);

export { css, withStyles, ThemedStyleSheet };

ここでは、react-with-styles から csswithStyles をそのまま渡すと便利です。これにより、使用するすべての場所でテーマとインターフェースが登録されていることを保証できます。これを、バンドルの先頭に追加されるイニシャライザとして設定し、コンポーネントで直接 react-with-styles を使用することもできます。

コンポーネントでは、上記の withStyles.js ファイルから、withStyles() を使用してスタイルを定義し、css() を使用してそれらを使用します。

import React from 'react';
import PropTypes from 'prop-types';
import { css, withStyles } from './withStyles';

function MyComponent({ styles }) {
  return (
    <div>
      <a
        href="/somewhere"
        {...css(styles.firstLink)}
      >
        A link to somewhere
      </a>

      {' '}
      and
      {' '}

      <a
        href="/somewhere-else"
        {...css(styles.secondLink)}
      >
        a link to somewhere else
      </a>
    </div>
  );
}

MyComponent.propTypes = {
  styles: PropTypes.object.isRequired,
};

export default withStyles(({ color }) => ({
  firstLink: {
    color: color.primary,
  },

  secondLink: {
    color: color.secondary,
  },
}))(MyComponent);

ThemedStyleSheet

テーマとインターフェースを登録します。

ThemedStyleSheet.registerTheme(theme)

テーマを登録します。 theme は、コンポーネントのスタイルを設定するときに使用できるようにするプロパティを持つオブジェクトです。

import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet';

ThemedStyleSheet.registerTheme({
  color: {
    primary: '#FF5A5F',
    secondary: '#00A699',
  },
});

ThemedStyleSheet.registerInterface(interface)

react-with-styles にスタイルの処理方法を指示します。

import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet';
import aphroditeInterface from 'react-with-styles-interface-aphrodite';

ThemedStyleSheet.registerInterface(aphroditeInterface);

withStyles([ stylesThunk [, options ] ])

これは、高階コンポーネントを返す高階関数です。React コンポーネントをラップして、テーマを使用してスタイルを追加するために使用します。テーマ付きスタイルをより使いやすくするために使用します。

stylesThunk は引数としてテーマを受け取り、コンポーネントのスタイルを含むオブジェクトを返す必要があります。

ラップされたコンポーネントは、このコンポーネントの処理済みスタイルを含む styles プロパティと、テーマオブジェクトを含む theme プロパティを受け取ります。ほとんどの場合、styles プロパティのみが必要になります。 theme プロパティへの依存は最小限に抑える必要があります。

使用例

import React from 'react';
import { css, withStyles } from './withStyles';

function MyComponent({ styles }) {
  return (
    <div {...css(styles.container)}>
      Try to be a rainbow in someone's cloud.
    </div>
  );
}

export default withStyles(({ color, unit }) => ({
  container: {
    color: color.primary,
    marginBottom: 2 * unit,
  },
}))(MyComponent);

または、デコレータとして

import React from 'react';
import { css, withStyles } from './withStyles';

@withStyles(({ color, unit }) => ({
  container: {
    color: color.primary,
    marginBottom: 2 * unit,
  },
}))
export default function MyComponent({ styles }) {
  return (
    <div {...css(styles.container)}>
      Try to be a rainbow in someone's cloud.
    </div>
  );
}

オプション

pureComponent (デフォルト: false, React 15.3.0+)

デフォルトでは、withStyles()React.Component を拡張するコンポーネントを作成します。 React.PureComponent によって提供される shouldComponentUpdate() 最適化を適用する場合は、pureComponent オプションを true に設定できます。 React.PureComponent は React 15.3.0 で導入されたため、これはそのバージョン以降を使用している場合にのみ機能します。

stylesPropName (デフォルト: 'styles')

デフォルトでは、withStyles()styles プロパティのラップされたコンポーネントにスタイルを渡しますが、このプロパティの名前は stylesPropName オプションを設定することでカスタマイズできます。これは、すでに styles というプロパティがあり、変更できない場合に役立ちます。

import React from 'react';
import { css, withStyles } from './withStyles';

function MyComponent({ withStylesStyles }) {
  return (
    <div {...css(withStylesStyles.container)}>
      Try to be a rainbow in someone's cloud.
    </div>
  );
}

export default withStyles(({ color, unit }) => ({
  container: {
    color: color.primary,
    marginBottom: 2 * unit,
  },
}), { stylesPropName: 'withStylesStyles' })(MyComponent);

themePropName (デフォルト 'theme')

同様に、テーマプロパティ名も themePropName オプションを設定することでカスタマイズできます。

import React from 'react';
import { css, withStyles } from './withStyles';

function MyComponent({ styles, withStylesTheme }) {
  return (
    <div {...css(styles.container)}>
      <Background color={withStylesTheme.color.primary}>
        Try to be a rainbow in someone's cloud.
      </Background>
    </div>
  );
}

export default withStyles(({ color, unit }) => ({
  container: {
    color: color.primary,
    marginBottom: 2 * unit,
  },
}), { themePropName: 'withStylesTheme' })(MyComponent);

flushBefore (デフォルト: false)

一部のコンポーネントは、マウント時にコンポーネントツリーで前のスタイルが準備できている必要があります (例: 寸法計算)。一部のインターフェースはページにスタイルを非同期的に追加しますが、これはこれにとって障害となります。そのため、レンダリングサイクルが始まる前にバッファされたスタイルをフラッシュするオプションを提供します。これが何を意味するかは、インターフェースによって定義されます。

css(...styles)

この関数は、withStyles() によって処理されたスタイル、プレーンオブジェクト、またはこれらのものの配列を受け取ります。JSX 要素にスプレッドする必要がある、不透明な構造を持つオブジェクトを返します。

import React from 'react';
import { css, withStyles } from './withStyles';

function MyComponent({ bold, padding, styles }) {
  return (
    <div {...css(styles.container, { padding })}>
      Try to be a rainbow in{' '}
      <a
        href="/somewhere"
        {...css(styles.link, bold && styles.link_bold)}
      >
        someone's cloud
      </a>
    </div>
  );
}

export default withStyles(({ color, unit }) => ({
  container: {
    color: color.primary,
    marginBottom: 2 * unit,
  },

  link: {
    color: color.secondary,
  },

  link_bold: {
    fontWeight: 700,
  },
}))(MyComponent);

className プロパティと style プロパティは、css() と同じ要素で使用しないでください。

React Router の Link を使用

React Router<Link/> および <IndexLink/> コンポーネントは、activeClassName='...' および activeStyle={{...}} をプロパティとして受け入れます。前述のように、css(...styles) は JSX にスプレッドする必要があるため、styles.thingcss(styles.thing) を直接渡しても機能しません。 activeClassName/activeStyles を模倣するには、React Router の withRouter() 高階コンポーネントを使用して router をプロパティとしてコンポーネントに渡し、router.isActive(pathOrLoc, indexOnly) に基づいてスタイルを切り替えることができます。これは、<Link />css(..styles) から生成された className を最終的なリーフに渡すためです。

import React from 'react';
import { withRouter, Link } from 'react-router';
import { css, withStyles } from '../withStyles';

function Nav({ router, styles }) {
  return (
    <div {...css(styles.container)}>
      <Link
        to="/"
        {...css(styles.link, router.isActive('/', true) && styles.link_bold)}
      >
        home
      </Link>
      <Link
        to="/somewhere"
        {...css(styles.link, router.isActive('/somewhere', true) && styles.link_bold)}
      >
        somewhere
      </Link>
    </div>
  );
}

export default withRouter(withStyles(({ color, unit }) => ({
  container: {
    color: color.primary,
    marginBottom: 2 * unit,
  },

  link: {
    color: color.primary,
  },

  link_bold: {
    fontWeight: 700,
  }
}))(Nav));

実際の使用例

react-with-styles を使用している組織とプロジェクト.