surf-uiby COLDSURF
Components

Popover

바깥클릭 · Escape · 위치잡기를 한 어휘로.

import { Chip, POPOVER_MENU_CLS, Popover } from '@coldsurfers/surf-ui/primitives'const LINKS = ['TAPE', 'MIND', 'DEV']export default function Example() {  return (    <Popover      role="menu"      menuClassName={POPOVER_MENU_CLS}      trigger={({ open, toggle }) => (        <Chip active={open} onClick={toggle}>          카테고리 ▾        </Chip>      )}    >      {({ close }) =>        LINKS.map((label) => (          <button            key={label}            type="button"            role="menuitem"            onClick={close}            style={{              display: 'block',              width: '100%',              padding: '8px 14px',              border: 0,              background: 'none',              textAlign: 'left',              cursor: 'pointer',            }}          >            {label}          </button>        ))      }    </Popover>  )}

그룹 칩이 쓰던 open 상태 · 바깥클릭/Escape 닫기 · 위치잡기 · 뷰포트 maxHeight 를 한 어휘로 수렴합니다.

위치잡기는 createPortal(document.body) + position: fixed 한 전략으로 통일했습니다 — 어떤 overflow · transform 조상 안에서도 클립되지 않습니다.

트리거는 inline-flex 앵커로 감싸 측정하므로, 트리거 컴포넌트에 forwardRef 를 강제하지 않습니다.

닫히는 조건

바깥 mousedown · Escape · 앵커를 품은 스크롤러의 스크롤(capture) · resize 시 재측정입니다.

스크롤에서 닫는 근거는 「스크롤했다」가 아니라 **「앵커가 움직였다」**입니다 — 메뉴는 fixed 라 앵커 rect 로 잡은 좌표가 어긋나야 닫을 이유가 생깁니다. 그래서 판정이 한 줄입니다: 이 스크롤러가 앵커를 품고 있나.

스크롤 출처앵커를 품나결과
페이지(document)O닫힘
앵커를 감싼 스크롤 패널O닫힘
메뉴 내부(긴 옵션 목록)X (body 로 portal)유지
옆에 놓인 가로 칩 줄X유지

마지막 줄이 이 판정을 좁힌 이유입니다. 「메뉴 밖 스크롤이면 전부 닫기」였을 땐, 팝오버 아래 가로 칩 줄이 관성으로 굴러가는 중에 트리거를 누르면 열리자마자 닫혔습니다.

표면은 소비처가 든다

메뉴 박스 장식 전체가 menuClassName 입니다. 기본 표면을 원하면 POPOVER_MENU_CLS 를 섞습니다.

<Popover menuClassName={cx(POPOVER_MENU_CLS, myMenu)} …>

Props

Prop

Type

On this page