chakra uiでReactのプロジェクトをスタイリングしてみよう

スタイリングデザインのイメージ プログラミング

Reactのスタイリングをするためのライブラリには、二種類あって

  • コンポーネントタイプ
  • クラスで定義するタイプ

といった感じです(このタイプの呼び方は私が考えたんで、別の言い方があるかもしれませんが)。

前者はchakra uiMaterial UI(MUI)など。

後者はBootstraptailwindcssといったものです。

ということで本記事では、chakra uiの使い方を簡単にご紹介。

chakra uiのインストール

まずは、chakra uiのライブラリをインストールしましょう。

chakra uiを使用する、Reactのディレクトリで

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

を入力しましょう。

詳細はこちらから(yarnやpnpmでのインストールも載っています。)。

chakra uiをimportする

// App.js

import React from "react";
import "./App.css";

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

import Todo from "./components/Todo";

function App() {
  return (
    {/* chakra-uiを使いたいコンポーネントを<ChakraProvider>で囲う */}
    <ChakraProvider>
      <div className="App">
        <Todo />
      </div>
    </ChakraProvider>
  );
}

export default App;

「import { chakra ui } from “@chakra-ui/react”;」でchakra uiをimport。

そして、chakra uiを使いたいコンポーネントを<ChakraProvider></ChakraProvider>で囲いましょう。

ちなみに、App.jsで展開している<Todo />コンポーネントのコードはこちら。

// Todo.js

import { useState } from "react";
import List from "./List";
import Form from "./Form";
import { Heading, VStack } from "@chakra-ui/react";

const Todo = () => {
  const todosList = [
    {
      id: 1,
      content: "英語の教材を購入する。",
    },
    {
      id: 2,
      content: "学際の衣装を作る",
    },
    {
      id: 3,
      content: "宅配便の再配送を頼む",
    },
  ];

  const [todos, setTodos] = useState(todosList);

  const deleteTodo = (id) => {
    const newTodos = todos.filter((todo) => {
      return todo.id !== id;
    });

    setTodos(newTodos);
  };

  const createTodo = (todo) => {
    setTodos([...todos, todo]);
  };

  return (
    <VStack p="10" spacing="10">
      <Heading color="blue.200" fontSize="5xl">
        Todoリスト
      </Heading>
      <List todos={todos} deleteTodo={deleteTodo} />
      <Form createTodo={createTodo} />
    </VStack>
  );
};
export default Todo;

chakra uiのサンプル

VStack, StackDivider, HStack, IconButton, Textコンポーネント

スタイリング前と後

chakra uiでスタイリングする前にはこんな感じの画面です。

chakra uiでスタイリングする前

スタイリングした後はこんな感じの画面になります。

chakra uiを適用したコード

// List.js

import { VStack, StackDivider, HStack, IconButton, Text } from "@chakra-ui/react";
import { VscCheck } from "react-icons/vsc";


const List = ({ todos, deleteTodo }) => {
  const complete = (id) => {
    deleteTodo(id);
  };
  return (
    <VStack
      divider={<StackDivider />}
      color={{base:'gray.600', sm:'red.600',md:'blue.600',lg:'green.600'}}
      borderColor="blackAlpha.300"
      borderWidth="5px"
      borderRadius="5px"
      p={5}
      alignItems="start"
    >
      {todos.map((todo) => {
        return (
          <HStack key={todo.id} spacing={5}>
            <IconButton
              onClick={() => complete(todo.id)}
              icon={<VscCheck/>}
              isRound
              bgColor="red.200"
              opacity="0.5"
              >
              完了
            </IconButton>
            <Text>{todo.content}</Text>
          </HStack>
        );
      })}
    </VStack>
  );
};

export default List;

では、chakra uiを「VStack, StackDivider, HStack, IconButton, Textコンポーネント」を使ってご紹介。

VStack:垂直方向に要素を積み重ねるために使用される

 import { VStack,StackDivider } from "@chakra-ui/react"; 

 <VStack
      divider={<StackDivider />}
      color={{base:'whiteAlpha.200', sm:'red.600',md:'blue.600',lg:'green.600'}}
      borderColor="blackAlpha.300"
      borderWidth="5px"
      borderRadius="5px"
      p={5}
      alignItems="start"
    >
      ・・・・・
    </VStack>

VStackを使ってリストをスタイリング。

「divider={<StackDivider />}」は、要素を分ける線を表示するというもの。

その他の指定は、だいたいcssに準じているのでわかると思います。

HStack: 水平方向に要素を積み重ねるために使用する。

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

  <HStack key={todo.id} spacing={5}>
       <button onClick={() => complete(todo.id)}>完了</button>
          <span>{todo.content}</span>
       </HStack>

<button>と<span>はinline要素なので、それを<HStack>によってきれいに配置します。

spacing={5}によって、1.25remの間隔を空けて<button>と<span>を並べるということ。

Iconbuttonは、ボタン内にあるアイコンを描画します。

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

 <IconButton onClick={() => complete(todo.id)} icon={<VscCheck/>}>完了</IconButton>

