Pagination Component
The Pagination
component is a flexible pagination component built with Vue 3. It provides a user-friendly interface for navigating through paginated data with customizable per-page options.
Basic Usage
Import and use Pagination
in your Vue components:
vue
<template>
<Pagination
:pagination="paginationData"
@pagination:change="handlePageChange"
@pagination:per-page="handlePerPageChange"
/>
</template>
<script setup>
import { ref } from 'vue';
import { Pagination } from '@robuust-digital/vue-components/core';
const paginationData = ref({
current_page: 1,
from: 1,
to: 10,
total: 50,
per_page: 10,
links: [
{ url: null, label: '«', active: false },
{ url: '1', label: '1', active: true },
{ url: '2', label: '2', active: false },
{ url: '3', label: '3', active: false },
{ url: '...', label: '...', active: false },
{ url: '5', label: '5', active: false },
{ url: '2', label: '»', active: false }
]
});
const handlePageChange = (url) => {
// Handle page change
};
const handlePerPageChange = (perPage) => {
// Handle items per page change
};
</script>
1 - 10 of 50
Props
Prop | Type | Default | Description |
---|---|---|---|
pagination | Object | Required | Pagination data object containing current state |
perPage | Number | 10 | Number of items to display per page |
perPageLabel | String | 'per page' | Label for the items per page dropdown |
perPageOptions | Array | [10, 20, 50] | Available options for items per page |
fromLabel | String | 'of' | Label used in "X - Y of Z" text |
Pagination Object Structure
The pagination object should have the following structure:
javascript
{
current_page: number, // Current active page
from: number, // First item number on current page
to: number, // Last item number on current page
total: number, // Total number of items
per_page: number, // Items per page
links: [ // Array of pagination links
{
url: string|null, // URL for the link (null for disabled links)
label: string, // Label to display (can be number or symbol)
active: boolean // Whether this is the current active page
}
]
}
Slots
Per Page Slot
Customize the items per page dropdown:
vue
<template>
<Pagination :pagination="paginationData">
<template #per-page="{ perPage }">
...
</template>
</Pagination>
</template>
Info Slot
Customize the pagination info text:
vue
<template>
<Pagination :pagination="paginationData">
<template #info="{ from, to, total }">
{{ from }} - {{ to }} of {{ total }}
</template>
</Pagination>
</template>
Events
Event | Arguments | Description |
---|---|---|
pagination:change | url | Emitted when page navigation is requested |
pagination:per-page | number | Emitted when items per page value changes |
Examples
Custom Labels and Options
vue
<template>
<Pagination
:pagination="paginationData"
:per-page-label="'items per page'"
:per-page-options="[5, 10, 25, 50]"
:from-label="'from'"
@pagination:change="handlePageChange"
@pagination:per-page="handlePerPageChange"
/>
</template>
11 - 20 from 100
Integration with DataTable
The Pagination component is designed to work seamlessly with the DataTable component:
vue
<template>
<div>
<DataTable
:headers="headers"
:items="items"
:pagination="paginationData"
@pagination:change="handlePageChange"
@pagination:per-page="handlePerPageChange"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { DataTable, Pagination } from '@robuust-digital/vue-components/core';
const paginationData = ref({
current_page: 1,
from: 1,
to: 10,
total: 50,
per_page: 10,
links: [/* ... */]
});
const handlePageChange = async (url) => {
// Fetch new page data
const response = await fetchData(url);
items.value = response.data;
paginationData.value = response.pagination;
};
const handlePerPageChange = async (perPage) => {
// Update items per page and fetch new data
const response = await fetchData(`/api/items?per_page=${perPage}`);
items.value = response.data;
paginationData.value = response.pagination;
};
</script>
CSS Customization ⚡️
To customize the pagination
styles global
css
:root {
/* Available variables */
--rvc-pagination-transition-duration: var(--rvc-base-transition-duration);
--rvc-pagination-transition-timing-function: var(--rvc-base-transition-timing-function);
--rvc-pagination-border-radius: var(--radius-md);
--rvc-pagination-size: calc(var(--spacing) * 6);
--rvc-pagination-font-size: var(--text-sm);
--rvc-pagination-font-weight: var(--font-weight-normal);
--rvc-pagination-font-weight-active: var(--font-weight-semibold);
--rvc-pagination-color: var(--color-slate-600);
--rvc-pagination-color-active: var(--color-slate-800);
--rvc-pagination-bg-color: transparent;
--rvc-pagination-bg-color-hover: var(--color-slate-100);
--rvc-pagination-info-color: var(--color-slate-400);
--rvc-pagination-info-font-size: var(--text-sm);
}