Native pagination controls emit cem-page for application-owned data. Page-size changes preserve the first visible item; unavailable boundary actions retain focus. Related: cem-expansion · cem-table · cem-sort-header.
Full examples and variation matrix · Property playground · Automated stories
{slice @name=label | Record pages}{cem-field @label="label" @value="{$datadom.slices.label}" @slice=label @slice-event=input @slice-value="$target.value"}
{slice @name=name | records}{cem-field @label="name" @value="{$datadom.slices.name}" @slice=name @slice-event=input @slice-value="$target.value"}
{slice @name=length | 120}{cem-field @label="length" @value="{$datadom.slices.length}" @slice=length @slice-event=input @slice-value="$target.value"}
{slice @name=page-index | 1}{cem-field @label="page-index" @value="{$datadom.slices.page-index}" @slice=page-index @slice-event=input @slice-value="$target.value"}
{slice @name=page-size | 25}{cem-field @label="page-size" @value="{$datadom.slices.page-size}" @slice=page-size @slice-event=input @slice-value="$target.value"}
{slice @name=page-size-options | 10 25 50 100}{cem-field @label="page-size-options" @value="{$datadom.slices.page-size-options}" @slice=page-size-options @slice-event=input @slice-value="$target.value"}
{slice @name=items-per-page-label | Items per page}{cem-field @label="items-per-page-label" @value="{$datadom.slices.items-per-page-label}" @slice=items-per-page-label @slice-event=input @slice-value="$target.value"}
{slice @name=first-page-label | First page}{cem-field @label="first-page-label" @value="{$datadom.slices.first-page-label}" @slice=first-page-label @slice-event=input @slice-value="$target.value"}
{slice @name=previous-page-label | Previous page}{cem-field @label="previous-page-label" @value="{$datadom.slices.previous-page-label}" @slice=previous-page-label @slice-event=input @slice-value="$target.value"}
{slice @name=next-page-label | Next page}{cem-field @label="next-page-label" @value="{$datadom.slices.next-page-label}" @slice=next-page-label @slice-event=input @slice-value="$target.value"}
{slice @name=last-page-label | Last page}{cem-field @label="last-page-label" @value="{$datadom.slices.last-page-label}" @slice=last-page-label @slice-event=input @slice-value="$target.value"}
{slice @name=of-label | of}{cem-field @label="of-label" @value="{$datadom.slices.of-label}" @slice=of-label @slice-event=input @slice-value="$target.value"}
{slice @name=class | }{cem-field @label="class" @value="{$datadom.slices.class}" @slice=class @slice-event=input @slice-value="$target.value"}
{slice @name=dir | ltr}{fieldset @role=group @aria-label="dir" @slice=dir @slice-event=change @slice-value="$target.value" | {legend | dir}{cem-radio @name="property-dir" @value="ltr" @label="ltr" @checked={if datadom.slices.dir == "ltr" {true} else {null}}}{cem-radio @name="property-dir" @value="rtl" @label="rtl" @checked={if datadom.slices.dir == "rtl" {true} else {null}}}}
{slice @name=show-first-last | absent}{fieldset @role=group @aria-label="show-first-last" @slice=show-first-last @slice-event=change @slice-value="$target.value" | {legend | show-first-last}{cem-radio @name="property-show-first-last" @value="absent" @label="absent" @checked={if datadom.slices.show-first-last == "absent" {true} else {null}}}{cem-radio @name="property-show-first-last" @value="present" @label="present" @checked={if datadom.slices.show-first-last == "present" {true} else {null}}}}
{slice @name=hide-page-size | absent}{fieldset @role=group @aria-label="hide-page-size" @slice=hide-page-size @slice-event=change @slice-value="$target.value" | {legend | hide-page-size}{cem-radio @name="property-hide-page-size" @value="absent" @label="absent" @checked={if datadom.slices.hide-page-size == "absent" {true} else {null}}}{cem-radio @name="property-hide-page-size" @value="present" @label="present" @checked={if datadom.slices.hide-page-size == "present" {true} else {null}}}}
{slice @name=disabled | absent}{fieldset @role=group @aria-label="disabled" @slice=disabled @slice-event=change @slice-value="$target.value" | {legend | disabled}{cem-radio @name="property-disabled" @value="absent" @label="absent" @checked={if datadom.slices.disabled == "absent" {true} else {null}}}{cem-radio @name="property-disabled" @value="present" @label="present" @checked={if datadom.slices.disabled == "present" {true} else {null}}}}
{slice @name=hidden | absent}{fieldset @role=group @aria-label="hidden" @slice=hidden @slice-event=change @slice-value="$target.value" | {legend | hidden}{cem-radio @name="property-hidden" @value="absent" @label="absent" @checked={if datadom.slices.hidden == "absent" {true} else {null}}}{cem-radio @name="property-hidden" @value="present" @label="present" @checked={if datadom.slices.hidden == "present" {true} else {null}}}}
{cem-paginator @label="{$datadom.slices.label}" @name="{$datadom.slices.name}" @length="{$datadom.slices.length}" @page-index="{$datadom.slices.page-index}" @page-size="{$datadom.slices.page-size}" @page-size-options="{$datadom.slices.page-size-options}" @items-per-page-label="{$datadom.slices.items-per-page-label}" @first-page-label="{$datadom.slices.first-page-label}" @previous-page-label="{$datadom.slices.previous-page-label}" @next-page-label="{$datadom.slices.next-page-label}" @last-page-label="{$datadom.slices.last-page-label}" @of-label="{$datadom.slices.of-label}" @class="{$datadom.slices.class}" @dir="{$datadom.slices.dir}" @show-first-last={if datadom.slices.show-first-last == "present" {true} else {null}} @hide-page-size={if datadom.slices.hide-page-size == "present" {true} else {null}} @disabled={if datadom.slices.disabled == "present" {true} else {null}} @hidden={if datadom.slices.hidden == "present" {true} else {null}} | }{cem-module-url @slice=sourceUrl @src="@epa-wg/cem-components/components/cem-paginator/cem-paginator.xhtml"}{cem:if @test="datadom.slices.sourceUrl" | {p | {a @href="{$datadom.slices.sourceUrl}" | Open canonical XHTML}}{cem-demo-element @legend="Canonical source" @src="{$datadom.slices.sourceUrl}" @type=xml @demo=false}}