jixoai-ui
the terminal design language
loading the style sheet…
Skip to content
docs · print medium: screen

registry:ui · NativeHTML

pagination — a nav of real links

W3C-first, composition-first: the nav landmark hosts composed parts — PaginationContent (ul), PaginationItem (li), PaginationLink (real hrefs or an onclick button, aria-current when active), Previous/Next at the edges. The page-window math lives in the exported pure helper pageRange with its current/total/siblings options: sticky edges, siblings around the current page, and two ellipsis TOKENS the consumer branches on. At the bounds Previous/Next become honest disabled spans — a link that goes nowhere is a lie to every input mode.

nav + a + aria-current pageRange helper ellipsis tokens no dead links

pagination

pageRange drives the window; the href template decides where page N lives — this demo routes back to the page itself. Watch the window slide and the ellipses collapse near the edges.

pagination-usage.svelte svelte
<script lang="ts">
  import {
    Pagination,
    PaginationContent,
    PaginationItem,
    PaginationLink,
    PaginationPrevious,
    PaginationNext,
    PaginationEllipsis,
    pageRange,
  } from '@ui/pagination/index';
</script>

<!-- the window math is a pure helper; the links are yours -->
{#each pageRange({ current: page, total: pages }) as page (page)}
  {#if page === 'ellipsis-start' || page === 'ellipsis-end'}
    <PaginationItem><PaginationEllipsis /></PaginationItem>
  {:else}
    <PaginationItem>
      <PaginationLink {page} isActive={page === current} href={href(page)} />
    </PaginationItem>
  {/if}
{/each}

composition

The window, as evidence

pageRange with its current/total/siblings options — sticky edges, siblings around the current page, ellipsis tokens only when something was actually collapsed. The helper returns numbers interleaved with 'ellipsis-start' | 'ellipsis-end'; consumers branch on the tokens and render PaginationEllipsis. Same math as the closed component, ported exactly.

page 1 / 30
1 2 … 30
page 5 / 30
1 … 4 5 6 … 30
page 12 / 30
1 … 11 12 13 … 30
page 30 / 30
1 … 29 30
page 2 / 4
1 2 3 4
usage
<script lang="ts">
  import {
    Pagination,
    PaginationContent,
    PaginationItem,
    PaginationLink,
    PaginationPrevious,
    PaginationNext,
    PaginationEllipsis,
    pageRange,
  } from '@ui/pagination/index';
</script>

<!-- the window math is a pure helper; the links are yours -->
{#each pageRange({ current: page, total: pages }) as page (page)}
  {#if page === 'ellipsis-start' || page === 'ellipsis-end'}
    <PaginationItem><PaginationEllipsis /></PaginationItem>
  {:else}
    <PaginationItem>
      <PaginationLink {page} isActive={page === current} href={href(page)} />
    </PaginationItem>
  {/if}
{/each}

types

Composable pagination parts

The nav root provides the landmark; small parts keep list structure, links, edges, and gaps semantically explicit.

Pagination

nav landmark and density root

PaginationContent

ul list container

PaginationItem

li list item

PaginationLink

numbered page link or button

PaginationPrevious / Next

edge controls or disabled spans

PaginationEllipsis

decorative collapsed range

usage

Render a page window

Use pageRange for the pure window calculation, then map its page numbers and ellipsis tokens to composed pagination parts.

usage
<script lang="ts">
  import {
    Pagination,
    PaginationContent,
    PaginationItem,
    PaginationLink,
    PaginationPrevious,
    PaginationNext,
    PaginationEllipsis,
    pageRange,
  } from '@ui/pagination/index';
</script>

<!-- the window math is a pure helper; the links are yours -->
{#each pageRange({ current: page, total: pages }) as page (page)}
  {#if page === 'ellipsis-start' || page === 'ellipsis-end'}
    <PaginationItem><PaginationEllipsis /></PaginationItem>
  {:else}
    <PaginationItem>
      <PaginationLink {page} isActive={page === current} href={href(page)} />
    </PaginationItem>
  {/if}
{/each}

a11y

Honest pagination controls

Every destination stays a real link, the active page is announced, and unavailable edges render as disabled text rather than dead links.

Keyboard

KeyAction
TabMove through page and edge controls
EnterFollow a numbered or edge link
SpaceActivate an onclick-only page button

ARIA

AttributeValueDescription
aria-label'Pagination' by defaultNames the navigation landmark.
aria-current'page' on active linkAnnounces the current page.
aria-disabledtrue at boundsMarks unavailable Previous and Next controls.
aria-hiddentrue on ellipsisKeeps collapsed-range decoration out of the reading order.

theming

Density-aligned page chips

List gaps, link targets, and chip labels all consume the shared density scale; press tokens give interactive pages their elevation pose.

xs
sm
default
lg
TokenDefaultSource
--jx-gap8 / 8 / 12 / 16pxdensity
--jx-hit28 / 32 / 40 / 48pxdensity
--jx-inset8 / 8 / 12 / 16pxdensity
--jx-text11 / 12 / 13 / 15pxdensity
--jx-line16 / 18 / 20 / 24pxdensity
--jx-press-shadow-hovervar(--shadow-xs)component
--jx-press-shadow-activevar(--shadow-xs-press)component

usage

Usage

Import the family parts and compose them in markup — the full usage file, as the canvas above runs it.

Pagination usage
<script lang="ts">
  import {
    Pagination,
    PaginationContent,
    PaginationItem,
    PaginationLink,
    PaginationPrevious,
    PaginationNext,
    PaginationEllipsis,
    pageRange,
  } from '@ui/pagination/index';
</script>

<!-- the window math is a pure helper; the links are yours -->
{#each pageRange({ current: page, total: pages }) as page (page)}
  {#if page === 'ellipsis-start' || page === 'ellipsis-end'}
    <PaginationItem><PaginationEllipsis /></PaginationItem>
  {:else}
    <PaginationItem>
      <PaginationLink {page} isActive={page === current} href={href(page)} />
    </PaginationItem>
  {/if}
{/each}

axes

Universal props

The eight-axis surface (explicit-props): size · shape · radius · density · color · theme · elevation · motion — each axis takes named steps, auto (inherit the ambient context; stamps nothing), an exact number (px · coefficient · dp · hue per axis), or query() for responsive/container-conditional values. The landmark nav carries no own — the size axis scales the root, the link parts ride plain inheritance.

Pagination · universal props

pagination-universal.svelte svelte
<Pagination size={18} density="small">…</Pagination>

api

Props

The root and links carry the core public contract; composition supplies list structure and page-window policy.

Pagination

PropertyTypeDefaultDescription
label string'Pagination'Accessible nav landmark name.
children * Snippet—Composed pagination parts.

Universal props

PropertyTypeDefaultDescription
size'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopethe base scale — root font-size; parts size in em
shape'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto''auto' · ambient scopecorner geometry (CSS corner-shape; §14 degrade table)
radius'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopecorner size; auto = the concentric broadcast (§3)
density'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopespacing/leading scale over the kernel channels (§4)
color'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string'auto' · ambient scopethe hue axis of the fixed oklch primary system (§5)
theme'light' | 'dark' | 'system' | 'auto''auto' · ambient scopelight/dark profile; system = the JS-mutable global (§6)
elevation'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number'auto' · ambient scopeofficial M3 levels over the surface ladder (§7)
motion'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number'auto' · ambient scopeintensity across the motion kernels (§8)

PaginationLink

PropertyTypeDefaultDescription
page * number—Page number and default visible label.
isActive booleanfalseApplies active paint and aria-current=page.
href string—Destination; omit only for an onclick-only button.
onclick (event: MouseEvent) => void—Click-only page action.
child Snippet—Optional replacement anchor element.

PaginationPrevious and PaginationNext

PropertyTypeDefaultDescription
href string—Destination; omission renders an honest disabled span.
onclick (event: MouseEvent) => void—Click-only edge action.
children Snippetdefault labelReplacement edge label.
jixoai-ui ui.jixoai.com the jixoai design language

Theme

Brand hue

0°

Auto cycle · 24h