Skip to content

Commit

Permalink
♻️ refactor: Drawer 컴포넌트 제어/비제어 로직 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
ojj1123 committed Apr 22, 2023
1 parent 4813acd commit 786cbf7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
11 changes: 9 additions & 2 deletions src/components/common/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import type { PropsWithChildren, ReactNode } from "react";
import { css } from "twin.macro";

import { useScrollLocker } from "@/application/hooks";
import { Portal } from "@/components/common/Portal";

import { DrawerContextProvider, useDrawerContext, useSetDrawerContext } from "./context";

export const Drawer = ({ children }: PropsWithChildren) => {
interface DrawerProps {
isOpen?: boolean;
onOpenChange?(open: boolean): void;
}
export const Drawer = ({ children, isOpen, onOpenChange }: PropsWithChildren<DrawerProps>) => {
return (
<DrawerContextProvider>
<DrawerContextProvider isOpen={isOpen} onOpenChange={onOpenChange}>
{/* NOTE: 공백 문자 제거 */}
<section css={{ fontSize: 0 }}>{children}</section>
</DrawerContextProvider>
Expand Down Expand Up @@ -38,6 +43,8 @@ const DrawerContent = ({
}: DrawerContentProps) => {
const isOpen = useDrawerContext();

useScrollLocker(isOpen);

return (
<Portal id="drawer-portal">
<div
Expand Down
34 changes: 25 additions & 9 deletions src/components/common/Drawer/context.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import type { PropsWithChildren } from "react";
import { createContext, useCallback, useContext, useState } from "react";
import { createContext, useCallback, useContext, useEffect, useState } from "react";

const DrawerContext = createContext(false);
const DrawerSetContext = createContext<(state: boolean) => void>(() => null);

export const DrawerContextProvider = ({ children }: PropsWithChildren) => {
const [isOpen, setIsOpen] = useState(false);
interface DrawerContextProviderProps {
isOpen?: boolean;
onOpenChange?(open: boolean): void;
}
export const DrawerContextProvider = ({
children,
isOpen: isOpenProp,
onOpenChange,
}: PropsWithChildren<DrawerContextProviderProps>) => {
const [isOpen = false, setIsOpen] = useState(isOpenProp);
const isControlled = isOpenProp !== undefined;
const value = isControlled ? isOpenProp : isOpen;

const handleDrawer = useCallback((state: boolean) => {
if (state) document.body.style.overflow = "hidden";
else document.body.style.overflow = "";
setIsOpen(state);
}, []);
const handleDrawer: React.Dispatch<React.SetStateAction<boolean | undefined>> = useCallback(
(nextValue) => {
const value = typeof nextValue === "function" ? nextValue(isOpenProp) : nextValue;
if (isControlled) {
if (value !== isOpenProp) onOpenChange?.(value as boolean);
} else {
setIsOpen(nextValue);
}
},
[isControlled, isOpenProp, onOpenChange],
);

return (
<DrawerContext.Provider value={isOpen}>
<DrawerContext.Provider value={value}>
<DrawerSetContext.Provider value={handleDrawer}>{children}</DrawerSetContext.Provider>
</DrawerContext.Provider>
);
Expand Down

0 comments on commit 786cbf7

Please sign in to comment.