Chakra UIのテーマの値をカラーモードに応じて切り替える方法

2 min read読了の目安(約2200字

Chakra UIのテーマで、とても基礎的なところでつまづいた。

MD内のスタイルをいじっていた

.mdrenderWrapperという要素にMarkdownの記事を表示するとする。

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

const EXTEND_CHAKRA = {
  styles: {
    global: {
      '.mdrenderWrapper': {
	  dl: {
            marginTop: '2rem',
            paddingBottom: '1rem',
            border: 'solid 2px #555',
          },
          dt: {
            position: 'relative',
            display: 'inline-block',
            background: 'white,
            top: '-0.8rem',
            left: '0.5rem',
            padding: '0 0.4rem',
          },
          dd: {
            position: 'relative',
            margin: 0,
            top: 0,
            paddingLeft: '1rem',
          },
        },
      },
    },
  },
};

export const theme = extendTheme(EXTEND_CHAKRA);

こういうスタイルを書いて、

<ChakraProvider theme={theme}>
  {children}
</ChakraProvider>

ChakraProviderで囲めばスタイルが適用され、

こういう感じのDLが作れる。

しかし、ダークモードを全く考えていなかったことに気づく。 これはまずい!

正しくはmodeを使う

https://chakra-ui.com/docs/features/global-styles
import { extendTheme } from '@chakra-ui/react';
import { mode } from '@chakra-ui/theme-tools';

const EXTEND_CHAKRA = {
  styles: {
    global: (props: any) => ({
      '.mdrenderWrapper': {
	  dl: {
            marginTop: '2rem',
            paddingBottom: '1rem',
            border: 'solid 2px #555',
          },
          dt: {
            position: 'relative',
            display: 'inline-block',
            background: mode('white', 'black')(props),
            top: '-0.8rem',
            left: '0.5rem',
            padding: '0 0.4rem',
          },
          dd: {
            position: 'relative',
            margin: 0,
            top: 0,
            paddingLeft: '1rem',
          },
        },
      },
    }),
  },
};

export const theme = extendTheme(EXTEND_CHAKRA);

こうすることで、EmotionのGlobalStyleコンポーネントにpropsが渡される。

そしてChakra UIのmodeを使えば、mode(ライト, ダーク)(props)という風に、二種類の値が書ける。

(なお、props.colorModeで判定してもいい)

よし!