Chakra UI使ってみた話


#はじめに
この記事は[N・S高等学校Advent Calendar 2021](https://qiita.com/advent-calendar/2021/n-s-highschool-1)の11日目の記事です。
N高等学校 横浜キャンパス生の荒井将伍です。N Code Labo生でもあります。
普段はWebサイト作ってます。
Qiitaで記事を書くのもアドベントカレンダーに参加するのも初めてなので、暖かい目で見てくれると嬉しいです。

#Chakra UIとは？
Chakra UIは[Material UI](https://mui.com/)のようなReactのUIコンポーネントライブラリです。
自分はN Code Laboの講師の方からこのChakra UIを知りました。

####Chakra UIの公式サイトの紹介文
>Chakra UIは、シンプルでモジュール化されたアクセス可能なコンポーネントライブラリで、Reactアプリケーションを構築するために必要なビルディングブロックを提供します。

>引用: https://chakra-ui.com/

#基本的な使い方
公式サイトにあるimportコードをコピーして貼り付けるだけで使えます。

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

BoxはHTMLでいうdivみたいなものです。
他にも Flex や Text, Inputなど様々なモジュールが用意されています。
自分が面白いと思ったのが、ダークモードがデフォルトで用意されているところです。
Chakra UIを用いることでかなりユーザビリティが高いWebサイトが作りやすくなるんじゃないかと思います。

#使ってみた印象
インストールも結構簡単にでき、そこまで複雑な感じではなかったので使いやすい印象が大きいです。

```:install
yarn create next-app --example with-chakra-ui next-chakra-dashboard
```

Log inフォーム制作の動画がChakra UIの公式YouTubeに載っていたので,これを参考に作ってみました。
>参考: https://www.youtube.com/watch?v=wI2vqXsjsIo&list=LL&index=16

```react:src/components/test.js
import { Button } from "@chakra-ui/button";
import { useColorModeValue } from "@chakra-ui/color-mode";
import { Input } from "@chakra-ui/input";
import { Flex, Heading } from "@chakra-ui/layout";

const IndexPage = () => {
  const formBackground = useColorModeValue("gray.100", "gray.700");

  return (
    <Flex height="100vh" alignItems="center" justifyContent="center">
      <Flex direction="column" background={formBackground} p={12} rounded={6}>
        <Heading mb={6}>Log in</Heading>
        <Input
          placeholder="lazar@chakra-ui.com"
          variant="filled"
          mb={3}
          type="email"
        />
        <Input placeholder="*******" variant="filled" mb={6} type="password" />
        <Button colorScheme="teal">Log in</Button>
      </Flex>
    </Flex>
  );
};

export default IndexPage;
```

```react:src/pages/index.js
import IndexPage from "../components/text";

const Index = () => (
<IndexPage />
);

export default Index;
```
###結果
![スクリーンショット 2021-12-02 16.59.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312585/ee788d2d-16a5-2c28-ebca-49c155738dba.png)

#Chakra UIを使ってポートフォリオ制作
このChakra UIを用いて試しにポートフォリオを制作しました。
かなり長くなってしまいますが、ソースコードを載せておきます。

```react:src/components/header.js
import { Box, Text, Divider, Grid } from "@chakra-ui/layout";
import { Image } from "@chakra-ui/image";
import MoonButtonIcon from "../images/brand/moon.svg";

export const Header = () => {
  return (
    <Box
      bg="#000"
      opacity="0.9"
      color="#ffffff"
      h={24}
      display="flex"
      justifyContent="center"
      alignItems="center"
    >
      <Text fontSize={44} fontFamily="Roboto" fontWeight="bold">
        Mp
        <Text as="span" color="#ECC94B">
          .
        </Text>
        2021
      </Text>
      <Divider w={96} borderColor="#ECC94B" opacity="1" ml={14} />
      <Grid templateColumns="repeat(3, 1fr)" gap={6} ml={14} mr={14}>
        <Text
          fontSize="3xl"
          fontFamily="Rajdhani"
          transition="all .0.2s"
          _hover={{ textDecoration: "underline 1px" }}
        >
          About
        </Text>
        <Text
          fontSize="3xl"
          fontFamily="Rajdhani"
          _hover={{ textDecoration: "underline 1px" }}
        >
          Works
        </Text>
        <Text
          fontSize="3xl"
          fontFamily="Rajdhani"
          _hover={{ textDecoration: "underline 1px" }}
        >
          Contact
        </Text>
      </Grid>
      <Divider
        h={14}
        orientation="vertical"
        borderColor="ffffff"
        opacity="1"
        mr={14}
      />
      <Image src={MoonButtonIcon.src}></Image>
    </Box>
  );
};
```

```react:src/components/about.js
import { Box, Text, Divider } from "@chakra-ui/layout";
import { Button } from "@chakra-ui/button";
import { Image } from "@chakra-ui/image";
import slackIcon from "../images/brand/slack.svg";
import githubIcon from "../images/brand/github.svg";
import penguinIcon from "../images/brand/penguinIcon.png";
import arrowIcon from "../images/brand/chevron_big_up.svg";

export const TopAbout = () => {
  return (
    <Box bg="#000" opacity="0.9" color="#ffffff" pt={28} pb={28}>
      <Box textAlign="center">
        <Text as="u" fontSize="3xl" color="#ECC94B" fontFamily="Rajdhani">
          About
        </Text>
      </Box>
      <Box ml={350}>
        <Box textAlign="left" display="flex" alignItems="center">
          <Box m={0}>
            <Text fontFamily="Roboto" fontWeight="bold" fontSize={72} m>
              Hi
              <Text as="span" color="#ECC94B">
                .
              </Text>
            </Text>
            <Text fontFamily="Roboto" fontWeight="bold" fontSize={72}>
              Im So1 bloom
            </Text>
          </Box>
          <Box ml={50}>
            <Image src={penguinIcon.src} />
          </Box>
        </Box>
        <Divider w={20} borderColor="#ECC94B" opacity="1" mb={5} />
        <Box display="flex" justifyContent="left" alignItems="center">
          <Image src={slackIcon.src} mr={2}></Image>
          <Text fontSize="3xl" fontFamily="Rajdhani">
            Slack : sol
          </Text>
        </Box>
        <Box display="flex" justifyContent="left" alignItems="center">
          <Image src={githubIcon.src} mr={2}></Image>
          <Text fontSize="3xl" fontFamily="Rajdhani">
            GitHub : loveruvwnSo1
          </Text>
        </Box>
        <Button
          ml={3}
          mt={3}
          fontFamily="Rajdhani"
          color="#ECC94B"
          borderColor="#ECC94B"
          variant="outline"
          _hover={{ background: "#ECC94B", color: "#ffffff" }}
        >
          Contact me
        </Button>
      </Box>
      <Box display="flex" justifyContent="center" alignItems="center">
        <Image src={arrowIcon.src} />
      </Box>
    </Box>
  );
};
```

```react:src/components/works.js
import { Box, Text, Divider, Grid } from "@chakra-ui/layout";
import { Image } from "@chakra-ui/image";
import deviceIcon from "../images/brand/device.svg";
import javasciprtIcon from "../images/brand/javascript.svg";
import editIcon from "../images/brand/edit.svg";

export const TopWorks = () => {
  return (
    <Box bg="#000" opacity="0.8" color="#ffffff" pt={28} pb={28}>
      <Box textAlign="center">
        <Box>
          <Text as="u" fontSize="3xl" color="#ECC94B" fontFamily="Rajdhani">
            Works
          </Text>
        </Box>
        <Box mt={10}>
          <Text fontFamily="Roboto" fontWeight="bold" fontSize={72}>
            Works
            <Text as="span" color="#ECC94B">
              .
            </Text>
          </Text>
        </Box>
        <Text fontFamily="Noto Sans JP" fontSize="sm">
          今年の主な活動一覧です
        </Text>
        <Box
          display="flex"
          alignItems="center"
          justifyContent="center"
          mt={10}
          mb={10}
        >
          <Divider
            h={14}
            orientation="vertical"
            borderColor="#ECC94B"
            opacity="1"
          />
        </Box>
      </Box>
      <Grid
        templateColumns="repeat(3, 1fr)"
        gap={50}
        display="flex"
        alignItems="center"
        justifyContent="center"
      >
        <Box
          p={10}
          border="1px solid #ffffff"
          borderRadius="4px"
          _hover={{ border: "1px solid rgba(236, 201, 75, 0.8)", color:"#ECC94B"}}
        >
          <Box display="flex" justifyContent="center">
            <Image src={deviceIcon.src} />
          </Box>
          <Text fontSize="3xl" fontFamily="Rajdhani">
            Make Website
          </Text>
          <Text fontSize="sm" fontFamily="Rajdhani" color="#ECC94B">
            Programming
          </Text>
        </Box>
        <Box
          p={10}
          bg="000"
          border="1px solid #ffffff"
          borderRadius="4px"
          _hover={{ border: "1px solid rgba(236, 201, 75, 0.8)", color:"#ECC94B" }}
        >
          <Box display="flex" justifyContent="center">
            <Image src={javasciprtIcon.src} />
          </Box>
          <Text fontSize="3xl" fontFamily="Rajdhani">
            New Language
          </Text>
          <Text fontSize="sm" fontFamily="Rajdhani" color="#ECC94B">
            Programming
          </Text>
        </Box>
        <Box
          p={10}
          bg="000"
          border="1px solid #ffffff"
          borderRadius="4px"
          _hover={{ border: "1px solid rgba(236, 201, 75, 0.8)", color:"#ECC94B" }}
        >
          <Box display="flex" justifyContent="center">
            <Image src={editIcon.src} />
          </Box>
          <Text fontSize="3xl" fontFamily="Rajdhani">
            Study ITpassport
          </Text>
          <Text fontSize="sm" fontFamily="Rajdhani" color="#ECC94B">
            study
          </Text>
        </Box>
      </Grid>
    </Box>
  );
};
```

```react:src/components/contact.js
import { Box, Text } from "@chakra-ui/layout";
import { Input, InputGroup, InputRightAddon } from "@chakra-ui/input";
import { Button } from "@chakra-ui/button";

export const TopContact = () => {
  return (
    <Box bg="#000" opacity="0.9" color="#ffffff" pt={28} pb={28}>
      <Box textAlign="center">
        <Text as="u" fontSize="3xl" color="#ECC94B" fontFamily="Rajdhani">
          Contact
        </Text>
      </Box>
      <Box mt={10}>
        <Text
          fontFamily="Roboto"
          fontWeight="bold"
          fontSize={72}
          textAlign="center"
        >
          Contact me
          <Text as="span" color="#ECC94B">
            ?
          </Text>
        </Text>
      </Box>
      <Text fontFamily="Noto Sans JP" fontSize="sm" textAlign="center">
        質問等ありましたらこちらから
      </Text>
      <Box display="flex" justifyContent="center" alignItems="center">
        <Box color="#000">
          <Box mt={14}>
            <InputGroup>
              <Input
                border="1px solid rgba(236, 201, 75, 0.8)"
                variant="outline"
                bg="ffffff"
                w={96}
                h={12}
                placeholder="Name"
                focusBorderColor="#ECC94B"
              ></Input>
            </InputGroup>
          </Box>
          <Box mt={14}>
            <InputGroup>
              <Input
                border="1px solid rgba(236, 201, 75, 0.8)"
                variant="outline"
                bg="ffffff"
                w={80}
                h={12}
                placeholder="EmailAddress"
                focusBorderColor="#ECC94B"
              ></Input>
              <InputRightAddon bg="#ECC94B" h={12} children=".com" />
            </InputGroup>
          </Box>
          <Box mt={14}>
            <InputGroup>
              <Input
                border="1px solid rgba(236, 201, 75, 0.8)"
                variant="outline"
                bg="ffffff"
                w={96}
                h={64}
                placeholder="Message"
                focusBorderColor="#ECC94B"
              ></Input>
            </InputGroup>
          </Box>
          <Box display="flex" justifyContent="center">
            <Button
              mt={14}
              p={6}
              fontFamily="Rajdhani"
              color="#ECC94B"
              borderColor="#ECC94B"
              variant="outline"
              _hover={{ background: "#ECC94B", color: "#ffffff" }}
            >
              Send
            </Button>
          </Box>
        </Box>
      </Box>
    </Box>
  );
};
```

```react:src/components/footer.js
import { Box, Text } from "@chakra-ui/layout";

export const Footer = () => {
  return (
    <Box bg="#000" opacity="0.9">
      <Text fontSize="lg" fontFamily="Rajdhani" color="#ECC94B" textAlign="right">
        MP.2021
      </Text>
    </Box>
  );
};
```

```react:src/pages/index.js
import { Box } from "@chakra-ui/layout";
import { Header } from "../components/header";
import { TopAbout } from "../components/about";
import { TopWorks } from "../components/works";
import { TopContact } from "../components/contact";
import { Footer } from "../components/footer";
const Index = () => (
  <Box>
    <Box>
      <Header />
    </Box>
    <Box>
      <TopAbout />
    </Box>
    <Box>
      <TopWorks />
    </Box>
    <Box>
      <TopContact />
    </Box>
    <Box>
      <Footer />
    </Box>
  </Box>
);

export default Index;
```

###結果
![スクリーンショット 2021-12-09 12.16.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2312585/b611a87a-b1d7-e857-40a8-c29045a30d25.png)

#最後に
まだこのポートフォリオは制作途中ですが、完成できるよう頑張ります。
せっかくなのでライトモードとダークモードに切り替えができるようにしたいなと思っています。
Chakra UIを通してReactの使い方にもだいぶ慣れていき、かなりモチベーションが上がりました。
今後はこのChakra UIを使って何か一つオリジナルWebアプリでも作ってみたいと思います。