Skip to content

Components · Tables and data grid

LoadMore

Cursor pagination footer with loading, error and retry, end of list and announcements.

@rookcom/monarch-reactComponent

With useLoadMore

  • Audit entry 1
  • Audit entry 2
  • Audit entry 3

Showing 3 of 9 entries

Usage examples

States

With react-query

Purpose

Appends the next page of a cursor-paginated list on request. LoadMore is the footer; useLoadMore holds the pages, cursor and status, while the product supplies the fetch.

Use when

  • Feeds, audit logs, search results and message history served with a cursor (?cursor=…&limit=…).
  • The reader scans forward and rarely needs to jump to page 7.

Avoid when

  • Readers need to jump to a page or know where they are in a fixed set: use Pagination.
  • The whole set is small enough to render at once.

Design principles

  • The button is always there while there is more, even with autoLoad: scrolling is a convenience, not the only way.
  • Every outcome is announced politely: how many items arrived, a failure, or the end of the list.
  • Errors are recoverable in place: the same button becomes Retry and repeats the failed cursor.
  • Data fetching stays in the product. The hook takes any fetchPage, and the component works with any data library through its props.

API reference

import { LoadMore, useLoadMore } from '@rookcom/monarch-react';
ExportKindRenderingRoot class
LoadMorecomponentclient.mn-load-more
useLoadMorehookclient–

useLoadMore({ fetchPage, initialPage?, loadOnMount? }) returns items, status (idle, loading, error, done), error, hasMore, total, loadMore, retry, reset and loadMoreProps to spread onto <LoadMore>.

fetchPage(cursor, { signal }) receives an AbortSignal that fires on reset and unmount; responses that arrive after a reset are ignored.

With react-query or SWR, skip the hook and pass hasMore, loading, error, onLoadMore and loadedCount from useInfiniteQuery directly.

The ref is forwarded to the root <div>.

Generated from the TypeScript declarations of packages/react/src/components/data-grid/load-more.

Properties

LoadMore

The footer of a cursor-paginated list: a Load more button with loading, error and retry, end-of-list states and polite announcements, plus optional auto-load on scroll. Pair it with `useLoadMore`, or drive it from any data library through its props.

PropTypeDescription
hasMore requiredbooleanThere is another page to load.
onLoadMore required() => voidLoads the next page.
autoLoadbooleanLoad the next page when the control scrolls into view (IntersectionObserver). The button always stays as the fallback and for keyboard users; auto-load pauses after an error. Default `false`.
autoLoadMarginstringIntersectionObserver root margin for `autoLoad`. Default `200px`.
classNamestring
endLabelReactNodeShown when everything is loaded; `null` hides it. Default "That’s everything".
errorbooleanThe last fetch failed. Shows `errorLabel` and turns the button into Retry. Auto-load pauses.
errorLabelReactNodeError message. Default "Couldn’t load more."
idstring
labelReactNodeButton text. Default "Load more".
loadedCountnumberItems currently on screen. Changes are announced ("20 more items loaded").
loadingbooleanA page is being fetched. The button stays focusable and shows a spinner.
loadingLabelReactNodeButton text while loading. Default "Loading…".
noun{ one: string; other: string; }Noun for counts and announcements. Default `{ one: 'item', other: 'items' }`.
onRetry(() => void)Called by the Retry button. Default: `onLoadMore`.
retryLabelReactNodeRetry button text. Default "Retry".
showCountbooleanShow "Showing 40 of 120 items" next to the button. Default `true` when `loadedCount` is given.
totalCountnumberTotal items, when the server knows it.

Variants

PropValuesDescription
autoLoad'false''true'Also loads when the footer scrolls into view (IntersectionObserver, autoLoadMargin ahead).
showCount'true''false'“Showing 40 of 120 items” beside the button. On by default when loadedCount is given.

States

StateExposed asBehaviour
Idledata-state="idle"Load more button, optional count.
Loadingdata-state="loading"The button shows a spinner and “Loading…”, stays focusable and ignores repeat clicks (aria-busy).
Errordata-state="error"errorLabel in danger text; the button reads Retry; auto-load pauses until it succeeds.
End of listdata-state="done"The button is replaced by endLabel (“That’s everything”), or nothing when endLabel={null}.

Interaction behaviour

  • Activating the button calls onLoadMore, or onRetry (default onLoadMore) after an error.
  • The hook ignores loadMore while a request is in flight and after the last page.
  • reset() clears the items and loads the first page again, aborting any request in flight.
  • When the last page arrives while the button has focus, focus moves to the end message, so it is not lost to the page body.

Keyboard support

KeysAction
TabMoves to the Load more (or Retry) button.
Enter / SpaceLoads the next page, or retries.

Accessibility

Role
button inside a group with a polite status region
Accessible name
“Load more”, “Loading…” or “Retry” (customisable labels).
  • A visually hidden role="status" region announces “20 more items loaded.”, the error and the end of the list.
  • Loading uses aria-busy and aria-disabled instead of disabled, so keyboard focus stays on the button.
  • Auto-load never removes the button, so keyboard and switch users can always load explicitly.

Responsive behaviour

  • The count, message and button wrap onto separate lines on narrow screens and stay centred.

Theme support

  • Muted text for the count and end message, danger text for the error; the button is a secondary Button. All are Monarch tokens.

Do and don't

Do

  • Give a noun so counts and announcements read naturally (“3 more entries loaded”).
  • Pass totalCount when the server knows it.
  • Call reset() when filters or search change.

Don't

  • Do not hide the button when using autoLoad.
  • Do not use LoadMore where readers must reach a specific page; use Pagination.
  • Do not fetch inside the component; pass fetchPage or the query state.

Dependencies

KindDepends on
npm packagesreact
Monarch componentsButton

Testing coverage

  • Loads the first page on mount, more on click, then shows the end of the list and announces each step.
  • Works with Enter and Space and moves focus to the end message when the button disappears.
  • Shows and announces an error; Retry repeats the same cursor, including a failed first page.
  • reset reloads from the first page and ignores a stale response.
  • Ignores repeat loadMore calls while loading.
  • Starts from initialPage without a request.
  • Auto-loads on intersection and pauses after an error, keeping the button.
  • Works controlled by props without the hook.
CheckCovered
Axe in jsdomYes
Server renderingYes
Browser suitesVisual baselines: /__gallery; Cross-browser axe: /components/load-more

Tests: packages/react/src/components/data-grid/load-more