ボタンをicon buttonにすることができます。

<IconButton>コンポーネントは、プロップスにreact-iconsのコンポーネントを渡すことによって、ボタンをicon buttonにすることができます。

react-iconsについては、こちらで紹介しています。

Text:インターフェイス内のテキストと段落をレンダリングするために使用される

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

 <Text>{todo.content}</Text>

<Text>コンポーネントは、<span>タグとほぼ同じ働きをしますが、<Text>コンポーネントに直接スタイリングをすることができます。

なので、chakura uiを使用しているなら、<span>タグを使用するより<Text>コンポーネントを使用した方が、後々のスタイリングが楽になります。

Input、Buttonコンポーネント useToast()関数

スタイリングの前と後

今回は赤枠のインプットエリアとボタンをchakra uiでスタイリングします。

スタイリング前にはこんな感じの画面です。

Input、Buttonコンポーネントでスタイリング

スタイリング後はこんな感じ。

chakra uiを適用した後のinputとbutton

chakra uiを適用したコード

// Form.js

  import { Button, Input, useToast } from "@chakra-ui/react";
  import { useState } from "react";
  const Form = ({ createTodo }) => {
  const [enteredTodo, setEnteredTodo] = useState("");

  const toast = useToast();

  const addTodo = (e) => {
    e.preventDefault();

    if (!enteredTodo) {
      toast({
        title: "タスクが入力されていません!",
        status: "error",
        duration: 2000,
        isClosable: true,
      });
      return;
    }

    const newTodo = {
      id: Math.floor(Math.random() * 1e5),
      content: enteredTodo,
    };

    createTodo(newTodo);

    setEnteredTodo("");
  };
  return (
    <div>
      <form onSubmit={addTodo}>
        <Input
          placeholder="タスクを入力してください"
          _placeholder={{ opacity:0.4, color:"gray.600"}}
          size="lg"
          variant="Filled"
          value={enteredTodo}
          onChange={(e) => setEnteredTodo(e.target.value)}
        />
        <Button
          colorScheme="blue"
          size="md"
          variant="outline"
          px={7}
          type="submit"
        >追加
        </Button>
      </form>
    </div>
  );
};

export default Form;

useToast()関数

少しスタイリングから離れますが、chakra uiでは、メッセージボードを出すことができます(トーストと呼んでいますが)。

今回の場合は、インプットエリアに何も記載されていないときに、「追加」ボタンが押下された場合に、メッセージが出るようにしました。

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

  const toast = useToast();

  if (!enteredTodo) {
    toast({
      title: "タスクが入力されていません!",
      status: "error",
      duration: 2000,
      isClosable: true,
    });
    return;
  }

「useToast」をimportします。

toastを定義します。

ここで定義する理由は、useToast()は、関数コンポーネントのトップレベルか、カスタムHookの中でしか呼ぶことができないからです。

定義したtoast()のプロパティは以下の通りです。

  • title:トーストに表示するタイトル
  • status:”error”で赤、”info”で青いメッセージになります
  • duration:メッセージが表示されている時間(ms)
  • isClosable:trueでメッセージを消す”×”ボタンを出します。

InputとButtonコンポーネント

  import { Button, Input } from "@chakra-ui/react";

      <Input
        placeholder="タスクを入力してください"
        _placeholder={{ opacity:0.4, color:"gray.600"}}
        size="lg"
        variant="Filled"
        value={enteredTodo}
        onChange={(e) => setEnteredTodo(e.target.value)}
      />
      <Button
        colorScheme="blue"
        size="md"
        variant="outline"
        px={7}
        type="submit"
      >追加
      </Button>

variantを説明します。

Inputには、outline、unstyled、flushed、filledのスタイルが用意されています。

Buttonのvariantには、olid、ghost、outline、linkのスタイルが用意されています。

用途に合わせて、簡単にスタイルを変更できます。

最後に

chakra uiにはその他にもいろいろスタイルコンポーネントが用意されているので、こちらのコンポーネント一覧から確認してみてください。

付録

chakra uiのカラーの指定するときの定型のカラー、スペースの定数、メディアクエリーの指定方法とその幅の値を書いておきます。

カラー

borderColor="blackAlpha.300"

chakra uiには「blackAlpha.300」に見られるように定型的なカラーの指定ができて、サイトにカラーの統一感を持たせやすくなっています。カラーサンプルはこちらを参照してください

スペース

p={5}

「p={5}」に見られるようにpaddingなどに対応するスペーシングの数値も定義されています。

スペーシングのサイズはこちらを参照してください

メディアクエリー

color={{base:'whiteAlpha.200', sm:'red.600',md:'blue.600',lg:'green.600'}}

sm: ,md: などのように、メディアクエリーを指定(min-width)することができます。

smは”30em”(親要素が16pxの場合480px)

mdは”48em”親要素が16pxの場合768px)

lgは”62em”(親要素が16pxの場合992px)

xlは”80em”,(親要素が16pxの場合1280px)

タイトルとURLをコピーしました