2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Chakra UI Drawerで、ハンバーガーメニューをコンポーネント化できない

Last updated at Posted at 2024-11-22

はじめに

Chakra UIのDrawerを使ってハンバーガーメニューをコンポーネント化しようとした際に、少しハマったので解決方法を共有します。

問題

Chakra UIのDrawerを使ってハンバーガーメニューをコンポーネント化しようとしましたが、うまくいきませんでした。

解決方法

ハンバーガーメニューの部分だけを子コンポーネントに移動しても解決しませんでした。propsやuseStateなどを試しましたが、うまく動作しませんでした。

解決策は、"DrawerTrigger asChild" コンポーネントを含めて子コンポーネントに移動することでした。

うまくいかなかったコード
Header.jsx
import { memo, useState } from 'react';
import { Flex, Heading, Link, Box, IconButton, Button } from '@chakra-ui/react';
import { MenuIconButton } from "@/components/atoms/button/MenuIconButton.tsx";

import {
    DrawerActionTrigger,
    DrawerBackdrop,
    DrawerBody,
    DrawerCloseTrigger,
    DrawerContent,
    DrawerFooter,
    DrawerHeader,
    DrawerRoot,
    DrawerTitle,
    DrawerTrigger,
} from "@/components/ui/drawer"

// 中略

export const Header: React.FC = memo(() => {
    return (
        <>
             <DrawerRoot placement={"start"} open={open} onOpenChange={(e) => setOpen(e.open)}>
              <DrawerBackdrop />
               <DrawerTrigger asChild> 
                    <MenuIconButton />
                </DrawerTrigger>
                <DrawerContent>
                    <DrawerHeader>
                        <DrawerTitle>Drawer Title</DrawerTitle>
                    </DrawerHeader>
                    <DrawerBody p={0} bg="gray.100">
                        <Button w="100%" variant="outline">Top</Button>
                        <Button w="100%" variant="outline">ユーザー一覧</Button>
                        <Button w="100%" variant="outline">設定</Button>
                    </DrawerBody>
                    <DrawerCloseTrigger />
                </DrawerContent>
            </DrawerRoot>
        </>
    )
});
MenuIconButton.jsx
import { memo } from 'react';
import { Flex, Heading, Link, Box, IconButton, Button } from '@chakra-ui/react';
import { FaBars } from "react-icons/fa6";

// 中略

export const MenuIconButton: React.FC = (() => {
    return (
        <>
            <IconButton
                align="right"
                aria-label="メニューボタン"
                size="sm"
                variant="unstyled"
                colorPalette={"teal"}
                display={{ base: "block", md: "none" }}

            >
                <FaBars />
            </IconButton>
        </>
    )
});
うまくいったコード
Header.jsx
import { memo, useState } from 'react';
import { Flex, Heading, Link, Box, IconButton, Button } from '@chakra-ui/react';
import { MenuIconButton } from "@/components/atoms/button/MenuIconButton.tsx";

import {
        DrawerActionTrigger,
        DrawerBackdrop,
        DrawerBody,
        DrawerCloseTrigger,
        DrawerContent,
        DrawerFooter,
        DrawerHeader,
        DrawerRoot,
        DrawerTitle,
        DrawerTrigger,
} from "@/components/ui/drawer"

// 中略

export const Header: React.FC = memo(() => {
    const [open, setOpen] = useState(false) //追加
    return (
        <>
            {/* open,onOpenChangeのpropsを追加 */}
            <DrawerRoot placement={"start"} open={open} onOpenChange={(e) => setOpen(e.open)}>
                <DrawerBackdrop />
                {/* MenuIconButton.jsxに移動 <DrawerTrigger asChild> */}
                    <MenuIconButton />
                {/* 同じく移動 </DrawerTrigger> */}
                <DrawerContent>
                    <DrawerHeader>
                        <DrawerTitle>Drawer Title</DrawerTitle>
                    </DrawerHeader>
                    <DrawerBody p={0} bg="gray.100">
                        <Button w="100%" variant="outline">Top</Button>
                        <Button w="100%" variant="outline">ユーザー一覧</Button>
                        <Button w="100%" variant="outline">設定</Button>
                    </DrawerBody>
                    <DrawerCloseTrigger />
                </DrawerContent>
            </DrawerRoot>
        </>
    )
});
MenuIconButton.jsx
import { memo } from 'react';
import { Flex, Heading, Link, Box, IconButton, Button } from '@chakra-ui/react';
import { FaBars } from "react-icons/fa6";
import {
        DrawerTrigger,
} from "@/components/ui/drawer" // Headerコンポーネントから移動

// 中略

export const MenuIconButton: React.FC = (() => {
    return (
        <>
            {/* Headerコンポーネントから移動 */}
            <DrawerTrigger asChild>
                <IconButton
                    align="right"
                    aria-label="メニューボタン"
                    size="sm"
                    variant="unstyled"
                    colorPalette={"teal"}
                    display={{ base: "block", md: "none" }}
                >
                    <FaBars />
                </IconButton>
            {/* Headerコンポーネントから移動 */}
            </DrawerTrigger>
        </>
    )
});

おわりに

細かい部分はドキュメントに記載されていないことも多いので、経験を積んで勘を磨いていきます。

参考

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?