Navigation
SlidePagination
Active indicator slides between pages
detent-slide-pagination
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 2
- Wave
- phase-2-navigation
- Group
- Navigation
5.5 KB gzip for the class module · inlines the shared spring
Variants
Recorded states
disabledrecorded state; no setterdark themerecorded state; no setteractiverecorded state; no setter
Usage
Import
import '/components/slide-pagination/define.js';
// or register it yourself
import { DetentSlidePagination } from '/components/slide-pagination/slide-pagination.js';
Attributes
default-pagepagepage-countshow-controlssibling-count
Properties
pageCountpagedefaultPagesiblingCountshowControlsonChange
Slots
No slots are recorded for this component.
Events
detent-change— { page: number }
Example
Runnable example: site/examples/slide-pagination.ts. The snippet below is generated from the catalogued attributes.
<detent-slide-pagination
default-page="1"
page
page-count
show-controls
sibling-count="1"
></detent-slide-pagination>
Property-only values
const element = document.querySelector('detent-slide-pagination');
if (element !== null) {
// onChange: (page: number) => void
element.onChange = () => {};
}
Source
The pinned upstream source for this row:
src/components/ui/SlidePagination.tsxsha256 7a619cdedb93…
Native files
The native module and its artifacts:
src/components/slide-pagination/slide-pagination.tssrc/components/slide-pagination/styles.csssrc/components/slide-pagination/define.tsdocs/components/slide-pagination.mdsite/examples/slide-pagination.tstests/browser/slide-pagination.spec.tsevidence/components/slide-pagination.md
API
Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.
Attributes
| Attribute | Property | Type | Default | Notes |
|---|---|---|---|---|
default-page | defaultPage | number | 1 | Kebab-case attribute; camelCase property. |
page | page | number | undefined | Kebab-case attribute; camelCase property. |
page-count | pageCount | number | undefined | Kebab-case attribute; camelCase property. |
show-controls | showControls | boolean | true | Presence semantics: present means true, absent means false. |
sibling-count | siblingCount | number | 1 | Kebab-case attribute; camelCase property. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
pageCount | number | undefined | Property-only: assign from script; not accepted as an attribute. |
page | number | undefined | Property-only: assign from script; not accepted as an attribute. |
defaultPage | number | 1 | Property-only: assign from script; not accepted as an attribute. |
siblingCount | number | 1 | Property-only: assign from script; not accepted as an attribute. |
showControls | boolean | true | Property-only: assign from script; not accepted as an attribute. |
onChange | (page: number) => void | undefined | Property-only: assign from script; not accepted as an attribute. |
Events
| Event | Upstream prop | Payload type | Notes |
|---|---|---|---|
detent-change | onChange | (page: number) => void | Composed, bubbles; fires only for a user action. |
Slots
No slots are recorded for this component.
CSS customisation
- React callback props become typed composed CustomEvents; programmatic state assignment emits none.
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- The pill travels on two axes with the recorded springSnappy (380/30/0.5) via the shared helper instead of `layoutId`.
- Upstream's docstring says items collapse and expand via AnimatePresence, but the pinned source imports no AnimatePresence and renders the windowed range without enter or exit motion (an upstream documentation defect). The native re-render matches that code: items do not animate in and out, and there is nothing to restore.
- `show-controls` resolves true and is reflected, and the property is the opt-out (PC-3.2), so `show-controls="false"` is still true.
- The requested page is stored unclamped and re-clamped when `page-count` changes, so a pre-definition `page` is never collapsed to 1.
- Page changes are announced through one visually hidden `role="status"` region ("Page N of M", "No pages" when empty) - an upstream gap (PC-12.5).
- Disabled controls keep `opacity: 1` and a muted colour instead of upstream `opacity-30`, which faded the icon below 3:1; lucide chevrons become a local decorative SVG and `className` maps to `part="nav"`.
What it does
A pagination control whose active pill travels between page buttons, with a windowed range (1 … 4 5 6 … 10), optional previous/next controls disabled at the boundaries, and a live announcement of the new page.
Upstream behaviour
- Active background uses framer-motion shared layoutId for visible travel between pages
- Snappy spring (springSnappy) drives the indicator for a precise, physical feel
- Configurable siblingCount for windowed page ranges with ellipsis
- Optional previous / next controls; disabled at boundaries
- Light/dark theme aware — works in both palettes
Differences from upstream
- React callback props become typed composed CustomEvents; programmatic state assignment emits none.
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- The pill travels on two axes with the recorded springSnappy (380/30/0.5) via the shared helper instead of `layoutId`.
- Upstream's docstring says items collapse and expand via AnimatePresence, but the pinned source imports no AnimatePresence and renders the windowed range without enter or exit motion (an upstream documentation defect). The native re-render matches that code: items do not animate in and out, and there is nothing to restore.
- `show-controls` resolves true and is reflected, and the property is the opt-out (PC-3.2), so `show-controls="false"` is still true.
- The requested page is stored unclamped and re-clamped when `page-count` changes, so a pre-definition `page` is never collapsed to 1.
- Page changes are announced through one visually hidden `role="status"` region ("Page N of M", "No pages" when empty) - an upstream gap (PC-12.5).
- Disabled controls keep `opacity: 1` and a muted colour instead of upstream `opacity-30`, which faded the icon below 3:1; lucide chevrons become a local decorative SVG and `className` maps to `part="nav"`.