Skip to content

OPagination ​

OPagination provides controlled page navigation for known and unknown result counts, with compact and Laravel-compatible layouts.

Usage ​

Step by step ​

  1. Import OPagination from the ooko-ui/pagination public subpath.
  2. Bind the current page with v-model and provide pageCount when the result total is known.
  3. Use the laravel preset when people need direct numbered-page navigation; otherwise keep the compact default.

Example ​

The rendered example and its source come from the same Vue single-file component.

Interactive playground ​

Change the page, total-count availability, preset, page window, and disabled state. The preview updates immediately.

Props ​

PropTypeDefaultDescription
modelValuenumberundefinedControlled current page, starting at one.
pageCountnumberundefinedTotal number of pages when the data source provides it.
hasNextPagebooleanfalseEnables the next control when the total page count is unknown.
presetOPaginationPreset"compact"Selects the compact layout or Laravel-compatible page window.
onEachSidenumber3Number of links on each side of the current page in the Laravel preset.
disabledbooleanfalsePrevents every page change.
ariaLabelstring"Pagination"Accessible name for the pagination navigation.

Events ​

EventPayloadDescription
update:modelValuenumberRequests a new controlled page.

Slots ​

SlotPropsDescription
nonenoneNo slots are exposed.
TypeDefinition
OPaginationPresettype OPaginationPreset = "compact" | "laravel";

CSS custom properties ​

Custom propertyDefaultDescription
--o-pagination-gapvar(--o-space-0-5)Sets the space between pagination items.
--o-pagination-control-size2remSets the minimum square size of page controls.
--o-pagination-track-backgroundvar(--o-background-track)Sets the background of the track that groups the pagination items.
--o-pagination-track-border1px solid var(--o-border-color-subtle)Sets the border shorthand of the track that groups the pagination items.
--o-pagination-track-paddingvar(--o-space-1)Sets the space between the track edge and its items.
--o-pagination-current-backgroundvar(--o-background-track-thumb)Sets the background of the current page, raised above the track.
--o-pagination-control-padding-inlinevar(--o-space-3)Sets the horizontal padding of previous and next controls.
--o-pagination-border-radiusvar(--o-radius-round)Sets the pagination control corner radius.

Override example ​

css
:root {
  --o-pagination-gap: var(--o-space-2);
  --o-pagination-border-radius: var(--o-radius-round);
}

Accessibility ​

The root is a labelled navigation landmark. Previous, next, and numbered page controls are native buttons with visible keyboard focus. The current Laravel page uses aria-current="page", while the compact status is announced politely after controlled updates. Disabled and unavailable controls use native disabled semantics, and forced-colors mode preserves visible boundaries and current-page state.

Behavior and edge cases ​

The controls sit in one pill-shaped track, like OTabs, with the current page raised as a filled pill; the track hugs its items and scrolls horizontally when it does not fit. --o-pagination-track-* and --o-pagination-current-background tune it.

modelValue is controlled and starts at one; interactions request changes through update:modelValue. pageCount enables bounded numbered navigation. Without it, hasNextPage supports Laravel simplePaginate-style previous and next navigation. Invalid current and total values are normalized for display without mutating parent state.

The laravel preset follows Laravel's default page window: three links on each side of the current page, two links at each distant edge, and ellipses between separated ranges. onEachSide adjusts the sliding window like Laravel's method. Consumers bind paginator JSON fields such as current_page, last_page, and next_page_url; Ooko emits page numbers and does not navigate backend URLs.

The built-in preset is compact. Applications may configure defaultProps.OPagination.preset once through the full Ooko plugin; an instance-level preset always wins. OSelect deliberately pins its nested pagination to compact so application defaults cannot make its popup unexpectedly wider. Rendering is deterministic during SSR and hydration. The packer currently combines component CSS in style.css; JavaScript imports remain independently tree-shaken, but component-level CSS isolation is not claimed.