사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
CLI 레퍼런스▾
AkanJS 레퍼런스▾
UI 레퍼런스▾

오버레이 UI

akanjs/ui의 오버레이 컴포넌트입니다. 모달 창, 확인 팝오버, 바텀 시트, 메뉴, 힌트, 복사 동작을 다룹니다. 먼저 Modal을 쓰고, 배치를 직접 짜야 할 때만 headless Dialog를 조합하세요.
이 페이지에서 쓰는 말
portal
요소를 DOM의 다른 자리, 여기서는 document.body 끝에 그리는 것입니다. 부모 상자가 잘라내지 못합니다.
trigger
사용자가 눌러 오버레이를 여는 요소입니다. trigger나 children으로 넘깁니다.
controlled (제어형)
open을 넘기고 onCancel에서 다시 바꿔 주는 방식입니다. 빼면 컴포넌트가 열림 상태를 직접 관리합니다.
오버라이드 슬롯
_overrides.tsx에서 컴포넌트를 라우트 하위 트리 단위로 바꿔 끼울 때 쓰는 이름입니다.
scrim
팝오버 뒤에 깔리는 투명한 층입니다. 팝오버 바깥을 누른 클릭을 받아 냅니다.
컴포넌트 고르기
컴포넌트
portal로 그림
트리거 기준
오버라이드 슬롯
화면을 덮는 창
Modal
✓
✓
제목·본문·하단 슬롯이 있는 가운데 창입니다. 모달이 필요하면 먼저 이것을 씁니다.
Dialog
✓
Modal을 이루는 headless 부품입니다. 배치를 직접 짜거나 에이전트에 이름을 알릴 때 씁니다.
BottomSheet
아래 가장자리에서 올라오는 모바일 패널입니다. 제자리에 그려지고 화면에 고정됩니다.
트리거에 붙는 것
Popconfirm
✓
✓
✓
되돌릴 수 없는 동작 앞에 뜨는 작은 확인/취소 팝오버입니다.
Dropdown
✓
✓
✓
목록 행의 동작 같은 짧은 동작 메뉴입니다.
Tooltip
✓
마우스를 올리거나 포커스하면 뜨는 순수 CSS 힌트입니다. 화면 가장자리에서는 옮겨지지 않고 잘립니다.
탐색과 도우미
Menu
✓
items 트리로 만드는 내비게이션 메뉴입니다. 사이드바나 상단 바에 씁니다.
Portal
자식을 id로 지정한 호스트 요소 안에 그립니다.
Copy
텍스트를 클립보드에 복사하고 성공 토스트를 띄웁니다.
✓해당해당 없음
  • portal로 그리는 오버레이는 잘리지 않습니다. Modal, Dropdown, Popconfirm, Select는 document.body에 그려지므로 스크롤되는 모달 본문이나 테이블의 overflow 컨테이너가 잘라내지 못합니다.
  • Portal은 같은 장치에 이름을 붙인 것입니다. body 끝이 아니라 id로 고른 호스트 요소 안에 그립니다.
  • Tooltip은 일부러 이 중 어느 것도 하지 않습니다. 순수 CSS라 비용이 거의 없는 대신, 화면 가장자리에서는 옮겨지지 않고 잘립니다.
함께 볼 페이지

Dialog

