surf-uiby COLDSURF
Components

Modal

body 로 portal 하는 백드롭 + 패널.

import { Button, Modal } from '@coldsurfers/surf-ui/primitives'import { useRef, useState } from 'react'export default function Example() {  const [open, setOpen] = useState(false)  const triggerRef = useRef<HTMLButtonElement>(null)  return (    <>      <Button ref={triggerRef} onClick={() => setOpen(true)}>        모달 열기      </Button>      <Modal        open={open}        onClose={() => setOpen(false)}        label="예매를 취소할까요?"        triggerRef={triggerRef}        panelClassName="preview-modal-panel"      >        <p style={{ margin: 0, fontWeight: 500 }}>예매를 취소할까요?</p>        <p style={{ margin: '8px 0 16px', color: 'var(--surf-text-secondary)' }}>          취소한 자리는 바로 다른 사람에게 넘어갑니다.        </p>        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>          <Button variant="ghost" onClick={() => setOpen(false)}>            돌아가기          </Button>          <Button variant="accent" onClick={() => setOpen(false)}>            취소하기          </Button>        </div>      </Modal>    </>  )}

행동은 useDialogBehavior 가, 마크업만 Modal 이 듭니다. 오버레이가 role="dialog" 를 들고, 오버레이 클릭은 dismissible 일 때만 닫습니다.

document.body 로 portal 한다

fixed inset-0 은 overflow 클리핑만 면해줄 뿐입니다. position: sticky · transform · filter 를 가진 조상이 있으면 그 조상이 stacking context 를 만들어, 오버레이의 z-index 가 페이지가 아니라 그 조상 안에서만 유효해집니다. 실제로 sticky 레일 위에서 티켓이 모달 위로 올라온 사고가 있었습니다.

대신 표면 오버라이드를 인라인으로 주입하는 서브트리 안에서는 그 값을 못 받습니다. 팔레트는 문제없습니다 — 스킴이 하나뿐이라 :root 가 곧 light 입니다. 바닥색이 필요하면 소비처가 직접 줍니다.

전면 시트처럼 백드롭/패널 구조가 아닌 표면은 이 컴포넌트 대신 훅만 씁니다.

Props

Prop

Type

On this page