Phi
Pagination
@dicehub/phiv1.0.0-beta.1

Pagination

A page navigation component for navigating through paginated content.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);

function setPage(nextPage: number) {
  page.value = nextPage;
}
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="10" :total-count="100" />
</template>

Installation

Barrel

import { Pagination } from "@dicehub/phi";

Granular

import { Pagination } from "@dicehub/phi/components/pagination";

Usage

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);

function setPage(nextPage: number) {
  page.value = nextPage;
}
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="10" :total-count="100" />
</template>

Examples

Full Controls (Default)

The default pagination includes first, previous, page input, next, and last buttons.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const setPage = (nextPage: number) => { page.value = nextPage; };
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="10" :total-count="100" controls="full" />
</template>

Simple Controls

Use controls="simple" for a minimal pagination with only previous and next buttons.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const setPage = (nextPage: number) => { page.value = nextPage; };
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="10" :total-count="100" controls="simple" />
</template>

Unknown Totals

Use `hasNextPage` for cursor-based APIs that report whether another result set exists but do not report a total. Pagination then shows sequential controls only.

<script setup lang="ts">
import { computed, ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const hasNextPage = computed(() => page.value < 3);
const setPage = (nextPage: number) => { page.value = nextPage; };
</script>

<template>
  <Pagination
    :page="page"
    :set-page="setPage"
    :has-next-page="hasNextPage"
    :text="() => `Page ${page}`"
  />
</template>

Mid-Page State

Pagination in the middle of a dataset with all navigation enabled.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(5);
const setPage = (nextPage: number) => { page.value = nextPage; };
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="10" :total-count="100" />
</template>

Large Dataset

Pagination handles large datasets with many pages.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const setPage = (nextPage: number) => { page.value = nextPage; };
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="25" :total-count="1250" />
</template>

Custom Text

You can set custom pagination text.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination, type PaginationInfoDetails } from "@dicehub/phi/components/pagination";

const page = ref(1);
const setPage = (nextPage: number) => { page.value = nextPage; };
const text = ({ perPage }: PaginationInfoDetails) => `Page ${page.value} - showing ${perPage} per page`;
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="25" :total-count="100" :text="text" />
</template>

Compound Components

For more control over layout and features, compose Pagination.Info,Pagination.PageSize, Pagination.Controls, andPagination.Separator in any order.

Page Size Selector

Add a dropdown to let users select the number of items per page.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const perPage = ref(25);
const setPage = (nextPage: number) => { page.value = nextPage; };
const setPageSize = (size: number) => {
  perPage.value = size;
  page.value = 1;
};
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="perPage" :total-count="500">
    <Pagination.Info />
    <Pagination.Separator />
    <Pagination.PageSize :value="perPage" @change="setPageSize" />
    <Pagination.Controls />
  </Pagination>
</template>

Custom Page Size Options

Customize the available page size options. Defaults to [25, 50, 100, 250].

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const perPage = ref(10);
const setPage = (nextPage: number) => { page.value = nextPage; };
const setPageSize = (size: number) => {
  perPage.value = size;
  page.value = 1;
};
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="perPage" :total-count="200">
    <Pagination.Info />
    <Pagination.Separator />
    <Pagination.PageSize :value="perPage" :options="[10, 20, 50]" @change="setPageSize" />
    <Pagination.Controls />
  </Pagination>
</template>

Custom Info Text

Use a scoped slot to customize the info text.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const perPage = 25;
const setPage = (nextPage: number) => { page.value = nextPage; };
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="perPage" :total-count="100">
    <Pagination.Info v-slot="{ page: currentPage, totalCount }">
      Page {{ currentPage }} of {{ Math.ceil((totalCount ?? 1) / perPage) }}
    </Pagination.Info>
    <Pagination.Controls />
  </Pagination>
</template>

Custom Layout

