LayerPopup
화면 가운데에 뜨는 대화상자다. 제목 · 본문 · 푸터를 갖고 닫기 버튼이 있으며, dim 클릭과 ESC 로 닫힌다. 선언형으로 열림 상태를 직접 소유하거나, 명령형으로 내용 컴포넌트를 등록해 연다.
import { LayerPopup, useLayerPopup } from "@nui-kit/react";
// 서브패스로 좁힐 때
import { LayerPopup } from "@nui-kit/react/popup";
import "@nui-kit/react/styles/popup.css"; // 온디맨드일 때선언형 — 열림 상태를 직접 소유
<LayerPopup open={isOpen} onRequestClose={() => setIsOpen(false)} isTopmost title="약관 동의">…</LayerPopup>open · onRequestClose · isTopmost
const [isOpen, setIsOpen] = useState(false);
<LayerPopup
open={isOpen}
onRequestClose={() => setIsOpen(false)}
isTopmost
title="약관 동의"
footer={<Button color="primary" onClick={() => setIsOpen(false)}>동의합니다</Button>}
>
내용
</LayerPopup>명령형 — 컴포넌트를 등록해서 열기
useLayerPopup().open({ component }) 로 내용 컴포넌트를 넘긴다. PopupHost 가 open · onRequestClose · onExited · isTopmost 를 넣어 렌더하므로 열림 상태를 화면 쪽에서 들고 있을 필요가 없다.
layerPopup.open({ component: ProfilePopup });useLayerPopup().open({ component })
function ProfilePopup({ open, onRequestClose, onExited, isTopmost }: LayerPopupComponentProps) {
return (
<LayerPopup open={open} onRequestClose={onRequestClose} onExited={onExited} isTopmost={isTopmost} title="프로필 수정">
…
</LayerPopup>
);
}
const layerPopup = useLayerPopup();
layerPopup.open({ component: ProfilePopup });크기
size 는 폭만 바꾼다. 다섯 종류 중 LayerPopup 만 크기를 받는다. BottomSheet 와 FullPopup 은 화면에 맞춰 자기 폭을 갖는다.
small22.5remregular30remlarge40rem<LayerPopup open={isOpen} size="large" title="제목">내용</LayerPopup>size 는 dialog 형태에만 적용된다
닫힘
컴포넌트는 닫아 달라고 요청만 한다. onRequestClose 가 dim 클릭 · ESC · 닫기 버튼에서 불리고, 실제로 open 을 내리는 것은 소비자다. 닫기 버튼만 따로 잡고 싶으면 onClickClose 를 쓴다. 둘 다 있으면 onClickClose 가 먼저, 그다음 onRequestClose 가 호출된다.
| prop | 기본값 | 효과 |
|---|---|---|
shouldCloseOnBackdrop | true | dim 클릭으로 닫힘 요청 |
shouldCloseOnEscape | true | ESC 로 닫힘 요청. 최상단일 때만 |
hasCloseButton | true | 헤더의 × 버튼. 제목이 없어도 버튼이 있으면 헤더가 렌더된다 |
onExited | — | 닫힘 애니메이션까지 끝난 뒤. 언마운트 타이밍을 잡을 때 |
접근성
- 제목이 없으면
aria-label="레이어 팝업"이 붙는다.dialogLabel로 바꾼다 - 닫기 버튼의 접근 이름은
closeButtonLabel(기본 "팝업 닫기")이고, 40px 로 보이지만 44px 을 누른다. 마크업에서는 패널의 마지막 요소라 첫 포커스는 본문·푸터로 간다 - 본문 정렬
contentAlign의 기본은left다. 긴 글은 왼쪽 정렬이 읽기 쉽다 - 포커스 트랩 · 배경 inert · 쌓임 · 모션 감소 등 공통 계약은 Popup 개요
API
LayerPopup
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
open * | boolean | — | — |
bodyClassName | string | — | — |
children | ReactNode | — | — |
className | string | — | — |
closeButtonLabel | string | — | — |
contentAlign | PopupContentAlign | — | — |
description | ReactNode | — | — |
dialogLabel | string | — | title 이 없을 때 dialog 에 붙일 접근 이름 |
footer | ReactNode | — | — |
footerClassName | string | — | — |
hasCloseButton | boolean | — | — |
icon | ReactNode | null | — | — |
id | string | — | — |
isTopmost | boolean | — | 스택 최상단인가 — 포커스 트랩과 ESC 를 이 팝업만 처리한다 |
onClickClose | () => void | — | — |
onExited | () => void | — | 닫힘 애니메이션까지 끝난 뒤 호출된다 |
onRequestClose | () => void | — | — |
panelClassName | string | — | — |
shouldCloseOnBackdrop | boolean | — | dim 클릭으로 닫히는가 |
shouldCloseOnEscape | boolean | — | — |
size | PopupSize | — | — |
title | ReactNode | — | — |
LayerPopupProps 에서 자동 생성됨 (components/Popup/Popup.types.ts).