ゼロから始めるChakraUIカスタムグローバル設定

ChakraUIをNextJSのサイトで使い始めてグローバル設定したのでまとめてみました。
現在絶賛、制作中のブログでお試しで導入したところ気に入っています。

→ 2021/11/8 追記：<a href="https://nora-dev.com/">野良開発のすすめ</a> というこれからWebサービスを作りたい人へ向けたブログサイトを Next,TS,ChakraUIを使って作成しました。

ChakraUI とは TailWindCSS にインスパイアされつつ styled-system 、 emotion や framer-motion をベースにして作られた Component Library です。
便利なChakraUI制のHooksなんかも用意されています。

使ってみた初日の感触としては TailWindCSS をもっとシンプルにしたスタイルのライブラリという印象を受けました。
今回はグローバル設定のところまで解説。

※この記事ではReact上でのChakraUI使用を想定しています

## ChakraUIをインストールする
https://chakra-ui.com/docs/getting-started

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

emotion や framer-motion を使っているため一緒にインストール。

## できるだけ親側でChakraProviderコンポーネントを設定する
ChakraProviderで囲われた親以下のコンポーネントに対して使えるようになります。
自分の場合はNextJSの初期化ページ（initialize pages）にあたる _app.tsx のコンポーネントで囲いました。

```_app.tsx
import { ChakraProvider } from "@chakra-ui/react"

export default function App({ Component, pageProps }) {
  return (
    <>
      <ChakraProvider theme={theme}>
        <Component {...pageProps} />
      </ChakraProvider>
    </>
  );
}

```


### Boxコンポーネントがdivタグ代わりになる
これでChakraProviderより以下のところでChakraUIが使えるようになったので使っていきたいと思います。
詳細は割愛しますがBoxコンポーネントがdivタグのような役割となります。

```hogeComponent.tsx
import { FC } from 'react'
import { Box, Text, Flex } from '@chakra-ui/react'

const HogeComponent: FC<{sitetitle: string, subtitle: string}> = ({sitetitle, subtitle}) => {
  return (
    <Flex justifyContent="center">
      <Box borderBottom="main" w="288px" p="8px 0">
        <Text fontSize="big">{siteTitle}<Text as="span" fontSize="12px" display="block">{subTitle}</Text></Text>
      </Box>
    </Flex>
  );
};
export default HogeComponent;
```

TailWind系のライブラリを触ったことがある人ならだいたい雰囲気がつかめるかなと。
marginはm、paddingはp、widthはw、heightはhのように省略形で記載できるプロパティもあります。

Boxコンポーネントはdiv、Texコンポーネントはp、Flexコンポーネントはdisplay: flexのdivのような粒度からもっと大きな粒度でコンポーネントが色々と用意されています。

### デフォルトでChakraUIのCSSresetが当たっている

resetCSSに関してはChakraProviderを囲うことでスタイルが当たってくれます。（オプションでfalseにすることもできる）

## 本題：グローバル設定をカスタマイズする
さて、準備ができたためここで本題のグローバル設定を行なっていきます。自分が使っている設定をコピペしました。

やり方としてはthemeの中身を設定したらChakraProviderにtheme引数を渡せばOKです。

```_app.tsx
import { ChakraProvider, extendTheme } from "@chakra-ui/react"

const theme = extendTheme({
  colors: {
    moji: {
      main: "#030D1B",
      sub: "#A09E9F"
    },
    solid: {
      main: "#DEDCDB",
    },
    brand: {
      main: "#4B95C2",
      mark: "#D8B189",
    },
  },
  fontSizes: {
    xmini: '0.7em',
    mini: '0.8em',
    base: '16px',
    big: '1.2em',
  },
  borders: {
    main: "1px solid #DEDCDB"
  },
  styles: {
    global: {
      "html, body": {
        color: "moji.main",
        background: "#fff",
        lineHeight: "1.4142135623",
        fontSize: "base",
        letterSpacing: "0.08em",
        textAlign: "justify",
        textJustify: "inter-ideograph",
        fontFamily: '"Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", "BIZ UDPGothic",Meiryo, sans-serif',
      },
      a: {
        color: "brand.main",
      },
    }
  }
})

export default function App({ Component, pageProps }) {
  return (
    <>
      <ChakraProvider theme={theme}>
        <Component {...pageProps} />
      </ChakraProvider>
    </>
  );
}


```
<ChakraProvider theme={theme}>のような形で設定した内容を渡してあげました。


単純に以下のglobalプロパティに好きな値を入れていけばスタイルが全体に当たってくれます。
キャメルケース式の書き方です（styled-componentやemotionなどを使ったことがある人ならわかるかと。素のcssはスネークケースですがだいたいそのままキャメルケース式に置き換えれば動きます。）

```_app.tsx
省略
  styles: {
    global: {
      "html, body": {
        color: "moji.main",
        background: "#fff",
        lineHeight: "1.4142135623",
        fontSize: "base",
        letterSpacing: "0.08em",
        textAlign: "justify",
        textJustify: "inter-ideograph",
        fontFamily: '"Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", "BIZ UDPGothic",Meiryo, sans-serif',
      },
      a: {
        color: "brand.main",
      },
    }
  }
省略
```

### ちょっとよくわからないところがあるぞ？

        color: "moji.main"
        fontSize: "base"

上は素のcssの値としては存在しないものですが、

```_app.tsx
省略
  colors: {
    moji: {
      main: "#030D1B",
      sub: "#A09E9F"
    },
    solid: {
      main: "#DEDCDB",
    },
    brand: {
      main: "#4B95C2",
      mark: "#D8B189",
    },
  },
  fontSizes: {
    xmini: '0.7em',
    mini: '0.8em',
    base: '16px',
    big: '1.2em',
  },
  borders: {
    main: "1px solid #DEDCDB"
  },
省略
```

で設定したものです。その場で引っ張ることができるためglobalプロパティ側でも使っています。

```
テーマプロパティ： {
  任意のプロパティ
},
```
といった形でカスタム設定していきます。
ただし、デフォルトで設定されているキーは使えません。（例えばテーマプロパティfontSizeの 'xs' や 'sm' など)

ドキュメントの以下のページにも"テーマプロパティ"が載っているのでそれらをキーとして追加カスタマイズしていくことができます。

https://chakra-ui.com/docs/theming/theme#typography

### ChakraUIがオプションで用意しているテーマ

https://chakra-ui.com/docs/theming/customize-theme#theme-extension-withdefaultcolorscheme

カスタマイズせずともChakraUI側が用意しているテーマもあります（詳細は割愛）

テーマプロパティに追加したプロパティは fontSize="big" のような形でスタイルを当てていくことができます。

```hogeComponent.tsx
import { FC } from 'react'
import { Box, Text, Flex } from '@chakra-ui/react'

const HogeComponent: FC<{sitetitle: string, subtitle: string}> = ({sitetitle, subtitle}) => {
  return (
    <Flex justifyContent="center">
      <Box borderBottom="main" w="288px" p="8px 0">
        // fontSize="big"はカスタムで追加したプロパティのキー
        <Text fontSize="big">{siteTitle}<Text as="span" fontSize="12px" display="block">{subTitle}</Text></Text>
      </Box>
    </Flex>
  );
};
export default HogeComponent;
```


## 少し気になったところ
公式ドキュメントのボリュームが小さいのでもう少し詳細な説明など欲しかったなあと。
あとテーマプロパティ一覧のページとか欲しいかも。