Arrange components in any order. Here the page size selector is on the right.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const perPage = ref(25);
const setPage = (nextPage: number) => { page.value = nextPage; };
const setPageSize = (size: number) => {
  perPage.value = size;
  page.value = 1;
};
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="perPage" :total-count="500" class-name="custom-pagination">
    <Pagination.Info />
    <div class="custom-pagination__right">
      <Pagination.Controls />
      <Pagination.Separator />
      <Pagination.PageSize :value="perPage" @change="setPageSize" />
    </div>
  </Pagination>
</template>

Use page-selector="dropdown" on Pagination.Controls to render a dropdown select instead of a text input.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination } from "@dicehub/phi/components/pagination";

const page = ref(1);
const perPage = ref(25);
const setPage = (nextPage: number) => { page.value = nextPage; };
const setPageSize = (size: number) => {
  perPage.value = size;
  page.value = 1;
};
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="perPage" :total-count="500">
    <Pagination.Info />
    <Pagination.Separator />
    <Pagination.PageSize :value="perPage" @change="setPageSize" />
    <Pagination.Controls page-selector="dropdown" />
  </Pagination>
</template>

Internationalization

Use the labels prop to customize aria labels. Visible text is customized with Pagination.Info scoped slots.

<script setup lang="ts">
import { ref } from "vue";
import { Pagination, type PaginationLabels } from "@dicehub/phi/components/pagination";

const page = ref(1);
const setPage = (nextPage: number) => { page.value = nextPage; };
const labels: PaginationLabels = {
  firstPage: "Premiere page",
  previousPage: "Page precedente",
  nextPage: "Page suivante",
  lastPage: "Derniere page",
  pageNumber: "Numero de page",
  pageSize: "Taille de page",
};
</script>

<template>
  <Pagination :page="page" :set-page="setPage" :per-page="10" :total-count="100" :labels="labels">
    <Pagination.Info v-slot="{ pageShowingRange, totalCount }">
      Affichage de <span class="tabular-nums">{{ pageShowingRange }}</span> sur
      <span class="tabular-nums">{{ totalCount }}</span>
    </Pagination.Info>
    <Pagination.Controls />
  </Pagination>
</template>

API Reference

PropTypeDefaultDescription
setPage(page: number) => void-Callback for controlled page changes.
v-model:pagenumber-Vue page binding alternative to setPage.
@page-change(page: number) => void-Emitted when the current page changes.
pagenumber1Current page number (1-indexed).
perPagenumber-Number of items displayed per page.
totalCountnumber-Total number of items across all pages.
hasNextPageboolean-Whether another page exists when totalCount is unknown. Unknown totals use sequential controls only.
classNamestring-Additional CSS classes for the container.
labelsPaginationLabels-Labels for aria labels. Visible text is customized through text or scoped slots.
controls"full" | "simple""full"Legacy default controls variant when no compound children are provided.
text(details: PaginationInfoDetails) => VNodeChild-Legacy custom info text renderer.

Compound API

ComponentProp / EventTypeDefaultDescription
Pagination.InfoclassNamestring-Additional CSS classes for the info text.
Pagination.Infodefault slotPaginationInfoDetails-Scoped slot for custom info text.
Pagination.PageSizevalue*number-Current page size value.
Pagination.PageSizev-model:valuenumber-Vue binding for the current page size value.
Pagination.PageSize@change(size: number) => void-Emitted when the page size changes.
Pagination.PageSizeoptionsnumber[][25, 50, 100, 250]Available page size options.
Pagination.PageSizelabelstring"Per page:"Label text shown before the selector.
Pagination.PageSizelabel slot--Custom label content shown before the selector.
Pagination.PageSizeclassNamestring-Additional CSS classes for the page size wrapper.
Pagination.Controlscontrols"full" | "simple""full"Controls variant.
Pagination.ControlspageSelector"input" | "dropdown""input"How the page selector is rendered in full mode.
Pagination.ControlsclassNamestring-Additional CSS classes for the controls wrapper.
Pagination.SeparatorclassNamestring-Additional CSS classes for the separator.