[React]Chakra Uiのすすめ

# はじめに

なにかReactのデザイン系のライブラリがないかと探しているときにChakra UIを見つけました｡使いやすく､シンプルでそれなりにカスタマイズ性も高く､気に入っているのでこの記事で気になった方はぜひ使ってみてください｡

# インストール

```
npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4
```

もしくは

```
yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4
```

インストール後､最も上位の階層に`ChakraProvider`を置く必要があります｡`npx create-react-app`などでプロジェクトを作成している場合は`index.js`を以下にように変更します｡

```jsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';

import { ChakraProvider } from "@chakra-ui/react"

ReactDOM.render(
  <React.StrictMode>
    <ChakraProvider>
      <App />
    </ChakraProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
```

`App`コンポーネントを`ChakraProvider`で囲んでいます｡これで囲むことでChakra UIが提供するコンポーネントを利用できるようになります｡

## ほぼ共通事項

Chakra UIの提供するコンポーネントでほぼ共通することについて説明します｡

## 色の指定

Chakra UIはデフォルトで`色の名前.数値`で色を指定することができるようになっています｡色のサンプルを以下に示します｡

|![color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2063050/c2f6a51f-01c0-1b1e-1031-866412c8752c.png)|
|:--|

上記のように指定する他に､16進数を利用して`#ff0000`などのようにRGB値で直接指定することもできます｡

## Props

Chakra UIが提供するコンポーネントはおおよそ共通のpropを持っています｡おもなPropsは以下の通りです｡

|Props名|説明|
|----|----|
|bg| 背景色
|m[treblsxy]| マージン
|p[treblsxy]| パディング
|color| 文字色
|opacity| 要素の透明度
|w| 要素の幅
|h| 要素の高さ
|minW| 要素の最小幅
|maxW| 要素の最大幅
|minH| 要素の最小高さ
|maxH|要素の最大高さ

# 基本的なコンポーネント

よく使われるコンポーネントについて説明します｡

## Box

HTMLタグの`<div>`に相当するコンポーネントです｡

```jsx
function App() {
  return (
    <Box>
      <Box>Hello World.</Box>
    </Box>
  );
}
```

![Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2063050/cc2e6e94-218c-f553-0912-57fa1cb51859.png)

|![box.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2063050/6d2a477b-08dd-9d9d-5c23-64af9e6ebae8.png)|
|:--|

## Button

ボタンを表示します｡押したときに少し色が濃くなるアニメーションがデフォルトでつけられています｡

```jsx
function App() {
  return (
    <Center>
      <Button>Push me!</Button>
    </Center>
  );
}
```

|![button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2063050/2fcf207f-9859-127e-5c3c-4d793b2fd74d.png)|
|:--|


# レイアウト

Chakra UIなどのデザイン系のライブラリを利用する主な理由は動的にレイアウトを変更するためであることが多いです｡ここではレイアウトに関するものの説明をします｡

## Center

`Center`コンポーネントで囲んだコンポーネントを中央に描写します｡

```jsx
function App() {
  return (
    <>
    <Box bg="red.500" w="40px" h="40px" />
    <Center>
      <Box bg="blue.500" w="40px" h="40px" />
    </Center>
    </>
  );
}
```

|![Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2063050/769f2244-b59c-be31-9098-32d5a8faae26.png)|
|:--|

青色の`Box`コンポーネントが`Center`コンポーネントで囲んだものです｡中央に寄せられていることがわかります｡

## HStack､VStack

コンポーネント内の要素を並べて表示します｡HStackはコンポーネント内の要素を横に並べ､VStackはコンポーネント内の要素を立てに並べます｡これらは組み合わせて使うこともできます｡

```jsx
function App() {
  return (
    <Center>
      <HStack>
        <VStack>
          <Box bg="red.700" w="40px" h="40px" />
          <Box bg="red.500" w="40px" h="40px" />
          <Box bg="red.300" w="40px" h="40px" />
        </VStack>
        <VStack>
          <Box bg="yellow.700" w="40px" h="40px" />
          <Box bg="yellow.500" w="40px" h="40px" />
          <Box bg="yellow.300" w="40px" h="40px" />
        </VStack>
        <VStack>
          <Box bg="blue.700" w="40px" h="40px" />
          <Box bg="blue.500" w="40px" h="40px" />
          <Box bg="blue.300" w="40px" h="40px" />
        </VStack>
      </HStack>
    </Center>
  );
}
```

|![Hstack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2063050/32ee2c09-2b61-3617-21fd-531869ed522f.png)|
|:--|

## Flex

`Flex`コンポーネントはその名の通り､cssのflexと同じようにコンポーネントに渡された要素を並べます｡要素間の隙間は`Spacer`コンポーネントを利用して指定します｡基本的に`Flex`は最大幅を満たすように要素を配置します｡

```jsx
function App() {
  return (
    <VStack>
      <Flex w="100%">
        <Box bg="red.500" w="20%" h="10px" />
        <Spacer />
        <Box bg="red.500" w="40%" h="10px" />
        <Spacer />
        <Box bg="red.500" w="20%" h="10px" />
      </Flex>
      <Flex w="100%">
        <Box bg="red.500" w="20%" h="10px" />
        <Spacer />
        <Box bg="red.500" w="20%" h="10px" />
        <Spacer />
        <Box bg="red.500" w="40%" h="10px" />
      </Flex>
    </VStack>
  );
}
```

|![flex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2063050/09842392-b620-a6c9-0b70-829151c615e7.png)|
|:--|

## Grid

マス目上に要素が当てはまるように配置するレイアウトです｡

```jsx
function App() {
  return (
    <Grid
      h="200px"
      templateRows="repeat(2, 1fr)"
      templateColumns="repeat(5, 1fr)"
      gap={4}
    >
      <GridItem rowSpan={2} colSpan={1} bg="red.500" />
      <GridItem colSpan={2} bg="red.500" />
      <GridItem colSpan={2} bg="red.500" />
      <GridItem colSpan={4} bg="red.500" />
    </Grid>
  );
}
```

|![grid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2063050/22e0f29c-2aa1-55cd-14e1-5a8afe6c57b2.png)|
|:--|

# まとめ

個人的にはbootstrapやskeltonなどのようにクラス名に書くよりもレイアウトなどの構造がわかりやすくなり､Reactのコーディングとデザインを同時に進められる感じが好きで気に入っています｡

これらの機能に加えて､framer-motionなどのアニメーションのライブラリと組み合わせることでよりモダンなサイトを作ることができます｡

この記事で興味を持った方はぜひ使ってみてください!