Coloriginz Design Systemshadcn custom registry

@col/pagination

Versie: 1.0.0 Toegevoegd: 2026-08-23

Herkomst

Geëxtraheerd uit growerportal2/src/components/ui/pagination.tsx, dat daar op één dag ontstond uit vijf handgeschreven kopieën van dezelfde Previous/Next-balk (admin/imports/batch-records-dialog.tsx, admin/imports/data-sync-tab.tsx, admin/imports/salessheet-tab.tsx, features/fust/components/fust-audit-log.tsx, features/fust/components/fust-email-log.tsx).

De aanleiding was concreet: de importmonitor toonde 2.743 orderregels over 55 bladzijden, en er was geen andere manier om bij pagina 40 te komen dan negenendertig keer Next. Drie van de vijf kopieën gebruikten tekstknoppen, twee pijl-iconen; verder waren ze identiek. KCB heeft dezelfde balk nog in eigen beheer, in components/settings/email-ingestion-log.tsx en de twee zendingenschermen — ook daar zonder kiezer.

Waarvoor

De navigatie onder een gepagineerde tabel: een pagina terug, een pagina vooruit, en een kiezer die rechtstreeks naar een willekeurig blad springt. Pak het zodra een lijst meer dan een handvol pagina's kan krijgen — het verschil met kale Previous/Next-knoppen wordt pas voelbaar voorbij een stuk of tien.

Gebruik het niet voor oneindig scrollen, voor een "meer laden"-knop, of voor paginering die de URL moet bijwerken zonder dat de aanroeper dat zelf regelt. Het component is controlled en weet niets van routing.

Het toont ook niet hoeveel rijen er in totaal zijn. Die tekst ("Toont 1-50 van 2.743") staat in de bronapp links naast de balk en verschilt per scherm — zet hem zelf ernaast in een flex items-center justify-between.

Wat je app moet leveren

Prop Type Betekenis
page number Huidige pagina, 1-based. Verplicht. Een waarde buiten 1…totalPages wordt geklemd, zodat een filterwijziging die het aantal pagina's verkleint geen kapotte balk oplevert voordat de aanroeper zijn state bijwerkt.
totalPages number Aantal pagina's. Verplicht. Bij <= 1 rendert het component null.
onPageChange (page: number) => void Aangeroepen met het nieuwe paginanummer. Verplicht. Het component houdt zelf niets bij.
disabled boolean Zet alle drie de besturingselementen uit, bedoeld voor de duur van een fetch.
className string Extra klassen op de wrapper.
labels zie hieronder Alle tekst die een gebruiker ziet of hoort.
interface PaginationLabels {
  previous?: string                                   // default 'Previous page'
  next?: string                                       // default 'Next page'
  picker?: string                                     // default 'Go to page'
  page?: (page: number, totalPages: number) => string // default '40 / 55'
  pageItem?: (page: number, totalPages: number) => string // default '40'
}

previous, next en picker zijn aria-labels: ze zijn de enige naam die de knoppen hebben, want er staat alleen een icoon in. Geef ze mee zodra je app vertaalt.

Typisch gebruik:

const [page, setPage] = useState(1)
const { data, loading } = useFetch(`/api/lots?page=${page}`)

<div className="flex items-center justify-between">
  <p className="text-sm text-muted-foreground">
    Toont {start}-{end} van {formatNumber(total)}
  </p>
  <Pagination
    page={page}
    totalPages={data?.totalPages ?? 1}
    onPageChange={setPage}
    disabled={loading}
    labels={{ page: (current, total) => `Pagina ${current} van ${total}` }}
  />
</div>

Zet de paginastate op één plek en reset hem naar 1 als een filter verandert — anders vraagt het scherm pagina 40 van een lijst die er nog maar 3 heeft.

Bestanden

Bestand Landt in Soort
pagination.tsx components/ beheerd

Upstream shadcn-afhankelijkheden: button, dropdown-menu. Geen cssVars.

Let op: shadcn heeft zelf óók een pagination-primitive. Die staat bewust niet in registryDependencies, en dit bestand landt in components/, niet in components/ui/ — zo overschrijft dit item die primitive niet en andersom.

Gebruikt door

App Sinds versie Opmerkingen
growerportal2 1.0.0 Vijf schermen: drie importtabbladen (admin/imports/*) en de twee fust-logs. De eigen kopie in src/components/ui/pagination.tsx is verwijderd. Labels komen uit src/components/pagination-labels.ts — één gedeeld object dat page naar Page 40 of 55 schrijft, want dat portaal is Engelstalig. Let op: npx shadcn add overschreef daar src/components/ui/button.tsx met een nieuwere upstream base-nova-versie (o.a. zónder 'use client'); teruggedraaid met git checkout — README-regel 6, en het is geen theorie.

Bewuste keuzes

Bekende beperkingen