<script setup lang="ts">
import { PaginationEllipsis, PaginationFirst, PaginationLast, PaginationList, PaginationListItem, PaginationNext, PaginationPrev, PaginationRoot } from 'akar';
import './styles.css';
</script>
<template>
<div class="akar-demo akar-demo-Pagination">
<PaginationRoot
:total="100"
:sibling-count="1"
show-edges
:default-page="2"
>
<PaginationList
v-slot="{ items }"
class="PaginationList"
>
<PaginationFirst class="Button">
<PIcon name="i-lucide-chevrons-left" />
</PaginationFirst>
<PaginationPrev
:style="{ marginRight: 16 }"
class="Button"
>
<PIcon name="i-lucide-chevron-left" />
</PaginationPrev>
<template v-for="(page, index) in items">
<PaginationListItem
v-if="page.type === 'page'"
:key="index"
class="Button"
:value="page.value"
>
{{ page.value }}
</PaginationListItem>
<PaginationEllipsis
v-else
:key="page.type"
:index="index"
class="PaginationEllipsis"
>
…
</PaginationEllipsis>
</template>
<PaginationNext
:style="{ marginLeft: 16 }"
class="Button"
>
<PIcon name="i-lucide-chevron-right" />
</PaginationNext>
<PaginationLast class="Button">
<PIcon name="i-lucide-chevrons-right" />
</PaginationLast>
</PaginationList>
</PaginationRoot>
</div>
</template>@import '../_colors/black-alpha.css';
@import '../_colors/mauve.css';
@import '../_colors/grass.css';
@scope (.akar-demo-Pagination) {
/* reset */
button {
all: unset;
}
.Button {
text-align: center;
font-size: 15px;
line-height: 1;
align-items: center;
justify-content: center;
height: 2.25rem;
width: 2.25rem;
border-radius: 0.25rem;
transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
}
.Button:disabled {
opacity: 0.5;
}
.Button:hover {
background-color: rgb(255 255 255 / 0.1);
}
.Button[data-selected] {
background-color: rgb(255 255 255);
color: var(--black-a11);
}
.PaginationEllipsis {
display: flex;
height: 2.25rem;
width: 2.25rem;
align-items: center;
justify-content: center;
}
.PaginationList {
display: flex;
align-items: center;
gap: 0.25rem;
color: rgb(255 255 255);
}
}Features
- Enable quick access to first, or last page
- Enable to show edges constantly, or not
Installation
Install the component from your command line.
pnpm add akar
yarn add akar
npm install akar
bun add akar
Anatomy
Import all parts and piece them together.
<script setup>
import { PaginationEllipsis, PaginationFirst, PaginationLast, PaginationList, PaginationListItem, PaginationNext, PaginationPrev, PaginationRoot } from 'akar';
</script>
<template>
<PaginationRoot>
<PaginationList v-slot="{ items }">
<PaginationFirst />
<PaginationPrev />
<template v-for="(page, index) in items">
<PaginationListItem
v-if="page.type === 'page'"
:key="index"
/>
<PaginationEllipsis
v-else
:key="page.type"
:index="index"
>
…
</PaginationEllipsis>
</template>
<PaginationNext />
<PaginationLast />
</PaginationList>
</PaginationRoot>
</template>
API Reference
Root
Contains all of the paginations parts.
| Prop | Default | Type |
|---|---|---|
as | "nav" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
defaultPage | 1 | numberThe value of the page that should be active when initially rendered. Use when you do not need to control the value state. |
disabled | booleanWhen | |
itemsPerPage* | numberNumber of items per page | |
page | numberThe controlled value of the current page. Can be binded as | |
showEdges | false | booleanWhen |
siblingCount | 2 | numberNumber of sibling should be shown around the current page |
total | 0 | numberNumber of items in your list |
| Event | Payload |
|---|---|
update:page | value: numberEvent handler called when the page value changes |
| Slot (default) | Payload |
|---|---|
page | numberCurrent page state |
pageCount | numberNumber of pages |
List
Used to show the list of pages. It also makes pagination accessible to assistive technologies.
| Prop | Default | Type |
|---|---|---|
as | "div" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
| Slot (default) | Payload |
|---|---|
items | { type: "ellipsis"; } | { type: "page"; value: number; }Pages item |
Item
Used to render the button that changes the current page. Reka's docs called this part PaginationItem; in Akar v2.0.20 the export is PaginationListItem.
| Prop | Default | Type |
|---|---|---|
as | "button" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
value* | numberValue for the page |
| Data attribute | Value |
|---|---|
[data-selected] | "true" | "" |
[data-type] | "page" |
Ellipsis
Placeholder element when the list is long, and only a small amount of siblingCount was set and showEdges was set to true.
| Prop | Default | Type |
|---|---|---|
as | "div" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
| Data attribute | Value |
|---|---|
[data-type] | "ellipsis" |
First
Triggers that set the page value to 1
| Prop | Default | Type |
|---|---|---|
as | "button" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Prev
Triggers that set the page value to the previous page
| Prop | Default | Type |
|---|---|---|
as | "button" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Next
Triggers that set the page value to the next page
| Prop | Default | Type |
|---|---|---|
as | "button" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Last
Triggers that set the page value to the last page
| Prop | Default | Type |
|---|---|---|
as | "button" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Examples
With ellipsis
You can add PaginationEllipsis as a visual cue for more previous and after items.
<script setup lang="ts">
import { PaginationEllipsis, PaginationList, PaginationListItem, PaginationRoot } from 'akar'
</script>
<template>
<PaginationRoot>
<PaginationList v-slot="{ items }">
<template v-for="(page, index) in items">
<PaginationListItem
v-if="page.type === 'page'"
:key="index"
/>
<PaginationEllipsis
v-else
:key="page.type"
:index="index"
>
…
</PaginationEllipsis>
</template>
</PaginationList>
</PaginationRoot>
</template>
With first/last button
You can add PaginationFirst to allow user to navigate to first page, or PaginationLast to navigate to last page.
<script setup lang="ts">
import { PaginationFirst, PaginationLast, PaginationList, PaginationListItem, PaginationRoot } from 'akar'
</script>
<template>
<PaginationRoot>
<PaginationList>
<PaginationFirst />
...
<PaginationLast />
</PaginationList>
</PaginationRoot>
</template>
Control page programmatically
You can control the current page by passing it a reactive value.
<script setup lang="ts">
import { PaginationRoot } from 'akar'
import { ref } from 'vue'
import { Select } from './custom-select'
const currentPage = ref(1)
</script>
<template>
<Select v-model="currentPage" />
<PaginationRoot v-model:page="currentPage">
...
</PaginationRoot>
</template>
Keyboard Interactions
| Key | Description |
|---|---|
| Tab | Moves focus to the next focusable element. |
| Space | When focus is on a any trigger, trigger selected page or arrow navigation |
| Enter | When focus is on a any trigger, trigger selected page or arrow navigation |