diff --git a/examples/grid-lite/components-react/src/App.tsx b/examples/grid-lite/components-react/src/App.tsx
index ac64cd3..cdb84e1 100644
--- a/examples/grid-lite/components-react/src/App.tsx
+++ b/examples/grid-lite/components-react/src/App.tsx
@@ -9,7 +9,9 @@ import {
DataTable,
ColumnDefaults,
Column,
- Description
+ Description,
+ Pagination,
+ Header
} from '@highcharts/grid-lite-react';
function App() {
@@ -61,6 +63,13 @@ function App() {
console.info('(callback) grid:', grid);
};
+ // Pagination
+ // const [paginationEnabled, setPaginationEnabled] = useState(false);
+
+ // const onPaginationClick = () => {
+ // setPaginationEnabled(true);
+ // };
+
return (
<>
Grid Caption v2.1
+
Grid Description
- {/* Grid Pagination */}
+
-
+
+
+ {/* */}
+
>
);
}
diff --git a/examples/grid-lite/components-react/src/index.css b/examples/grid-lite/components-react/src/index.css
index 04bacd8..9a63579 100644
--- a/examples/grid-lite/components-react/src/index.css
+++ b/examples/grid-lite/components-react/src/index.css
@@ -18,9 +18,16 @@ body {
padding: 20px;
}
+#controls {
+ margin-top: 20px;
+ display: flex;
+ gap: 10px;
+}
+
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
color: #ffffff;
}
}
+
diff --git a/packages/grid-lite-react/src/index.ts b/packages/grid-lite-react/src/index.ts
index 4272e3d..79cbac6 100644
--- a/packages/grid-lite-react/src/index.ts
+++ b/packages/grid-lite-react/src/index.ts
@@ -11,7 +11,15 @@ import GridLite from '@highcharts/grid-lite';
export { default as Grid } from './Grid';
export { default as GridLite } from './Grid';
-export { Caption, Data, ColumnDefaults, Column, Description } from '@highcharts/grid-shared-react';
+export {
+ Caption,
+ Data,
+ ColumnDefaults,
+ Column,
+ Description,
+ Pagination,
+ Header
+} from '@highcharts/grid-shared-react';
export { DataTable, DataConnector } from '@highcharts/grid-lite';
export { merge } from '@highcharts/grid-lite/es-modules/Shared/Utilities.js';
export type {
@@ -26,6 +34,10 @@ export type {
ColumnOptionsProps,
ColumnDataType,
ColumnSortingOrder,
- CellValueGetterContext
+ CellValueGetterContext,
+ PaginationProps,
+ HeaderProps,
+ GroupedHeaderOptions,
+ HeaderCellAccessibilityProps
} from '@highcharts/grid-shared-react';
export type GridOptions = GridLite.Options;
diff --git a/packages/grid-pro-react/src/index.ts b/packages/grid-pro-react/src/index.ts
index a8a0200..7ba334f 100644
--- a/packages/grid-pro-react/src/index.ts
+++ b/packages/grid-pro-react/src/index.ts
@@ -11,7 +11,15 @@ import GridPro from '@highcharts/grid-pro';
export { default as Grid } from './Grid';
export { default as GridPro } from './Grid';
-export { Caption, Data, ColumnDefaults, Column, Description } from '@highcharts/grid-shared-react';
+export {
+ Caption,
+ Data,
+ ColumnDefaults,
+ Column,
+ Description,
+ Pagination,
+ Header
+} from '@highcharts/grid-shared-react';
export { DataTable, DataConnector } from '@highcharts/grid-pro';
export { merge } from '@highcharts/grid-pro/es-modules/Shared/Utilities.js';
export type {
@@ -26,6 +34,10 @@ export type {
ColumnOptionsProps,
ColumnDataType,
ColumnSortingOrder,
- CellValueGetterContext
+ CellValueGetterContext,
+ PaginationProps,
+ HeaderProps,
+ GroupedHeaderOptions,
+ HeaderCellAccessibilityProps
} from '@highcharts/grid-shared-react';
export type GridOptions = GridPro.Options;
diff --git a/packages/grid-shared-react/src/components/options/header/Header.tsx b/packages/grid-shared-react/src/components/options/header/Header.tsx
new file mode 100644
index 0000000..b952ef3
--- /dev/null
+++ b/packages/grid-shared-react/src/components/options/header/Header.tsx
@@ -0,0 +1,19 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+import type { HeaderProps } from './headerProps';
+
+export function Header(_props: HeaderProps) {
+ return null;
+}
+
+Header._GridReact = {
+ type: 'Grid_Option',
+ gridOption: 'header'
+};
diff --git a/packages/grid-shared-react/src/components/options/header/headerProps.ts b/packages/grid-shared-react/src/components/options/header/headerProps.ts
new file mode 100644
index 0000000..86f57bb
--- /dev/null
+++ b/packages/grid-shared-react/src/components/options/header/headerProps.ts
@@ -0,0 +1,36 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+/**
+ * Accessibility options for a header cell in the header tree.
+ */
+export interface HeaderCellAccessibilityProps {
+ description?: string;
+}
+
+/**
+ * Header node in the `header` tree. A group (with `columns`) or a leaf
+ * (with `columnId`). Mirrors Grid Core `GroupedHeaderOptions`.
+ */
+export interface GroupedHeaderOptions {
+ accessibility?: HeaderCellAccessibilityProps;
+ format?: string;
+ className?: string;
+ columnId?: string;
+ columns?: Array;
+}
+
+export interface HeaderProps {
+ /**
+ * Header tree: column order, inclusion, and grouping.
+ * Each entry is a column id (`string`) or a {@link GroupedHeaderOptions}
+ * object. Maps to Grid Core `options.header`.
+ */
+ header?: Array;
+}
diff --git a/packages/grid-shared-react/src/components/options/header/index.ts b/packages/grid-shared-react/src/components/options/header/index.ts
new file mode 100644
index 0000000..e25312d
--- /dev/null
+++ b/packages/grid-shared-react/src/components/options/header/index.ts
@@ -0,0 +1,15 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+export { Header } from './Header';
+export type {
+ HeaderProps,
+ GroupedHeaderOptions,
+ HeaderCellAccessibilityProps
+} from './headerProps';
diff --git a/packages/grid-shared-react/src/components/options/index.ts b/packages/grid-shared-react/src/components/options/index.ts
index dbbf7f4..36984b3 100644
--- a/packages/grid-shared-react/src/components/options/index.ts
+++ b/packages/grid-shared-react/src/components/options/index.ts
@@ -22,3 +22,11 @@ export type {
} from './columns/columnProps';
export { Description } from './description';
export type { DescriptionProps } from './description';
+export { Pagination } from './pagination';
+export type { PaginationProps } from './pagination';
+export { Header } from './header';
+export type {
+ HeaderProps,
+ GroupedHeaderOptions,
+ HeaderCellAccessibilityProps
+} from './header';
diff --git a/packages/grid-shared-react/src/components/options/pagination/Pagination.tsx b/packages/grid-shared-react/src/components/options/pagination/Pagination.tsx
new file mode 100644
index 0000000..8a169d7
--- /dev/null
+++ b/packages/grid-shared-react/src/components/options/pagination/Pagination.tsx
@@ -0,0 +1,19 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+import type { PaginationProps } from './paginationProps';
+
+export function Pagination(_props: PaginationProps) {
+ return null;
+}
+
+Pagination._GridReact = {
+ type: 'Grid_Option',
+ gridOption: 'pagination'
+};
diff --git a/packages/grid-shared-react/src/components/options/pagination/index.ts b/packages/grid-shared-react/src/components/options/pagination/index.ts
new file mode 100644
index 0000000..d5d79cb
--- /dev/null
+++ b/packages/grid-shared-react/src/components/options/pagination/index.ts
@@ -0,0 +1,11 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+export { Pagination } from './Pagination';
+export type { PaginationProps } from './paginationProps';
diff --git a/packages/grid-shared-react/src/components/options/pagination/paginationProps.ts b/packages/grid-shared-react/src/components/options/pagination/paginationProps.ts
new file mode 100644
index 0000000..a5f9a93
--- /dev/null
+++ b/packages/grid-shared-react/src/components/options/pagination/paginationProps.ts
@@ -0,0 +1,57 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+export interface PaginationProps {
+ /**
+ * Whether pagination should be rendered.
+ * Defaults to `true` when the `` component is used.
+ * Pass `false` to disable pagination while keeping other options.
+ */
+ enabled?: boolean;
+ /**
+ * The current page number.
+ */
+ page?: number;
+ /**
+ * Number of rows per page.
+ */
+ pageSize?: number;
+ /**
+ * Alignment of pagination elements within the wrapper.
+ */
+ align?: 'left' | 'center' | 'right' | 'distributed';
+ /**
+ * Whether to show the page information text.
+ */
+ pageInfo?: boolean;
+ /**
+ * Whether to show the page size selector.
+ */
+ pageSizeSelector?: boolean;
+ /**
+ * Available options for the page size selector dropdown.
+ */
+ pageSizeOptions?: number[];
+ /**
+ * Whether to show numbered page buttons.
+ */
+ pageButtons?: boolean;
+ /**
+ * Maximum number of page number buttons to show before using ellipsis.
+ */
+ pageButtonsCount?: number;
+ /**
+ * Whether to show the first and last page navigation buttons.
+ */
+ firstLast?: boolean;
+ /**
+ * Whether to show the previous and next page navigation buttons.
+ */
+ previousNext?: boolean;
+}
diff --git a/packages/grid-shared-react/src/index.ts b/packages/grid-shared-react/src/index.ts
index 3814da0..4cfc3ca 100644
--- a/packages/grid-shared-react/src/index.ts
+++ b/packages/grid-shared-react/src/index.ts
@@ -12,7 +12,15 @@ import { GridType, GridInstance } from './hooks/useGrid';
import type { GridProps, GridRefHandle } from './components/BaseGrid';
export { BaseGrid };
-export { Caption, Data, ColumnDefaults, Column, Description } from './components/options';
+export {
+ Caption,
+ Data,
+ ColumnDefaults,
+ Column,
+ Description,
+ Pagination,
+ Header
+} from './components/options';
export { getChildProps } from './utils/getChildProps';
export type {
CaptionProps,
@@ -24,6 +32,10 @@ export type {
ColumnOptionsProps,
ColumnDataType,
ColumnSortingOrder,
- CellValueGetterContext
+ CellValueGetterContext,
+ PaginationProps,
+ HeaderProps,
+ GroupedHeaderOptions,
+ HeaderCellAccessibilityProps
} from './components/options';
export type { GridType, GridInstance, GridProps, GridRefHandle };
diff --git a/packages/grid-shared-react/src/utils/getChildProps.test.tsx b/packages/grid-shared-react/src/utils/getChildProps.test.tsx
deleted file mode 100644
index 1498a4e..0000000
--- a/packages/grid-shared-react/src/utils/getChildProps.test.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { describe, it, expect } from 'vitest';
-import { Data } from '../components/options/data/Data';
-import { getChildProps } from './getChildProps';
-
-describe('getChildProps', () => {
- it('maps Data columns to options.data.columns', () => {
- const columns = {
- name: ['Alice', 'Bob'],
- age: [23, 34]
- };
-
- expect(getChildProps()).toEqual({
- data: {
- columns
- }
- });
- });
-
- it('maps all Data props to options.data', () => {
- const columns = {
- name: ['Alice']
- };
- const connector = { id: 'csv' };
- const dataTable = { id: 'table-1' };
-
- expect(
- getChildProps(
-
- )
- ).toEqual({
- data: {
- providerType: 'local',
- autogenerateColumns: false,
- columns,
- connector,
- dataTable,
- updateOnChange: true,
- idColumn: 'id'
- }
- });
- });
-});
diff --git a/packages/grid-shared-react/src/utils/getChildProps.ts b/packages/grid-shared-react/src/utils/getChildProps.ts
index 572376d..4564d86 100644
--- a/packages/grid-shared-react/src/utils/getChildProps.ts
+++ b/packages/grid-shared-react/src/utils/getChildProps.ts
@@ -9,7 +9,8 @@
import { Fragment, isValidElement, ReactElement, ReactNode } from 'react';
import type { BaseGridOptionsComponent, BaseGridOptions } from '../components/BaseGridOptions';
-import { normalizeColumnOptions } from './mappers/columnOptions';
+import { normalizeColumnOptions } from './mappers/column';
+import { normalizePaginationOptions } from './mappers/pagination';
function objInsert(
obj: Record,
@@ -203,6 +204,20 @@ export function getChildProps(children: ReactNode): Record {
return;
}
+ if (meta.gridOption === 'pagination') {
+ optionsFromChildren.pagination = normalizePaginationOptions(props);
+ return;
+ }
+
+ if (meta.gridOption === 'header') {
+ const { header, children: _ignored } = props;
+
+ if (header !== void 0) {
+ optionsFromChildren.header = header;
+ }
+ return;
+ }
+
const optionParent = optionsFromChildren[meta.gridOption] ?? (
optionsFromChildren[meta.gridOption] = meta.isArrayType ? [] : {}
);
diff --git a/packages/grid-shared-react/src/utils/mappers/columnOptions.ts b/packages/grid-shared-react/src/utils/mappers/column/columnOptions.ts
similarity index 90%
rename from packages/grid-shared-react/src/utils/mappers/columnOptions.ts
rename to packages/grid-shared-react/src/utils/mappers/column/columnOptions.ts
index 300c39c..f1ae833 100644
--- a/packages/grid-shared-react/src/utils/mappers/columnOptions.ts
+++ b/packages/grid-shared-react/src/utils/mappers/column/columnOptions.ts
@@ -7,7 +7,7 @@
*
*/
-import { mapPrefixedProps } from './mapPrefixedProps';
+import { mapPrefixedProps } from '../mapPrefixedProps';
/** Flat prop prefix → nested Grid option key for columns. */
const COLUMN_PROP_PREFIXES = {
diff --git a/packages/grid-shared-react/src/utils/mappers/column/index.ts b/packages/grid-shared-react/src/utils/mappers/column/index.ts
new file mode 100644
index 0000000..01a620a
--- /dev/null
+++ b/packages/grid-shared-react/src/utils/mappers/column/index.ts
@@ -0,0 +1,10 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+export { normalizeColumnOptions } from './columnOptions';
diff --git a/packages/grid-shared-react/src/utils/mappers/pagination/index.ts b/packages/grid-shared-react/src/utils/mappers/pagination/index.ts
new file mode 100644
index 0000000..de3e9f4
--- /dev/null
+++ b/packages/grid-shared-react/src/utils/mappers/pagination/index.ts
@@ -0,0 +1,10 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+export { normalizePaginationOptions } from './paginationOptions';
diff --git a/packages/grid-shared-react/src/utils/mappers/pagination/paginationOptions.ts b/packages/grid-shared-react/src/utils/mappers/pagination/paginationOptions.ts
new file mode 100644
index 0000000..0db2d55
--- /dev/null
+++ b/packages/grid-shared-react/src/utils/mappers/pagination/paginationOptions.ts
@@ -0,0 +1,84 @@
+/**
+ * Grid React integration.
+ * Copyright (c) 2025, Highsoft
+ *
+ * A valid license is required for using this software.
+ * See highcharts.com/license
+ *
+ */
+
+import type { PaginationProps } from '../../../components/options/pagination/paginationProps';
+
+export function normalizePaginationOptions(
+ props: Record
+): Record {
+ const {
+ pageInfo,
+ pageSizeSelector,
+ pageSizeOptions,
+ pageButtons,
+ pageButtonsCount,
+ firstLast,
+ previousNext,
+ enabled,
+ page,
+ pageSize,
+ align
+ } = props as PaginationProps;
+
+ const result: Record = {
+ enabled: enabled ?? true
+ };
+
+ if (page !== void 0) {
+ result.page = page;
+ }
+ if (pageSize !== void 0) {
+ result.pageSize = pageSize;
+ }
+ if (align !== void 0) {
+ result.align = align;
+ }
+
+ const controls: Record = {};
+
+ if (pageInfo !== void 0) {
+ controls.pageInfo = pageInfo;
+ }
+
+ if (pageSizeSelector === false) {
+ controls.pageSizeSelector = false;
+ } else if (pageSizeOptions !== void 0) {
+ controls.pageSizeSelector = {
+ enabled: true,
+ options: pageSizeOptions
+ };
+ } else if (pageSizeSelector !== void 0) {
+ controls.pageSizeSelector = pageSizeSelector;
+ }
+
+ if (pageButtons === false) {
+ controls.pageButtons = false;
+ } else if (pageButtonsCount !== void 0) {
+ controls.pageButtons = {
+ enabled: true,
+ count: pageButtonsCount
+ };
+ } else if (pageButtons !== void 0) {
+ controls.pageButtons = pageButtons;
+ }
+
+ if (firstLast !== void 0) {
+ controls.firstLastButtons = firstLast;
+ }
+
+ if (previousNext !== void 0) {
+ controls.previousNextButtons = previousNext;
+ }
+
+ if (Object.keys(controls).length > 0) {
+ result.controls = controls;
+ }
+
+ return result;
+}