🌓

chakra-uiでダークモードを導入する手順

2022/09/03に公開

先日、運営中の小説執筆Webサービスにダークモードを実装しました。
https://maxragi.com/

サービスではCSSフレームワークに「chakra-ui」を利用しています。
chakra-ui についての説明は公式や他の記事を参考にしてください。

https://chakra-ui.com/
https://zenn.dev/terrierscript/books/2021-05-chakra-ui

この記事では chakra-ui を利用したWebサービスにダークモードを導入する手順を、ケースに分けてコードと共に説明していきます。

chakra-ui でのダークモード対応には複数の手段があります。

  • サイトのテーマを変える
  • useColorModeValue を利用する
  • theme-tools でダークモード用の値を theme に設定する

サイトのテーマを変える

一番手っ取り早いのが chakra-ui に入っているダークモードをそのまま利用することです。

chakra-ui のコンポーネントはデフォルトでダークモードに対応しており、全体の設定を切り替えると見た目を変えることが出来ます。
モードの切り替え、取得にはuseColorModeを使います。

import { IconButton, IconButtonProps, Tooltip, useColorMode } from "@chakra-ui/react";
import { FaMoon, FaSun } from "react-icons/fa"

export const ColorSwitchButton: React.FC<IconButtonProps> = props => {
  const { colorMode, toggleColorMode } = useColorMode()
  const tooltipLabel = colorMode === "light" ? 
      "ダークモードへ切り替えます" : "ライトモードへ切り替えます"
  return (<Tooltip label={tooltipLabel}>
    <IconButton {...props}
      icon={colorMode === "light" ? <FaMoon /> : <FaSun />}
      onClick={toggleColorMode}
    />
  </Tooltip>)
}

toggleColorMode でカラーモードを変更するとサイト全体に反映されます。
chakra-ui が提供するコンポーネントに手を加えていなければ、全てのコンポーネントをダークモードへと切り替えられます。

デフォルトのカラーモードは light ですが、テーマ機能を使うことで dark に変更できます。

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

const theme = {
  config: {
    initialColorMode: 'dark', // ダークモードをデフォルトに設定
    useSystemColorMode: false, // OSの設定を使わせない
  }
}

export const Index: React.FC = props => {  
  return (<ChakraProvider theme={extendTheme(theme)}>
    <App/>
  </ChakraProvider>)
}

useColorModeValueで値を切り替える

useBreakPointValue などのように、カラーモードによって値を切り替えるフックを chakra-ui は提供しています。

例えば背景色を設定した色で切り替えたい場合、以下のようにします。

import { Box, BoxProps, Tooltip, useColorMode } from "@chakra-ui/react";

export const CustomBox: React.FC<BoxProps> = props => {
  const bgColor = useColorModeValue("#ac844e", "#a3b3e5")
  const border = useColorModeValue(undefined, "solid") // 色以外も使える
  
  return (<Box {...BoxProps} bgColor={bgColor} border={border}>
    {props.children}
  </Box>)
}

しかし各コンポーネントにカスタマイズ用の設定を書いてしまうのは管理が煩雑になりがちです。
そこで次の項目で chakra-ui のテーマ機能の中で切り替える方法を説明します。

theme-toolsでダークモード用の値をthemeに設定する

テーマ機能の中で、各カラーモードでの色などを設定することが出来ます。

import { extendTheme } from "@chakra-ui/react"
import { mode } from '@chakra-ui/theme-tools';

const theme = {
  config: {
    initialColorMode: 'dark',
    useSystemColorMode: false,
  },
  colors: {
    brand: {
      ml: "#26a99e", // main light
      md: "#1f427a", // main dark
    },
  },
  styles: {
    global: (props: any) => ({
      // classで切り替えられるようにする
      ".tBG": {
        bg: mode("#ffffff", "#1a2231")(props)
      },      
      ".tHeader": {
        bg: mode("brand.ml", "brand.md")(props) // colorsで設定した色が利用可能
      },
      ".tBGSub": {
        bg: mode("gray.100", "gray.700")(props) // chakra-uiが提供するセットも使える
      },
      ".tBGFooter": {
        bg: mode("gray.200", "gray.600")(props)
      }
    }),
  },
}

export default extendTheme(theme)

おわり

以上です。
ダークモード対応は近年当たり前のものとなっており、近年のcssフレームワークではほぼ労力なく実装できるようになりました。

記事で取り上げた小説執筆Webサービス「まくらぎ」の方も是非お試しください。
利用していただければ次の技術記事を書く励みにもなります。

https://maxragi.com/

ここまでお読みいただきありがとうございました。

Discussion