Chakra UI は UI ライブラリの一つでコンポーネントを利用して効率よくユーザインターフェイスを構築することができます。Chakra UI には 1 つのコンポーネントから作成できる Button コンポーネントから複数のコンポーネントを組み合わせて作成できる Modal コンポーネントまで用途毎にさまざまなコンポーネントが提供されています。どのようなコンポーネントが提供されているのかはドキュメントの Components ページから一覧で確認することができます。

コンポーネント一覧
コンポーネント一覧

Chakra UI は React だけではなく Vue でも利用することができますが、本文書では React を利用して動作確認を行なっているので React の知識があることを前提としています。提供されているコンポーネントの数も多いので利用頻度の高いコンポーネントを利用して Chakra UI の基本的な使い方を説明しています。

Reactプロジェクトの作成

Vite を利用して React プロジェクトの作成を行います。npm create vite@latest コマンドの引数にプロジェクト名を指定して実行します。プロジェクトは任意の名前をつけることができるので react-chakra としています。Framework には react-chakra, variant には TypeScript を選択しています。


 % npm create vite@latest react-chakra
✔ Select a framework: › React
✔ Select a variant: › TypeScript

Scaffolding project in /Users/mac/Desktop/react-chakra...

Done. Now run:

  cd react-chakra
  npm install
  npm run dev

プロジェクトの作成が完了したらプロジェクトフォルダに移動してnpm installコマンドを実行します。


 % cd react-chakra
 % npm install

Chakra UIのインストール

Chakra UIのインストールを行います。


 % npm i @chakra-ui/react @emotion/react @emotion/styled framer-motion

インストール直後のpackage.jsonファイルを確認することでインストールされているパッケージのバージョンを確認することができます。


{
  "name": "react-chakra",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "@chakra-ui/react": "^2.8.0",
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "framer-motion": "^10.15.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.15",
    "@types/react-dom": "^18.2.7",
    "@typescript-eslint/eslint-plugin": "^6.0.0",
    "@typescript-eslint/parser": "^6.0.0",
    "@vitejs/plugin-react": "^4.0.3",
    "eslint": "^8.45.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.3",
    "typescript": "^5.0.2",
    "vite": "^4.4.5"
  }

インストールした chakura-ui のバージョンは 2.8.0 であることがわかります。本文書はバージョン 2.8.0 で動作確認を行っています。

インストール完了後、アプリケーション全体でChakra UIを利用できるようにルートコンポーネントをChakra ProviderでWrapする必要があります。更新するファイルはsrcフォルダのmain.tsxファイルです。デフォルトではindex.cssファイルがimportされていますがindex.cssに記述されたスタイルがChakra UIに影響を与えないように削除しておきます。


import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { ChakraProvider } from '@chakra-ui/react';

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <ChakraProvider>
      <App />
    </ChakraProvider>
  </React.StrictMode>
);

はじめてのChakra Componentsの利用

Boxコンポーネント

Chakra UIではコンポーネントを利用してスタイルを設定していきます。App.tsxファイルを開いてChakraのコンポーネントの中で基本となるBoxコンポーネントを利用してみましょう。


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

function App() {
  return <Box>This is the Box</Box>;
}

export default App;

npm run devコマンドを実行してBoxコンポーネントによりどのようなスタイルが適用されて表示されるのか確認してみましょう。

Chakra UI ではコンポーネントに対して Style Props(Props)を渡すことでコンポーネントをスタイルを変更します。Box タグを利用していますが Style Props は渡していません。Style Props を設定していな場合にはブラウザには Box タグの中に挿入した文字列”This is the Box”が表示されるだけです。デベロッパーツールから要素を確認すると div タグに class 属性で css-0 が設定されていますが class の css-0 には何もスタイルが設定されていません。Box コンポーネントに Style Props を渡していない場合は、<div>This is the Box</div>と記述することと違いはありません。

Boxコンポーネント
Boxコンポーネント

背景色の設定

Box コンポーネントも Style Props を設定しないとただの div 要素だということがわかったので背景色をつけてみましょう。先ほど説明したようにコンポーネントのスタイルを変更したい場合には Style Props を渡します。“background-color”のキャメルケースである backgroundColor で背景色を設定を行うことができます。引数には orange とカラー名をつけていますがカラーコードを利用することもできます。


import './App.css';
import { Box } from '@chakra-ui/react';

function App() {
  return (
    <div className="App">
      <Box backgroundColor="orange">This is the Box</Box>
    </div>
  );
}

export default App;

ブラウザで確認すると Style Props により背景色が設定できることが確認できます。デベロッパーツールで要素を確認すると class 名が css-0 から css-86qm5n に変更されており background-color プロパティの値が orange に設定されていることがわかります。

Style Propsによる背景色の設定
Style Propsによる背景色の設定

キャメルケースで background-color と記述しましたが Style Props では backgroundColor を bgColor と短縮して記述することができます。短縮しても背景色を設定することができます。


<Box bgColor="orange">This is the Box</Box>

Chakra UIのStyle PropsはbackgroundをbgColorと短縮できたように記述量を減らすことで効率よくコードを記述することができます。

width, heightの設定

幅や高さもStyle Propsを通して設定することができます。widthやheightもwやhと短縮することができます。しかしすべてのStyle Propsが省略できるわけではなく文字色を設定するcolorについては”c”とすることはできません。


import './App.css';
import { Box } from '@chakra-ui/react';

function App() {
  return (
    <div className="App">
      <Box bg="orange" w="200px" h="50px" color="white">
        This is the Box
      </Box>
    </div>
  );
}

