🎨

Chakra UIのベースのスタイルをカスタマイズする方法

2023/03/08に公開

https://chakra-ui.com/

概要

Chakra UIは便利ですが、コンポーネントのベースとなるスタイルを調整したいときに度々四苦八苦することがあったので、注意点を記しておきます。

ちなみにドキュメントにはしっかりと書いてあるので、ちゃんと読みましょう😇

https://chakra-ui.com/docs/styled-system/customize-theme#customizing-component-styles

モチベーション

Chakra UIを使っていて、自分のブランドに合ったベースとなるスタイルをあてておきたい、という気持ちになることがあると思います。そんなときにちょっとしたWrapperコンポーネントを作ってスタイルをあてる方法もありますが、Chakra UIがスタイルをカスタマイズする方法を用意してくれています。

それが Customize Theme になります。

Customize Theme

ドキュメントから引用しますが、以下のように記載することで、例えばButtonコンポーネントのスタイルを調整することができます。

// theme.ts (tsx file with usage of StyleFunctions, see 4.)
import { extendTheme } from '@chakra-ui/react'
import type { StyleFunctionProps } from '@chakra-ui/styled-system'

const theme = extendTheme({
  components: {
    Button: {
      // 1. We can update the base styles
      baseStyle: {
        fontWeight: 'bold', // Normally, it is "semibold"
      },
      // 2. We can add a new button size or extend existing
      sizes: {
        xl: {
          h: '56px',
          fontSize: 'lg',
          px: '32px',
        },
      },
      // 3. We can add a new visual variant
      variants: {
        'with-shadow': {
          bg: 'red.400',
          boxShadow: '0 0 2px 2px #efdfde',
        },
	// 割愛
      },
      // 6. We can overwrite defaultProps
      defaultProps: {
        size: 'lg', // default is md
        variant: 'sm', // default is solid
        colorScheme: 'green', // default is gray
      },
    },
  },
})

export default theme

一見、これは直感的に調整できそうに見えるのですが、注意点があります。

ポイントとしては以下の2点に気をつけておけば概ね大丈夫です。

  • 対象コンポーネントはSingle Componentか、あるいはMultipart Componentか
  • 対象コンポーネントにはデフォルトのvariantが適用されていないか

ただし、元も子もないこと言いますと、要は「ソース見て自分でいい具合に調整してね」です。

順に見ていきましょう。

コンポーネントはSingleか、Multipartか

Chakraのコンポーネントは単体で完結するSingle Componentと、複数のコンポーネントから構成されるMultipart Componentに分かれます。

ButtonのようなコンポーネントはSingleですし、MenuのようにMenuList, MenuButton, MenuItemなど複数のコンポーネントから構成されているものがMultipartになります。

見分け方ですが、(僕の認識が正しければ)ドキュメントを見て複数のコンポーネントがリストアップされているものはMultipartと思われます。

以下、ドキュメントのキャプチャ

また、別手段としてはコンポーネントのページから以下の「Theme source」というボタンを押下することで、ソースに飛ぶことができます。

Menuコンポーネントであれば以下です。
https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/theme/src/components/menu.ts

ここで createMultiStyleConfigHelpers という関数が使われていたらMultipart Componentです。

これによってスタイルの調整方法が異なるので注意しましょう。この点を注意しておけば以下のドキュメントのとおり、variantなりbaseStyleなりで値を調整することでスタイルが変更できるはずです。

https://chakra-ui.com/docs/styled-system/component-style#styling-multipart-components

デフォルトのvariantが適用されていないか

extendTheme するときに注意が必要なのが、コンポーネントにデフォルトの variant が適用されていないかどうかですい。というのも、なんとなく響きとしては baseStyle を調整することでスタイルが変わりそうな気がしますが、実際には variantbaseStyle を上書きしてしまうので、どれだけ baseStyle を変更しても適用されない、という問題が発生します。

Textarea

Textarea コンポーネントを例にみてみましょう。このTextareaの標準の幅を width で指定したいとします。

import { extendTheme } from "@chakra-ui/react";

export const theme = extendTheme({
  components: {
    Textarea: {
      baseStyle: {
        w: "100px"
      }
    }
  }
});

上記のように extendThemeTextareabaseStyle を調整することで、Textareaは標準の状態で 100px のwidthになってくれます。

では、背景の色もredに調整したかったとしましょう。直感的には以下の設定にするかと思います。

import { extendTheme } from "@chakra-ui/react";

export const theme = extendTheme({
  components: {
    Textarea: {
      baseStyle: {
        w: "100px",
+       bgColor: 'red'
      }
    }
  }
});

ただし、これではTextareaは変化しません。なぜなら、Textareaにはデフォルトの variant が適用されているからです。

https://github.com/chakra-ui/chakra-ui/blob/eb7cab94cc6e762e96c61c63c17d3414b9c71ed6/packages/components/theme/src/components/textarea.ts#L32-L40

これは上記のソースを見てもわかります。 outline が適用されているのです。そしてこれを辿っていくとInputコンポーネントの outline variantが見つかるのですが、その中身が以下の通り。

https://github.com/chakra-ui/chakra-ui/blob/eb7cab94cc6e762e96c61c63c17d3414b9c71ed6/packages/components/theme/src/components/input.ts#L81-L113

bg: 'inherit' が適用されているのです。よって、 baseStylebgColor: 'red' が無視されてしまいます。

ではどうするのかと言うと、 baseStyle ではなく、 variants を上書きすれば良いのです。

import { extendTheme } from "@chakra-ui/react";

export const theme = extendTheme({
  components: {
    Textarea: {
+     variants: {
+       outline: {
+         bgColor: 'red'
+       }
+     },
      baseStyle: {
        w: "100px",
-       bgColor: 'red'
      }
    }
  }
});

これでTextareaの背景色が標準で red になってくれます。

まとめ

Chakra UIでスタイルをカスタマイズするときの注意点について記載しました。結局のところ「ドキュメントをちゃんと読めばわかる」内容ではあるものの、割とトリッキーなので、自分のためというのもあって記事にしておきました。

以下のCodeSandboxに実際のコードも置いてみたので、気になる人は触ってみてください。

https://codesandbox.io/s/customizing-chakra-ui-styles-qdwrsj

Discussion