Pagination
総件数からページ番号列(省略記号を含む)を決定的に導出するページ送りです。fandhe-frontend-headless-ui の pagination mod は Root / Item / Ellipsis / PrevTrigger / NextTrigger / FirstTrigger / LastTrigger の 7 anatomy パーツを提供する unstyled 部品であり、Themes 版と異なりスタイル(CSS)は一切持ちません。クリックで dispatch する Button モードと、href 遷移の Link モードの両方に対応します。
キーボード操作
| キー | 対象 | 効果 |
|---|---|---|
| Tab / Shift+Tab | Item / 各トリガー | ネイティブのフォーカス移動です。各パーツはネイティブ <button>/<a> のため roving tabindex 等の独自実装は持ちません(ark-ui と同じ契約)。 |
| Enter / Space | Item / 各トリガー(Button モード) | ネイティブ <button> の既定動作としてクリックと同じ効果で発火します。 |
| Enter | Item / 各トリガー(Link モード) | ネイティブ <a> の既定動作として href へ遷移します。 |
参考サイトとの差分
ark-ui Pagination(chakra-ui Pagination も同型。Radix Primitives / Radix Themes に Pagination は存在しません)と突合し、以下を是正しました。
- FirstTrigger / LastTrigger パーツを新設(5 → 7 anatomy パーツ)。ark-ui の Anatomy・Data Attributes 表に準拠し、
prev-trigger/next-triggerと同じdisabled/aria-disabled/data-disabled契約を持ちます。 itemへdata-index(ページ番号の 10 進数文字列)を追加。ark-ui の Item Data Attributes 表に準拠します。PaginationAction::First/Lastを追加し、"first"/"last"dispatch でpageを1/total_pagesへ直接遷移できるようにしました(ark-ui のgoToFirstPage/goToLastPage相当)。- 呼び出し側
attrsからの固定属性キー偽装を除去するdrop_reservedを追加しました(data-selected/data-index/aria-current/href/type/disabled/aria-disabled/data-disabled/aria-hidden)。
一方、以下は意図的に合わせていません。
- キーボードの独自実装: ark-ui も roving tabindex 等の独自キーボード操作を持たず、ネイティブ
<button>/<a>の既定操作に委ねる契約のため、本部品も新規実装していません(上表参照)。 aria-label("page N" 相当のローカライズ文字列): ark のtranslations.itemLabelはローカライズ機構前提のため、item/トリガー系パーツではaria-labelを予約キーに含めません。呼び出し側がattrs経由で明示的に供給する契約のまま維持しています。- chakra-ui の
PageText/Items("1–10 of 50" 相当の件数レンジ文字列): 数値整形はアプリケーションロジックであり、UI コンポーネント層の責務外として不採用です。 fandhe-frontend-wasm-fullのクリック配線:"goto"/"next"/"prev"/"first"/"last"を DOM イベントへ接続する処理は別クレート責務のため未実装です。
スタイル済みの表示例は Pagination を参照してください。
関連 API: fandhe-frontend-headless-ui API
自前 CSS の最小例
Themes 版を使わず本部品を直接使う場合、[data-scope="pagination"][data-part="..."] セレクタでスタイルを当てます(positioner のような非表示パーツを持たないため [hidden] ガードは不要です)。
[data-scope="pagination"][data-part="item"][data-selected] {
font-weight: 600;
background: #eff6ff;
}
[data-scope="pagination"][data-part="prev-trigger"][data-disabled],
[data-scope="pagination"][data-part="next-trigger"][data-disabled],
[data-scope="pagination"][data-part="first-trigger"][data-disabled],
[data-scope="pagination"][data-part="last-trigger"][data-disabled] {
color: #9ca3af;
pointer-events: none;
}
[data-scope="pagination"][data-part="ellipsis"] {
color: #9ca3af;
}Demo
枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。
Features
- ページ送り。Root / Item / Ellipsis / PrevTrigger / NextTrigger / FirstTrigger / LastTrigger の 7 anatomy パーツを持つ(pagination.rs モジュール doc、FirstTrigger/LastTrigger はイシュー #1655 で ark-ui との突合により追加)。
- page_range は総件数・ページサイズ・現在ページ・sibling/boundary 件数から省略記号を含むページ列を O(boundary_count + sibling_count) で決定的に導出する純粋関数(total_pages を全列挙しないため巨大 count 入力でも有界、DoS 対策)。
- Button(クリックで dispatch する SPA 向け)/ Link(href 起点の SSR・SEO 向け)の 2 つの ItemMode に両対応する。
- data-state を持たない(連続的なページ位置を扱うため)。現在ページは item の aria-current="page"/data-selected、端到達は prev_trigger/next_trigger/first_trigger/last_trigger の disabled/data-disabled で表現する。
- item は data-index(ページ番号の 10 進数文字列)を常時出力する(ark-ui の Item Data Attributes 表準拠、イシュー #1655 で追加)。
- 呼び出し側 attrs によるフレームワーク固定キー(data-selected/data-index/aria-current/href/type/disabled/aria-disabled/data-disabled/aria-hidden)の偽装は各パーツが fail-closed に除去する(イシュー #1655)。
Anatomy
root
first-trigger
prev-trigger
item
ellipsis
next-trigger
last-triggerAPI Reference
Arguments
| Name | Type | Default | Description |
|---|---|---|---|
root(aria_label) | &str | — | root(nav)へ付与する aria-label。既定値相当は呼び出し側が明示指定する契約。 |
item(mode) | ItemMode | — | Button(button type="button")/ Link(a href)のいずれで描画するかを選ぶ。 |
item(page) | u64 | — | ページ番号。data-index として 10 進数文字列で出力される(イシュー #1655)。 |
item(current) | bool | — | true のとき aria-current="page"+data-selected を付与する。 |
item(disabled) | bool | — | Button モードのみネイティブ disabled を出力。両モード共通で aria-disabled/data-disabled を出力する。 |
first_trigger(disabled) / last_trigger(disabled) | bool | — | 先頭・末尾ページへ移動するトリガー(イシュー #1655 で新設)。prev_trigger/next_trigger と同じ disabled 契約。 |
Data Attributes
| Part | Attribute | Observed Values |
|---|---|---|
first-trigger | data-disabled | (値なし) |
item | data-index | 1, 2, 3, 500 |
item | data-selected | (値なし) |
prev-trigger | data-disabled | (値なし) |
Examples
ItemMode::Link のみで構成した SSR/SEO 向けページ送り
Root / FirstTrigger / PrevTrigger / Item / NextTrigger / LastTrigger を全て ItemMode::Link に統一し、href 遷移によるページ送りを実演します。
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
| Tab / Shift+Tab | ネイティブのフォーカス移動(各パーツはネイティブ <button>/<a> のため roving tabindex 等の独自実装は持たない、ark-ui と同じ契約)。 |
| Enter / Space | Button モードの item/トリガーをクリックと同じ効果で発火する(ネイティブ <button> の既定動作)。 |
| Enter | Link モードの item/トリガーで href へ遷移する(ネイティブ <a> の既定動作)。 |
WAI-ARIA
| Attribute | Description |
|---|---|
| aria-current="page" / data-selected | item に付与(current が true のときのみ)。 |
| data-index | item に常時付与(ページ番号の 10 進数文字列、イシュー #1655)。 |
| aria-hidden="true" | ellipsis に固定付与。 |
| aria-disabled | item/prev-trigger/next-trigger/first-trigger/last-trigger に付与(disabled が true のときのみ)。Button モードのみ併せてネイティブ disabled を出力する。 |
| aria-label | root は必須引数として供給。item/トリガーでは予約キーに含めず、呼び出し側が "page N" 相当のローカライズ文字列を attrs 経由で任意に供給できる(zag の translations 相当、イシュー #1655)。 |