Popover
트리거 기준으로 뜨는 논모달 패널 — 외부 클릭/Escape 닫기, 하단 공간 부족 시 상단 플립. 포커스 트랩 없이 Tab이 자연 진행합니다. 비제어(defaultOpen).
마지막 업데이트 2026-06-11
한눈에#
트리거 곁에 뜨는 논모달 패널입니다 — 링크·버튼이 섞인 가벼운 콘텐츠를 담고, 외부 클릭·Escape로 닫히며 포커스를 가두지 않습니다(Tab 자연 진행).
- 논모달 패널
- 외부 클릭·Escape 닫기
- 포커스 트랩 없음
- 하단 공간 부족 시 상단 플립
트리거를 눌러 외부 클릭·Escape 닫기를 직접 확인하세요:
사용 시점#
링크·버튼이 섞인 가벼운 비차단 패널이면 Popover — 순수 설명·액션 메뉴·차단 흐름은 다른 컴포넌트입니다.
상세 설명·링크가 섞인 가벼운 보조 패널(외부 클릭·Escape로 가볍게 닫힘, 포커스 비가둠)
플레이그라운드#
컨트롤로 props를 조작하면 미리보기와 코드가 실시간 갱신됩니다.
import { Popover } from '@wds/ui-web';
<Popover trigger="도움말 보기">이 값은 최근 7일 평균입니다.</Popover>변형#
패널 안에 텍스트·링크 등 임의 콘텐츠를 둘 수 있습니다.
패널은 트리거 하단에 정렬되고, 뷰포트 하단 공간이 부족하면 상단으로
플립됩니다(data-placement 속성으로 노출).
크기#
단일 크기입니다 — 트리거 높이 control.height-md(44px), 패널 폭
14rem~20rem(콘텐츠에 따라 가변).
상태#
- 열림 — 트리거
aria-expanded="true"+ 패널 렌더 - Hover — 트리거 배경
color.surface-hover - Focus — 트리거
:focus-visible에 2px primary 아웃라인
논모달입니다 — 포커스 트랩이 없고, 열린 채로 Tab을 누르면 문서 흐름대로 이동하며, 닫혀도 포커스를 강제로 옮기지 않습니다. 행동을 요구하는 흐름이면 Modal/Drawer를 쓰세요.
제어/비제어 — 기본은 비제어(defaultOpen)이며 내부에서 상태를 소유합니다.
open을 주면 제어 모드가 되어 부모가 상태를 소유하고, 트리거 클릭·Escape·외부
클릭 등 모든 열림/닫힘 전환은 onOpenChange(open)로 통지됩니다(렌더는 부모 open을 따름).
적응형 (ADR-012 B-P2)#
adaptToSheetOnCompact를 켜면 compact 뷰포트(< 600px)에서 작은 앵커 패널 대신
BottomSheet로 강등됩니다 — 좁은 폭의 터치 환경에 맞춘
Apple popover↔sheet 적응입니다. 이때 trigger가 시트 제목이 되고, 닫기/배경/Escape는
BottomSheet 계약을 따릅니다. opt-in이 없으면(기본) 뷰포트와 무관하게 앵커 패널을
유지하므로 기존 사용처는 영향이 없습니다.
Props#
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
trigger | ReactNode | — | 트리거 콘텐츠 — 내부에서 button으로 감쌈(자체 button 전달 금지) |
open | boolean | — | 제어 열림 상태 — 제공하면 제어 모드(내부 상태 무시, 모든 전환이 onOpenChange로 통지) |
onOpenChange | (open: boolean) => void | — | 열림/닫힘 전환 통지 — 제어/비제어 모두에서 호출 |
defaultOpen | boolean | false | 초기 열림 여부 — 이후 상태는 내부 소유(비제어, open 미제공 시) |
adaptToSheetOnCompact | boolean | false | compact 뷰포트에서 앵커 패널 대신 BottomSheet로 강등 (trigger가 시트 제목) |
children | ReactNode | — | 패널 콘텐츠 |
className | string | — | 루트(div)에 적용 — 레이아웃 조정용 |
접근성#
- 트리거 button에
aria-expanded+aria-controls(패널 id) 연결 Escape로 닫기 — 포커스 위치 무관(document 레벨)- 외부 클릭(mousedown)으로 닫기
- 논모달이므로 포커스를 가두지 않습니다 — 패널 진입은 Tab 자연 진행
- 등장 모션은
prefers-reduced-motion존중
토큰#
component 토큰 없이 semantic을 직접 소비합니다(신설 기준 §4 미충족).
| 속성 | 토큰 |
|---|---|
| 트리거 | color.surface + color.border (hover surface-hover/border-strong · pressed surface-pressed) |
| 트리거 높이/라운드 | control.height-md · radius.control |
| 패널 | color.surface-raised · radius.md · shadow.lg · z.dropdown |
| 패널 텍스트 | font.size-body-2 · color.text |
| 간격 | 트리거-패널 space.2 · 패딩 space.4 |
| 모션 | duration.fast + ease.emphasized-decelerate |