@jinsewoon/react-modal-manager-hook
v0.1.18
Published
<!-- | Props | 필수여부 | 타입 | 설명 | 초기값 | | -- | :--: | -- | -- | :--: | -->
Readme
@jsw/react-modal-manager-hook
React 애플리케이션에서 동적 모달 관리를 간단하게 구현할 수 있도록 설계된 커스텀 훅입니다. 배열 상태로 모달을 관리하며, 다중 모달을 처리할 수 있도록 설계되어 동일한 모달을 중복 렌더링하거나 여러 모달을 동시에 띄우는 것이 가능합니다. 가장 최근에 추가된 모달은 항상 최상단에 표시되며, 단일 모달 닫기와 모든 모달 초기화 기능을 제공합니다. 스타일과 UI는 완전히 커스터마이징할 수 있어 다양한 요구 사항에 유연하게 대응할 수 있습니다.
이 라이브러리의 특징 🚀
1. 독립적인 전역 상태 관리
내부 Store 클래스를 통해 외부 라이브러리에 의존하지 않고도 Redux, Zustand와 유사한 전역 상태 관리 구조를 구현합니다.
2. React 최적화 및 SSR 지원
React 18+의 useSyncExternalStore를 사용해 상태 구독과 서버 사이드 렌더링(SSR)을 안정적으로 지원합니다.
3. 유연한 확장성과 커스터마이징
제네릭 타입(TModalConfig)을 활용하여 다양한 모달 설정을 유연하게 정의할 수 있으며,
openModal, closeModal, closeAllModal 메서드를 통해 직관적이고 간편하게 모달을 제어할 수 있습니다.
1.ModalProvider
사용 방법
ModalProvider는 @jsw/react-modal-manager-hook 라이브러리의 모달 상태와 컨테이너를 관리하는 핵심 컴포넌트입니다. 모든 하위 컴포넌트에서 모달 상태에 접근하려면 반드시 ModalProvider로 앱을 감싸야 합니다.
import { ModalProvider } from "@jsw/react-modal-manager-hook";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ModalProvider>
<App />
</ModalProvider>
</StrictMode>
);| Props | 필수여부 | 타입 | 설명 | 초기값 |
| ---------------------- | :------: | ----------------- | ------------------------------------------------------------- | :----: |
| children | 필수 | React.ReactNode | ModalProvider 하위에 렌더링될 React 컴포넌트 | 없음 |
| customModalContainer | 선택 | React.ReactNode | 기본 ModalContainer 대신 사용할 커스텀 모달 컨테이너 컴포넌트 | 없음 |
customModalContainer 사용 예시
import { useModalState } from "@jsw/react-modal-manager-hook";
export const CustomModalContainer = () => {
const { modals } = useModalState();
return modals.map((modal) => (
<Fragment key={modal.state.id}>{modal.content}</Fragment>
));
};
//main.tsx
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ModalProvider customModalContainer={<CustomModalContainer />}>
<App />
</ModalProvider>
</StrictMode>
);ModalContainer와 App 간의 z-index와 위계 구조를 유연하게 조정할 수 있도록 설계되었습니다.
상황에 따라 customModalContainer를 활용하거나, App 및 그 내부 컴포넌트의 구조를 유연하게 구성하여 모달의 레이아웃과 스타일이 자연스럽게 어우러지도록 설정할 수 있습니다.
2.DefaultModalLayout
@jsw/react-modal-manager-hook에서 제공하는 기본 ModalLayout 컴포넌트입니다.
모달 레이아웃의 기본 동작과 스타일을 설정하며, useModal 훅과 함께 사용됩니다.
사용법
import { DefaultModalLayout, useModal } from "@jsw/react-modal-manager-hook";
function App() {
const { openModal, closeModal } = useModal();
const handleOpenModal = () => {
openModal(
<DefaultModalLayout
defaultConfig={{
useDim: true,
allowDimClickClose: false,
allowBackgroundScroll: false,
}}
>
<div>
<h2>Modal Content</h2>
<button type="button" onClick={closeModal}>
Close Modal
</button>
</div>
</DefaultModalLayout>
);
};
return (
<div>
<button type="button" onClick={handleOpenModal}>
Open Modal
</button>
</div>
);
}DefaultModalLayout을 사용자가 유연하게 확장하는 것을 추천합니다.
아래와 같이 DefaultModalLayout을 커스텀 컴포넌트로 래핑하면 반복 설정을 줄이고 재사용성을 높일 수 있습니다.
import { DefaultModalLayout } from "@jsw/react-modal-manager-hook";
const CustomModalLayout = ({ children }: PropsWithChildren) => {
return (
<DefaultModalLayout
defaultConfig={{
useDim: true,
allowDimClickClose: true,
allowBackgroundScroll: false,
}}
>
{children}
</DefaultModalLayout>
);
};Props 테이블
| Props | 필수여부 | 타입 | 설명 | 초기값 |
| --------------- | :------: | --------------------- | ------------------------------------------------- | :----: |
| children | 선택 | ReactNode | DefaultModalLayout 하위에 렌더링될 React 컴포넌트 | 없음 |
| defaultConfig | 선택 | TModalDefaultConfig | 모달 레이아웃의 기본 설정을 정의하는 객체 | {} |
defaultConfig 객체 구조
| Props | 필수여부 | 타입 | 설명 | 초기값 |
| ---------------------------------- | :------: | ----------------------------------------- | ------------------------------------------------ | :---------------: |
| baseZindex | 선택 | number | 모달의 기본 z-index 값을 설정합니다. | 10000 |
| customDimColor | 선택 | CSSProperties["backgroundColor"] | 모달 딤(Dim) 영역의 배경 색상을 설정합니다. | rgba(0,0,0,0.5) |
| className | 선택 | string | 모달 레이아웃에 적용할 커스텀 클래스 이름입니다. | 없음 |
| initialStyle | 선택 | CSSProperties | 초기 스타일을 적용할 수 있는 스타일 객체입니다. | 없음 |
| ...Required<TModalConfig> | 필수 | - | TModalConfig의 필수 설정값들입니다. |
- 기본 설정: defaultConfig는 모달의 동작과 스타일을 손쉽게 제어할 수 있도록 기본 설정값을 제공합니다.
- 커스텀 확장: TModalConfig를 통해 필요에 따라 사용자 정의 설정을 확장할 수 있습니다.
- 유연한 확장: DefaultModalLayout을 커스텀 컴포넌트로 래핑하면 일관된 설정과 반복 코드 작성 부담을 줄일 수 있습니다.
3.useModal
useModal은 @jsw/react-modal-manager-hook 라이브러리에서 제공하는 모달 상태 관리를 위한 핵심 커스텀 훅입니다. 이 훅을 통해 모달을 열고 닫는 메서드와 현재 모달 상태에 접근할 수 있습니다.
사용법
import { useModal } from "@jsw/react-modal-manager-hook";
//중첩 모달
const NestedModal = () => {
const { openModal, closeAllMcloseAllModalsodal } = useModal();
return (
<div>
<h2>Nested Modal Content</h2>
<button type="button" onClick={closeAllModals}>
Close Modal
</button>
</div>
);
};
const CustomModalContent = () => {
const { openModal, closeModal } = useModal();
const handleNestedModal = () => {
openModal(<NestedModal />);
};
return (
<div>
<h2>Modal Content</h2>
<div>
<button type="button" onClick={handleNestedModal}>
Open Nested Modal
</button>
<button type="button" onClick={closeModal}>
Close Modal
</button>
</div>
</div>
);
};
function App() {
const { openModal } = useModal();
const handleOpenModal = () => {
openModal(
<CustomModalLayout>
<CustomModalContent />
</CustomModalLayout>
);
};
return (
<div>
<button type="button" onClick={handleOpenModal}>
Open Modal
</button>
</div>
);
}위 코드에서 <CustomModalContent/>과 <NestedModal/>은 중첩으로 렌더링 될수있으며 CloseAllModals 매서드를 통해서 모든 모달을 닫을수 있다.
| 매서드/값 | 타입 | 설명 |
| ---------------- | ------------------------------------------------------ | --------------------------------------- |
| latestModal | TModalObject<T> | 가장 최근에 열린 모달 객체입니다. |
| modals | TModalObject<T>[] | 현재 열린 모든 모달들의 배열입니다. |
| openModal | (content: ReactNode, config?: object) => void | 새로운 모달을 추가합니다. |
| closeModal | VoidFunction | 최상단에 있는 모달을 닫습니다. |
| closeAllModals | VoidFunction | 모든 모달을 닫습니다. |
제네릭 확장을 통한 커스텀 훅
useModal은 제네릭 타입을 지원하므로 사용자 정의 설정을 확장할 수 있습니다.
커스텀 훅으로 래핑하면 타입 안정성을 유지하면서 유연하게 사용할 수 있습니다.
import { TModalConfig, useModal } from "@jsw/react-modal-manager-hook";
// 사용자 정의 모달 설정 타입
export type CustomModalConfig = {
type: "modal" | "dialog"; // 모달 타입
animationDuration?: number; // 애니메이션 지속 시간
};
// 커스텀 훅으로 래핑
export const useCustomModal = () => {
const { latestModal, modals, openModal, closeModal, closeAllModals } =
//CustomModalConfig을 TModalConfig의 제네릭으로 전달
useModal<TModalConfig<CustomModalConfig>>();
return { latestModal, modals, openModal, closeModal, closeAllModals };
};커스텀 훅 사용법
import { useCustomModal } from "./useCustomModal";
function App() {
const { openModal, closeModal } = useCustomModal();
const handleOpenCustomModal = () => {
openModal(
<div>
<h2>Custom Modal</h2>
<p>이 모달은 사용자 정의 타입을 사용합니다.</p>
<button onClick={closeModal}>Close</button>
</div>,
{ type: "dialog", animationDuration: 300 }
);
};
return (
<div>
<button type="button" onClick={handleOpenCustomModal}>
Open Custom Modal
</button>
</div>
);
}useModal은 모달 상태 관리를 위한 강력한 도구로, 제네릭 타입과 커스텀 훅을 활용해 확장성과 유연성을 극대화할 수 있습니다. 커스텀 설정을 통해 프로젝트 요구사항에 맞게 모달 시스템을 커스터마이징하세요. 🚀
