Pagination
여러 페이지로 나뉜 목록에서 원하는 페이지로 이동할 때 사용하는 컴포넌트입니다.
Installation
의존성 설치
아래 코드를 복사 후 붙여넣고 사용하세요
Usage
totalPages는 0 이상의 전체 페이지 수입니다. 페이지가 0개 또는 1개면 Pagination을 표시하지 않습니다.
화면 너비가 480px 이상이면 이전·다음 버튼과 생략 표시를 포함해 최대 9개 슬롯을, 그보다 좁으면 최대 7개 슬롯을 표시합니다. 작은 화면의 페이지 영역은 5개 슬롯을 유지하며, 현재 페이지의 앞뒤 페이지를 직접 선택할 수 있도록 첫 페이지와 마지막 페이지를 필요한 구간에서만 표시합니다. 첫 페이지에서는 이전 버튼을, 마지막 페이지에서는 다음 버튼을 숨기되 각 영역의 너비는 유지합니다. 따라서 첫 페이지와 마지막 페이지 주변에서도 나머지 버튼의 위치가 바뀌지 않습니다.
여러 페이지로 나뉜 일반 목록이나 검색 결과의 아래쪽 중앙에 배치하세요. 데이터 표에서 페이지당 행 수와 표시 범위를 함께 제어해야 한다면 Table Pagination을 사용하세요.
Localization
스니펫 파일 상단의 numberFormatter와 paginationText를 앱의 언어에 맞게 수정하세요. 숫자 형식뿐 아니라 루트, 이전·다음 버튼, 개별 페이지의 접근성 이름도 이곳에서 바꿀 수 있습니다.
Props
Prop
Type
color?(string & {}) | ScopedColorFg | ScopedColorPalette | undefinedbackground?(string & {}) | ScopedColorPalette | ScopedColorBg | ScopedColorBanner | undefinedbackgroundGradient?"glowMagic" | "glowMagicPressed" | "highlightMagic" | "highlightMagicPressed" | "shimmerMagic" | "shimmerNeutral" | undefinedborderColor?(string & {}) | ScopedColorPalette | ScopedColorStroke | undefinedborderWidth?0 | (string & {}) | 1 | undefinedborderTopWidth?0 | (string & {}) | 1 | undefinedborderRightWidth?0 | (string & {}) | 1 | undefinedborderBottomWidth?0 | (string & {}) | 1 | undefinedborderLeftWidth?0 | (string & {}) | 1 | undefinedborderRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedborderTopLeftRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedborderTopRightRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedborderBottomRightRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedborderBottomLeftRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedboxShadow?(string & {}) | "s1" | "s2" | "s3" | undefinedwidth?ResponsiveValue<Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full"> | undefinedminWidth?ResponsiveValue<Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full"> | undefinedmaxWidth?ResponsiveValue<Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full"> | undefinedheight?ResponsiveValue<Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full"> | undefinedminHeight?ResponsiveValue<Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full"> | undefinedmaxHeight?ResponsiveValue<Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full"> | undefinedtop?0 | (string & {}) | undefinedleft?0 | (string & {}) | undefinedright?0 | (string & {}) | undefinedbottom?0 | (string & {}) | undefinedpadding?ResponsiveValue<0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {})> | undefinedpaddingX?ResponsiveValue<0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {})> | undefinedpaddingY?ResponsiveValue<0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {})> | undefinedpaddingTop?ResponsiveValue<0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "safeArea"> | undefinedpaddingRight?ResponsiveValue<0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {})> | undefinedpaddingBottom?ResponsiveValue<0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "safeArea"> | undefinedpaddingLeft?ResponsiveValue<0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {})> | undefinedposition?"fixed" | "relative" | "absolute" | "sticky" | undefinedoverflowX?"hidden" | "auto" | "visible" | "scroll" | undefinedoverflowY?"hidden" | "auto" | "visible" | "scroll" | undefinedzIndex?number | (string & {}) | undefinedjustifyContent?"flex-start" | "flex-end" | "center" | "space-between" | "space-around" | undefinedalignItems?"flex-start" | "flex-end" | "center" | "stretch" | undefinedalignContent?"flex-start" | "flex-end" | "center" | "stretch" | undefinedalignSelf?"flex-start" | "flex-end" | "center" | "stretch" | undefinedgap?ResponsiveValue<0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {})> | undefinedgridColumn?string | undefinedgridRow?string | undefinedunstable_transform?string | undefined_active?{ bg?: ScopedColorBg | ScopedColorPalette | (string & {}); background?: ScopedColorBg | ScopedColorPalette | (string & {}); } | undefinedasChild?boolean | undefinedhideFrom?BreakpointThreshold | undefinedExamples
Controlled
page와 onPageChange를 사용하면 페이지 상태를 외부에서 제어할 수 있습니다. 변경된 목록의 로딩, 포커스 이동, 결과 안내는 Pagination이 아니라 목록 영역에서 처리하세요.
onPageChange Details
onPageChange의 두 번째 인자는 변경 원인을 나타내는 reason과 변경 전 페이지인 previousPage를 제공합니다.
| reason | 발생 조건 |
|---|---|
page-item | 페이지 번호를 선택했을 때 |
previous | 이전 페이지 버튼을 선택했을 때 |
next | 다음 페이지 버튼을 선택했을 때 |
constraint | 외부에서 전달한 페이지가 유효 범위를 벗어나 보정됐을 때 |
외부 페이지가 범위를 벗어나면 보정된 페이지를 먼저 렌더링하고, 이후 constraint 변경을 한 번 알립니다.
Accessibility
루트는 nav로 렌더링되며 기본 접근성 이름은 페이지 탐색입니다. 같은 화면에 Pagination이 여러 개 있으면 aria-label이나 aria-labelledby로 대상을 구분하세요.
현재 페이지 버튼에는 aria-current="page"가 적용됩니다. 키보드 사용자는 Tab으로 버튼 사이를 이동하고 Enter 또는 Space로 페이지를 선택할 수 있습니다.
Last updated on