現在携わっているプロジェクトでは、UIライブラリとしてChakraUIを導入しています。
実装を進めるうちに便利だな〜と思う部分がたくさんあったので、今回はChakraUIの概要について共有したいと思います。
対象読者
ChakraUIの導入を検討している人・ChakraUIに興味がある人
そもそも ChakraUIとは?
“Chakra UI”は、UIコンポーネントライブラリの一つです。これを使用することで、1からCSSを記述することなくスタイルに一貫性を持たせたUIを楽に実装することができます。
Our goal is to design simple, composable components that cater to real-life UI design problems. In order to do that, we developed a set of principles that help us always be on that path.
私たちの目標は、実際のUIデザインの問題に対応するシンプルで構成可能なコンポーネントを設計することです。それを行うために、私たちは常にその道を歩むのに役立つ一連の原則を開発しました。
(公式ドキュメントより引用)
またTailwind CSSと同様にUtility firstの一面も持っており、コンポーネント内をシンプルに保ちつつ、クラス名のネーミングという苦行からも解放されます。
Simplicity:
Strive to keep the component API fairly simple and show real world scenarios of using the component.シンプルさ:
コンポーネントAPIをかなりシンプルに保ち、コンポーネントを使用する実際のシナリオを示すように努めます。
Naming Props:
We all know naming is the hardest thing in this industry. Generally, ensure a prop name is indicative of what it does. Boolean props should be named using auxiliary verbs such asdoes
,has
,is
andshould
. For example,Button
usesisDisabled
,isLoading
, etc.ネーミングProps:
ネーミングがこの業界で最も難しいことであることは誰もが知っています。一般的に、propsの名前がそれが何をするかを示していることを確認してください。Boolean propsでは、does
やhas
,is
などの助動詞を使用して名前を付ける必要があります。たとえばButton
ではisDisable
,isLoading
を使用します。
(公式ドキュメントより引用)
ChakraUIの良い点は、上記のようなUtility firstとしてのメリットを享受つつ、UIライブラリとしてしっかりとしたUIを提供してくれるところにあると思います。
Tailwind CSSの場合はUIライブラリとしての機能は比較的薄く、Utility firstの考え方で1からスタイルを作り上げる必要があるので、ChakraUIよりも学習コストも初期実装工数もかかります。(TailwindUIのようなUIカタログを使えば解決する点かもしれません)
逆を言えば、ChakraUIはTailwindよりもデザインのカスタマイズに多少なりとも制限がかかってくるので、一長一短です。
仮にどちらかを選ぶ必要がある状況になった時は、『独自のデザインを多く適用する必要があるか否か』を基準に考えると良いのかもしれません。
Pure Typescript である
ChakraUIの良い点の一つとして、Reactでアプリを構築する前提で作られているため、typescriptで型保護されている という点も挙げられるかと思います。
スタイルを指定していくときなどもサジェストを出してくれるので、とても開発者体験が良いです!
例えば Button
にスタイルをつける場合、propsに記述してオーバーライドさせていくことができるのですが
こんな感じで、Button
に使用できるものをサジェストしてくれます。
使用できないものが指定されていた場合もtscでエラーを出してくれるので、非常に素早く確実に実装していくことができます。
💡 余談:ちなみにvue用のchakraUIライブラリも存在します。(まだバージョンは v0.10.*
)
使用例
では、実際にどのように使用するかについてです。
※ 具体的なChakraUI導入の方法は今回は割愛します(詳しくは公式サイトを参照)
基本的にはimportしたChakraUIのモジュールを使用し、すでにスタイルがついているコンポーネントを適用していくイメージです。
例えばspinner
というモジュールを使用すれば、ChakraUIのデフォルトスタイルが当たったスピナーを表示できます。必要であればpropsでスタイルを上書きしていく形になります。
// Boxモジュールをインポート
import { Spinner } from '@chakra-ui/react'
...
<Spinner
thickness='4px'
speed='0.65s'
emptyColor='gray.200' // colorはChakraUIで定義されたものから
color='blue.500'
size='xl'
/>
参考: https://chakra-ui.com/docs/feedback/spinner#spinner-with-empty-area-color
そのままでも機能としては十分ですし、スタイルも上書きして使用できるので汎用的です。
また、その他よく使うモジュールもいくつか紹介します。
Box
Box
モジュールは、デフォルトでは div
としてレンダリングされるもので、抽象度が高いのでwrapperなどに使用することが多いです。
以下の場合は、Labelコンポーネント(タグのようなUI)を作成した例です。
// Boxモジュールをインポート
import { Box } from '@chakra-ui/react'
// props 型定義
type LabelTagProps = {
children: string
}
export const Label = ({ children }: LabelTagProps) => {
return (
<Box
as={'span'} // spanとしてタグを出力
bg={'white'}
border={'1px solid'}
borderColor={'Cyan.500'}
borderRadius={'4px'}
color={'Cyan.500'}
fontSize={{ base: 'xs', md: 'sm' }} // オブジェクトで渡すことでレスポンシブ対応
fontWeight={700}
>
{children}
</Box>
)
}
こちらでもインポートしたChakraUIの Box
を、Reactコンポーネントと同じような形で適用します。
propsを渡すことで、スタイルを指定していきます。
ここで指定するスタイルの名前は、実際のCSSの指定とは違いキャメルケースとなるので注意が必要です。
とはいえ、chakraUIが気を利かせてサジェストを出してくれるので、困るケースはほとんどないかと思います。
また、as
を指定することで、出力されるタグをオーバーライド可能です。
ここでは、as
にspanを指定することで、spanタグとして使用しています。
The Box component is useful because it helps with 3 common use cases:
・ Create responsive layouts with ease.
・ Provide a shorthand way to pass styles via props (bg
instead ofbackgroundColor
).
・ Compose new component and allow for override using theas
prop.Boxコンポーネントは、次の3つの一般的なユースケースに役立つため便利です。
・レスポンシブレイアウトを簡単に作成できます。
・propsを介してスタイルを渡すための簡単な方法を提供します(backgroundColor
はbg
となります)
・新しいコンポーネントを作成し、as
propsを使用してオーバーライドできるようにします。
(公式ドキュメントより引用)
上記は、基本的にはどのモジュールでも同様な仕組みとなります。
例えば DL/DT/DD
タグをマークアップをしたい場合、ChakraUIにはデフォルトでそのタグを出力するモジュールは用意されていません。
そのため、
import { Box, Heading, Text } from '@chakra-ui/react'
...
<Box as={'dl'} mt={{ base: 4, md: 8 }}>
<Heading as={'dt'}>
タイトル
</Heading>
<Text as={'dd'}>
内容
</Text>
</Box>
このような形で as
を利用すると「Heading」と「Text」という構造も直感的に読み取れるので、コードの可読性アップさせる書き方ができるケースもあります。
Stack, VStack, HStack
このモジュールは、複数要素をラップすることで簡単に横並び・縦並びを実現でき、またそれら間のスペースをコントロールできます。
これはChakraUI独自の機能で、これを使うためにChakraUIを導入したいと言っても過言ではないほど便利な機能です。
- Stack:縦並び / 左寄せ
- VStack:縦並び / 横中央寄せ
- HStack:横並び / 縦中央寄せ
例えば HStack
を使用することで、中の要素を横並びにし、spacing
を指定することで隙間の大きさを調整できます。(デフォルトでも少し隙間が空いた状態になります)
import { Box, HStack } from '@chakra-ui/react'
<HStack spacing='24px'> // 24pxの隙間を空ける
<Box w='40px' h='40px' bg='yellow.200'>
1
</Box>
<Box w='20px' h='20px' bg='tomato'>
2
</Box>
<Box w='40px' h='40px' bg='pink.100'>
3
</Box>
</HStack>
また、propsでspacing
を指定せずに、要素の間にSpacer
というモジュールを使用することで、隙間を親の幅から自動で均等に配置してくれます。
import { Box, HStack, Spacer } from '@chakra-ui/react'
<HStack>
<Box w='40px' h='40px' bg='yellow.200'>
1
</Box>
<Spacer />
<Box w='20px' h='20px' bg='tomato'>
2
</Box>
<Spacer />
<Box w='40px' h='40px' bg='pink.100'>
3
</Box>
</HStack>
上記のようなレイアウトは、Flexbox
などでももちろん実現可能ですが、スタイルの指定をせずにタグから直感的にレイアウトがイメージできるのは大きなメリットであると思います。
レスポンシブ対応
ChakraUIのレスポンシブ対応は、propsで指定するスタイルを 配列 もしくは オブジェクト で渡す形で実装します。
ブレイクポイントの指定
import { createBreakpoints } from '@chakra-ui/theme-tools'
const breakpoints = createBreakpoints({
sm: '30em',
md: '48em',
lg: '62em',
xl: '80em',
'2xl': '96em',
})
テーマファイルに、createBreakpoints
を使ってブレークポイントを指定することができます。
レスポンシブスタイルの指定方法
①配列形式
配列で指定する場合、小さい方のブレイクポイントから順に適用されます。
<Box
bg='teal.400'
width={[
'100%', // 0-30em
'50%', // 30em-48em
'25%', // 48em-62em
'15%', // 62em+
]}
/>
この例だと4つの指定をしているため、62em以上は4つ目のスタイルが適用されます。
②オブジェクト形式
オブジェクトで指定する場合は、ブレイクポイントのエイリアスを使用してレスポンシブ値を定義します。
<Text fontSize={{ base: '24px', md: '40px', lg: '56px' }}>
This is responsive text
</Text>
base
は設定された値以下の場合を定義します。つまり、この例では
- base: 0-48em
- md: 48-62em
- lg: 62em+
という2つのブレイクポイントでスタイルが分かれるように記述されています。
実装した所感としては、配列よりもオブジェクトで定義したほうがブレイクポイントの範囲が明示的ですし、
柔軟に色々なパターンに対応できるため使いやすい印象です。
ChakraUIのメリット・デメリット まとめ
メリット
- デフォルトのデザインが割とキレイなのでそのまま使っても違和感がない
- Figmaにテンプレートがあるのでデザイナーさんとも連携取りやすい
- Pure Typescript で開発者体験◎
- 便利な独自フックが存在する
- アクセシビリティもいい感じに対応されている
デメリット
- 使えるモジュールの数が多いので、最初は学習コストがそれなりに掛かる
- 実装デザインが完全オリジナルな場合、ChakraUIのデフォルトのスタイルが邪魔に感じる時もある
- 場合によっては、HeadlessUIとかで機能だけ使ってスタイルは自分で書く方式を選択肢に入れる
- Themeのカスタマイズ管理は初期実装にコストがかかる
最後に
ChakraUIの概要についてざっくりとご説明しました。
使用感やコードの書き味のイメージを掴んでいただけていれば幸いです。
また、今回詳しく記載しきれなかった以下のような便利機能がまだまだあります。
- ThemeでのUIカスタマイズ(スタイルをpropsで直接上書きしない方法)
- 独自フックについて
- アクセシビリティの考慮
こちらについても、機会があればまとめてみたいと思います!