Skip to content

Pagination ​

Moves between the pages of a long list, such as quotes, orders or customers.

vue
<script setup lang="ts">
import { FsPagination } from '@fivespark/ui'
import { ref } from 'vue'

const pagina = ref(5)
</script>

<template>
  <FsPagination v-model:page="pagina" :pages="12" class="w-full" />
</template>

Usage ​

vue
<script setup lang="ts">
import { FsPagination } from '@fivespark/ui'
import { ref } from 'vue'

const pagina = ref(1)
</script>

<template>
  <FsPagination v-model:page="pagina" :pages="12" />
</template>

pages is the number of pages, not of items; work it out from your list. Nothing renders when there is one page or none. Up to seven pages are shown as numbers; with more, seven slots hold the first and last page, the current page with its neighbours and an ellipsis, and in a narrow container the numbers give way to "Pagina 5 van 12". For loading more by scrolling, or jumping to any page, this is not the component.

Examples ​

Give to a function that returns the address of a page and every control becomes a link, so pages can be bookmarked and opened in a new tab. Keep the list's filters and sorting in the address.

vue
<script setup lang="ts">
import { FsPagination } from '@fivespark/ui'

const naar = (pagina: number) => `/offertes?pagina=${pagina}`
</script>

<template>
  <FsPagination :page="3" :pages="8" :to="naar" class="w-full" />
</template>

Beside a range ​

The pager has no range text of its own. Write it next to the pager, where the list shows it.

vue
<script setup lang="ts">
import { FsPagination } from '@fivespark/ui'
import { computed, ref } from 'vue'

const pagina = ref(5)
const totaal = 300
const perPagina = 25
const van = computed(() => (pagina.value - 1) * perPagina + 1)
const tot = computed(() => Math.min(pagina.value * perPagina, totaal))
</script>

<template>
  <div class="flex w-full flex-wrap items-center justify-between gap-4">
    <p class="type-body text-text-muted">Offerte {{ van }}–{{ tot }} van {{ totaal }}</p>
    <FsPagination v-model:page="pagina" :pages="Math.ceil(totaal / perPagina)" />
  </div>
</template>

Dense ​

vue
<script setup lang="ts">
import { FsPagination } from '@fivespark/ui'
import { ref } from 'vue'

const pagina = ref(2)
</script>

<template>
  <FsPagination v-model:page="pagina" :pages="6" size="dense" class="w-full" />
</template>

Naming a second pager ​

The landmark is called "Paginering". When a page has two lists, rename each with aria-label.

vue
<script setup lang="ts">
import { FsPagination } from '@fivespark/ui'
import { ref } from 'vue'

const pagina = ref(1)
</script>

<template>
  <FsPagination v-model:page="pagina" :pages="4" aria-label="Paginering orders" class="w-full" />
</template>

Keyboard ​

KeyDoes
Tab, Shift + TabMoves through previous, the page numbers and next
Enter, SpaceGoes to the page; Space only on buttons, not on links

API Reference ​

FsPagination ​

PropTypeDefaultDescription
pagenumberrequiredThe current page, from 1. Updated with `v-model:page` when there is no `to`.
pagesnumberrequiredHow many pages there are, not how many items. With one page or none, nothing is shown.
to((page: number) => string | object)Makes every control a link: the route or URL of a page, keeping the list's other query parameters.
size"default" | "dense""default"`default` is 36px high; `dense` is 32px, for tables and toolbars.
EventPayloadDescription
update:page[page: number]The page pressed, without `to`. Not emitted for the current page, nor for previous or next at the ends.