OPagination
OPagination provides controlled page navigation for known and unknown result counts, with compact and Laravel-compatible layouts.
Usage
Step by step
- Import
OPaginationfrom theooko-ui/paginationpublic subpath. - Bind the current page with
v-modeland providepageCountwhen the result total is known. - Use the
laravelpreset 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
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | number | undefined | Controlled current page, starting at one. |
pageCount | number | undefined | Total number of pages when the data source provides it. |
hasNextPage | boolean | false | Enables the next control when the total page count is unknown. |
preset | OPaginationPreset | "compact" | Selects the compact layout or Laravel-compatible page window. |
onEachSide | number | 3 | Number of links on each side of the current page in the Laravel preset. |
disabled | boolean | false | Prevents every page change. |
ariaLabel | string | "Pagination" | Accessible name for the pagination navigation. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | number | Requests a new controlled page. |
Slots
| Slot | Props | Description |
|---|---|---|
| none | none | No slots are exposed. |
Related types
| Type | Definition |
|---|---|
OPaginationPreset | type OPaginationPreset = "compact" | "laravel"; |
CSS custom properties
| Custom property | Default | Description |
|---|---|---|
--o-pagination-gap | var(--o-space-0-5) | Sets the space between pagination items. |
--o-pagination-control-size | 2rem | Sets the minimum square size of page controls. |
--o-pagination-track-background | var(--o-background-track) | Sets the background of the track that groups the pagination items. |
--o-pagination-track-border | 1px solid var(--o-border-color-subtle) | Sets the border shorthand of the track that groups the pagination items. |
--o-pagination-track-padding | var(--o-space-1) | Sets the space between the track edge and its items. |
--o-pagination-current-background | var(--o-background-track-thumb) | Sets the background of the current page, raised above the track. |
--o-pagination-control-padding-inline | var(--o-space-3) | Sets the horizontal padding of previous and next controls. |
--o-pagination-border-radius | var(--o-radius-round) | Sets the pagination control corner radius. |
Override example
: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.