export default App;

cssの名前は背景を設定した時とは異なり.css-1f28ameとなります。設定するスタイルによって変わることがわかります。

幅から高さ、文字の色の設定
幅から高さ、文字の色の設定

css-1f28ameで利用されているCSSプロパティを見るとcolorプロパティにはwhiteではなくCSSカスタムプロパティの–chakra-color-whiteが設定されていることがわかります。この理由については後ほど説明します。

要素の変更

Boxコンポーネントを利用するとdiv要素が利用されていましたがPropsの asを利用することで他の要素に変更することができます。下記ではデフォルトのdiv要素からsection要素へと変更しています。


<Box bg="orange" w="200px" h="50px" color="white" as="section">

ブラウザ上での表示に変化はありませんがデベロッパーツールで要素を確認するとタグがdivタグからsectionタグになっていることが確認できます。

as Propsによる要素の変更
as Propsによる要素の変更

色の濃さの変更

Style PropsのbgColorに”orange”を設定することで背景色を設定できるだけではなく色の濃さを変更することも可能です。その場合は色の名前の後に.をつけ数値を設定します。ここではorange.600と設定します。


<Box bg="orange.600" w="200px" h="50px" color="white">
  This is the Box
</Box>
色の濃さの変更
色の濃さの変更

classの設定値を確認するとbackground-colorプロパティで先ほどまで”orange”だった値がorange.600に変更するとCSSカスタムプロパティの–chakra-colors-orange-600に変わっていることがわかります。

背景の色を”orange”から”lime”を設定してみます。


<Box bgColor="lime" w="200px" h="50px" color="white">
  This is the Box
</Box>

limeを設定しても問題なく背景色は設定されます。

bgColorにlimeを設定した場合
bgColorにlimeを設定した場合

lime.600 に変更してみましょう。背景色が設定されず文字の色を white に設定しているため画面には何も表示されなくなってしまいます。class に設定されている background-color プロパティを確認すると lime.600 は Invalid property value と表示され対応する CSS カスタムプロパティが存在しないことがわかります。このことからブラウザでサポートしている色はすべて色の濃さを変更できるわけではないことがわかります。

lime.600に変更した場合
lime.600に変更した場合

色の濃さを調整できる色とできない色はどこで判断できるのでしょう。また色の後に設定した数値にはどのような値を設定できるのでしょうか。それは次に説明を行う Theme で定義されています。

Themeについて

Chakra UI では Theme を利用して色の定義を行っています。デフォルトで適用されているので Default Theme と呼ばれ Chakra UI のドキュメントを見るとどのような色が定義されているのか確認することができます。Chakra のドキュメントの左のメニューの”THEMING”の Default Themeから確認できます。

ドキュメントに記載さている色の定義
ドキュメントに記載さている色の定義

色の名前の後に設定する数値については Orange では以下のように 50 から 900 まで定義されています。これはカラーパレットと呼ばれ数値は任意の値をつけることができますが Chakra UI では 50 から 900 までの値を設定することを推奨しています。

Orangeのカラーパレット
Orangeのカラーパレット

Default Theme は Chakra UI の内部ではオブジェクトを利用して設定されており、CSS カスタムプロパティに変換されています。color の white や orange.600 を設定した時に class 内の CSS プロパティに var(—chakra-colors-white), var(—chakura-colors-orange-600)が表示されていたのはこのためです。

オブジェクトからCSSカスタムプロパティへの変換
オブジェクトからCSSカスタムプロパティへの変換

white, blackについてはDefault Themeで定義されているためorangeのように直接CSSプロパティに値が指定されずCSSカスタムプロパティで設定されます。

Colorの定義はnode_modules¥@chakra-ui¥theme¥dist¥fondationsフォルダにあるcolors.jsに記述されています。GitHubのhttps://github.com/chakra-ui/chakra-ui/blob/main/packages/components/theme/src/foundations/colors.tsでも確認できます。

red, orange, tealなどの他にfacebook, messengerやtwitterなどのいくつかの有名はサービスのカラーも定義されていることが確認できます。


var colors = {
  transparent: "transparent",
  current: "currentColor",
  black: "#000000",
  white: "#FFFFFF",
  whiteAlpha: {
    50: "rgba(255, 255, 255, 0.04)",
    100: "rgba(255, 255, 255, 0.06)",
    200: "rgba(255, 255, 255, 0.08)",
    300: "rgba(255, 255, 255, 0.16)",
    400: "rgba(255, 255, 255, 0.24)",
    500: "rgba(255, 255, 255, 0.36)",
    600: "rgba(255, 255, 255, 0.48)",
    700: "rgba(255, 255, 255, 0.64)",
    800: "rgba(255, 255, 255, 0.80)",
    900: "rgba(255, 255, 255, 0.92)"
  },
  blackAlpha: {
    50: "rgba(0, 0, 0, 0.04)",
    100: "rgba(0, 0, 0, 0.06)",
    200: "rgba(0, 0, 0, 0.08)",
    //略
  whatsapp: {
    50: "#dffeec",
    100: "#b9f5d0",
    200: "#90edb3",
    300: "#65e495",
    400: "#3cdd78",
    500: "#22c35e",
    600: "#179848",
    700: "#0c6c33",
    800: "#01421c",
    900: "#001803"
  },
  twitter: {
    50: "#E5F4FD",
    100: "#C8E9FB",
    200: "#A8DCFA",
    300: "#83CDF7",
    400: "#57BBF5",
    500: "#1DA1F2",
    600: "#1A94DA",
    700: "#1681BF",
    800: "#136B9E",
    900: "#0D4D71"
  },
  //略

試しにtwitter.500を設定してみましょう。


<Box bgColor="twitter.500" w="200px" h="50px" color="white">

ブラウザで確認するとDefault Themeで定義されているTwitterカラーも利用できることがわかります。

Twitterのカラーの確認
Twitterのカラーの確認

Themeのカスタマイズ

Theme に自社のブランドカラーを設定したい場合、brand.500 や company.500 のようにカラー名.数値として追加することができます。試しに Starbucks のロゴカラー#00704A を追加してみましょう。@chakra-ui/react から import した extendTheme の引数にオブジェクトで追加したいカラーを設定し theme に保存します。

theme の値は ChakraProvider の theme Props を利用して渡します。設定は完了です。ここではカラーのカスタマイズを行いましたが color 以外の Style Props のカスタマイズも同様の方法で行うことができます。


import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { ChakraProvider, extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  colors: {
    starbucks: {
      500: '#00704A',
    },
  },
});

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <ChakraProvider theme={theme}>
      <App />
    </ChakraProvider>
  </React.StrictMode>
);