Modal을 이루는 headless compound 부품입니다. Modal의 정해진 배치가 맞지 않거나, 인페이지 에이전트가 이 창을 열고 닫게 하고 싶을 때 조합합니다.
속성과 API
Dialog{ open?, defaultOpen? = false, namespace?, className? }
열림 상태를 쥐는 루트입니다. open이 바뀌면 그 값을 따라갑니다.
namespacestring
인페이지 에이전트에게 이 창의 이름을 알립니다. 없으면 툴을 하나도 공개하지 않습니다.
Dialog.Trigger{ className?, children }
안에 있는 무엇을 눌러도 창이 열립니다.
Dialog.Modal{ onCancel?, confirmClose?, closeButton?, className?, bodyClassName? }
Modal이 그리는 기본 창입니다. Escape, 배경 클릭, 모서리 버튼으로 닫힙니다.
Dialog.LegacyModal{ onCancel?, confirmClose?, className?, bodyClassName? }
이전 창입니다. 스프링 애니메이션으로 열리고 닫히며, 터치로 끌어내려 닫을 수 있습니다.
Dialog.Title / Dialog.Action{ children }
쓴 자리에는 아무것도 그리지 않고, 자식을 제목 행과 하단 행으로 넘깁니다.
Dialog.Content{ className?, children }
전체 너비를 차지하는 본문입니다.
  • namespace 하나가 이름 셋을 공개합니다. namespace="share"를 주면 에이전트가 openDialogInShare, closeDialogInShare 툴과 dialogInShare 상태를 봅니다. 한 화면에 창이 둘이면 이름을 다르게 주세요.
  • 에이전트도 사람과 같은 길로 닫습니다. 창 자체의 닫기 동작을 거치므로 confirmClose와 onCancel도 그대로 실행됩니다. Modal은 namespace를 받지 않아 아무것도 공개하지 않습니다.
사용 예시

Popconfirm

되돌릴 수 없는 동작 앞에 세우는 작은 확인/취소 팝오버입니다. 트리거를 감싸고, 실행할 동작은 onConfirm으로 넘깁니다.
속성과 API
titleReactNode
굵게 표시되는 질문입니다.
descriptionReactNode
제목 아래에 붙는 선택적 설명입니다.
onConfirm() => void
사용자가 확인을 누르면 호출됩니다. 팝오버가 먼저 닫힙니다.
okText / cancelTextReactNode
버튼 라벨입니다. 기본값은 사전의 base.ok와 base.cancel입니다.
okButtonProps / cancelButtonPropsButtonHTMLAttributes & { loading? }
기본 버튼 두 개에 그대로 펼쳐 넣는 속성입니다.
iconReactNode | false
메시지 옆 아이콘이며 기본값은 경고 아이콘입니다. false면 그리지 않습니다.
actionsReactNode
하단 전체를 바꿉니다. 바꿔 넣으면 확인과 닫기를 모두 직접 처리해야 합니다.
triggerClassName / decoClassNamestring
트리거 래퍼와 말풍선 꼭지에 적용할 class입니다. decoClassName을 주면 꼭지 위치도 직접 정해야 합니다.
  • 잘리지 않습니다. 팝오버는 document.body에 portal로 그려지고 트리거의 끝 쪽 아래에 자리 잡습니다. 아래 공간이 모자라면 위로 뒤집히고, 꼭지도 따라갑니다.
  • 바깥 클릭은 scrim이 받습니다. 바깥을 누르거나 Escape를 누르면 팝오버만 취소됩니다. 이것을 연 Dropdown이나 모달은 열린 채로 남습니다.
  • 모델 레코드를 지우는 거라면 Model.RemoveWrapper를 쓰세요. 이 팝오버를 그리고 삭제 동작을 에이전트 툴로 공개하는 일까지 해 줍니다.
사용 예시

BottomSheet

모바일용 오버레이로, 아래 가장자리에서 올라오는 패널입니다. 거의 모든 것은 type이 정하며, Modal처럼 controlled로도, 자기 trigger로도 동작합니다.
속성과 API
type"full" | "half"
필수입니다. half는 화면 높이의 90%에 손잡이를 그리고, full은 화면 전체를 덮고 닫기 행을 그립니다.
open / onCancelboolean / () => void
controlled 상태입니다. 빼면 시트가 상태를 직접 관리하며, trigger나 ref로 엽니다.
triggerReactNode
시트를 여는 요소입니다.
header / handle / closeReactNode
header는 맨 위 행 전체를, handle과 close는 그 안의 표시만 바꿉니다.
className / bodyClassNamestring
시트 표면과 스크롤되는 본문에 적용할 class입니다.
refBottomSheetRef
{ open, close } 명령형 핸들입니다. 트리거 없이 시트를 열 때 씁니다.
  • 닫는 길은 넷입니다. half 시트의 손잡이를 높이의 1/3 넘게 끌어내리기, 배경 누르기, Escape, full 시트의 닫기 행입니다. 어느 쪽이든 onCancel이 호출됩니다.
