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