themeの設定が完了したらApp.tsxファイルのStyle Propsのbgにstarbucks.500を設定します。


<Box bg="starbucks.500" w="200px" h="50px" color="white">

StarBucksのロゴカラーをThemeに追加して表示させることができました。

StarBucksカラーの設定
StarBucksカラーの設定

このように簡単にDefault Themeをカスタマイズすることができます。

margin, paddingの設定

Default ThemeのドキュメントページをスクロールしていくとColorだけではなくTypographyやSpacingなどの設定を確認することができます。

Boxコンポーネントでpaddingを設定したい場合にはStyle Propsを利用してpadding=”1em”と設定することも可能ですが、paddingの名前を短縮したpとDefault Themeで定義されているSpacingの値4を利用してp=”4″と設定することができます。


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

function App() {
  return (
    <Box bgColor="orange.500" color="white" p="4">
      This is the Box
    </Box>
  );
}

export default App;

ブラウザで確認するとpaddingが設定されていることがわかります。

paddingの設定
paddingの設定

4というのがどのようなサイズに対応するのかはカラーと同様にドキュメントのDefault Themeに記載されています。4は1remに対応することがわかります。padding=”16px”と記述するよりもp=”4″と短縮して記述できるため効率化につながります。


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

const spacing = {
  space: {
    px: '1px',
    0.5: '0.125rem',
    1: '0.25rem',
    1.5: '0.375rem',
    2: '0.5rem',
    2.5: '0.625rem',
    3: '0.75rem',
    3.5: '0.875rem',
    4: '1rem',
    5: '1.25rem',
    6: '1.5rem',
    7: '1.75rem',
    8: '2rem',
    9: '2.25rem',
    10: '2.5rem',
    12: '3rem',
    14: '3.5rem',
    16: '4rem',
    20: '5rem',
    24: '6rem',
    28: '7rem',
    32: '8rem',
    36: '9rem',
    40: '10rem',
    44: '11rem',
    48: '12rem',
    52: '13rem',
    56: '14rem',
    60: '15rem',
    64: '16rem',
    72: '18rem',
    80: '20rem',
    96: '24rem',
  },
}

const theme = extendTheme({ ...spacing })

Spacingの値についてはPaddingだけに限定されたものではなくMarginでも利用することができます。

marginの設定を行うため異なるカラーを設定したBoxコンポーネントを2つ記述します。Boxコンポーネントは下記のように入れ子にして利用することもできます。Style Propsを設定していないBoxコンポーネントはただのdiv要素だということがわかっているのでdivタグの中に2つのdivタグが設定されることになります。


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

function App() {
  return (
    <Box>
      <Box bgColor="orange.500" color="white" p="4">
        This is the Box
      </Box>
      <Box bgColor="green.500" color="white" p="4">
        This is the Box
      </Box>
    </Box>
  );
}

export default App;

2つのdiv要素が下記のように表示され2つのBoxコンポーネントの間にはスペースはありません。

複数のBoxコンポーネントの利用
複数のBoxコンポーネントの利用

2つ目のBoxコンポーネントの上にmarginを取りたい場合はStyle Propsのmt=”4″を設定するだけで1rem分のmarginが2つ目のコンポーネントの上に追加されます。mtはmarginTopの短縮系です。


<Box>
  <Box bgColor="orange.500" color="white" p="4">
    This is the Box
  </Box>
  <Box bgColor="green.500" color="white" p="4" mt="4">
    This is the Box
  </Box>
</Box>

ブラウザで確認するとBoxコンポーネントの間にスペースが追加されたことがわかります。

mt-4の設定
mt-4の設定

Style Propsの一覧

ここまでの説明でbgColor, mt, pなどのStyle Propsを利用してきましたがその他のStyle PropsにはどのようなPropsがあり、どのように短縮するのか知りたいという人もいるかと思います。Style PropsについてはChakra UIのドキュメントに記載されているのでぜひ下記のリンクを確認してみてください。

Style Props

Boxコンポーネントを通してStyle Propsの設定方法や記述方法を理解することができました。さらに他のコンポーネントを確認していきます。

Components

Chakra UI のドキュメントの Components のページを見ると左側のメニューには LAYOUT, FORMS, DATA DISPLAY, FEEDBACK, TYPOGRAPHY, OVERLAY, DISCLOSURE, NAVIGATION, MEDIA AND ICONS, OTHER の 10 つのカテゴリーに分けられていることがわかります。それぞれのカテゴリーに複数のコンポーネントが含まれています。説明を行った BOX コンポーネントは LAYOUT に含まれています。

