LayerPopup
LayerPopup과 useLayerPopup usage를 기준으로 컴포넌트 등록형 popup 구조와 전역 store stack 흐름을 정리한 가이드 페이지입니다.
LayerPopup
LayerPopup은 PopupBase를 기반으로 한 일반적인 중앙 레이어 팝업입니다. Alert/Confirm과 달리 popup 컴포넌트 자체를 등록하고, 콘텐츠는 각 popup 컴포넌트 내부에서 직접 구성합니다.
title | children | footer | size | hasCloseButton | shouldCloseOnBackdrop | shouldCloseOnEscape | className
ReactNode | ReactNode | ReactNode | PopupSize | boolean | boolean | boolean | string- LayerPopup은 Alert/Confirm처럼 옵션만으로 형태를 고정하는 팝업이 아니라, popup 컴포넌트 안에서 `children`과 `footer`를 조합해서 화면을 구성하는 일반적인 중앙 레이어 팝업입니다.
- hook으로 넘기는 값은 `component`와 선택적인 `id` 정도만 두고, 실제 콘텐츠와 상세 설정은 각 popup 컴포넌트 내부에서 직접 정의합니다.
- `size`, `hasCloseButton`, `shouldCloseOnBackdrop`, `shouldCloseOnEscape` 같은 shell 설정도 필요하면 해당 popup 컴포넌트 안의 `LayerPopup`에 바로 선언합니다.
PopupBase shell / design props
title | icon | description | children | footer | className | panelClassName | bodyClassName | footerClassName | size | contentAlign | hasCloseButton | closeButtonLabel | shouldCloseOnBackdrop | shouldCloseOnEscape | dialogLabel | onClickClose- LayerPopup은 `PopupBase` shell을 감싼 wrapper이므로, custom popup 컴포넌트 안에서 `title`, `footer`, `size`, `contentAlign`, `panelClassName` 같은 shell props를 직접 설정할 수 있습니다.
- 반대로 `id`, `open`, `onRequestClose`, `onExited`는 디자인 props가 아니라 `PopupHost`가 runtime에 주입하는 인스턴스 제어용 props입니다.
- 그래서 보통 custom popup 컴포넌트에서는 `...runtimeProps`를 펼친 뒤, 필요한 shell props만 추가 선언하는 패턴을 사용합니다.
function ExamplePopup(runtimeProps: LayerPopupComponentProps) {
return (
<LayerPopup
{...runtimeProps}
title="팝업 제목"
description="PopupBase shell props를 직접 제어하는 예시"
size="large"
contentAlign="left"
panelClassName="customPanel"
bodyClassName="customBody"
footerClassName="customFooter"
hasCloseButton
closeButtonLabel="닫기"
shouldCloseOnBackdrop={false}
shouldCloseOnEscape={true}
dialogLabel="상세 설정 팝업"
onClickClose={() => {
console.log("close button clicked");
}}
footer={<button onClick={runtimeProps.onRequestClose}>닫기</button>}
>
<div>custom contents</div>
</LayerPopup>
);
}- Header / content: `title`, `icon`, `description`, `children`, `footer`
- Layout / style: `size`, `contentAlign`, `className`, `panelClassName`, `bodyClassName`, `footerClassName`
- Close / accessibility: `hasCloseButton`, `closeButtonLabel`, `shouldCloseOnBackdrop`, `shouldCloseOnEscape`, `dialogLabel`, `onClickClose`
- Runtime from host: `id`, `open`, `onRequestClose`, `onExited`
component | id
React.ComponentType<LayerPopupComponentProps> | string | undefined- `useLayerPopup().open()`에는 실제로 렌더할 popup 컴포넌트 자체를 `component`로 넘깁니다.
- popup 내용에 필요한 데이터는 외부 props로 넘기지 않고, 해당 컴포넌트 내부 로직에서 바로 구성합니다.
- `id`, `open`, `onRequestClose`, `onExited`는 여전히 `PopupHost`가 runtime에 주입합니다.
layerPopup.open({
id: "workspace-share-popup",
component: WorkspaceShareLayerPopup,
});useLayerPopup()
{ open: (options) => string; close: (id?: string) => void; closeAll: () => void; layerPopups: Array<{ id: string; type: "layerPopup"; status: "open" | "closing" }>; }- `useLayerPopup()`은 등록형 LayerPopup을 전역 store에 쌓고, 마지막 popup만 닫거나 현재 타입만 한 번에 닫을 수 있게 해줍니다.
- `open()`은 생성된 id를 반환하고, `close(id?)`는 특정 id 또는 마지막 LayerPopup을 닫습니다.
- 이 예제처럼 두 개를 연 뒤에는 `closeAll()`로 현재 열린 LayerPopup만 묶어서 정리할 수 있습니다.
usePopupStack()
Array<{ id: string; type: "alert" | "confirm" | "layerPopup" | "bottomSheet" | "fullPopup"; status: "open" | "closing" }>전역 popup stack을 그대로 조회할 수 있어서 LayerPopup이 다른 popup 타입과 함께 열려 있는 상태도 바로 확인할 수 있습니다.
열린 팝업이 없습니다.
LayerPopup props 한눈에 보기
LayerPopup shell에서 직접 제어하는 디자인 props와 PopupHost가 주입하는 runtime props를 함께 정리했습니다.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
title | description | children | footer | React.ReactNode | undefined | Optional | Popup shell의 헤더, 본문, 하단 액션 영역을 직접 조합합니다. |
icon | React.ReactNode | null | undefined | Optional | description 위에 아이콘 영역을 추가합니다. null이면 아이콘 슬롯을 비웁니다. |
size | "small" | "regular" | "large" | "regular" | Optional | LayerPopup만 지원하는 패널 폭 규칙입니다. |
contentAlign | "left" | "center" | "left" | Optional | 본문 텍스트와 footer 정렬 기준을 제어합니다. |
hasCloseButton | closeButtonLabel | boolean | string | true | "팝업 닫기" | Optional | 우측 상단 닫기 버튼 노출 여부와 접근성 라벨을 제어합니다. |
shouldCloseOnBackdrop | shouldCloseOnEscape | boolean | true | true | Optional | backdrop 클릭과 Escape 키로 닫힐지 제어합니다. topmost popup에만 Escape가 반응합니다. |
dialogLabel | string | "레이어 팝업" | Optional | title이 없을 때 dialog aria-label fallback으로 사용합니다. |
className | panelClassName | bodyClassName | footerClassName | string | undefined | Optional | 루트, 패널, body, footer wrapper 각각에 커스텀 클래스를 추가합니다. |
onClickClose | () => void | undefined | Optional | 닫기 버튼 클릭 시 onRequestClose 직전에 부가 동작을 실행합니다. |
id | open | onRequestClose | onExited | isTopmost | runtime props from PopupHost | injected | Optional | 커스텀 popup 컴포넌트에서는 보통 `...runtimeProps`로 받고, PopupHost가 실제 인스턴스 lifecycle을 주입합니다. |
LayerPopup은 PopupBase를 감싼 dialog variant wrapper입니다. variant는 고정이고 size만 LayerPopup에서 직접 선택할 수 있습니다.useLayerPopup API 한눈에 보기
LayerPopup 등록과 stack 제어에 사용하는 hook API를 표로 정리했습니다.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
open | (options: LayerPopupOptions) => string | - | Required | 새 LayerPopup 인스턴스를 stack에 추가하고 생성된 id를 반환합니다. |
open.options.component | React.ComponentType<LayerPopupComponentProps> | - | Required | PopupHost가 렌더링할 custom LayerPopup 컴포넌트입니다. runtime props를 받아야 합니다. |
open.options.id | string | auto generated id | Optional | 특정 인스턴스를 직접 추적하거나 close(id) 대상으로 삼고 싶을 때 사용합니다. |
close | (id?: string) => void | - | Required | id를 주면 해당 LayerPopup을 닫고, 생략하면 현재 타입 stack의 마지막 popup을 닫습니다. |
closeAll | () => void | - | Required | 현재 열린 LayerPopup 타입 인스턴스만 모두 closing 상태로 전환합니다. |
layerPopups | Array<{ id: string; type: "layerPopup"; status: "open" | "closing" }> | - | Required | 전역 popup stack 중 LayerPopup 항목만 필터링한 snapshot 배열입니다. |
useLayerPopup()는 store action을 감싼 얇은 wrapper입니다. 실제 shell props는 component 안의 <LayerPopup {...runtimeProps} />에서 선언합니다.