オブジェクトスタイルをテンプレートリテラルに変換 — Numio
css({...}) や styled.x({...}) のオブジェクトスタイルを、styled-components、Emotion、Linaria 向けのタグ付きテンプレートリテラルに書き換えます。camelCase のキーは kebab-case になり、数値には単位なしプロパティを除いて px が付き、JS の式は ${} の埋め込みになります。
Emotion や Glamor のオブジェクトスタイルを、テンプレートリテラルの CSS を前提とする styled-components や Linaria に移行する。
こんなときに使えます
- Emotion や Glamor のオブジェクトスタイルを、テンプレートリテラルの CSS を前提とする styled-components や Linaria に移行する。
- styled(Component)({...}) の定義をテンプレート構文に変換し、通常の CSS として読み書きできるようにする。
使い方
- css({...})、styled.tag({...})、styled(Component)({...}) を呼び出す JavaScript または TypeScript(JSX/TSX 可)を Object Styles エディターに貼り付けます。
- 「設定」で "Transpile css tags" と "Transpile styled tags" をオンのままにするか、一方をオフにしてその呼び出しを変更せずに残します。オフにすると警告バナーが表示されます。
- 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>`...` になります。