사용 예시

Tooltip

마우스를 올리거나 키보드로 포커스하면 뜨는 힌트이며, 순수 CSS로 그립니다. 힌트 전용이라, 반드시 읽혀야 하는 내용은 툴팁에 넣지 마세요.
속성과 API
contentReactNode
힌트 내용입니다. 비어 있거나 null·undefined면 children만 그립니다.
childrenReactNode
말풍선이 붙는 트리거입니다.
side"top" | "right" | "bottom" | "left" = "top"
말풍선이 놓일 방향입니다.
variant"default" | "primary" | "info" = "default"
말풍선 색입니다. Field.Label은 필드 설명 옆 도움말 아이콘에 info를 씁니다.
classNamestring
말풍선에 적용할 class입니다.
  • 가볍지만 움직이지 않습니다. 상태도 portal도 위치 계산도 없어서 서버가 그린 HTML만으로 동작합니다. 대신 뷰포트 가장자리에서는 말풍선이 뒤집히지 않고 잘립니다.
  • 조건부 힌트에 래퍼가 필요 없습니다. content를 비워 두면 트리거만 그립니다. 말풍선은 마우스를 올리고 300ms 뒤에, 키보드 포커스에는 바로 뜹니다.
  • 뒤집히거나 포인터를 따라가는 툴팁이 필요하다면 _overrides.tsx에서 직접 만든 것을 연결하세요. Tooltip은 오버라이드 슬롯이라 기존 호출부가 모두 따라옵니다.
사용 예시

Portal

children을 페이지에 이미 있는 요소 안에 그리며, 그 요소는 id로 지정합니다. Layout.Navbar가 이것으로 동작합니다. 라우트 깊숙한 컴포넌트가 서로를 모른 채 상단 바를 채웁니다.
속성과 API
idstring
호스트 요소의 id입니다. 그 요소가 마운트되기 전에는 아무것도 그리지 않습니다.
childrenReactNode
호스트 안에 그릴 내용입니다.
  • 프레임 슬롯은 Layout 컴포넌트로 채우세요. Layout.Navbar, Layout.TopInset, Layout.TopLeftAction, Layout.BottomInset이 CSR 빌드에서도 맞는 호스트를 고르고, TopLeftAction을 뺀 나머지는 슬롯 높이까지 잡아 줍니다.
  • 프레임 슬롯은 첫 HTML에 들어 있습니다. SSR 중에 내용을 바로 써 넣으므로 hydration이 끝난 뒤에야 나타나는 일이 없습니다. 직접 만든 호스트는 브라우저에서 채워집니다.
  • 잘리는 부모에서 빠져나오는 수단이 아닙니다. Modal은 이미 document.body에 portal로 그려지고, Dropdown, Popconfirm, Select는 여기에 더해 트리거 기준으로 자리를 잡습니다.
사용 예시

Copy

트리거를 감싸서, 누르면 text를 클립보드에 복사하고 성공 토스트를 띄웁니다.
속성과 API
textstring = ""
클립보드에 복사할 텍스트입니다.
copyMessagestring
성공 토스트 문구입니다. 기본값은 언어에 맞춘 "복사되었습니다"입니다.
childrenReactNode
트리거입니다. 요소라면 원래 onClick이 유지되고, 복사보다 먼저 실행됩니다.
  • Clipboard API가 없어도 동작합니다. navigator.clipboard가 없으면 숨긴 textarea로 복사합니다. 토스트는 store의 showMessage로 띄웁니다.
사용 예시

MIT 라이선스 하에 배포되었습니다.

내 AI에 이 문서 연결하기

MCPhttps://akanjs.com/mcp
Copyright © 2026 Akan.js 모든 권리 보유.시스템 관리자bassman