LAYOUT

最初のLAYOUTのカテゴリーに含まれているコンポーネントをいくつか確認していきます。

Centerコンポーネント

これまで利用してきたコードをBoxコンポーネントからCenterコンポーネントに変更を行います。コンポーネントを利用する時にはimportが必要となるのでBoxと一緒にCenterもimportします。


import { Box, Center } from '@chakra-ui/react';

function App() {
  return (
    <Box>
      <Center bgColor="orange.500" color="white" p="4">
        This is the Box
      </Center>
      <Box bgColor="green.500" color="white" p="4" mt="4">
        This is the Box
      </Box>
    </Box>
  );
}

export default App;

Centerコンポーネントは名前の通り、文字が中央に表示され利用するタグはBoxコンポーネントと同様にdivであることがわかります。さらにclassに含まれるプロパティではFlexboxを利用して中央に表示させていることがわかります。

Centerコンポーネントの利用
Centerコンポーネントの利用

Stackコンポーネント(Stack, VStack, HStack)

2つのBoxコンポーネントをWrapしていたBoxコンポーネントをStackコンポーネントに変更します。Boxコンポーネントのmarginは削除しています。


import { Box, Stack } from '@chakra-ui/react';

function App() {
  return (
    >Stack<
      >Box bgColor="orange.500" color="white" p="4"<
        This is the Box
      >/Box<
      >Box bgColor="green.500" color="white" p="4"<
        This is the Box
      >/Box<
    >/Stack<
  );
}

export default App;

ブラウザで確認するとStackコンポーネントでは2つのコンポーネント間に自動でスペースを付与してくれることがわかります。

Stackコンポーネントの利用
Stackコンポーネントの利用

Stackコンポーネントはdirection Propsを利用して方向を設定することでき、要素を表示させる向きを下向きか横向きか選択できます。デフォルトではdirectionの値はcolumnになります。columnをrowに変更してみましょう。


import { Box, Stack } from '@chakra-ui/react';

function App() {
  return (
    >Stack direction="row"<
      >Box bgColor="orange.500" color="white" p="4"<
        This is the Box
      >/Box<
      >Box bgColor="green.500" color="white" p="4"<
        This is the Box
      >/Box<
    >/Stack<
  );
}

export default App;

directionの値をrowにすることで横向きに並びました。classを見るとFlexboxを利用されていることがわかります。

Stackのdirectionにrowを設定
Stackのdirectionにrowを設定

スペースがついているのは2つ目の要素にmarginが設定されていることがわかります。

2つのコンポーネントのSpacingの確認
2つのコンポーネントのSpacingの確認

Stackコンポーネントと以外にStackを名前に含むVStack, HStackコンポーネントが存在します。VはVertical, HはHorizontalを意味しておりVStackはStackのdirectionのcolumnに対応し、HStackはdirectionのrowに対応します。先ほどのStack direction=”row”のコードはHStackで置き換えることができます。異なるコンポーネントで同じ設定を行うこともできます。


import { Box, HStack } from '@chakra-ui/react';

function App() {
  return (
    <HStack>
      <Box bgColor="orange.500" color="white" p="4">
        This is the Box
      </Box>
      <Box bgColor="green.500" color="white" p="4">
        This is the Box
      </Box>
    </HsStack>
  );
}

export default App;

コンポーネント間のSpacingの調整はStyle Propsのspacingで行うことができます。値はpaddingやmarginと同じSpacingで定義された値を利用できます。


<HStack spacing="12">

spacingの値を12にすることでコンポーネント間の間が大きくなったことがわかります。

Spacingの設定
Spacingの設定

Flexコンポーネント

Stackコンポーネントを利用した際にclassを見るとflexboxが利用されていることを確認しました。Chakra UIではFlexコンポーネントも存在します。Stackとの違いを確認するためにStackコンポーネントをFlexコンポーネントに変更します。


import { Box, Flex } from '@chakra-ui/react';

function App() {
  return (
    <Flex>
      <Box bgColor="orange.500" color="white" p="4">
        This is the Box
      </Box>
      <Box bgColor="green.500" color="white" p="4">
        This is the Box
      </Box>
    </Flex>
  );
}

export default App;

ブラウザで確認すると大きな違いが一目でわかります。Stackの場合は自動で要素間にSpacingが設定されていましたがFlexには存在しません。

Flexコンポーネント
Flexコンポーネント

FlexコンポーネントとSpacerコンポーネントを利用することで要素間に等間隔のSpacingをつくることができます。


import { Box, Flex, Spacer } from '@chakra-ui/react';

function App() {
  return (
    <Flex>
      <Box bgColor="orange.500" color="white" p="4">
        This is the Box
      </Box>
      <Spacer />
      <Box bgColor="green.500" color="white" p="4">
        This is the Box
      </Box>
      <Spacer />
      <Box bgColor="blue.500" color="white" p="4">
        This is the wider Box
      </Box>
    </Flex>
  );
}

export default App;
Spacerコンポーネントで等間隔なSpacing
Spacerコンポーネントで等間隔なSpacing

Flexコンポーネントではflexboxで利用するflex-direction, flex-wrap, flex-basis, flex-growなどもPropsを利用して設定することができます。justify-contentでflex-endを設定した場合には下記のように行うことができます。


import { Box, Flex, Spacer } from '@chakra-ui/react';

