import { SidebarStoreType } from "@/types/store/sidebar.type";
import { create } from "zustand";
export const useSidebarStore = create<SidebarStoreType>((set) => ({
isOpen: false,
items: [
{ text: "제로 칼로리", isSelect: false, query: "zero_calories" },
{ text: "로우 칼로리", isSelect: false, query: "low_calories" },
{ text: "제로 슈가", isSelect: false, query: "zero_sugar" },
{ text: "로우 슈가", isSelect: false, query: "low_sugar" },
],
setItem: (index) =>
set((state) => ({
items: state.items.map((el, i) => (i === index ? { ...el, isSelect: true } : { ...el, isSelect: false })),
})),
open: () => set((state) => ({ ...state, isOpen: true })),
close: () => set((state) => ({ ...state, isOpen: false })),
}));
사이드바 상태 스토어
export type SidebarStoreType = {
isOpen: boolean;
items: item[];
setItem: (index : number) => void;
open: () => void;
close: () => void;
};
type item = {
text:string;
isSelect:boolean;
query:string;
};
사이드바 상태 타입
"use client";
import * as React from "react";
import SwipeableDrawer from "@mui/material/SwipeableDrawer";
import Button from "@mui/material/Button";
import { useSidebarStore } from "@/store/sidebarStore";
import SidebarItem from "./SidebarItem";
import styled from "styled-components";
const Sidebar = () => {
const { items, isOpen, open, close } = useSidebarStore();
const RenderMenuArr = items.map((el, idx) => {
return <SidebarItem key={idx} index={idx} text={el.text} isSelect={el.isSelect} query={el.query} />;
});
return (
<>
<Button onClick={() => open()}>사이드바 버튼</Button>
<Container open={isOpen} onClose={close} onOpen={open}>
{RenderMenuArr}
</Container>
</>
);
};
export default Sidebar;
const Container = styled(SwipeableDrawer)`
/* 사이드바 컨테이너 선택자 */
& > .MuiPaper-root {
background-color: white;
}
`;
사이드바 컴포넌트
"use client";
import { useProductStore } from "@/store";
import { useSidebarStore } from "@/store/sidebarStore";
import styled from "styled-components";
type PropsType = {
index : number;
text: string;
isSelect: boolean;
query: string;
};
const SidebarItem = ({ index, text, isSelect, query }: PropsType) => {
const setMajorCategory = useProductStore((state) => state.setMajorCategory);
const setItem = useSidebarStore((state)=> state.setItem);
function handleClick() {
setMajorCategory(query);
setItem(index);
}
return (
<Container onClick={handleClick} $isSelect={isSelect}>
{text}
</Container>
);
};
export default SidebarItem;
////////////////////////////// 스타일드 컴포넌트
type ContainerType = {
$isSelect: boolean;
};
const Container = styled.div<ContainerType>`
width: 150px;
height: 50px;
display: flex;
align-items: center;
padding: 0px 12px;
font-size: 16px;
background-color: ${({ $isSelect }) => ($isSelect === true ? "white" : "#F6F7F9")};
color: ${({ $isSelect }) => ($isSelect === true ? "var(--black)" : "var(--gray)")};
`;
사이드바 아이템 컴포넌트
'프론트엔드 > Component' 카테고리의 다른 글
[Component] 2단 사이드바 컴포넌트(MUI + styled-components + Zustand) (1) | 2024.12.26 |
---|---|
[Component] 전역 모달 컴포넌트 (0) | 2024.12.18 |
[Component] 모달(팝업)창 컴포넌트 (0) | 2024.12.18 |
[Component] React + MUI + react-swipeable + styled-component를 활용한 캐러셀 구현 (0) | 2024.11.21 |
리액트 모바일 슬라이더 라이브러리 (0) | 2024.03.13 |