今までstyled-componentsとmaterial-uiそれぞれ入れて使ってたのですが、material-uiにstyled-componentっぽいAPIが生えてたのに気づいたので使ってみたメモ(キャッチアップできてないだけですね。。。)。@material-ui/core
のバージョンは4.1.0です。
リファレンス
使ってみる
基本
公式に載ってるコードだとこんな感じですね。本家の方はTemplateStringsArrayでスタイル定義しますが、こちらはデフォルトだとCSSPropertiesのObjectを食わすのでよりJSっぽいスタイルです。
import React from 'react'; import { styled } from '@material-ui/styles'; import Button from '@material-ui/core/Button'; const MyButton = styled(Button)({ background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', border: 0, borderRadius: 3, boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)', color: 'white', height: 48, padding: '0 30px', });
MUIのComponentではなく普通のHTMLのタグを指定したいときはstringを指定します。
import React from 'react'; import { styled } from '@material-ui/styles'; const MyButton = styled('button')({ background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', border: 0, borderRadius: 3, boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)', color: 'white', height: 48, padding: '0 30px', });
Propsに応じてスタイルを変える
Propsに応じてスタイルを変えたい時はこんな感じです。Componentは必要なPropsを渡せる形にして、スタイルは値ではなくpropsを受け取って値を返す関数を設定します。
import React from 'react'; import { styled } from '@material-ui/styles'; type MyButtonProps = { size: 'small' | 'normal'; }; // lintで怒られるの不本意なんですけど・・・ // eslint-disable-next-line @typescript-eslint/no-unused-vars const MyButton = styled(({ size, ...other }: MyButtonProps) => <button {...other} />)({ background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', border: 0, borderRadius: 3, boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)', color: 'white', height: 48, padding: '0 30px', fontSize: ({ size }: MyButtonProps) => (size === 'small' ? '12px' : '16px'), });
自分で定義したComponentで使う
classNameをPropsで渡してRootのComponentに渡します。
MyComponent.tsx
import React from 'react'; import { styled } from '@material-ui/styles'; type MyComponentProps = { className?: string; }; const MyComponent = ({ className }: MyComponentProps) => ( <div className={className}>こんぽーねんと</div> ); export default MyComponent;
CustomComponent.tsx
import React from 'react'; import { styled } from '@material-ui/styles'; import MyComponent from './MyComponent'; const StyledMyComponent = styled(MyComponent)({ background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)', }); const CustomComponent = () => ( <div><StyledMyComponent /></div> ); export default CustomComponent;
おしまい
- 少し試しただけですが最初から作るならMaterialUIに寄せてもいいかなと思いました。