라이브러리/MUI

[MUI] <SwipeableTemporaryDrawer/> 전역 상태로 상태 관리 방법 feat.예시코드

순코딩 2025. 4. 15. 16:07
src/components/SwipeableTemporaryDrawer.tsx
"use client";

import * as React from "react";
import Box from "@mui/material/Box";
import SwipeableDrawer from "@mui/material/SwipeableDrawer";
import { Typography } from "@mui/material";
import { useDrawerStore } from "@/store/ui/drawerStore";

type Anchor = "top" | "left" | "bottom" | "right";

export default function SwipeableTemporaryDrawer() {
  const { anchor, isOpen, setIsOpen } = useDrawerStore();

  // 하위 컴포넌트
  const DrawerContent = (anchor: Anchor) => (
    <Box
      sx={{ width: anchor === "top" || anchor === "bottom" ? "auto" : 250 }}
      role="presentation"
      onClick={()=>{setIsOpen(false)}}
      onKeyDown={()=>{setIsOpen(false)}}
    >
      <Typography variant="h5">1</Typography>
      <Typography variant="h5">2</Typography>
      <Typography variant="h5">3</Typography>
      <Typography variant="h5">4</Typography>
    </Box>
  );

  return (
    <div>
      <React.Fragment key={anchor}>
        <SwipeableDrawer
          anchor={anchor}
          open={isOpen}
          onClose={()=>{setIsOpen(false)}}
          onOpen={()=>{setIsOpen(true)}}
        >
          {DrawerContent(anchor)}
        </SwipeableDrawer>
      </React.Fragment>
    </div>
  );
}

 

src/store/ui/drawerStore.ts
import { create } from "zustand";

type Anchor = "top" | "left" | "bottom" | "right";

interface DrawerState {
  // 상태
  anchor: Anchor;
  isOpen: boolean;
  // 액션
  setAnchor: (anchor: Anchor) => void;
  setIsOpen: (isOpen: boolean) => void;
}

export const useDrawerStore = create<DrawerState>((set) => ({
  // 상태
  anchor: "top",
  isOpen: false,
  // 액션
  setAnchor: (anchor: Anchor) => set({ anchor }),
  setIsOpen: (isOpen: boolean) => set({ isOpen }),
}));

 

사용 예시
"use client";

import { mixinContainer } from "@/styles/mixins";
import { AddCircleOutlineRounded } from "@mui/icons-material";
import { Box, Button, Typography } from "@mui/material";

import { styled } from "@mui/material";
// import { useState } from "react";
import SwipeableTemporaryDrawer from "./drawer/SwipeableTemporaryDrawer";
import { useDrawerStore } from "@/store";

const TemplatesMakeContainer = () => {
  // const [templateBlocks, setTemplateBlocks] = useState<BlockType[]>([]);

  const {isOpen, setIsOpen} = useDrawerStore();


  return (
    <Container>
      <Typography variant="h5">템플릿 만들기</Typography>
      <SwipeableTemporaryDrawer/>
      <Button onClick={()=>{setIsOpen(true);}} variant="outlined" fullWidth endIcon={<AddCircleOutlineRounded />}>
        블럭 생성
      </Button>
    </Container>
  );
};

export default TemplatesMakeContainer;

const Container = styled(Box)`
  ${mixinContainer()}
`;