<script setup>
import { Pagination } from "@dicehub/kappa/components/pagination";
</script>
<template>
<Pagination.Root :count="120" :default-page="4" aria-label="Results pages">
<Pagination.Context v-slot="pagination">
<span>Showing {{ pagination.pageRange.start + 1 }}–{{ pagination.pageRange.end }} of 120</span>
</Pagination.Context>
<Pagination.Controls />
</Pagination.Root>
</template>Installation
Pagination is part of the main Kappa package. Ark UI owns page calculation, current-page state, link or button semantics, and boundary disabling.
Barrel
import { Pagination } from "@dicehub/kappa";Granular
import { Pagination } from "@dicehub/kappa/components/pagination";Usage
Compose the root with a native list, boundary triggers, and a renderless Context. Context supplies page and ellipsis entries so the list stays synchronized with the Ark machine.
<script setup>
import { Pagination } from "@dicehub/kappa/components/pagination";
</script>
<template>
<Pagination.Root :count="42" :default-page-size="10" aria-label="Search results">
<ul>
<li><Pagination.PrevTrigger aria-label="Previous results" /></li>
<Pagination.Context v-slot="pagination">
<template v-for="(page, index) in pagination.pages" :key="page.type === 'page' ? page.value : 'ellipsis-' + index">
<li v-if="page.type === 'page'">
<Pagination.Item type="page" :value="page.value">{{ page.value }}</Pagination.Item>
</li>
<li v-else><Pagination.Ellipsis :index="index" /></li>
</template>
</Pagination.Context>
<li><Pagination.NextTrigger aria-label="Next results" /></li>
</ul>
</Pagination.Root>
</template>Use type="link" with getPageUrl and as-child anchors when pages need stable URLs. Keep router-specific behavior in the URL callback or an application adapter.
Composition
Pagination.Root <nav>
├── Pagination.Controls (compact alternative)
├── Pagination.FirstTrigger
├── Pagination.PrevTrigger
├── Pagination.Context (renderless)
│ ├── Pagination.Item
│ └── Pagination.Ellipsis
├── Pagination.NextTrigger
└── Pagination.LastTrigger<Pagination.Root>
├── Pagination.FirstTrigger
├── Pagination.PrevTrigger
├── Pagination.Context
│ ├── Pagination.Item
│ └── Pagination.Ellipsis
├── Pagination.NextTrigger
└── Pagination.LastTrigger
</Pagination.Root>Pagination.Root renders the navigation landmark. The native list belongs in the root slot. Pagination.Context exposes pages, where each entry is a page or an ellipsis.
Kappa adds compact token-based controls and focus states. Ark UI remains the behavior authority for controlled and uncontrolled pages, link generation, accessible labels, current-page state, and disabled boundary triggers.
Pagination.Controls groups single Previous/Next arrows, double First/Last arrows, and a page input in a compact layout. Use it inside a button-mode root. The input saves on Enter or blur, clamps to the page range, and restores invalid text; Escape restores the current page. Use the individual parts below for numbered pages or links.
Examples
Text Labels
Use showLabels for short First, Previous, Next, and Last labels. Accessible names keep the word page. Custom root translations are preserved; individual triggers accept a label prop for custom visible text.
<template>
<Pagination.Root :count="120" :default-page="4" aria-label="Labeled pages">
<Pagination.Controls show-labels />
</Pagination.Root>
</template>Simple Controls
Use only previous and next arrows when direct page entry is not needed.
<template>
<Pagination.Root :count="120" :default-page="4" aria-label="Simple pages">
<Pagination.Controls controls="simple" />
</Pagination.Root>
</template>Right-to-left
DirectionProvider mirrors the arrows and control order for right-to-left layouts. Set pageLabel and root translations for your language.
<script setup>
import { DirectionProvider } from "@dicehub/kappa/components/direction-provider";
import { Pagination } from "@dicehub/kappa/components/pagination";
</script>
<template>
<DirectionProvider locale="ar">
<Pagination.Root :count="120" :default-page="4" aria-label="RTL pages">
<Pagination.Controls page-label="رقم الصفحة" />
</Pagination.Root>
</DirectionProvider>
</template>Link Mode
Use link mode when each page should be addressable and support normal browser navigation.
<script setup>
import { Pagination } from "@dicehub/kappa/components/pagination";
const getPageUrl = ({ page, pageSize }) => "/runs?page=" + page + "&pageSize=" + pageSize;
</script>
<template>
<Pagination.Root
:count="250"
type="link"
:get-page-url="getPageUrl"
aria-label="Run history pages"
>
<ul>
<li><Pagination.PrevTrigger as-child><a><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="15 18 9 12 15 6" /></svg></a></Pagination.PrevTrigger></li>
<Pagination.Context v-slot="pagination">
<template v-for="(page, index) in pagination.pages" :key="page.type === 'page' ? page.value : 'ellipsis-' + index">
<li v-if="page.type === 'page'">
<Pagination.Item type="page" :value="page.value" as-child><a>{{ page.value }}</a></Pagination.Item>
</li>
<li v-else><Pagination.Ellipsis :index="index" /></li>
</template>
</Pagination.Context>
<li><Pagination.NextTrigger as-child><a><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="9 18 15 12 9 6" /></svg></a></Pagination.NextTrigger></li>
</ul>
</Pagination.Root>
</template>Controlled
Use v-model:page when the current page belongs to application state or a router adapter.
<script setup>
import { Pagination } from "@dicehub/kappa/components/pagination";
import { ref } from "vue";
const page = ref(3);
</script>
<template>
<Pagination.Root v-model:page="page" :count="80" aria-label="Jobs pages">
<Pagination.Controls />
</Pagination.Root>
<output aria-live="polite">Page {{ page }}</output>
</template>Sibling Pages
Increase siblingCount when users need more nearby page landmarks in a large result set.
<template>
<Pagination.Root :count="500" :sibling-count="2" aria-label="Large result set">
<!-- Compose the same Context and navigation triggers as the usage example. -->
</Pagination.Root>
</template>Boundary States
Ark disables first and previous at page one, and next and last at the final page.
<template>
<Pagination.Root :count="80" :default-page="1" aria-label="Boundary states">
<ul>
<li><Pagination.FirstTrigger /></li>
<li><Pagination.PrevTrigger /></li>
<!-- Page items from Pagination.Context go here. -->
<li><Pagination.NextTrigger /></li>
<li><Pagination.LastTrigger /></li>
</ul>
</Pagination.Root>
</template>Accessibility
- Give the root a concise accessible name with
aria-labeloraria-labelledby. - Ark marks the active item with
aria-current="page"and disables triggers at the first and last pages. - Default arrows are decorative; Ark supplies each trigger's accessible name. Customize names with root translations or an explicit aria-label.
- Link mode preserves normal browser navigation. Button mode is useful when page state is controlled by an application view.
- Focus-visible, forced-colors, reduced-motion, and narrow-layout styles remain distinct.
Keyboard Support
| Key | Behavior |
|---|---|
Tab | Moves to the next enabled pagination control. |
Enter / Space | Activates a focused button trigger or page item. |
Shift + Tab | Moves to the previous enabled pagination control. |
API Reference
Pagination.Root
| Prop | Type | Default | Description |
|---|---|---|---|
count | number | 0 | Total number of data items used to calculate total pages. |
page / defaultPage | number | 1 | Controlled or initial active page. |
pageSize / defaultPageSize | number | 10 | Controlled or initial number of data items per page. |
siblingCount | number | 1 | Number of page items shown beside the active page. |
type | "button" | "link" | "button" | Chooses native button triggers or links generated with getPageUrl. |
getPageUrl | (details) => string | — | Returns href values when type is link. Details include page and pageSize. |
translations | IntlTranslations | Ark defaults | Customizes the root, trigger, and page-item accessible names. |
id / ids / asChild | string / partial ID map / boolean | generated / false | Overrides machine IDs or composes the root with its direct child. |
Pagination.Item
| Prop | Type | Default | Description |
|---|---|---|---|
type | "page" | required | Identifies this part as a page item for the Ark machine. |
value | number | required | Page number represented by the item. |
disabled / asChild | boolean / boolean | false / false | Disables the native item or composes it with a direct child. |
Pagination.Controls
| Prop | Type | Default | Description |
|---|---|---|---|
controls | "full" | "simple" | "full" | Full: first, previous, page input, next, last. Simple: previous and next only. Use inside a button-mode Root. |
showLabels | boolean | false | Shows First, Previous, Next, and Last beside the arrows. Custom root translations are preserved; accessible names stay unchanged. |
pageLabel | string | "Page number" | Accessible name of the page input; localize with your application. |
Navigation Triggers
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Optional visible text beside the default single or double arrow. The default slot replaces the icon and label together. |
asChild | boolean | false | Compose a custom element, such as an anchor. Supply its content through the default slot. |
Parts
| Part | Element | Description |
|---|---|---|
Pagination.Controls | div | Compact grouped arrow controls with a page input; composes the existing Ark-backed triggers. |
Pagination.Root | nav | Owns page state, page range calculation, and pagination semantics. |
Pagination.RootProvider | nav | Provides an externally created Ark pagination machine. |
Pagination.FirstTrigger / PrevTrigger | button | a | Moves to the first page or previous page; Ark disables them at the lower boundary. |
Pagination.Item | button | a | Selects a page and exposes the current page through aria-current. |
Pagination.Ellipsis | span | Marks an omitted page range. The part is non-interactive and aria-hidden by Ark. |
Pagination.NextTrigger / LastTrigger | button | a | Moves to the next page or last page; Ark disables them at the upper boundary. |
Pagination.Context | renderless | Exposes pages, totalPages, pageRange, and navigation methods to a slot. |
Events
| Event | Payload | Description |
|---|---|---|
update:page | number | Updates v-model:page after a page change. |
pageChange | PaginationPageChangeDetails | Reports page and pageSize after a page change. |
update:pageSize | number | Updates v-model:pageSize after the page size changes. |
pageSizeChange | PaginationPageSizeChangeDetails | Reports the new pageSize. |
Slots
| Slot | Description |
|---|---|
Root.default | Native list markup and Pagination navigation parts. |
RootProvider.default | Native list markup and parts backed by an external machine. |
Item / trigger.default | Custom page or trigger content. Triggers have default arrows; label adds optional text. |
Context.default | Receives the renderless pagination API, including pages and totalPages. |
Data Attributes
| Attribute | Value | Description |
|---|---|---|
data-slot | "pagination" | "pagination-item" | "pagination-ellipsis" | "pagination-*-trigger" | Identifies Kappa root and navigation parts. |
data-scope / data-part | "pagination" / Ark anatomy part | Ark UI machine and anatomy markers. |
aria-current | "page" on current item | Marks the active page for assistive technology and styling. |
data-disabled / disabled | present at boundaries | Exposes Ark disabled trigger state at the first and last pages. |
Exports
| Export | Description |
|---|---|
PaginationControls / PaginationControlsProps | Compact control group and its public options. |
Pagination | Compound Ark-backed pagination component. |
PaginationRoot / RootProvider / Item / Ellipsis | Named root, provider, page-item, and ellipsis parts. |
PaginationFirstTrigger / PrevTrigger / NextTrigger / LastTrigger | Named boundary-navigation trigger parts. |
PaginationContext | Renderless page-range context part. |
PaginationProps / PaginationRootProps / PaginationEmits | Public root props and event contracts for button or link pagination. |
PaginationItemProps / PaginationEllipsisProps / Pagination*TriggerProps | Public part props for page items, ellipsis, and boundary triggers. |
Pagination*Slots | Public default and renderless Context slot contracts. |
usePagination / usePaginationContext / paginationAnatomy | Ark UI composition exports. |