본문으로 건너뛰기

Popover

자신을 연 컨트롤 옆에 열리는 시트입니다. Tooltip과 달리 그대로 떠 있고 포인터와 키보드로 닿을 수 있어서, 안의 내용을 누르고 입력할 수 있습니다.

tsx
import { Button, Popover } from 'neba';

<Popover trigger={<Button variant="outline">Share</Button>} title="Share this page">
  <TextField size="sm" label="Link" defaultValue="https://…" readOnly />
</Popover>;

Props

Prop타입기본값설명
localestringBCP 47 태그. ×의 접근성 이름을 이 언어로 씁니다. 지원하지 않는 태그는 영어로
triggerReactElementpopup이 매달리고 또 popup을 여는 요소. ref를 받고 props를 펼치는 요소 하나여야 합니다. 모든 Neba 컴포넌트가 그렇습니다
size공통'xs' | 'sm' | 'md' | 'lg' | 'xl''md'타입 스케일과 여백, 그리고 popup이 넓어질 수 있는 한계까지 함께 정합니다
color공통'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'의미론적 색 역할. 시트는 물들지 않으므로 가장자리와 포커스 링에만 나타납니다
density공통'default' | 'compact''default'여백만 바꿉니다
titleReactNode제목. popup의 이름이 되는 요소로 렌더링됩니다
descriptionReactNode제목 아래 한 줄이자 popup의 접근성 설명
childrenReactNode본문
side'top' | 'right' | 'bottom' | 'left''bottom'트리거의 어느 쪽에 뜨는지. 자리가 없으면 반대쪽으로 넘어갑니다
align'start' | 'center' | 'end''center'그 변을 따라 놓이는 위치
sideOffsetnumber6트리거와의 거리(px)
alignOffsetnumber0그 변을 따라 밀어내는 거리(px)
arrowbooleanfalse트리거를 가리키는 작은 쐐기. Tooltip과 달리 기본이 꺼짐입니다. 이 표면은 반투명이고, popup의 상자 밖으로 튀어나온 쐐기는 그 backdrop을 함께 가져갈 수 없습니다
openboolean열림 여부. onOpenChange와 함께
defaultOpenbooleanfalse비제어 popover의 초기 상태
onOpenChange(open: boolean) => void열리거나 닫힐 때 호출
modalboolean | 'trap-focus'false뒤 페이지를 가져갈지. 기본이 꺼짐인 것이 popover와 Dialog를 가릅니다. popover는 페이지 대신이 아니라 페이지 옆의 한 부분입니다
dismissiblebooleantrueEscape나 바깥 클릭으로 닫히는지. 꺼도 PopoverClose는 통과하므로 갇히지 않습니다
showClosebooleanfalse모서리의 ×
closeLabelstring× 버튼의 접근성 이름
widthnumber | stringsize가 정한 최대 너비를 대신할 값. 숫자는 픽셀입니다

<div>의 native 속성은 popup으로 전달됩니다. color · title · children만 위 표와 이름이 겹쳐 제외됩니다.

PopoverClose는 Base UI의 Popover.Close를 그대로 내보낸 것입니다. render prop을 주면 어떤 요소든 자기가 속한 popup을 닫습니다: <PopoverClose render={<Button>Apply</Button>} />.

공통 축은 prop 규칙에서 설명합니다.

예시

side와 align

side는 trigger의 어느 변에 popup이 놓일지, align은 그 변을 따라 어디에 놓일지입니다. 창에 자리가 없으면 반대쪽으로 자동으로 넘어갑니다. sideOffset으로 간격을, alignOffset으로 변을 따라 미는 거리를 조절합니다.

popup은 focus를 받을 수 있는 내용을 담으므로, 필터 패널이나 작은 form, 색 선택기는 Dialog가 아니라 여기에 들어갑니다. form을 채우는 동안 뒤 페이지가 계속 읽힙니다. 내용이 너비를 정해야 할 때는 width로 상한을 둡니다.

제어 컴포넌트

openonOpenChange를 함께 넘기면 state의 주인은 caller가 되므로, 페이지의 다른 무엇이든 이 popup을 열고 닫을 수 있습니다. 넘기지 않으면 popover가 스스로 관리하고 defaultOpen이 초기 상태를 정합니다.

arrow

arrow는 trigger를 가리키는 쐐기를 그립니다. 기본은 꺼짐입니다. 이 표면은 흐린 backdrop 위의 반투명이고, popup의 상자 밖으로 튀어나온 쐐기는 그 backdrop을 함께 가져갈 수 없기 때문입니다. trigger가 멀어서 popup이 무엇에 속하는지 말해야 할 때 켜세요.

tsx
<Popover arrow trigger={<Button>Details</Button>}>
  Anchored to the button it came from.
</Popover>

접근성

  • popup에 role="dialog"가 붙습니다. title이 이름이 되고 description이 설명이 되며 aria-labelledbyaria-describedby로 연결됩니다. 둘 다 없는 popover에는 aria-label을 따로 주세요.
  • 열리면 focus가 popup 안으로 들어가고, 닫히면 trigger로 돌아갑니다.
  • Esc로 닫히고 바깥 클릭으로도 닫힙니다. dismissible={false}는 둘 다 취소하지만 PopoverClose는 통과하므로 갇히지 않습니다.
  • modal은 기본이 false이므로 뒤 페이지는 계속 스크롤되고 쓸 수 있습니다. 다른 것을 건드리기 전에 반드시 답해야 하는 popup에는 'trap-focus'를 쓰세요.
  • ×의 접근성 이름은 locale이 정합니다. closeLabel로 직접 쓸 수도 있습니다.

Released under the MIT License