はじめに
お疲れ様です。りつです。
今回はChakra UI v3でドロワーを実装中に意図しない挙動になったので、その解決記事です。
問題
現在、以下のようなヘッダーメニューを作成中です。
画面右上のハンバーガーメニューのアイコンをクリックすると、以下の画像のようなドロワーメニューが表示されるのですが、メニュー(例えば「TOP」の部分)をクリックしてもドロワーメニューが閉じませんでした。
(遷移先のURLに遷移自体はしています)
ソースコード
src/components/organisms/layout/Hader.tsx
import React, { memo, useCallback, useState } from "react";
import { useNavigate } from "react-router";
import { Box, Flex, Heading, Link } from "@chakra-ui/react";
import { MenuDrawer } from "@/components/molecules/MenuDrawer";
export const Header: React.FC = memo(() => {
const [ open, setOpen ] = useState(false);
const navigate = useNavigate ();
const onClickHome = useCallback(() => navigate('/home'), []);
const onClickUserManagement = useCallback(() => navigate('/home/user_management'), []);
const onClickSetting = useCallback(() => navigate('/home/setting'), []);
return (
<>
<Flex
as="nav"
bg="teal.500"
color="gray.50"
align="center"
justify="space-between"
padding={{ base: 3, md: 5 }}
>
<Flex align="center" as="a" mr={8} _hover={{ cursor: "pointer" }} onClick={onClickHome}>
<Heading as="h1" fontSize={{ base: "md", md: "lg" }}>
ユーザー管理アプリ
</Heading>
</Flex>
<Flex align="center" fontSize="sm" flexGrow={2} display={{ base: "none", md: "flex" }}>
<Box pr={4}>
<Link color="gray.50" onClick={onClickUserManagement}>ユーザー一覧</Link>
</Box>
<Link color="gray.50" onClick={onClickSetting}>設定</Link>
</Flex>
<MenuDrawer
open={open}
setOpen={setOpen}
onClickHome={onClickHome}
onClickUserManagement={onClickUserManagement}
onClickSetting={onClickSetting}
/>
</Flex>
</>
);
});
src/components/molecules/MenuDrawer.tsx
import React, { memo } from "react";
import { Button } from "@chakra-ui/react";
import {
DrawerBackdrop,
DrawerBody,
DrawerContent,
DrawerRoot,
DrawerTrigger,
} from "@/components/ui/drawer"
import { MenuIconButton } from "@/components/atoms/button/MenuIconButton";
type Props = {
open: boolean;
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
onClickHome: () => void;
onClickUserManagement: () => void;
onClickSetting: () => void;
}
export const MenuDrawer: React.FC<Props> = memo((props) => {
const { open, setOpen, onClickHome, onClickUserManagement, onClickSetting } = props;
return (
<DrawerRoot placement="start" size="xs" open={open} onOpenChange={(e) => setOpen(e.open)}>
<DrawerBackdrop />
<DrawerTrigger asChild>
<MenuIconButton/>
</DrawerTrigger>
<DrawerContent>
<DrawerBody p={0} bg="gray.100">
<Button w="100%" bg="gray.100" color="gray.800" onClick={onClickHome}>TOP</Button>
<Button w="100%" bg="gray.100" color="gray.800" onClick={onClickUserManagement}>ユーザー一覧</Button>
<Button w="100%" bg="gray.100" color="gray.800" onClick={onClickSetting}>設定</Button>
</DrawerBody>
</DrawerContent>
</DrawerRoot>
);
});
src/components/atoms/button/MenuIconButton.tsx
import React, { memo } from "react";
import { IconButton } from "@chakra-ui/react";
import { RxHamburgerMenu } from "react-icons/rx";
export const MenuIconButton: React.FC = memo(React.forwardRef<HTMLButtonElement>((props, ref) => {
return (
<IconButton
ref={ref}
{...props}
aria-label="メニューボタン"
size="sm"
bg="teal.500"
display={{ base: "block", md: "none"}}
>
<RxHamburgerMenu />
</IconButton>
);
}));
解決方法
ページ遷移用のボタンを<DrawerActionTrigger>
で囲むことで解消できました。
src/components/molecules/MenuDrawer.tsx
import React, { memo } from "react";
import { Button, DrawerActionTrigger } from "@chakra-ui/react";
import {
DrawerBackdrop,
DrawerBody,
DrawerContent,
DrawerRoot,
DrawerTrigger,
} from "@/components/ui/drawer"
import { MenuIconButton } from "@/components/atoms/button/MenuIconButton";
type Props = {
open: boolean;
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
onClickHome: () => void;
onClickUserManagement: () => void;
onClickSetting: () => void;
}
export const MenuDrawer: React.FC<Props> = memo((props) => {
const { open, setOpen, onClickHome, onClickUserManagement, onClickSetting } = props;
return (
<DrawerRoot placement="start" size="xs" open={open} onOpenChange={(e) => setOpen(e.open)}>
<DrawerBackdrop />
<DrawerTrigger asChild>
<MenuIconButton/>
</DrawerTrigger>
<DrawerContent>
<DrawerBody p={0} bg="gray.100">
<DrawerActionTrigger asChild> {/* ボタンをDrawerActionTriggerで囲む */}
<Button w="100%" bg="gray.100" color="gray.800" onClick={onClickHome}>TOP</Button>
</DrawerActionTrigger>
<DrawerActionTrigger asChild> {/* ボタンをDrawerActionTriggerで囲む */}
<Button w="100%" bg="gray.100" color="gray.800" onClick={onClickUserManagement}>ユーザー一覧</Button>
</DrawerActionTrigger>
<DrawerActionTrigger asChild> {/* ボタンをDrawerActionTriggerで囲む */}
<Button w="100%" bg="gray.100" color="gray.800" onClick={onClickSetting}>設定</Button>
</DrawerActionTrigger>
</DrawerBody>
</DrawerContent>
</DrawerRoot>
);
});
おわりに
解決方法としてはシンプルでした。
今後もChakra UI v3については調べつつ実装していきたいと思います。
参考