beautiful-grid 1.0.10 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +153 -117
  2. package/cjs/BGrid.js +208 -53
  3. package/cjs/components/Table.js +75 -63
  4. package/cjs/components/TableBody.js +51 -174
  5. package/cjs/components/TableBodyCell.js +2 -1
  6. package/cjs/components/TableBodyFrozen.js +1 -1
  7. package/cjs/components/TableBodyRow.js +245 -0
  8. package/cjs/components/TreeCell.js +88 -0
  9. package/cjs/components/TreeContext.js +42 -0
  10. package/cjs/store/createAppStore.js +32 -47
  11. package/cjs/utils/checkedIndexes.js +45 -0
  12. package/cjs/utils/gridSearch.js +1 -1
  13. package/cjs/utils/index.js +2 -0
  14. package/cjs/utils/treeData.js +205 -0
  15. package/cjs/utils/useBodyData.js +53 -21
  16. package/esm/BGrid.js +234 -78
  17. package/esm/components/Table.js +23 -11
  18. package/esm/components/TableBody.js +47 -104
  19. package/esm/components/TableBodyCell.js +2 -1
  20. package/esm/components/TableBodyFrozen.js +1 -1
  21. package/esm/components/TableBodyRow.js +125 -0
  22. package/esm/components/TreeCell.js +49 -0
  23. package/esm/components/TreeContext.js +5 -0
  24. package/esm/store/createAppStore.js +13 -25
  25. package/esm/utils/checkedIndexes.js +19 -0
  26. package/esm/utils/gridSearch.js +1 -1
  27. package/esm/utils/index.js +2 -0
  28. package/esm/utils/treeData.js +174 -0
  29. package/esm/utils/useBodyData.js +26 -17
  30. package/package.json +1 -1
  31. package/style.css +125 -43
  32. package/types/BGrid.d.ts +1 -1
  33. package/types/components/Table.d.ts +1 -0
  34. package/types/components/TableBody.d.ts +8 -1
  35. package/types/components/TableBodyCell.d.ts +2 -2
  36. package/types/components/TableBodyFrozen.d.ts +2 -1
  37. package/types/components/TableBodyRow.d.ts +56 -0
  38. package/types/components/TreeCell.d.ts +9 -0
  39. package/types/components/TreeContext.d.ts +16 -0
  40. package/types/types.d.ts +52 -4
  41. package/types/utils/checkedIndexes.d.ts +1 -0
  42. package/types/utils/gridSearch.d.ts +1 -1
  43. package/types/utils/index.d.ts +2 -0
  44. package/types/utils/treeData.d.ts +22 -0
package/README.md CHANGED
@@ -144,17 +144,26 @@ const columns: BGridColumn<OrderItem>[] = [
144
144
  width: 120,
145
145
  align: 'center',
146
146
  itemRender: ({ value }) => (
147
- <span style={{ color: value === 'DELIVERED' ? '#16a34a' : '#ea580c', fontWeight: 600 }}>
148
- {value}
149
- </span>
147
+ <span style={{ color: value === 'DELIVERED' ? '#16a34a' : '#ea580c', fontWeight: 600 }}>{value}</span>
150
148
  ),
151
149
  },
152
150
  ];
153
151
 
154
152
  const sampleData: BGridDataItem<OrderItem>[] = [
155
- { values: { id: 'ORD-001', customer: 'Acme Corp', product: 'Sensor A1', qty: 12, amount: 1440, status: 'DELIVERED' } },
153
+ {
154
+ values: { id: 'ORD-001', customer: 'Acme Corp', product: 'Sensor A1', qty: 12, amount: 1440, status: 'DELIVERED' },
155
+ },
156
156
  { values: { id: 'ORD-002', customer: 'Global Tech', product: 'Module X', qty: 5, amount: 850, status: 'PENDING' } },
157
- { values: { id: 'ORD-003', customer: 'Logi Systems', product: 'Gateway V2', qty: 20, amount: 3200, status: 'SHIPPED' } },
157
+ {
158
+ values: {
159
+ id: 'ORD-003',
160
+ customer: 'Logi Systems',
161
+ product: 'Gateway V2',
162
+ qty: 20,
163
+ amount: 3200,
164
+ status: 'SHIPPED',
165
+ },
166
+ },
158
167
  ];
