題名の通り、Chakra-uiの公ドキュメントの検索バーを作ります。
環境{
Next.js:"12.2.3"
React: "18.2.0"
Typescript: "4.7.4"
chakra-ui/react: "^2.2.4"
chakra-ui/icons: "^2.0.4"
react-icons: "^4.4.0"
vscode
Mac
}
上記をインストールしといてください。
詳しくはこちらをご覧ください。
作るもののイメージ
ヘッダー
ディレクトリ構成は以下の通りです。
src/components/SumpleHeader
SumpleHeader
コンポーネントを作り以下のよう記述してください。
// src/components/SumpleHeader
import { Box,Button,Flex,HStack,Icon,Kbd,Select,}
from "@chakraui/react";
import { SiChakraui } from "react-icons/si";
import {AiFillHeart,AiFillYoutube,AiOutlineGithub,AiOutlineSearch,}
from "react-icons/ai";
import { FaDiscord, FaMoon } from "react-icons/fa";
export const SumpleHeader = () => {
return (
<Flex>
<Box>
<HStack>
<Flex>
<Icon as={SiChakraui} />
<Flex>chakra</Flex>
</Flex>
<Flex>
<Button>
<Flex>
<HStack >
<Flex>
<Icon as={AiOutlineSearch} />
<Box>Search the docs</Box>
</Flex>
<Flex>
<span>
<Kbd>⌘</Kbd><Kbd>K</Kbd>
</span>
</Flex>
</HStack>
</Flex>
</Button>
</Flex>
<Flex>
<Select>
<option>v2.2.3</option>
<option>v1.8.8</option>
<option>v0.8.x</option>
</Select>
<Icon as={AiOutlineGithub} />
<Icon as={FaDiscord} />
<Icon as={AiFillYoutube} />
<Icon as={FaMoon} />
</Flex>
<Flex>
<Button>
<Icon as={AiFillHeart} /> Sponsor
</Button>
</Flex>
</HStack>
</Box>
</Flex>
);
};
そしたら、src/pages/
配下のindex
コンポーネントにSumpleHeader
をインポートします。
// src/components/index
import type { NextPage } from "next";
import { SumpleHeader } from "../componets/SumpleHeader";
const Home: NextPage = () => {
return (
<>
<SumpleHeader />
</>
);
};
export default Home;
下の様になります。いい感じです! 楽しくなってきました!
次にスタイルを充てます。
SumpleHeader
コンポーネントを以下のように書き換えてください。
// src/components/SumpleHeader
import {Box,Button,Flex,HStack,Icon,Input,Kbd,Select,}
from "@chakra-ui/react";
import { SiChakraui } from "react-icons/si";
import {AiFillHeart,AiFillYoutube,AiOutlineGithub,AiOutlineSearch,}
from "react-icons/ai";
import { FaDiscord, FaMoon } from "react-icons/fa";
export const SumpleHeader = () => {
return (
<Flex justify="center" mt="100px">
<Box>
<HStack>
<Flex align="center" pr="100px">
<Icon as={SiChakraui} fontSize="43px" color="teal.300" pr="10px" />
<Flex fontWeight="600" fontSize="30px">
chakra
</Flex>
</Flex>
<Button
bgColor="white"
boxShadow=" 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);"
transform="translate(1px)"
>
<Flex>
<HStack>
<Flex align="center">
<Icon as={AiOutlineSearch} fontSize="30px" pr="10px" />
<Box pr="450px" fontWeight="300" color="gray.700">
Search the docs
</Box>
</Flex>
<Flex align="center" color="gray.700">
<span>
<Kbd mr="3px">⌘</Kbd>
<Kbd>K</Kbd>
</span>
</Flex>
</HStack>
</Flex>
</Button>
<Flex align="center" pl="5px" color="gray.400">
<Select
fontWeight="700"
color="gray.600"
border="none"
outline="none"
>
<option>v2.2.3</option>
<option>v1.8.8</option>
<option>v0.8.x</option>
</Select>
<HStack spacing="20px">
<Icon as={AiOutlineGithub} fontSize="2xl" />
<Icon as={FaDiscord} fontSize="xl" />
<Icon as={AiFillYoutube} fontSize="xl" />
<Icon as={FaMoon} fontSize="xl" />
</HStack>
</Flex>
<Flex pl="20px" align="center">
<Button
bgColor="gray.50"
boxShadow=" 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);"
w="110px"
>
<Icon as={AiFillHeart} color="red.500" fontSize="xl" mr="5px" />
Sponsor
</Button>
</Flex>
</HStack>
</Box>
</Flex>
);
};
検索バー
下のように検索バーをクリックするとオーバーレイされます。これを作ります。
SumpleHeader
の以下の部分をそのまんまコピーしてから削除してください。
// /src/components/SumpleHeader
<Button
bgColor="white"
boxShadow=" 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);"
transform="translate(1px)"
>
<Flex>
<HStack>
<Flex align="center">
<Icon as={AiOutlineSearch} fontSize="30px" pr="10px" />
<Box pr="450px" fontWeight="300" color="gray.700">
Search the docs
</Box>
</Flex>
<Flex align="center" color="gray.700">
<span>
<Kbd mr="3px">⌘</Kbd>
<Kbd>K</Kbd>
</span>
</Flex>
</HStack>
</Flex>
</Button>
そしたら、src/components/
配下に新しくSearchBtn
コンポーネントを作成し、コピーした記述を貼り付けます。
// src/components/SearchBtn
import { Box, Button, Flex, HStack, Icon, Kbd } from "@chakra-ui/react";
import { AiOutlineSearch } from "react-icons/ai";
export const SearchBtn = () => {
return (
<>
<Button
bgColor="white"
boxShadow=" 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);"
transform="translate(1px)"
>
<Flex>
<HStack>
<Flex align="center">
<Icon as={AiOutlineSearch} fontSize="30px" pr="10px" />
<Box pr="450px" fontWeight="300" color="gray.700">
Search the docs
</Box>
</Flex>
<Flex align="center" color="gray.700">
<span>
<Kbd mr="3px">⌘</Kbd>
<Kbd>K</Kbd>
</span>
</Flex>
</HStack>
</Flex>
</Button>
</>
);
};
そしたら、SearchBtn
コンポーネントをSumpleHeader
コンポーネントからButtonを削除した位置にインポートします。
// src/components/SumpleHeader
//省略
<Flex fontWeight="600" fontSize="30px">
chakra
</Flex>
</Flex>
//ここにインポート
<SearchBtn />
<Flex align="center" pl="5px" color="gray.400">
<Select
fontWeight="700"
//省略
これでコンポーネント分割前と同じなったはずです。
次で最後の工程です。
SearchBtn
コンポーネントを以下のように書き換えてください。
// src/components/SearchBtn
import {AlertDialog,AlertDialogContent,AlertDialogOverlay,
Box,Button,Flex,HStack,Icon,Input,Kbd,useDisclosure,}
from "@chakra-ui/react";
import React from "react";
import { AiOutlineSearch } from "react-icons/ai";
export const SearchBtn = () => {
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = React.useRef<HTMLButtonElement>(null);
return (
<>
<Button
bgColor="white"
boxShadow=" 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);"
transform="translate(1px)"
onClick={onOpen}
>
<Flex>
<HStack>
<Flex align="center">
<Icon as={AiOutlineSearch} fontSize="30px" pr="10px" />
<Box pr="450px" fontWeight="300" color="gray.700">
Search the docs
</Box>
</Flex>
<Flex align="center" color="gray.700">
<span>
<Kbd mr="3px">⌘</Kbd>
<Kbd>K</Kbd>
</span>
</Flex>
</HStack>
</Flex>
</Button>
<AlertDialog
isOpen={isOpen}
leastDestructiveRef={cancelRef}
onClose={onClose}
>
<AlertDialogOverlay>
<AlertDialogContent mt="150px" w="550px" h="65px">
<Flex justify="center">
<HStack bgColor="white" borderRadius="10px">
<Icon
as={AiOutlineSearch}
fontSize="27px"
color="teal.500"
ml="8px"
w="50px"
/>
<Input
border="none"
outline="transparent solid 2px"
placeholder="Search the docs"
w="550px"
h="65px"
/>
</HStack>
</Flex>
</AlertDialogContent>
</AlertDialogOverlay>
</AlertDialog>
</>
);
};
いかがでしょうか!
上が作った方
下が公式です。
お疲れ様でした!
全体のコード
// src/components/SumpleHeader
import { Box, Button, Flex, HStack, Icon, Select } from "@chakra-ui/react";
import { SiChakraui } from "react-icons/si";
import { AiFillHeart, AiFillYoutube, AiOutlineGithub } from "react-icons/ai";
import { FaDiscord, FaMoon } from "react-icons/fa";
import { SearchBtn } from "./SearchBtn";
export const SumpleHeader = () => {
return (
<Flex justify="center" mt="100px">
<Box>
<HStack>
<Flex align="center" pr="100px">
<Icon as={SiChakraui} fontSize="43px" color="teal.300" pr="10px" />
<Flex fontWeight="600" fontSize="30px">
chakra
</Flex>
</Flex>
<SearchBtn />
<Flex align="center" pl="5px" color="gray.400">
<Select
fontWeight="700"
color="gray.600"
border="none"
outline="none"
>
<option>v2.2.3</option>
<option>v1.8.8</option>
<option>v0.8.x</option>
</Select>
<HStack spacing="20px">
<Icon as={AiOutlineGithub} fontSize="2xl" />
<Icon as={FaDiscord} fontSize="xl" />
<Icon as={AiFillYoutube} fontSize="xl" />
<Icon as={FaMoon} fontSize="xl" />
</HStack>
</Flex>
<Flex pl="20px" align="center">
<Button
bgColor="gray.50"
boxShadow=" 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);"
w="110px"
>
<Icon as={AiFillHeart} color="red.500" fontSize="xl" mr="5px" />
Sponsor
</Button>
</Flex>
</HStack>
</Box>
</Flex>
);
};
// src/components/SearchBtn
import {
AlertDialog,
AlertDialogContent,
AlertDialogOverlay,
Box,
Button,
Flex,
HStack,
Icon,
Input,
Kbd,
useDisclosure,
} from "@chakra-ui/react";
import React from "react";
import { AiOutlineSearch } from "react-icons/ai";
export const SearchBtn = () => {
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = React.useRef<HTMLButtonElement>(null);
return (
<>
<Button
bgColor="white"
boxShadow=" 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);"
transform="translate(1px)"
onClick={onOpen}
>
<Flex>
<HStack>
<Flex align="center">
<Icon as={AiOutlineSearch} fontSize="30px" pr="10px" />
<Box pr="450px" fontWeight="300" color="gray.700">
Search the docs
</Box>
</Flex>
<Flex align="center" color="gray.700">
<span>
<Kbd mr="3px">⌘</Kbd>
<Kbd>K</Kbd>
</span>
</Flex>
</HStack>
</Flex>
</Button>
<AlertDialog
isOpen={isOpen}
leastDestructiveRef={cancelRef}
onClose={onClose}
>
<AlertDialogOverlay>
<AlertDialogContent mt="150px" w="550px" h="65px">
<Flex justify="center">
<HStack bgColor="white" borderRadius="10px">
<Icon
as={AiOutlineSearch}
fontSize="27px"
color="teal.500"
ml="8px"
w="50px"
/>
<Input
border="none"
outline="transparent solid 2px"
placeholder="Search the docs"
w="550px"
h="65px"
/>
</HStack>
</Flex>
</AlertDialogContent>
</AlertDialogOverlay>
</AlertDialog>
</>
);
};
後書き
ご覧いただきありがとうございます。
もっと丁寧にやれば見やすい記述だったり、不要な記述を減らせられると思いますが、目標は達したので良しとします。
個人的に創ってたもので検索バーの仕様をchakra-uiみたくしたくて書いてみました。
終わり