Skip to main content

Pagination

OGrid includes a built-in pagination bar with page navigation buttons, page size selector, and a row count summary. It works seamlessly with both client-side data arrays and server-side data sources.

Live Demo​

Use the pagination controls to navigate pages
Live
Framework-Specific Styling

The live demo above shows React Radix UI styling (lightweight default). To see how pagination controls look in your framework's design system, click the framework buttons above the demo to open online demo. Each framework renders with its native button and dropdown components, so the styling matches your design system.

Quick Example​

import { OGrid } from '@alaarab/ogrid-react-radix';

const columns = [
{ columnId: 'name', name: 'Name' },
{ columnId: 'email', name: 'Email' },
{ columnId: 'department', name: 'Department' },
{
columnId: 'salary',
name: 'Salary',
type: 'numeric' as const,
valueFormatter: (v) => `$${Number(v).toLocaleString()}`,
},
];

function App() {
return (
<OGrid
columns={columns}
data={people}
getRowId={(item) => item.id}
defaultPageSize={5}
pageSizeOptions={[5, 10, 25, 50]}
entityLabelPlural="people"
/>
);
}
Switching UI libraries

The OGrid component has the same props across all React UI packages. To switch, just change the import:

  • Radix (lightweight, default): from '@alaarab/ogrid-react-radix'
  • Fluent UI (Microsoft 365 / SPFx): from '@alaarab/ogrid-react-fluent' - wrap in <FluentProvider>

How It Works​

Pagination is automatic. When your data exceeds the page size, the pagination bar appears at the bottom of the grid with:

  • Previous / Next buttons
  • Page number indicator ("Page 1 of 5")
  • Page size selector (dropdown to change rows per page)
  • Row count summary ("Showing 1-25 of 120 projects")

Client-Side Pagination​

When you pass a data array, OGrid slices it automatically based on the current page and page size. Sorting and filtering are applied before slicing.

Server-Side Pagination​

When you pass a dataSource, the grid calls fetchPage() with page and pageSize parameters. Your server returns only the rows for that page along with a totalCount:

const dataSource: IDataSource<Project> = {
fetchPage: async ({ page, pageSize, sort, filters }) => {
const res = await fetch(`/api/projects?page=${page}&pageSize=${pageSize}`);
const json = await res.json();
return { items: json.data, totalCount: json.total };
},
};

function App() {
return (
<OGrid
columns={columns}
dataSource={dataSource}
getRowId={(item) => item.id}
defaultPageSize={50}
entityLabelPlural="projects"
/>
);
}

Controlled Pagination​

For full control over page state (e.g., URL-synced pagination), pass page, pageSize, onPageChange, and onPageSizeChange:

function App() {
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(25);

return (
<OGrid
columns={columns}
data={items}
getRowId={(item) => item.id}
page={page}
pageSize={pageSize}
onPageChange={setPage}
onPageSizeChange={setPageSize}
/>
);
}

Props​

PropTypeDefaultDescription
defaultPageSizenumber | 'all'25Initial page size (uncontrolled mode). 'all' shows every row on one page.
pageSizeOptions(number | 'all')[][10, 25, 50, 100]Options shown in the page size dropdown. Include 'all' for an "All" entry that shows every filtered row on one page (e.g. [50, 250, 500, 'all']). If the active page size isn't in the list, it's auto-inserted.
pagenumber--Current page number (controlled mode, 1-indexed).
pageSizenumber | 'all'--Rows per page (controlled mode).
onPageChange(page: number) => void--Called when page changes.
onPageSizeChange(size: number | 'all') => void--Called when page size changes.
entityLabelPluralstring'items'Label used in the row count summary (e.g., "Showing 1-25 of 100 projects").
  • Sorting -- sort results before pagination
  • Filtering -- filter results before pagination