本文へスキップ

オブジェクトスタイルをテンプレートリテラルに変換 — Numio

css({...}) や styled.x({...}) のオブジェクトスタイルを、styled-components、Emotion、Linaria 向けのタグ付きテンプレートリテラルに書き換えます。camelCase のキーは kebab-case になり、数値には単位なしプロパティを除いて px が付き、JS の式は ${} の埋め込みになります。

Emotion や Glamor のオブジェクトスタイルを、テンプレートリテラルの CSS を前提とする styled-components や Linaria に移行する。

Object Styles

Template Literal

こんなときに使えます

  • Emotion や Glamor のオブジェクトスタイルを、テンプレートリテラルの CSS を前提とする styled-components や Linaria に移行する。
  • styled(Component)({...}) の定義をテンプレート構文に変換し、通常の CSS として読み書きできるようにする。

使い方

  1. css({...})、styled.tag({...})、styled(Component)({...}) を呼び出す JavaScript または TypeScript(JSX/TSX 可)を Object Styles エディターに貼り付けます。
  2. 「設定」で "Transpile css tags" と "Transpile styled tags" をオンのままにするか、一方をオフにしてその呼び出しを変更せずに残します。オフにすると警告バナーが表示されます。
  3. Template Literal パネルをコピーします。変換対象の呼び出し以外のコードは残りますが、Prettier で再整形されます。

オブジェクトスタイル(JavaScript または TypeScript)

const Button = styled.button({
  padding: 8,
  fontSize: '14px',
  backgroundColor: theme.primary,
  '&:hover': {
    opacity: 0.8,
  },
})

const card = css({
  display: 'flex',
  marginTop: 16,
})

タグ付きテンプレートリテラル

const Button = styled.button`
  padding: 8px;
  font-size: 14px;
  background-color: ${theme.primary};

  &:hover {
    opacity: 0.8;
  }
`
const card = css`
  display: flex;
  margin-top: 16px;
`

仕様と制限

変換はブラウザー内で実行されます。Web Worker が Babel standalone で babel-plugin-object-styles-to-template を適用し(プレーンな JavaScript としてパースできない場合は TypeScript 構文でパース)、結果はセミコロンなしで Prettier により整形されます。

変換されるのは、引数が単一のプレーンなオブジェクトである呼び出しだけです。関数や複数の引数を取る styled("div")(obj, props => ...) や、css([...]) の配列はそのまま残ります。

zIndex、lineHeight、opacity などの単位なしプロパティは数値のまま、それ以外の数値には px が付きます。配列の値は展開されず、${[0, 4]} のような埋め込みになります。

Prettier は変更されていないコードも正規化します。たとえばシングルクォートはダブルクォートになります。

FAQ

どの呼び出し名が認識されますか?

プラグインは css(...) と styled の呼び出し、つまり styled.button(...)、styled("div")(...)、styled(Link)(...) を変換します。someFn({ color: 'red' }) のような、オブジェクト引数を取るその他の関数は変更されません。

変数やテーマの値はどう扱われますか?

theme.primary や colors.white などリテラルでない値は、テンプレート内の ${...} に JavaScript の式として残るため、実行時にそのまま解決されます。

&:hover のようなネストしたセレクターに対応していますか?

対応しています。'&:hover' などのキーの下にあるネストしたオブジェクトは、テンプレート内のネストしたブロックになり、親の宣言とは空行で区切られます。

TypeScript で使えますか?

使えます。コードが JavaScript としてパースできない場合、Babel の TypeScript 構文で再度パースされます。型は保持され、interface はそのまま残り、styled.button<Props>({...}) は styled.button<Props>`...` になります。

仕様を確認する