Chakra UIのベースのスタイルをカスタマイズする方法
概要
Chakra UIは便利ですが、コンポーネントのベースとなるスタイルを調整したいときに度々四苦八苦することがあったので、注意点を記しておきます。
ちなみにドキュメントにはしっかりと書いてあるので、ちゃんと読みましょう😇
モチベーション
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コンポーネントであれば以下です。
ここで createMultiStyleConfigHelpers
という関数が使われていたらMultipart Componentです。
これによってスタイルの調整方法が異なるので注意しましょう。この点を注意しておけば以下のドキュメントのとおり、variantなりbaseStyleなりで値を調整することでスタイルが変更できるはずです。
デフォルトのvariantが適用されていないか
extendTheme
するときに注意が必要なのが、コンポーネントにデフォルトの variant
が適用されていないかどうかですい。というのも、なんとなく響きとしては baseStyle
を調整することでスタイルが変わりそうな気がしますが、実際には variant
が baseStyle
を上書きしてしまうので、どれだけ baseStyle
を変更しても適用されない、という問題が発生します。
Textarea
Textarea
コンポーネントを例にみてみましょう。このTextareaの標準の幅を width
で指定したいとします。
import { extendTheme } from "@chakra-ui/react";
export const theme = extendTheme({
components: {
Textarea: {
baseStyle: {
w: "100px"
}
}
}
});
上記のように extendTheme
で Textarea
の baseStyle
を調整することで、Textareaは標準の状態で 100px
のwidthになってくれます。
では、背景の色もredに調整したかったとしましょう。直感的には以下の設定にするかと思います。
import { extendTheme } from "@chakra-ui/react";
export const theme = extendTheme({
components: {
Textarea: {
baseStyle: {
w: "100px",
+ bgColor: 'red'
}
}
}
});
ただし、これではTextareaは変化しません。なぜなら、Textareaにはデフォルトの variant
が適用されているからです。
これは上記のソースを見てもわかります。 outline
が適用されているのです。そしてこれを辿っていくとInputコンポーネントの outline
variantが見つかるのですが、その中身が以下の通り。
bg: 'inherit'
が適用されているのです。よって、 baseStyle
の bgColor: '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に実際のコードも置いてみたので、気になる人は触ってみてください。
Discussion