💅
styled-componentsの理解
styled-componentsを採用することになりました、勉強していきます
styled-components
Reactアプリケーションで使用される、コンポーネントベースのCSS-in-JSライブラリ
導入
本体
TypeScriptで使いたいので、型定義ファイルもインストール
$ yarn add styled-components
$ yarn add --dev @types/styled-components
使い方
import styled from 'styled-components';
// スタイルを書く
// StyledXXXにすることが一般的
const StyledButton = styled.button`
padding: 4px 10px;
color: #fff;
background-color: blue;
border-radius: 5px;
&:disabled {
background-color: gray;
}
`;
// そのままexport可能
export default StyledButton;
組み合わせて使うことも可能
const StyledGroup = styled.div`
border: 1px solid #cccccc;
border-radius: 8px;
`;
// コンポーネントからpropsを受け取ることが可能
const StyledLabel = styled.label<{ $type: 'correct' | 'wrong' }>`
background-color: ${(props) =>
props.$type === 'correct'
? '#d4edda'
: '#fff'};
`;
function Group({ isAnswer }: Props){
return (
<StyledGroup>
<StyledLabel $type={ isAnswer ? "correct" : "wrong"}>
{isAnswer ? '正解' : '不正解'}
</StyledLabel>
</StyledGroup>
)
}
Theming
次にコンポーネントにテーマを用いてスタイルを適用していく
Themingとは
<ThemeProvider>
でラッパーすると、
それ自身の下にあるすべてのReactコンポーネントにテーマが提供され、すべての styled-componentsはテーマにアクセスすることができる
導入
ベースファイル
config/theme.tsを作る
(ファイルを作るかどうかや、ファイル名、ファイルの置き場所はプロジェクトによる)
ここにスタイルの定義を書く
export const theme = {
pallet: {
primary: {
light: '#42a5f5',
main: '#1976d2',
dark: '#1565c0',
contrastText: '#ffffff',
},
secondary: {
light: '#ba68c8',
main: '#9c27b0',
dark: '#7b1fa2',
contrastText: '#ffffff',
}
},
offset: {
gap: 8,
}
}
型定義
styled-components用の型定義ファイルを作成
styled-components.d.ts
import 'styled-components';
import { theme } from '@/config/theme';
type Theme = typeof theme;
declare module 'styled-components' {
// config/theme.ts で定義したもので DefaultTheme を上書きする
export interface DefaultTheme extends Theme {}
}
これで型解決します!
(props.themeの補完や、静的型チェックが有効になる)
プロバイダーの設置
アプリケーションルートを <ThemeProvider>
でラップする
themeプロパティに使用したいthemeを設定(ここではベースファイルを使用)
import { theme } from '@/config/theme';
export default function App({ Component, pageProps }: AppProps) {
return (
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
);
}
あとはコンポーネント内で使いまわす
type ThemeType = 'primary' | 'secondary';
type StyledButtonProps = {
readonly $theme: ThemeType;
};
const StyledButton = styled.button<StyledButtonProps>`
&:disabled {
background-color: ${(props) => props.theme.pallet.disabled.main};
}
/* こんな感じでも使える */
background-color: ${(props) => props.theme.pallet[props.$theme].main};
`;
// 青いボタン
<Button $theme="primary">click me</Button>
// 紫のボタン
<Button $theme="secondary">click me</Button>
Discussion