React

Popover

트리거 요소에 앵커링되어 화면 위에 떠 있는 컨테이너입니다. Header/Body/Footer 구조로 부가 정보나 액션을 제공할 때 사용됩니다.

사용 가능 버전@seed-design/[email protected], @seed-design/[email protected]

Installation

npx @seed-design/cli@latest add ui:popover

Props

PopoverRoot

Prop

Type

childrenReact.ReactNode

PopoverTrigger

Prop

Type

PopoverAnchor

Prop

Type

PopoverContent

Prop

Type

title?React.ReactNode
description?React.ReactNode
positionerContainer?React.RefObject<HTMLElement | null> | undefined
width?ResponsiveValue<(string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | "full"> | undefined
maxWidth?ResponsiveValue<(string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | "full"> | undefined

PopoverBody

Prop

Type

paddingX?ResponsiveValue<0 | (string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText"> | undefined
height?ResponsiveValue<(string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | "full"> | undefined
maxHeight?ResponsiveValue<(string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | "full"> | undefined
minHeight?ResponsiveValue<(string & {}) | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | "full"> | undefined
justifyContent?"flex-start" | "flex-end" | "center" | "space-between" | "space-around" | undefined
alignItems?"flex-start" | "flex-end" | "center" | "stretch" | undefined

PopoverFooter

Prop

Type

PopoverAction

Prop

Type

Examples

Trigger

<PopoverTrigger>는 aria-haspopup="dialog" 속성을 설정하고, Popover의 open 상태에 따라 aria-expanded 속성을 자동으로 설정합니다. 열려 있는 동안에는 <PopoverContent>를 가리키는 aria-controls 속성도 함께 설정합니다. 이 속성은 스크린 리더와 같은 보조 기술에 유용합니다.

Controlled

Trigger 외의 방식으로 Popover를 열고 닫을 수 있습니다. 이 경우 open prop을 사용하여 Popover의 상태를 제어합니다.

Open Change

onOpenChange(open, details)에서 열림 상태가 바뀐 이유를 확인할 수 있습니다.

  • trigger: 트리거로 열거나 닫음
  • closeButton: PopoverAction 또는 닫기 버튼으로 닫음
  • escapeKeyDown: Escape 키로 닫음
  • interactOutside: 외부 영역을 눌러 닫음
  • focusOut: Tab 등으로 포커스가 밖으로 이동하여 닫음
  • cascadeDismiss: 상위 레이어가 닫혀 함께 닫음

cascadeDismiss는 details.dismissedParent를, 나머지는 details.event를 제공합니다. focusOut의 이벤트는 FocusEvent입니다.

Popover는 열릴 때 콘텐츠로 포커스를 옮기지만 가두지 않습니다. closeOnInteractOutside={false}가 아니라면 Tab 등으로 포커스가 밖으로 이동할 때 닫히며, 이동한 곳의 포커스를 유지합니다.

Placement

<PopoverRoot>에 placement prop을 설정하여 트리거 기준 위치를 지정합니다. 뷰포트 경계를 벗어나면 자동으로 뒤집히거나(flip) 이동합니다(shift).

Anchor

<PopoverAnchor>를 사용하면 트리거와 분리된 요소를 기준으로 Popover의 위치를 잡을 수 있습니다. 이 경우 열림 상태는 open prop으로 직접 제어합니다.

Scroll

<PopoverContent>의 max-height(600px)를 넘는 긴 콘텐츠는 <PopoverBody>가 스크롤됩니다. 콘텐츠가 실제로 넘칠 때에만 하단에 scroll fog가 표시되고, 위에 Header가 있는 Body를 아래로 스크롤하면 상단에 divider가 나타납니다. 뷰포트가 작으면 max-height는 가용 높이에 맞춰 줄어듭니다.

Show Close Button

<PopoverContent>에 showCloseButton prop을 전달하여 닫기 버튼 표시 여부를 제어합니다. 기본값은 true이며, 표시될 때 Header 우측에 여백이 확보됩니다.

Prevent Close

PopoverAction의 onClick에서 e.preventDefault()를 호출하면 Popover가 닫히지 않습니다.

Last updated on

목차