Pagination
먼저 보고, 그다음 계약을 읽습니다
페이지 네비게이션 컨트롤 (DataTable 와 짝).
Component intent의도와 경계 읽기
page/pageSize/total 세 값만 받으면 페이지 버튼(boundary + sibling + ellipsis), "X-Y / Total" 정보 줄, ←/→ 키보드 이동을 자체 계산해 제공하는 controlled 컴포넌트다. 페이지 수가 boundaryCount·siblingCount 로 정해지는 한계 이하면 ellipsis 없이 전부 표시한다. compact 모드는 좁은 컨테이너/모바일용으로 이전/다음 + "현재/총" 만 노출한다. 숫자는 tabular-nums 로 자리수를 시각적으로 안정시키고 총량은 ko-KR 콤마로 포맷한다.
예제
SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.
import { Pagination } from "@axe/ui";const [page, setPage] = useState(1);<Pagination page={page} pageSize={20} total={480} onPageChange={setPage} />import { Pagination } from "@axe/ui";<Pagination page={3} pageSize={20} total={480} compact onPageChange={setPage} /><nav class="axe-pagination axe-pagination--size-md" aria-label="Pagination"> <div class="axe-pagination__info"> <span class="axe-pagination__info-range">1-20</span> <span class="axe-pagination__info-sep"> / </span> <span class="axe-pagination__info-total">480</span> </div> <ul class="axe-pagination__list"> <li><button class="axe-pagination__btn axe-pagination__btn--nav" aria-label="이전 페이지" disabled aria-disabled="true">‹</button></li> <li><button class="axe-pagination__btn axe-pagination__btn--active" aria-current="page" aria-label="1페이지 · 현재">1</button></li> <li><button class="axe-pagination__btn" aria-label="2페이지">2</button></li> <li aria-hidden="true"><span class="axe-pagination__ellipsis">…</span></li> <li><button class="axe-pagination__btn" aria-label="24페이지">24</button></li> <li><button class="axe-pagination__btn axe-pagination__btn--nav" aria-label="다음 페이지">›</button></li> </ul></nav>Props
TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.
| 이름 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
page | number | 필수 | — | 1-based 현재 페이지. 내부적으로 [1, totalPages] 로 clamp. |
pageSize | number | 필수 | — | 페이지당 항목 수 (정보 줄·totalPages 계산에 사용). |
total | number | 필수 | — | 전체 항목 수 (페이지 수가 아님). 0 이면 페이지 리스트 숨김. |
onPageChange | (page: number) => void | 필수 | — | 페이지 변경 콜백. 상위 상태를 갱신 (controlled). |
siblingCount | number | — | 1 | 활성 페이지 좌우로 보여줄 페이지 수. |
boundaryCount | number | — | 1 | 시작/끝에서 항상 보여줄 페이지 수. |
showInfo | boolean | — | true | "X-Y / Total" 정보 줄 표시 (compact 시 무시). |
size | "sm" | "md" | — | "md" | 버튼 크기. md 는 기본(별도 CSS 규칙 없음), sm 은 28px 축소. |
compact | boolean | — | false | 모바일/좁은 컨테이너용 — 이전/다음 + "현재/총" 만 표시. size 무시. |
ariaLabel | string | — | "Pagination · 페이지 네비게이션 (←/→ 키)" | SR 용 nav label. |
...rest | React.HTMLAttributes<HTMLElement> | — | — | 나머지는 루트 <nav> 로 전파 (onChange 는 Omit). |
.axe-* 클래스 계약
React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.
| 클래스 | 안정성 | 용도 |
|---|---|---|
.axe-pagination | stable | <nav> 루트 (flex space-between, tabular-nums). |
.axe-pagination--size-sm | stable | sm 크기 변형 (버튼 28px). |
.axe-pagination--compact | stable | compact 모바일 변형 (중앙 정렬, 이전/다음 + n/총). |
.axe-pagination__info | stable | "X-Y / Total" 정보 줄. |
.axe-pagination__info-range | internal | 범위(X-Y) — primary 색. |
.axe-pagination__info-sep | internal | 정보 줄 구분자. |
.axe-pagination__info-total | internal | 총량. |
.axe-pagination__list | stable | 페이지 버튼 <ul> (←/→ 키 핸들러가 붙는 영역). |
.axe-pagination__btn | stable | 페이지/nav 버튼 (32px, hover/focus/disabled). |
.axe-pagination__btn--active | stable | 현재 페이지 버튼 (accent 배경). |
.axe-pagination__btn--nav | stable | 이전/다음 (‹ ›) 버튼. |
.axe-pagination__ellipsis | stable | 생략(…) 표시. |
.axe-pagination__compact-label | internal | compact 모드 "n / 총" 컨테이너. |
.axe-pagination__compact-current | internal | compact 현재 페이지 (semibold). |
.axe-pagination__compact-sep | internal | compact 구분자. |
.axe-pagination__compact-total | internal | compact 총 페이지. |
접근성
키보드, ARIA, 구현 노트를 함께 검토합니다.
- <ul> 영역에서 ← / → 로 이전/다음 페이지 이동 (경계에서 무시)
- 버튼은 Enter/Space 로 실행 (네이티브 button)
루트 <nav aria-label>(ariaLabel prop). 현재 페이지 버튼 = aria-current="page". 이전/다음 = aria-label "이전 페이지"/"다음 페이지" + 경계 시 aria-disabled(+실제 disabled). 페이지 버튼 aria-label "N페이지"(현재 시 "· 현재" 추가). ellipsis <li> = aria-hidden="true". compact 라벨 = aria-current="page".
←/→ 는 리스트 영역 포커스에서만 동작(정보 줄/외곽 nav 는 무시). total=0 이면 페이지 리스트를 숨기고 "0 / 0" 정보만 노출. reduced-motion 시 버튼 트랜지션 없음.