159
168
 
160
169
  export default function OrderGridPage() {
@@ -168,7 +177,7 @@ export default function OrderGridPage() {
168
177
  height={380}
169
178
  data={sampleData}
170
179
  columns={columnsState}
171
- rowKey="id"
180
+ rowKey='id'
172
181
  showLineNumber
173
182
  rowChecked={{
174
183
  checkedRowKeys,
@@ -415,12 +424,12 @@ function ProductTable({ data }: { data: BGridDataItem<Product>[] }) {
415
424
  height={400}
416
425
  data={data}
417
426
  columns={columns}
418
- rowKey="id"
427
+ rowKey='id'
419
428
  dataControl={{
420
429
  mode: 'client', // 'client' performs in-memory filtering & sorting; 'manual' delegates to server
421
430
  multiSort: true,
422
431
  query,
423
- onChange: (nextQuery) => setQuery(nextQuery),
432
+ onChange: nextQuery => setQuery(nextQuery),
424
433
  }}
425
434
  />
426
435
  );
@@ -476,8 +485,8 @@ const columnGroups: BGridColumnGroupNode[] = [
476
485
  columns={columns}
477
486
  columnGroups={columnGroups}
478
487
  data={data}
479
- rowKey="orderNo"
480
- />
488
+ rowKey='orderNo'
489
+ />;
481
490
  ```
482
491
 
483
492
  ---
@@ -522,14 +531,14 @@ const columns: BGridColumn<Item>[] = [
522
531
  width={720}
523
532
  height={380}
524
533
  editable
525
- editTrigger="dblclick" // 'click' | 'dblclick'
534
+ editTrigger='dblclick' // 'click' | 'dblclick'
526
535
  columns={columns}
527
536
  data={data}
528
- rowKey="id"
537
+ rowKey='id'
529
538
  onChangeData={(rowIndex, colIndex, item, column, meta) => {
530
539
  console.log('Cell updated:', rowIndex, colIndex, item, meta);
531
540
  }}
532
- />
541
+ />;
533
542
  ```
534
543
 
535
544
  #### Plugin Editors (Select, Date, Custom)
@@ -612,14 +621,14 @@ Configure active cell handling and keyboard behavior with `cellNavigationOptions
612
621
  height={400}
613
622
  columns={columns}
614
623
  data={data}
615
- rowKey="id"
624
+ rowKey='id'
616
625
  cellNavigationOptions={{
617
626
  enabled: true,
618
627
  defaultActiveCell: { rowIndex: 0, columnIndex: 0 },
619
628
  wrap: false,
620
629
  editOnEnter: true,
621
630
  keyRepeat: { enabled: true, interval: 16 },
622
- onActiveCellChange: (cell) => {
631
+ onActiveCellChange: cell => {
623
632
  console.log('Active cell moved to:', cell?.rowIndex, cell?.columnIndex);
624
633
  },
625
634
  }}
@@ -648,15 +657,15 @@ Cell range selection and clipboard copy/paste are enabled by default.
648
657
  height={400}
649
658
  columns={columns}
650
659
  data={data}
651
- rowKey="id"
660
+ rowKey='id'
652
661
  cellSelectionOptions={{
653
662
  enabled: true,
654
663
  clearOnEscape: true,
655
664
  clearOnOutsideClick: true,
656
665
  maxClipboardCells: 100000,
657
666
  maxClipboardTextLength: 8 * 1024 * 1024,
658
- onCopyError: (error) => console.warn('Copy skipped:', error),
659
- onPasteError: (error) => console.warn('Paste failed:', error),
667
+ onCopyError: error => console.warn('Copy skipped:', error),
668
+ onPasteError: error => console.warn('Paste failed:', error),
660
669
  createRowOnPaste: ({ rowIndex, clipboardRow, columns }) => ({
661
670
  values: createNewRowModel(clipboardRow),
662
671
  }),
@@ -680,14 +689,14 @@ Built-in full-text search across loaded store data and right-click context menus
680
689
  height={420}
681
690
  columns={columns}
682
691
  data={data}
683
- rowKey="id"
692
+ rowKey='id'
684
693
  searchOptions={{
685
694
  enabled: true,
686
695
  shortcut: true, // Cmd+F / Ctrl+F
687
696
  }}
688
697
  contextMenuOptions={{
689
698
  enabled: true,
690
- items: (target) => [
699
+ items: target => [
691
700
  {
692
701
  id: 'view-details',
693
702
  label: 'View Row Details',
@@ -720,7 +729,7 @@ BeautifulGrid provides customizable scrollbars and unified bottom bar controls:
720
729
  height={400}
721
730
  columns={columns}
722
731
  data={data}
723
- rowKey="id"
732
+ rowKey='id'
724
733
  bottomBarHeight={34}
725
734
  scrollbar={{
726
735
  variant: 'modern', // 'modern' (sleek overlay) | 'classic' (win-style) | 'native'
@@ -730,7 +739,9 @@ BeautifulGrid provides customizable scrollbars and unified bottom bar controls:
730
739
  status={{
731
740
  visible: true,
732
741
  content: ({ visibleItems, totalItems }) => (
733
- <span>Showing {visibleItems} of {totalItems} entries</span>
742
+ <span>
743
+ Showing {visibleItems} of {totalItems} entries
744
+ </span>
734
745
  ),
735
746
  }}
736
747
  />
@@ -754,13 +765,13 @@ function PaginatedGrid() {
754
765
  height={450}
755
766
  columns={columns}
756
767
  data={pageData}
757
- rowKey="id"
768
+ rowKey='id'
758
769
  page={{
759
770
  currentPage,
760
771
  pageSize,
761
772
  totalElements,
762
773
  totalPages: Math.ceil(totalElements / pageSize),
763
- onChange: (newPage) => setCurrentPage(newPage),
774
+ onChange: newPage => setCurrentPage(newPage),
764
775
  }}
765
776
  />
766
777
  );
@@ -778,10 +789,10 @@ Fix leading columns and top rows while the remaining area scrolls smoothly:
778
789
  width={900}
779
790
  height={500}
780
791
  frozenColumnIndex={2} // Columns 0 and 1 are pinned to the left
781
- frozenRowCount={3} // First 3 data rows are pinned to the top
792
+ frozenRowCount={3} // First 3 data rows are pinned to the top
782
793
  columns={columns}
783
794
  data={data}
784
- rowKey="id"
795
+ rowKey='id'
785
796
  />
786
797
  ```
787
798
 
@@ -797,11 +808,11 @@ Enable drag-and-drop or keyboard row sorting:
797
808
  height={400}
798
809
  columns={columns}
799
810
  data={data}
800
- rowKey="id"
811
+ rowKey='id'
801
812
  showLineNumber // Line number handle hosts the reorder grip
802
813
  reorder={{
803
814
  enabled: true,
804
- onReorder: (nextData) => {
815
+ onReorder: nextData => {
805
816
  setData(nextData);
806
817
  return true; // Return false to roll back
807
818
  },
@@ -823,7 +834,7 @@ Add top or bottom summary/aggregation rows:
823
834
  height={400}
824
835
  columns={columns}
825
836
  data={data}
826
- rowKey="id"
837
+ rowKey='id'
827
838
  summary={{
828
839
  position: 'bottom', // 'top' | 'bottom'
829
840
  columns: [
@@ -832,9 +843,7 @@ Add top or bottom summary/aggregation rows:
832
843
  columnIndex: 3,
833
844
  align: 'right',
834
845
  itemRender: ({ data }) => (
835
- <strong>
836
- ${data.reduce((sum, item) => sum + (item.values.amount || 0), 0).toLocaleString()}
837
- </strong>
846
+ <strong>${data.reduce((sum, item) => sum + (item.values.amount || 0), 0).toLocaleString()}</strong>
838
847
  ),
839
848
  },
840
849
  ],
@@ -854,7 +863,7 @@ Merge consecutive identical cells vertically:
854
863
  height={400}
855
864
  columns={columns}
856
865
  data={data}
857
- rowKey="id"
866
+ rowKey='id'
858
867
  cellMergeOptions={{
859
868
  columnsMap: {
860
869
  0: { mergeBy: 'department' }, // Column index 0 merges based on department field
@@ -899,8 +908,8 @@ const pivotConfig: BGridProps<SalesRecord>['pivot'] = {
899
908
  columns={baseColumns}
900
909
  data={salesData}
901
910
  pivot={pivotConfig}
902
- variant="vertical-bordered"
903
- />
911
+ variant='vertical-bordered'
912
+ />;
904
913
  ```
905
914
 
906
915
  ---
@@ -934,6 +943,32 @@ Set `hideable: false` on columns that must remain available. The final visible c
934
943
 
935
944
  ---
936
945
 
946
+ ### 15. Tree Grid
947
+
948
+ Add the `tree` prop to `<BGrid>` for flat parent/child data. `rowKey` identifies each row and `tree.parentRowKey` names the field containing its parent's key. `tree.treeColumnId` selects the column that renders indentation and the folding icon. Expansion can be uncontrolled with `defaultExpandedRowKeys` or controlled with `expandedRowKeys`.
949
+
950
+ ```typescript jsx
951
+ const [expandedRowKeys, setExpandedRowKeys] = React.useState(['group-a']);
952
+
953
+ <BGrid
954
+ width={800}
955
+ height={420}
956
+ columns={columns}
957
+ data={rows}
958
+ rowKey='id'
959
+ tree={{
960
+ parentRowKey: 'parentId',
961
+ treeColumnId: 'name',
962
+ expandedRowKeys,
963
+ onExpandedRowKeysChange: setExpandedRowKeys,
964
+ }}
965
+ />;
966
+ ```
967
+
968
+ Rows whose parent is missing are treated as roots. Cycles are contained, the source row order is retained, and edit callbacks receive the original source index even when ancestors are collapsed.
969
+
970
+ ---
971
+
937
972
  ## Props Reference
938
973
 
939
974
  ### BGridProps
@@ -942,107 +977,108 @@ Below is a categorized reference of `<BGrid>` props. For exact TypeScript types,
942
977
 
943
978
  #### Required Props
944
979
 
945
- | Prop | Type | Description |
946
- |---|---|---|
947
- | `width` | `number` | Total pixel width of the grid container (required for virtualization). |
948
- | `height` | `number` | Total pixel height of the grid container (required for virtualization). |
949
- | `columns` | `BGridColumn<T>[]` | Array of column definitions (`width` defaults to 100 if omitted). |
980
+ | Prop | Type | Description |
981
+ | --------- | ------------------ | ----------------------------------------------------------------------- |
982
+ | `width` | `number` | Total pixel width of the grid container (required for virtualization). |
983
+ | `height` | `number` | Total pixel height of the grid container (required for virtualization). |
984
+ | `columns` | `BGridColumn<T>[]` | Array of column definitions (`width` defaults to 100 if omitted). |
950
985
 
951
986
  #### Data & Selection
952
987
 
953
- | Prop | Type | Description |
954
- |---|---|---|
955
- | `data` | `BGridDataItem<T>[]` | Array of row data wrapped in `{ values: T }`. |
956
- | `rowKey` | `React.Key \| React.Key[]` | Unique identifier field in `item.values` (string or array path). |
957
- | `selectedRowKey` | `React.Key \| React.Key[]` | Key of the currently focused/highlighted row. |
958
- | `rowChecked` | `BGridRowChecked<T>` | Checkbox / radio row selection configuration. |
959
- | `getRowClassName` | `(ri: number, item: BGridDataItem<T>) => string \| undefined` | Custom row class name generator. |
988
+ | Prop | Type | Description |
989
+ | ----------------- | ------------------------------------------------------------- | ---------------------------------------------------------------- |
990
+ | `data` | `BGridDataItem<T>[]` | Array of row data wrapped in `{ values: T }`. |
991
+ | `rowKey` | `React.Key \| React.Key[]` | Unique identifier field in `item.values` (string or array path). |
992
+ | `selectedRowKey` | `React.Key \| React.Key[]` | Key of the currently focused/highlighted row. |
993
+ | `rowChecked` | `BGridRowChecked<T>` | Checkbox / radio row selection configuration. |
994
+ | `getRowClassName` | `(ri: number, item: BGridDataItem<T>) => string \| undefined` | Custom row class name generator. |
960
995
 
961
996
  #### Layout & Sizing
962
997
 
963
- | Prop | Type | Default | Description |
964
- |---|---|---|---|
965
- | `headerHeight` | `number` | `30` | Header row height in pixels. |
966
- | `bottomBarHeight` | `number` | `30` | Bottom bar (pagination / status) height in pixels. |
967
- | `summaryHeight` | `number` | `30` | Summary row height in pixels. |
968
- | `itemHeight` | `number` | `15` | Body row content height. |
969
- | `itemPadding` | `number` | `7` | Body row top/bottom padding (total row height = `itemHeight + itemPadding * 2`). |
970
- | `getRowHeight` | `(row: T, index: number) => number` | — | Complete rendered height for each displayed row. Invalid values fall back to `itemHeight + itemPadding * 2`. |
971
- | `frozenColumnIndex` | `number` | `0` | Pinned column boundary index (columns `< frozenColumnIndex` are fixed). |
972
- | `frozenRowCount` | `number` | `0` | Number of leading rows pinned below the top summary row. |
973
- | `showLineNumber` | `boolean` | `false` | Shows row index numbers and reorder handles on the left. |
974
- | `variant` | `'default' \| 'vertical-bordered'` | `'default'` | Visual border styling variant. |
998
+ | Prop | Type | Default | Description |
999
+ | ------------------- | ----------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------ |
1000
+ | `headerHeight` | `number` | `30` | Header row height in pixels. |
1001
+ | `bottomBarHeight` | `number` | `30` | Bottom bar (pagination / status) height in pixels. |
1002
+ | `summaryHeight` | `number` | `30` | Summary row height in pixels. |
1003
+ | `itemHeight` | `number` | `15` | Body row content height. |
1004
+ | `itemPadding` | `number` | `7` | Body row top/bottom padding (total row height = `itemHeight + itemPadding * 2`). |
1005
+ | `getRowHeight` | `(row: T, index: number) => number` | — | Complete rendered height for each displayed row. Invalid values fall back to `itemHeight + itemPadding * 2`. |
1006
+ | `frozenColumnIndex` | `number` | `0` | Pinned column boundary index (columns `< frozenColumnIndex` are fixed). |
1007
+ | `frozenRowCount` | `number` | `0` | Number of leading rows pinned below the top summary row. |
1008
+ | `showLineNumber` | `boolean` | `false` | Shows row index numbers and reorder handles on the left. |
1009
+ | `variant` | `'default' \| 'vertical-bordered'` | `'default'` | Visual border styling variant. |
975
1010
 
976
1011
  #### Columns & Headers
977
1012
 
978
- | Prop | Type | Description |
979
- |---|---|---|
980
- | `columnGroups` | `BGridColumnGroupNode[]` | Tree-based multi-level grouped header configuration. |
981
- | `columnSortable` | `boolean` | Enables dragging header columns to reorder. |
982
- | `onChangeColumns` | `(columnIndex: number \| null, info: BGridChangeColumnsInfo<T>) => void` | Callback fired when column widths or orders change. |
1013
+ | Prop | Type | Description |
1014
+ | ----------------- | ------------------------------------------------------------------------ | ---------------------------------------------------- |
1015
+ | `columnGroups` | `BGridColumnGroupNode[]` | Tree-based multi-level grouped header configuration. |
1016
+ | `columnSortable` | `boolean` | Enables dragging header columns to reorder. |
1017
+ | `onChangeColumns` | `(columnIndex: number \| null, info: BGridChangeColumnsInfo<T>) => void` | Callback fired when column widths or orders change. |
983
1018
 
984
1019
  #### Editing & Interactivity
985
1020
 
986
- | Prop | Type | Default | Description |
987
- |---|---|---|---|
988
- | `editable` | `boolean` | `false` | Master switch for cell editing. |
989
- | `editTrigger` | `'click' \| 'dblclick'` | `'dblclick'` | User event that activates inline editors. |
990
- | `onChangeData` | `(index, columnIndex, item, column, meta) => void` | - | Callback fired after a cell edit commits. |
991
- | `onClick` | `(params: BGridClickParams<T>) => void` | - | Cell click callback. |
992
- | `cellNavigationOptions` | `BGridCellNavigationOptions` | - | Active cell focus, arrow key navigation, and repeat options. |
993
- | `cellSelectionOptions` | `BGridCellSelectionOptions` | - | Range drag selection and clipboard copy/paste options. |
1021
+ | Prop | Type | Default | Description |
1022
+ | ----------------------- | -------------------------------------------------- | ------------ | ------------------------------------------------------------ |
1023
+ | `editable` | `boolean` | `false` | Master switch for cell editing. |
1024
+ | `editTrigger` | `'click' \| 'dblclick'` | `'dblclick'` | User event that activates inline editors. |
1025
+ | `onChangeData` | `(index, columnIndex, item, column, meta) => void` | - | Callback fired after a cell edit commits. |
1026
+ | `onClick` | `(params: BGridClickParams<T>) => void` | - | Cell click callback. |
1027
+ | `cellNavigationOptions` | `BGridCellNavigationOptions` | - | Active cell focus, arrow key navigation, and repeat options. |
1028
+ | `cellSelectionOptions` | `BGridCellSelectionOptions` | - | Range drag selection and clipboard copy/paste options. |
994
1029
 
995
1030
  #### Additional Features & Overlays
996
1031
 
997
- | Prop | Type | Description |
998
- |---|---|---|
999
- | `dataControl` | `BGridDataControl` | Controlled sort & filter state (`mode: 'client' \| 'manual'`). |
1000
- | `sort` | `BGridSortInfo` | Simple sorting state and callback (superseded by `dataControl` when present). |
1001
- | `page` | `BGridPage` | Pagination state, totals, and page change callback. |
1002
- | `scrollbar` | `BGridScrollbarOptions` | Scrollbar variant (`'modern' \| 'classic' \| 'native'`) and visibility. |
1003
- | `status` | `BGridStatusOptions` | Bottom bar status text / custom render function. |
1004
- | `pagination` | `BGridPaginationViewOptions` | Bottom bar pagination element visibility. |
1005
- | `searchOptions` | `BGridSearchOptions<T>` | Grid in-memory search UI, shortcuts (`Cmd+F`), and highlights. |
1006
- | `contextMenuOptions` | `BGridContextMenuOptions<T>` | Right-click and `Shift+F10` cell context menu items. |
1007
- | `reorder` | `BGridReorderInfo<T>` | Drag and keyboard row reordering configuration. |
1008
- | `summary` | `{ position: 'top' \| 'bottom'; columns: BGridSummaryColumn<T>[] }` | Static summary row configuration. |
1009
- | `cellMergeOptions` | `{ columnsMap: Record<number, BGridCellMergeColumn> }` | Vertical cell merge rules. |
1010
- | `pivot` | `BGridPivotOptions<T>` | Pivot table dimensions, aggregation rules, and metrics. |
1011
- | `columnVisibility` | `boolean \| BGridColumnVisibilityOptions<T>` | Enables controlled or uncontrolled column hiding and restore controls (since `1.0.6`). |
1012
- | `loading` | `boolean` | Displays full-grid loading overlay. |
1013
- | `spinning` | `boolean` | Displays body-area spinner. |
1014
- | `msg` | `{ emptyList?: string }` | Custom empty state text. |
1032
+ | Prop | Type | Description |
1033
+ | -------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
1034
+ | `dataControl` | `BGridDataControl` | Controlled sort & filter state (`mode: 'client' \| 'manual'`). |
1035
+ | `sort` | `BGridSortInfo` | Simple sorting state and callback (superseded by `dataControl` when present). |
1036
+ | `page` | `BGridPage` | Pagination state, totals, and page change callback. |
1037
+ | `scrollbar` | `BGridScrollbarOptions` | Scrollbar variant (`'modern' \| 'classic' \| 'native'`) and visibility. |
1038
+ | `status` | `BGridStatusOptions` | Bottom bar status text / custom render function. |
1039
+ | `pagination` | `BGridPaginationViewOptions` | Bottom bar pagination element visibility. |
1040
+ | `searchOptions` | `BGridSearchOptions<T>` | Grid in-memory search UI, shortcuts (`Cmd+F`), and highlights. |
1041
+ | `contextMenuOptions` | `BGridContextMenuOptions<T>` | Right-click and `Shift+F10` cell context menu items. |
1042
+ | `reorder` | `BGridReorderInfo<T>` | Drag and keyboard row reordering configuration. |
1043
+ | `summary` | `{ position: 'top' \| 'bottom'; columns: BGridSummaryColumn<T>[] }` | Static summary row configuration. |
1044
+ | `cellMergeOptions` | `{ columnsMap: Record<number, BGridCellMergeColumn> }` | Vertical cell merge rules. |
1045
+ | `pivot` | `BGridPivotOptions<T>` | Pivot table dimensions, aggregation rules, and metrics. |
1046
+ | `columnVisibility` | `boolean \| BGridColumnVisibilityOptions<T>` | Enables controlled or uncontrolled column hiding and restore controls (since `1.0.6`). |
1047
+ | `tree` | `BGridTreeOptions<T>` | Renders flat parent-key data as collapsible hierarchical rows. |
1048
+ | `loading` | `boolean` | Displays full-grid loading overlay. |
1049
+ | `spinning` | `boolean` | Displays body-area spinner. |
1050
+ | `msg` | `{ emptyList?: string }` | Custom empty state text. |
1015
1051
 
1016
1052
  ---
1017
1053
 
1018
1054
  ### BGridColumn
1019
1055
 
1020
- | Property | Type | Description |
1021
- |---|---|---|
1022
- | `id` | `string` | Unique column identifier (recommended for `columnGroups`, toolboxes, and persistence). |
1023
- | `key` | `string \| string[]` | Field key or nested path array to read from `item.values`. |
1024
- | `label` | `ReactNode` | Header label content. |
1025
- | `width` | `number` | Column width in pixels (defaults to `100` if omitted). |
1026
- | `align` | `'left' \| 'center' \| 'right'` | Body cell horizontal text alignment. |
1027
- | `headerAlign` | `'left' \| 'center' \| 'right'` | Header cell horizontal text alignment. |
1028
- | `sortDisable` | `boolean` | Disables sorting on this column. |
1029
- | `className` | `string` | Static class name applied to body cells. |
1030
- | `getClassName` | `(item: BGridDataItem<T>) => string` | Dynamic class name generator for body cells. |
1031
- | `headerClassName` | `string` | Custom class name for the column header. |
1032
- | `headerStyle` | `React.CSSProperties` | Custom CSS style for the column header. |
1033
- | `itemRender` | `React.FC<BGridItemRenderProps<T>>` | Custom cell content render function. |
1034
- | `editable` | `boolean` | Enables editing on this specific column. |
1035
- | `editor` | `BGridCellEditorConfig<T>` | Editor configuration (`type: 'text' \| 'checkbox' \| 'plugin'`). |
1036
- | `editTrigger` | `'click' \| 'dblclick'` | Overrides grid-level edit trigger for this column. |
1037
- | `editorIcon` | `BGridEditorIconConfig<T>` | Inline icon trigger for dropdowns, popups, or lookup dialogs. |
1038
- | `onChangeValue` | `(params: BGridChangeValueParams<T>) => void \| Promise<void>` | Column-level change interceptor with commit/cancel controller. |
1039
- | `getClipboardText` | `(params: BGridCellClipboardTextParams<T>) => any` | Custom string serializer for clipboard copy. |
1040
- | `searchable` | `boolean` | Whether this column participates in grid search (defaults to `true`). |
1041
- | `getSearchText` | `(params: BGridSearchCellParams<T>) => unknown` | Custom string extractor for grid search matching. |
1042
- | `toolbox` | `boolean \| BGridToolboxConfig<T>` | Enables header sort/filter toolbox popup. |
1043
- | `hideable` | `boolean` | Allows this column to be hidden through the visibility menu (defaults to `true`, since `1.0.6`). |
1044
- | `filter` | `false \| BGridColumnFilterConfig<T>` | Column filter configuration (`type: 'values' \| 'text' \| 'number'`). |
1045
- | `sortComparator` | `(a, b, params) => number` | Custom comparator function for sorting. |
1056
+ | Property | Type | Description |
1057
+ | ------------------ | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
1058
+ | `id` | `string` | Unique column identifier (recommended for `columnGroups`, toolboxes, and persistence). |
1059
+ | `key` | `string \| string[]` | Field key or nested path array to read from `item.values`. |
1060
+ | `label` | `ReactNode` | Header label content. |
1061
+ | `width` | `number` | Column width in pixels (defaults to `100` if omitted). |
1062
+ | `align` | `'left' \| 'center' \| 'right'` | Body cell horizontal text alignment. |
1063
+ | `headerAlign` | `'left' \| 'center' \| 'right'` | Header cell horizontal text alignment. |
1064
+ | `sortDisable` | `boolean` | Disables sorting on this column. |
1065
+ | `className` | `string` | Static class name applied to body cells. |
1066
+ | `getClassName` | `(item: BGridDataItem<T>) => string` | Dynamic class name generator for body cells. |
1067
+ | `headerClassName` | `string` | Custom class name for the column header. |
1068
+ | `headerStyle` | `React.CSSProperties` | Custom CSS style for the column header. |
1069
+ | `itemRender` | `React.FC<BGridItemRenderProps<T>>` | Custom cell content render function. |
1070
+ | `editable` | `boolean` | Enables editing on this specific column. |
1071
+ | `editor` | `BGridCellEditorConfig<T>` | Editor configuration (`type: 'text' \| 'checkbox' \| 'plugin'`). |
1072
+ | `editTrigger` | `'click' \| 'dblclick'` | Overrides grid-level edit trigger for this column. |
1073
+ | `editorIcon` | `BGridEditorIconConfig<T>` | Inline icon trigger for dropdowns, popups, or lookup dialogs. |
1074
+ | `onChangeValue` | `(params: BGridChangeValueParams<T>) => void \| Promise<void>` | Column-level change interceptor with commit/cancel controller. |
1075
+ | `getClipboardText` | `(params: BGridCellClipboardTextParams<T>) => any` | Custom string serializer for clipboard copy. |
1076
+ | `searchable` | `boolean` | Whether this column participates in grid search (defaults to `true`). |
1077
+ | `getSearchText` | `(params: BGridSearchCellParams<T>) => unknown` | Custom string extractor for grid search matching. |
1078
+ | `toolbox` | `boolean \| BGridToolboxConfig<T>` | Enables header sort/filter toolbox popup. |
1079
+ | `hideable` | `boolean` | Allows this column to be hidden through the visibility menu (defaults to `true`, since `1.0.6`). |
1080
+ | `filter` | `false \| BGridColumnFilterConfig<T>` | Column filter configuration (`type: 'values' \| 'text' \| 'number'`). |
1081
+ | `sortComparator` | `(a, b, params) => number` | Custom comparator function for sorting. |
1046
1082
 
1047
1083
  ---
1048
1084
 
@@ -1123,7 +1159,7 @@ npm run preview
1123
1159
 
1124
1160
  ## Test Coverage
1125
1161
 
1126
- BeautifulGrid maintains high test coverage to ensure stability across complex features like virtualization, cell editing, and focus management.
1162
+ BeautifulGrid maintains high test coverage to ensure stability across complex features like virtualization, cell editing, and focus management.
1127
1163
  Coverage reports are generated via Vitest. To view the detailed HTML report, run:
1128
1164
 
1129
1165
  ```bash