107
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ChakraUIについてまとめてみた(概要編)

Posted at

現在携わっているプロジェクトでは、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 as doeshasis and should. For example, Button uses isDisabledisLoading, etc.

ネーミングProps:
ネーミングがこの業界で最も難しいことであることは誰もが知っています。一般的に、propsの名前がそれが何をするかを示していることを確認してください。Boolean propsでは、doeshas,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に記述してオーバーライドさせていくことができるのですが

20220217-210718.png

こんな感じで、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 of backgroundColor).
・ Compose new component and allow for override using the as prop.

Boxコンポーネントは、次の3つの一般的なユースケースに役立つため便利です。
・レスポンシブレイアウトを簡単に作成できます。
・propsを介してスタイルを渡すための簡単な方法を提供します(backgroundColorbgとなります)
・新しいコンポーネントを作成し、aspropsを使用してオーバーライドできるようにします。

公式ドキュメントより引用)

上記は、基本的にはどのモジュールでも同様な仕組みとなります。

例えば 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を指定することで隙間の大きさを調整できます。(デフォルトでも少し隙間が空いた状態になります)

20220222-175224.png

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というモジュールを使用することで、隙間を親の幅から自動で均等に配置してくれます。

20220222-175549.png

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で直接上書きしない方法)
  • 独自フックについて
  • アクセシビリティの考慮

こちらについても、機会があればまとめてみたいと思います!

参考サイト

107
70
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
107
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?