호버 카드
이름 · 링크 뒤의 정보를 화면을 떠나지 않고 엿보는 지름길입니다. 뜬 층(60)의 판지이고 지붕 모서리 · 화살표가 없습니다.
같은 정보와 동작은 링크 대상(프로필 · 문서)에 언제나 있습니다. 그래서 카드는 읽기 프로그램에 따로 알리지 않고(aria-describedby 없음), 카드 안 버튼은 Tab 순서에 넣지 않습니다. 터치에서는 열지 않습니다. 시각은 UTC 를 받아 그 사람의 시간대로 바꿔 보이고, 한국어 · 일본어는 24시간, 영어는 12시간으로 적습니다. radix-ui 가 필요합니다.
- import
- import { HoverCard, HoverCardTrigger, HoverCardContent, PersonCard, LinkPreviewCard } from "@uyoolabs/ui/overlay";
- 쓰는 경우
- 멘션(@이름) · 담당자 · 아바타의 사람 카드(PersonCard), 문서 · 작업 · 바깥 링크의 미리 보기(LinkPreviewCard). 같은 트리거에서 한 번 가져온 데이터는 앱이 5분 둡니다.
- 쓰지 않는 경우
- 폼 · 긴 목록(→ Popover · Sheet), 카드에만 있는 정보 · 동작(대상 페이지에도 둡니다), 아이콘 버튼의 이름(→ Tooltip). 카드 안에 지름길 버튼을 셋 넘게 두지 않습니다.
사람 카드
이름 · 소속 · 접속 · 현지 시각 · 지름길 2개. 탈퇴한 사람은 회색 사람 아이콘과 떠난 날만 보이고 동작이 없습니다.
웹훅 서명 검증은 @이도현 님이 맡아 주시기로 했습니다.
링크 미리 보기
바깥: 그림 · 사이트 · 제목 · 두 줄 설명 / 안: 위치 · 상태 배지 · 마지막 고침 / 볼 권한 없음: 제목도 보이지 않습니다 / 미리 볼 수 없음: 주소만.
자세한 기준은 환불 정책 v2 문서를 봅니다.
키보드 · 포인터
APG 패턴이 없는 보조 미리 보기입니다.
| 키 | 동작 |
|---|---|
| 포인터를 올리고 500ms | 연다 |
| 떠나고 300ms | 닫는다. 그 사이 카드 위로 옮기면 열린 채다 |
| Tab | 트리거에 오면 500ms 뒤 연다. 떠나면 닫는다(포커스는 옮기지 않는다) |
| Esc | 닫는다. 포커스는 트리거에 그대로 |
| Enter | 링크로 간다(카드는 닫힌다) |
| 터치 | 열지 않는다. 누르면 바로 링크로 간다 |
| 스크롤 · 바깥 누름 | 바로 닫는다 |
props
소스의 타입과 JSDoc 에서 생성한 표입니다. 컴포넌트를 고치면 pnpm gen 으로 다시 만듭니다.
HoverCard
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| openDelay | number | 500 | 열기 전 기다림(ms). 툴팁(400)보다 늦게 연다 — 지나가는 손에 뜨지 않게 |
| closeDelay | number | 300 | 떠난 뒤 닫기 전 기다림(ms). 그 사이 카드 위로 옮기면 열린 채다 |
이 밖에 Radix HoverCard.Root props를 그대로 받습니다. 기본값을 바꾼 것은 defaultOpen=false 입니다.
HoverCardContent
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| size | "md" | "lg" | "md" | md 300 · lg 360(링크 미리 보기) |
| sideOffset | number | 4 | 트리거와의 간격(px) |
| align | "start" | "center" | "end" | "start" | 트리거 기준 맞춤. 기본은 시작선 |
이 밖에 Radix HoverCard.Content props를 그대로 받습니다. 기본값을 바꾼 것은 collisionPadding=8 입니다.
PersonCard
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| name필수 | string | — | |
| handle | string | — | |
| title | ReactNode | — | 소속 · 역할(결제팀 · 백엔드 개발) |
| avatar | ReactNode | — | 40 아바타(접속 점 포함). ./avatar 의 Avatar 나 ./ui 의 AvatarMark |
| presence | "online" | "away" | "dnd" | "offline" | — | |
| timeZone | string | — | 그 사람의 IANA 시간대. 보는 사람과 시차가 같으면 현지 시각 줄을 그리지 않는다 |
| place | ReactNode | — | 현지 시각 줄의 곳 이름(서울). 없으면 UTC 차이만 |
| viewerTimeZone | string | — | 보는 사람의 시간대. 없으면 브라우저의 시간대 |
| now | Date | — | 지금. 테스트 · 스냅샷에서 고정한다 |
| deleted | boolean | — | 탈퇴: 회색 사람 아이콘 · 동작 없음 |
| leftAt | string | Date | — | 떠난 시각(UTC). 탈퇴 문장의 날짜 |
| loading | boolean | — | 불러오는 중: 뼈대(앱이 300ms 넘을 때 켠다) |
| actions | ReactNode | — | 지름길 버튼(최대 2). 같은 동작이 프로필에 있다 |
| lang | "ko" | "en" | "ja" | "ko" | |
| labels | Partial<HoverCardLabels> | — | |
| className | string | — |
LinkPreviewCard
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| kind필수 | "web" | "internal" | "private" | "unavailable" | — | web 바깥 링크 · internal 안 링크(문서 · 작업) · private 볼 권한 없음 · unavailable 가져오지 못함 |
| site필수 | ReactNode | — | 사이트 이름(docs.example) · 안 링크의 위치(우유랩스 · 결제 개편 · 문서) |
| url | string | — | 미리 볼 수 없을 때 보이는 주소 |
| title | ReactNode | — | |
| description | ReactNode | — | 두 줄까지 |
| image | ReactNode | false | — | 바깥 링크의 그림. 없으면 그림 자리(파인 홈 + 아이콘). false 면 자리도 두지 않는다 |
| status | ReactNode | — | 안 링크의 상태 배지 |
| meta | ReactNode | — | 안 링크의 마지막 고침(아바타 · 이름 · 상대 시각) |
| lang | "ko" | "en" | "ja" | — | |
| labels | Partial<HoverCardLabels> | — | |
| className | string | — |