function App() {
  return (
    <Flex justify="flex-end">
      <Box bgColor="orange.500" color="white" p="4">
        This is the Box
      </Box>
      <Box bgColor="green.500" color="white" p="4">
        This is the Box
      </Box>
      <Box bgColor="blue.500" color="white" p="4">
        This is the wider Box
      </Box>
    </Flex>
  );
}

export default App;
justify-contentのflex-endの設定
justify-contentのflex-endの設定

Flexboxを利用できるコンポーネントが存在するようにGirdを利用することができるGridコンポーネントも存在します。Girdコンポーネントの説明は行いませんが簡単に設定を行うことができます。

TYPOGRAPHY

Typographyのカテゴリーの中にはText, Heading, Highlightコンポーネントが含まれます。ここではHeadingとTextコンポーネントを説明します。

Headingコンポーネント

Headingコンポーネントはh1, h2などの見出しタグとして利用することができます。


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

function App() {
  return <Heading>Hello World!</Heading>;
}

export default App;

デフォルトではh2タグが設定されておりfont-sizeには4xlが設定されていることがわかります。

Headingコンポーネント
Headingコンポーネント

h2以外の見出しタグに変更したい場合にはBoxコンポーネントと同様にas Propsを利用することができ、フォントのサイズの変更にはsize Propsを利用することができます。


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

function App() {
  return (
    <Heading as="h1" size="lg">
      Hello World
    </Heading>
  );
}

export default App;

h1タグになっていることは確認できますがfont-sizeはlgでは3xlであることがわかります。

as, size Propsの設定
as, size Propsの設定

Chakra UIではfont-sizeを変更したい場合にはfontSize Propsを利用して行うことができます。font-sizeもChakra UIのDefault Themeに定義されています。


