From dc2402bbf22f3e27a8c801acac8ded8a88e972e1 Mon Sep 17 00:00:00 2001 From: Sebastian Bochan Date: Mon, 6 Jul 2026 12:57:08 +0200 Subject: [PATCH 1/3] Added basic pagination component. --- .../grid-lite/components-react/src/App.tsx | 29 ++++++- .../grid-lite/components-react/src/index.css | 7 ++ packages/grid-lite-react/src/index.ts | 5 +- packages/grid-pro-react/src/index.ts | 5 +- .../src/components/options/index.ts | 2 + .../options/pagination/Pagination.tsx | 21 +++++ .../components/options/pagination/index.ts | 11 +++ .../options/pagination/paginationProps.ts | 57 +++++++++++++ packages/grid-shared-react/src/index.ts | 5 +- .../src/utils/getChildProps.test.tsx | 50 ----------- .../src/utils/getChildProps.ts | 8 +- .../mappers/{ => column}/columnOptions.ts | 2 +- .../src/utils/mappers/column/index.ts | 10 +++ .../src/utils/mappers/pagination/index.ts | 10 +++ .../mappers/pagination/paginationOptions.ts | 84 +++++++++++++++++++ 15 files changed, 245 insertions(+), 61 deletions(-) create mode 100644 packages/grid-shared-react/src/components/options/pagination/Pagination.tsx create mode 100644 packages/grid-shared-react/src/components/options/pagination/index.ts create mode 100644 packages/grid-shared-react/src/components/options/pagination/paginationProps.ts delete mode 100644 packages/grid-shared-react/src/utils/getChildProps.test.tsx rename packages/grid-shared-react/src/utils/mappers/{ => column}/columnOptions.ts (90%) create mode 100644 packages/grid-shared-react/src/utils/mappers/column/index.ts create mode 100644 packages/grid-shared-react/src/utils/mappers/pagination/index.ts create mode 100644 packages/grid-shared-react/src/utils/mappers/pagination/paginationOptions.ts diff --git a/examples/grid-lite/components-react/src/App.tsx b/examples/grid-lite/components-react/src/App.tsx index ac64cd3..caa4be7 100644 --- a/examples/grid-lite/components-react/src/App.tsx +++ b/examples/grid-lite/components-react/src/App.tsx @@ -9,7 +9,8 @@ import { DataTable, ColumnDefaults, Column, - Description + Description, + Pagination } from '@highcharts/grid-lite-react'; function App() { @@ -61,6 +62,13 @@ function App() { console.info('(callback) grid:', grid); }; + // Pagination + // const [paginationEnabled, setPaginationEnabled] = useState(false); + + // const onPaginationClick = () => { + // setPaginationEnabled(true); + // }; + return ( <> 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..2929529 100644 --- a/packages/grid-lite-react/src/index.ts +++ b/packages/grid-lite-react/src/index.ts @@ -11,7 +11,7 @@ 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 } 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 +26,7 @@ export type { ColumnOptionsProps, ColumnDataType, ColumnSortingOrder, - CellValueGetterContext + CellValueGetterContext, + PaginationProps } 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..9eaacc3 100644 --- a/packages/grid-pro-react/src/index.ts +++ b/packages/grid-pro-react/src/index.ts @@ -11,7 +11,7 @@ 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 } 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 +26,7 @@ export type { ColumnOptionsProps, ColumnDataType, ColumnSortingOrder, - CellValueGetterContext + CellValueGetterContext, + PaginationProps } from '@highcharts/grid-shared-react'; export type GridOptions = GridPro.Options; diff --git a/packages/grid-shared-react/src/components/options/index.ts b/packages/grid-shared-react/src/components/options/index.ts index dbbf7f4..67c6419 100644 --- a/packages/grid-shared-react/src/components/options/index.ts +++ b/packages/grid-shared-react/src/components/options/index.ts @@ -22,3 +22,5 @@ export type { } from './columns/columnProps'; export { Description } from './description'; export type { DescriptionProps } from './description'; +export { Pagination } from './pagination'; +export type { PaginationProps } from './pagination'; 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..f2c9ad9 --- /dev/null +++ b/packages/grid-shared-react/src/components/options/pagination/Pagination.tsx @@ -0,0 +1,21 @@ +/** + * 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 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..a225c83 --- /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 './Pagination'; 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..989215c 100644 --- a/packages/grid-shared-react/src/index.ts +++ b/packages/grid-shared-react/src/index.ts @@ -12,7 +12,7 @@ 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 } from './components/options'; export { getChildProps } from './utils/getChildProps'; export type { CaptionProps, @@ -24,6 +24,7 @@ export type { ColumnOptionsProps, ColumnDataType, ColumnSortingOrder, - CellValueGetterContext + CellValueGetterContext, + PaginationProps } 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..a33c900 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,11 @@ export function getChildProps(children: ReactNode): Record { return; } + if (meta.gridOption === 'pagination') { + optionsFromChildren.pagination = normalizePaginationOptions(props); + 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; +} From 5841659398105250603a0e745d8d9716819fa34c Mon Sep 17 00:00:00 2001 From: Sebastian Bochan Date: Mon, 6 Jul 2026 13:06:13 +0200 Subject: [PATCH 2/3] Cleaned up. --- .../src/components/options/pagination/Pagination.tsx | 2 -- .../src/components/options/pagination/index.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/grid-shared-react/src/components/options/pagination/Pagination.tsx b/packages/grid-shared-react/src/components/options/pagination/Pagination.tsx index f2c9ad9..8a169d7 100644 --- a/packages/grid-shared-react/src/components/options/pagination/Pagination.tsx +++ b/packages/grid-shared-react/src/components/options/pagination/Pagination.tsx @@ -9,8 +9,6 @@ import type { PaginationProps } from './paginationProps'; -export type { PaginationProps } from './paginationProps'; - export function Pagination(_props: PaginationProps) { return null; } diff --git a/packages/grid-shared-react/src/components/options/pagination/index.ts b/packages/grid-shared-react/src/components/options/pagination/index.ts index a225c83..d5d79cb 100644 --- a/packages/grid-shared-react/src/components/options/pagination/index.ts +++ b/packages/grid-shared-react/src/components/options/pagination/index.ts @@ -8,4 +8,4 @@ */ export { Pagination } from './Pagination'; -export type { PaginationProps } from './Pagination'; +export type { PaginationProps } from './paginationProps'; From c6ad53e8f570611a89c9bcf5e93fab1806f217e4 Mon Sep 17 00:00:00 2001 From: Sebastian Bochan Date: Mon, 6 Jul 2026 14:39:26 +0200 Subject: [PATCH 3/3] Added header component. --- .../grid-lite/components-react/src/App.tsx | 10 +++++- packages/grid-lite-react/src/index.ts | 15 ++++++-- packages/grid-pro-react/src/index.ts | 15 ++++++-- .../src/components/options/header/Header.tsx | 19 ++++++++++ .../components/options/header/headerProps.ts | 36 +++++++++++++++++++ .../src/components/options/header/index.ts | 15 ++++++++ .../src/components/options/index.ts | 6 ++++ packages/grid-shared-react/src/index.ts | 15 ++++++-- .../src/utils/getChildProps.ts | 9 +++++ 9 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 packages/grid-shared-react/src/components/options/header/Header.tsx create mode 100644 packages/grid-shared-react/src/components/options/header/headerProps.ts create mode 100644 packages/grid-shared-react/src/components/options/header/index.ts diff --git a/examples/grid-lite/components-react/src/App.tsx b/examples/grid-lite/components-react/src/App.tsx index caa4be7..cdb84e1 100644 --- a/examples/grid-lite/components-react/src/App.tsx +++ b/examples/grid-lite/components-react/src/App.tsx @@ -10,7 +10,8 @@ import { ColumnDefaults, Column, Description, - Pagination + Pagination, + Header } from '@highcharts/grid-lite-react'; function App() { @@ -98,6 +99,13 @@ function App() { cellRowHeader={false} /> Grid Caption v2.1 +
; +} + +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 67c6419..36984b3 100644 --- a/packages/grid-shared-react/src/components/options/index.ts +++ b/packages/grid-shared-react/src/components/options/index.ts @@ -24,3 +24,9 @@ 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/index.ts b/packages/grid-shared-react/src/index.ts index 989215c..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, Pagination } from './components/options'; +export { + Caption, + Data, + ColumnDefaults, + Column, + Description, + Pagination, + Header +} from './components/options'; export { getChildProps } from './utils/getChildProps'; export type { CaptionProps, @@ -25,6 +33,9 @@ export type { ColumnDataType, ColumnSortingOrder, CellValueGetterContext, - PaginationProps + PaginationProps, + HeaderProps, + GroupedHeaderOptions, + HeaderCellAccessibilityProps } from './components/options'; export type { GridType, GridInstance, GridProps, GridRefHandle }; diff --git a/packages/grid-shared-react/src/utils/getChildProps.ts b/packages/grid-shared-react/src/utils/getChildProps.ts index a33c900..4564d86 100644 --- a/packages/grid-shared-react/src/utils/getChildProps.ts +++ b/packages/grid-shared-react/src/utils/getChildProps.ts @@ -209,6 +209,15 @@ export function getChildProps(children: ReactNode): Record { 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 ? [] : {} );