내비게이션
페이지 사이를 옮기는 링크 줄(TabNav), offset 목록의 페이지 이동(Pagination), 지금 위치(Breadcrumb)입니다. 모두 href 로 이동하므로 상태가 URL 에 남습니다.
세 컴포넌트 모두 ./ui 의 서버 컴포넌트이고 Next 를 모릅니다. 링크는 LinkProvider 로 주입된 라우터 Link 로 그립니다. 주입이 없으면 평범한 a 입니다. Next 앱은 루트에 NextLinkProvider 를 한 번 두거나, ./next 의 같은 이름 컴포넌트를 씁니다.
내장 문구는 lang(ko · en · ja)으로 고르고 labels 로 일부만 덮습니다. 이전 · 다음의 방향은 chevron 아이콘이 말하므로 문구에 화살표를 넣지 않습니다.
- 쓰는 경우
- 목록을 상태별로 나눈 화면 사이를 옮길 때(TabNav), offset 기반 목록을 넘길 때(Pagination), 제품 화면의 위치와 이름을 말할 때(Breadcrumb) 씁니다.
- 쓰지 않는 경우
- 같은 화면 안에서 패널만 바꾸는 탭은 Tabs(W2)입니다. TabNav 에 role="tablist" 를 붙이지 않습니다. 커서 기반 목록에는 Pagination 이 맞지 않습니다. 방문 기록(뒤로 가기)과 단계 진행(Stepper)에는 Breadcrumb 를 쓰지 않습니다.
- 금지
- 본문 맨 위에 h1 으로 화면 이름을 한 번 더 적지 않습니다(이름은 브레드크럼의 마지막 항목). 현재 탭을 파랑 글자나 왼쪽 세로 강조선으로 표시하지 않습니다. 구분자로 / · > 글자를 쓰지 않습니다.
// 정적 · 서버 컴포넌트 · Next 없음
import { Breadcrumb, BreadcrumbItem, Pagination, TabNav } from "@uyoolabs/ui/ui";
// … 메뉴(radix)
import { BreadcrumbOverflow } from "@uyoolabs/ui/nav";
// Next 앱: 루트에 한 번 두면 ./ui 의 링크가 모두 next/link 로 그려진다
import { NextLinkProvider } from "@uyoolabs/ui/next";
// 또는 v1 처럼 Next 링크를 바로 쓰는 래퍼(props 가 같다)
import { Breadcrumb, Pagination, TabNav } from "@uyoolabs/ui/next";Next · 라우터 연결
링크를 라우터 Link 로 그리게 하는 방법입니다.
// app/layout.tsx (서버 컴포넌트여도 된다)
import { NextLinkProvider } from "@uyoolabs/ui/next";
<body>
<NextLinkProvider>{children}</NextLinkProvider>
</body>
// Vite · React Router 앱은 LinkProvider 에 라우터 Link 를 감싸 넘긴다
<LinkProvider component={({ href, ...props }) => <RouterLink to={href} {...props} />}>TabNav
가로는 굵기 + primary 2px 밑줄, 손을 올리면 경계색 밑줄입니다. 굵어져도 줄이 흔들리지 않게 굵은 폭을 미리 잡고, 넘치면 가로로 스크롤하며 현재 탭이 보이게 맞춥니다.
세로
Pagination
첫 페이지의 '이전'은 링크가 아닌 비활성 키캡으로 자리를 지킵니다. 현재 번호는 눌린 키캡입니다.
offset 0 · limit 20 · total 57
offset 20 · limit 20 · total 57
numbered · total 180
Breadcrumb
링크는 muted(hover 에 밑줄), 현재는 600 fg-strong 이고 링크가 아닙니다. 구분자 chevron 은 읽지 않습니다.
키보드
| 키 | 동작 |
|---|---|
| Tab | 탭 · 페이지 · 경로 링크와 … 버튼을 차례로 지난다. 화살표 이동은 없다(탭 목록이 아니다) |
| Enter | 링크로 이동한다 |
| EnterSpace↓ | … 버튼: 숨긴 경로 메뉴를 열고 첫 항목에 선다 |
| ↑↓HomeEnd | 메뉴 항목을 옮긴다 |
| Esc | 메뉴를 닫고 … 버튼으로 돌아간다 |
props
소스의 타입과 JSDoc 에서 생성한 표입니다. 컴포넌트를 고치면 pnpm gen 으로 다시 만듭니다.
TabNav
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| items필수 | TabNavItem[] | — | |
| active필수 | string | — | 지금 화면의 value |
| orientation | "horizontal" | "vertical" | "horizontal" | horizontal: 밑줄 탭 줄 · vertical: 사이드바 항목과 같은 세로 목록 |
| lang | "ko" | "en" | "ja" | — | 내장 문구의 언어. 기본값은 ko 다(tab-nav.labels.ts) |
| labels | Partial<TabNavLabels> | — | lang 의 기본 문구 중 바꿀 것만 넘긴다. 예: { nav: "상태 필터" } |
| className | string | — |
Pagination
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| baseHref필수 | string | — | |
| offset필수 | number | — | |
| limit필수 | number | — | |
| total필수 | number | — | |
| param | string | "offset" | offset 쿼리 이름 |
| variant | "simple" | "numbered" | "simple" | simple: 범위 + 이전 · 다음. numbered: 범위 + 번호 키캡 |
| siblingCount | number | 1 | numbered 에서 현재 양옆에 보일 번호 수. 그 밖은 … 으로 줄인다 |
| lang | "ko" | "en" | "ja" | — | 내장 문구의 언어. 숫자 자릿수 구분도 이 언어를 따른다. 기본값은 ko 다(pagination.labels.ts) |
| labels | Partial<PaginationLabels> | — | lang 의 기본 문구 중 바꿀 것만 넘긴다. 예: { prev: "Back" } |
| className | string | — |
Breadcrumb
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| maxItems | number | 4 | 이보다 많으면 처음 1 + … + 마지막 2 로 줄인다. 0 이면 줄이지 않는다. 좁은 화면(lg 미만)은 늘 부모 + 현재다 |
| overflow | (hidden: BreadcrumbItemData[]) => ReactNode | — | 줄인 단계를 그리는 방법. ./nav 의 BreadcrumbOverflow 를 넘기면 … 이 메뉴가 된다. 넘기지 않으면 … 은 숨긴 단계 중 가장 아래 것으로 가는 링크다(radix 없이도 한 단계씩 올라간다) |
| lang | "ko" | "en" | "ja" | — | 내장 문구의 언어. 기본값은 ko 다(breadcrumb.labels.ts) |
| labels | Partial<BreadcrumbLabels> | — | lang 의 기본 문구 중 바꿀 것만 넘긴다 |
| children필수 | ReactNode | — | BreadcrumbItem 들. 다른 컴포넌트로 감싸지 않고 바로 넘긴다(항목의 props 를 읽어 줄인다) |
이 밖에 <nav> props를 그대로 받습니다.
BreadcrumbItem
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| href | string | — | |
| asChild | boolean | false | 라우터 Link 를 자식으로 받는다: <BreadcrumbItem asChild><Link href="/p">결제 개편</Link></BreadcrumbItem> |
| icon | ReactNode | — | 16. 첫 항목(워크스페이스 사각 아바타)과 종류가 섞이는 항목(채널 # · 자물쇠 · 회의 · 문서)에만 |
| current | boolean | false | 지금 화면. 링크가 아니다(href 를 무시한다). Breadcrumb 안에서는 넘기지 않아도 마지막 항목이 현재다 |
| loading | boolean | false | 이름을 불러오는 중. 폭 72 뼈대 + aria-busy |
| lang | "ko" | "en" | "ja" | — | 내장 문구의 언어. Breadcrumb 안에서는 Breadcrumb 의 값을 받는다 |
| labels | Partial<BreadcrumbLabels> | — | |
| children필수 | ReactNode | — |
이 밖에 <a> props(children 제외)를 그대로 받습니다.
BreadcrumbOverflow
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| items필수 | BreadcrumbItemData[] | — | Breadcrumb 의 overflow 가 넘기는 숨긴 단계(위에서부터) |
| lang | "ko" | "en" | "ja" | — | 내장 문구의 언어. Breadcrumb 와 같은 값을 넘긴다 |
| labels | Partial<BreadcrumbLabels> | — | lang 의 기본 문구 중 바꿀 것만 넘긴다(more) |
| className | string | — |