const theme = extendTheme({
  colors: {...},
  fonts: {
    body: "system-ui, sans-serif",
    heading: "Georgia, serif",
    mono: "Menlo, monospace",
  },
  fontSizes: {
    xs: "0.75rem",
    sm: "0.875rem",
    md: "1rem",
    lg: "1.125rem",
    xl: "1.25rem",
    "2xl": "1.5rem",
    "3xl": "1.875rem",
    "4xl": "2.25rem",
    "5xl": "3rem",
    "6xl": "3.75rem",
    "7xl": "4.5rem",
    "8xl": "6rem",
    "9xl": "8rem",
  },
  //略

Headingコンポーネントはsize PropsもfontSize Propsも設定することができるのでfontSizeも設定してみます。


import { Heading, Stack } from '@chakra-ui/react';

function App() {
  return (
    <Stack>
      <Heading as="h1" size="lg">
        Hello World
      </Heading>
      <Heading as="h1" fontSize="lg">
        Hello World
      </Heading>
    </Stack>
  );
}

export default App;

fontSize Propsでlgを指定した場合には–chakra-fontSize-lgが適用されていることがわかります。sizeとfontSizeで同じ名前のlgを設定してもフォントの大きさに違いがあることがわかります。

size PropとfontSize Propsの違い
size PropとfontSize Propsの違い

sizeはfontSizeとは異なり、ブラウザのWindowのサイズよって自動でフォントの大きさの調整を行なってくれます。

Textコンポーネント

pタグに対応するコンポーネントがTextコンポーネントです。アプリケーション内でpタグを利用する機会が頻繁にあることからTextコンポーネントも頻繁に利用するコンポーネントの一つであることがわかります。文字のサイズを変更するためにfontSize、文字の太さを変更するためにfontWeight、文字の書式を変更するためにfontStyleなどのPropsでスタイルを変更することができます。


import { Stack, Text } from '@chakra-ui/react';

function App() {
  return (
    <Stack>
      <Text fontSize="2xl">This is first paragraph</Text>
      <Text fontWeight="bold">This is second paragraph</Text>
      <Text fontStyle="italic">This is third paragraph</Text>
    </Stack>
  );
}

export default App;
TextコンポーネントにPropsを設定してスタイルを変更
TextコンポーネントにPropsを設定してスタイルを変更

Textコンポーネントにはスタイルを変更するだけではなくnoOfLines Propsを利用して文章をtruncateすることができます。


import { Stack, Text } from '@chakra-ui/react';

function App() {
  return (
    <Stack>
      <Text>
        "The quick brown fox jumps over the lazy dog" is an English-language
        pangram—a sentence that contains all of the letters of the English
        alphabet. Owing to its existence, Chakra was created.
      </Text>
      <Text noOfLines={1}>
        "The quick brown fox jumps over the lazy dog" is an English-language
        pangram—a sentence that contains all of the letters of the English
        alphabet. Owing to its existence, Chakra was created.
      </Text>
    </Stack>
  );
}

export default App;

noOfLines={1}を設定したTextコンポーネントでは文章が長く複数行になる場合に1行目のみ表示させその行の後に”…”と表示させることができます。ブラウザの幅によって表示される文字列の長さは変わります。引数を2にすると2行目まで表示させることができます。

TextコンポーネントのnoOfLinesの設定
TextコンポーネントのnoOfLinesの設定

FORMS

入力フォームを作成する際に利用するコンポーネントが含まれています。

Buttonコンポーネント

WEBアプリケーションを構築する上で欠かせない要素であるButtonコンポーネントの利用方法を確認していきます。

Propsを設定なしでButtonコンポーネントを利用します。


import { Box, Button } from '@chakra-ui/react';

function App() {
  return (
    <Box>
      <Button>ボタン</Button>
    </Box>
  );
}

export default App;

ブラウザで確認するとボタンが表示されます。適用されているclassの中身を確認するとinline-flex, transition, backgroundなどさまざまなプロパティがデフォルトで設定されていることがわかります。

Buttonコンポーネントのデフォルト
Buttonコンポーネントのデフォルト

ボタンの背景色はデフォルトでは薄いgrayが設定されておりボタンの上にカーソルを乗せるとボタンの色が変わります。

ボタンの背景色を変更するためにbgColor, bgのStyle Propsを利用して設定を行います。


<Button bgColor="red.500">ボタン</Button>

設定通り背景色の色はred.500に変わりました。

bgColor Propsによる背景色の設定
bgColor Propsによる背景色の設定

カーソルをボタンの上に乗せてください。デフォルトのgrayのままです。

ボタンにHoverした時の背景色
ボタンにHoverした時の背景色

Chakra UIではcolor, bgColor, bgとは別にcolorSchema Propsによって色の設定を行うことができます。

color Propsを利用すると文字の色がわかります。

colorScheme

colorScheme Propsを利用して色を設定します。colorShemeの設定値にはred.500というように色と色の濃さを表す数値ではなく色の名前を設定します。設定できる値についてはDefault Themeで定義されている色の名前です。


<Button colorScheme="red">ボタン</Button>

ブラウザで確認すると背景色だけではなく文字の色も白に変更されていることがわかります。

colorShemeの設定
colorShemeの設定

ボタンの上にカーソルを乗せるとgrayではなく赤の濃い色に変わっていることがわかります。

colorSchemeを設定した後にhover
colorSchemeを設定した後にhover

variant

colorSchemeでは色の設定を行いましたがvariantではボタンのスタイルを変更することができます。でデフォルトではsolidが設定されています。この値をoutline, ghost, linkに変更します。


<HStack spacing={4} align="center">
  <Button colorScheme="red" variant="solid">
    ボタン
  </Button>
  <Button colorScheme="red" variant="outline">
    ボタン
  </Button>
  <Button colorScheme="red" variant="ghost">
    ボタン
  </Button>
  <Button colorScheme="red" variant="link">
    ボタン
  </Button>
</HStack>

outline を設定すると border のみ表示されるボタンとなります。ghost ではボタンの背景色、border も表示されます。link についてはボタンにカーソルを乗せると underline が表示されます。カーソルを載せていない時は ghost と同じ表示です。outline, ghost についてはカーソルを乗せると薄い背景色が表示されます。

variantの設定の確認
variantの設定の確認

size

ボタンのサイズはsize Propsを利用してxs, sm, md, lgから設定値を選択することができます。デフォルトではlgが設定されています。


<HStack spacing={4} align="center">
  <Button colorScheme="red" size="xs">
    ボタン
  </Button>
  <Button colorScheme="red" size="sm">
    ボタン
  </Button>
  <Button colorScheme="red" size="md">
    ボタン
  </Button>
  <Button colorScheme="red" size="lg">
    ボタン
  </Button>
</HStack>
size Propsの設定
size Propsの設定

Pseudo(擬似) Style Props

Buttonコンポーネントではカーソルを乗せた場合にボタンの背景色が自動で変わりますがPseudo Style Propsの_hoverを利用することで色を指定することができます。


<Box>
  <Button colorScheme="red" _hover={{ bgColor: 'blue.500' }}>
    ボタン
  </Button>
</Box>

通常はボタンの背景色はcolorSchemeにより赤が設定されていますがカーソルをボタンの上に乗せると青となります。

Pseudo Style Propsは_hoverだけではなくButtonコンポーネントであればクリックした際にボタンのスタイルを変更できる_activeなどもあります。ボタンをクリックした時だけボタンが青になります。


<Box>
  <Button colorScheme="red" _active={{ bgColor: 'blue.500' }}>
    ボタン
  </Button>
</Box>

他のPseudoのStyle Propsについてはドキュメントに記載されています。

FORMS + React Hook Form

Chakra UI の FORMS コンポーネントの理解を深めるために React のフォームライブラリの中で最も人気の高いライブラリの一つである React Hook Form を利用してフォームの作成を行います。React Hook Form を利用するためにはライブラリのインストールが必要です。


 % npm install react-hook-form

FORMS のコンポーネントを利用してフォームの作成方法を確認するために React Hook Form で作成した以下のフォームを FORMS のコンポーネントを利用して書き換えてみましょう。


import { useForm } from 'react-hook-form';

type FormData = {
  email: string;
  password: string;
};

function App() {
  const { register, handleSubmit } = useForm<FormData>();

  const onSubmit = handleSubmit((data) => console.log(data));

  return (
    <div className="App">
      <h1>ログイン</h1>
      <form onSubmit={onSubmit}>
        <div>
          <label htmlFor="email">Email</label>
          <input id="email" {...register('email')} />
        </div>
        <div>
          <label htmlFor="password">Password</label>
          <input id="password" {...register('password')} type="password" />
        </div>
        <button type="submit">ログイン</button>
      </form>
    </div>
  );
}

export default App;

フォームの作成には FormControl, FormLabel, Input, Button コンポーネントを利用しています。


import { useForm } from 'react-hook-form';
import {
  Heading,
  Box,
  FormLabel,
  FormControl,
  Input,
  Button,
} from '@chakra-ui/react';

type FormData = {
  email: string;
  password: string;
};

function App() {
  const { register, handleSubmit } = useForm<FormData>();

  const onSubmit = handleSubmit((data) => console.log(data));

  return (
    <Box p={4}>
      <Heading>ログイン</Heading>
      <form onSubmit={onSubmit}>
        <FormControl>
          <FormLabel htmlFor="email">Email</FormLabel>
          <Input id="email" placeholder="email" {...register('email')} />
        </FormControl>
        <FormControl>
          <FormLabel htmlFor="password">Password</FormLabel>
          <Input
            id="password"
            type="password"
            placeholder="password"
            {...register('password')}
          />
        </FormControl>
        <Button colorScheme="blue" type="submit" mt={4}>
          ログイン
        </Button>
      </form>
    </Box>
  );
}

export default App;

ブラウザで確認するとフォームが表示されます。Email と Passowrd に文字列を入力して”ログイン”ボタンをクリックするとブラウザのコンソールに email, password のオブジェクトが表示されます。シンプルなコードですが、Chakra UI と React Hook Form を一緒に利用することができるようになりました。フォームの表示

フォームの表示

エラー表示

フォームにバリデーションを設定した場合にはバリデーションに失敗した場合にエラーメッセージが表示されるように設定する必要があります。FORMS コンポーネントの FormErrorMessage コンポーネントを利用します。email に required のバリデーションを設定して動作確認を行います。


import { useForm } from 'react-hook-form';
import {
  Heading,
  Box,
  FormLabel,
  FormControl,
  Input,
  Button,
  FormErrorMessage,
} from '@chakra-ui/react';

type FormData = {
  email: string;
  password: string;
};

function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<FormData>();

  const onSubmit = handleSubmit((data) => console.log(data));

  return (
    <Box p={4}>
      <Heading>ログイン</Heading>
      <form onSubmit={onSubmit}>
        <FormControl>
          <FormLabel htmlFor="email">Email</FormLabel>
          <Input
            id="email"
            placeholder="email"
            {...register('email', { required: '入力が必須の項目です。' })}
          />
          <FormErrorMessage>
            {errors.email && errors.email.message}
          </FormErrorMessage>
        </FormControl>
        <FormControl>
          <FormLabel htmlFor="password">Password</FormLabel>
          <Input
            id="password"
            type="password"
            placeholder="password"
            {...register('password')}
          />
        </FormControl>
        <Button colorScheme="blue" type="submit" mt={4}>
          ログイン
        </Button>
      </form>
    </Box>
  );
}

export default App;

email の入力項目を何も文字列を入力せずに”ログイン”ボタンをクリックします。FormErrorMessage コンポーネントを設定しただけでは何も変化はありません。FormControl コンポーネントの isValid プロパティを利用します。isValid の値は boolean 値を取る必要があるため Boolean 関数を利用しています。


<FormControl isInvalid={Boolean(errors.email)}>

設定後に何も入力せずに”ログイン”ボタンをクリックすると FormErrorMessage コンポーネントの場所にメッセージが表示されます。

エラーメッセージの表示
エラーメッセージの表示

バリデーションエラーのメッセージも表示できるようになりました。

Responsive Style

ブラウザのWindowサイズによって適用したいStyleを変更する場合に通常はMedia Queriesを利用しますがChakra UIはMedia Queriesを指定することなく簡単に設定を行うことができます。

デフォルトのBreakPointsの設定はDefault Themeで以下のように設定が行われています。

node_modules/@chakra-ui/theme/dist/foundations/breakpoints.jsファイルに記載されています。


var breakpoints = {
  base: "0em",
  sm: "30em", //468px
  md: "48em", //768px
  lg: "62em", //992px
  xl: "80em", //1280px
  "2xl": "96em" //1536px
};

breakpointsの定義に対応するように配列でスタイルを指定していきます。Textコンポーネントを利用してWindowサイズによって文字の大きさを変更したい場合には以下のように行うことができます。


import { Box, Text } from '@chakra-ui/react';

function App() {
  return (
    <Box>
      <Text fontSize={['sm', 'md', 'lg', 'xl', '2xl','4xl']}>Hello World</Text>
    </Box>
  );
}

export default App;

動作を確認すると0から467pxまではfontSizeはsm, 468から767pxまではfontSizeはmd, 768pxから991pxまではfontSizeはlg, 992pxから1279pxまではfontSizeはxl, 1280から1535pxはfontSizeは2xl, 1536px以上はfontSizeは4xlとなります。

breakpointsと対応する値を配列ですべて指定する必要はなく下記のように記述することもできます。


<Box>
  <Text fontSize={['xl', null, '2xl']}>Hello World</Text>
</Box>

0pxから767pxまではfontSizeはxlで、768pxからはfontSizeは2xlとなります。

配列で指定を行いましたがオブジェクトでも設定することができます。オブジェクトのプロパティにはbreakpointsにある’base’, ‘sm’,..などのプロパティを利用します。下記では配列で指定した場合と同じ設定を行っています。


<Box>
  <Text fontSize={{ base: 'xl', md: '2xl' }}>Hello World</Text>
</Box>

useBreakpointValue Hook

Chakra UIはいくつかHooksも持っています。その中のuseBreakpointValue Hookは引数に指定したオブジェクトのbreakpointsのプロパティに対応する値を戻してくれるので戻される値を利用してfontSizeの設定に利用することができます。


import { Box, Text, useBreakpointValue } from '@chakra-ui/react';

function App() {
  const fontSize = useBreakpointValue({
    base: 'xl',
    md: '2xl',
  });
  return (
    <Box>
      <Text fontSize={fontSize}>Hello World</Text>
    </Box>
  );
}

export default App;

0pxから767pxまではuseBreakpointValue Hookからxlが戻されるのでfontSizeはxlとなり、768pxからはuseBreakpointValue Hookから2xlが戻されるのでfontSizeは2xlとなります。

Overlay

Modalの設定

アプリケーションを構築する際にモーダルを利用する機会は多いかと思います。Chakra UIを利用すればモーダルも簡単に設定することができます。

モーダルを構築する際にはモーダルが表示されているかどうかの状態を持つ変数やモーダルを表示させる関数や非表示にする関数を作成する必要がありますがChakra UIではHookとして準備しているので新たに関数を作成する必要がありません。利用するHookの名前はuseDisclosure Hookです。

モーダルを実装するために最低限必要なコンポーネントのみ利用して作成すると下記のコードとなります。useDisclosureの戻り値のisOpen, onOpen, onCloseを利用します。isOpenはデフォルト値はfalseです。onOpen, onCloseは関数です。


import { Modal, ModalContent, useDisclosure, Button } from '@chakra-ui/react';

function App() {
  const { isOpen, onOpen, onClose } = useDisclosure();

  return (
    <>
      <Button onClick={onOpen}>Open Modal</Button>

      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalContent>Hello!</ModalContent>
      </Modal>
    </>
  );
}

export default App;

デフォルトではモーダルは非表示の状態なのでボタンのみ表示されます。

ボタンの表示
ボタンの表示

ボタンをクリックするとモーダルが表示されます。

モーダルの表示
モーダルの表示

モーダルを非表示にしたい場合にはシャドウがかかっている領域以外の場所をクリックするとモーダルが非表示になります。

モーダルの背景にオーバレイをつけたい場合にはModalOverlayコンポーネントを追加します。


<Modal isOpen={isOpen} onClose={onClose}>
  <ModalOverlay />
  <ModalContent>Hello!</ModalContent>
</Modal>

オーバーレイを追加したことにより表示されるコンテンツがより明確になりました。

オーバーレイの表示
オーバーレイの表示

ModalHeader, ModalBody, ModalFooter, ModalCloseコンポーネントも提供されているのでそれらのコンポーネントを利用するとデザイン性のあるモーダルが簡単に作成できます。


import {
  Modal,
  ModalContent,
  useDisclosure,
  Button,
  ModalOverlay,
  ModalHeader,
  ModalCloseButton,
  ModalBody,
  ModalFooter,
} from '@chakra-ui/react';

function App() {
  const { isOpen, onOpen, onClose } = useDisclosure();

  return (
    <>
      <Button onClick={onOpen}>Open Modal</Button>

      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Modal Title</ModalHeader>
          <ModalCloseButton />
          <ModalBody>Hello</ModalBody>

          <ModalFooter>
            <Button colorScheme="blue" mr={3} onClick={onClose}>
              Close
            </Button>
            <Button variant="outline">Action</Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </>
  );
}

export default App;
デザインの整ったモーダル
デザインの整ったモーダル

Global Styles

アプリケーション全体にスタイルを設定したい場合にはGlobal Stylesを利用することができます。設定はThemeのカスタムを行う場合と同じで設定した値をChakraProviderのtheme Propsを通して設定します。


import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
// import './index.css';
import { ChakraProvider, extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  styles: {
    global: {
      body: {
        backgroundColor: 'gray.100',
        color: 'gray.700',
      },
    },
  },
  colors: {
    starbucks: {
      500: '#00704A',
    },
  },
});

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <ChakraProvider theme={theme}>
      <App />
    </ChakraProvider>
  </React.StrictMode>
);

bodyの背景にgray.100を設定したのでアプリケーション全体で背景色がgray.100になり、文字の色はgray.700に設定されます。コンポーネントのデフォルトの背景色がgray.100になりますが個々のコンポーネントでbgColorを設定することで背景色の設定は可能です。

Color Modeの設定

Chakra UIではDarkモードとLightモードの切り替えもHooksを利用して簡単に行うことができます。利用するHooksはuseColorModeです。戻り値であるtoggleColorMode関数を利用することでカラーモードの切り替えが可能です。


import { Button, useColorMode } from '@chakra-ui/react';

function App() {
  const { toggleColorMode } = useColorMode();
  return >Button onClick={toggleColorMode}<Toggle Color>/Button<;
}

export default App;
light mode
light mode
dark mode
dark mode

現在のカラーモードについてはデフォルトでchakra-ui-color-modeという名前でlocalStorageに保存されます。リロードを行うとlocalStorageに保存された値を利用してカラーモードが設定されます。”Toggle Color”ボタンをクリックしてValueが変わることを確認してみてください。

localStorageに保存されたカラーモード
localStorageに保存されたカラーモード

ユーザが初めてアプリケーションにアクセスした場合のカラーモードも設定することができます。Themeのカスタマイズと動揺にconfigプロパティにinitialColorModeで設定を行います。


const theme = extendTheme({
  config: {
    initialColorMode: 'dark',
    useSystemColorMode: false,
  },
  colors: {
    starbucks: {
      500: '#00704A',
    },
  },
});

initialColorModeは’dark’, ‘light’, ‘system’の3つの値から設定することができsystemはsystemのカラーモードから値を取得します。mac OSの場合外観モードとして値を設定することができるのでsystemでは外観モードから値を取得します。

useSystemColorModeはデフォルトではfalseですが、trueにするとsystemのカラーモードが変更されると一緒にアプリケーションのカラーモードもsystemに合わせて変更されます。

Chakra UIにはまだまだたくさんのコンポーネント、機能が存在するのでそれらを使いこなすことができればUIの開発を効率的に進めることができるのでぜひマニュアルを確認してその他のコンポーネントを確認してみてください。