beautiful-grid 1.0.4 → 1.0.6

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 (35) hide show
  1. package/README.md +47 -4
  2. package/cjs/BGrid.js +167 -39
  3. package/cjs/components/Table.js +71 -57
  4. package/cjs/components/TableHeadColumn.js +4 -1
  5. package/cjs/components/toolbox/TableHeadToolbox.js +8 -3
  6. package/cjs/components/toolbox/ToolboxColumnVisibilitySection.js +131 -0
  7. package/cjs/components/toolbox/index.js +1 -0
  8. package/cjs/store/createAppStore.js +2 -0
  9. package/cjs/utils/columnVisibility.js +114 -0
  10. package/cjs/utils/coordinate.js +7 -7
  11. package/cjs/utils/getVisibleScrollableRowRange.js +5 -4
  12. package/cjs/utils/index.js +1 -0
  13. package/esm/BGrid.js +168 -50
  14. package/esm/components/Table.js +23 -4
  15. package/esm/components/TableHeadColumn.js +4 -1
  16. package/esm/components/toolbox/TableHeadToolbox.js +8 -3
  17. package/esm/components/toolbox/ToolboxColumnVisibilitySection.js +68 -0
  18. package/esm/components/toolbox/index.js +1 -0
  19. package/esm/store/createAppStore.js +2 -0
  20. package/esm/utils/columnVisibility.js +89 -0
  21. package/esm/utils/coordinate.js +1 -1
  22. package/esm/utils/getVisibleScrollableRowRange.js +5 -4
  23. package/esm/utils/index.js +1 -0
  24. package/package.json +1 -1
  25. package/style.css +87 -0
  26. package/types/BGrid.d.ts +1 -1
  27. package/types/components/Table.d.ts +2 -1
  28. package/types/components/toolbox/ToolboxColumnVisibilitySection.d.ts +11 -0
  29. package/types/components/toolbox/index.d.ts +1 -0
  30. package/types/store/createAppStore.d.ts +1 -1
  31. package/types/types.d.ts +38 -0
  32. package/types/utils/columnVisibility.d.ts +21 -0
  33. package/types/utils/coordinate.d.ts +1 -0
  34. package/types/utils/getVisibleScrollableRowRange.d.ts +2 -1
  35. package/types/utils/index.d.ts +1 -0
package/README.md CHANGED
@@ -2,12 +2,23 @@
2
2
 
3
3
  **Beautiful. Powerful. Naturally React.**
4
4
 
5
- [![NPM version](https://img.shields.io/npm/v/beautiful-grid.svg?style=flat)](https://npmjs.org/package/beautiful-grid)
6
- [![NPM downloads](https://img.shields.io/npm/dm/beautiful-grid.svg?style=flat)](https://npmjs.org/package/beautiful-grid)
5
+ [![NPM version](https://img.shields.io/npm/v/beautiful-grid?logo=npm)](https://npmjs.org/package/beautiful-grid)
6
+ [![NPM downloads](https://img.shields.io/npm/dm/beautiful-grid?color=blue&logo=npm)](https://npmjs.org/package/beautiful-grid)
7
+ [![Bundle size](https://img.shields.io/badge/minzipped-62.6%20KiB-success)](https://bgrid.axisj.com)
8
+ [![Unpacked size](https://img.shields.io/npm/unpacked-size/beautiful-grid?color=informational)](https://www.npmjs.com/package/beautiful-grid)
9
+ [![Test](https://img.shields.io/github/actions/workflow/status/axisj/beautiful-grid/tests.yml?branch=main&label=tests&logo=github)](https://github.com/axisj/beautiful-grid/actions/workflows/tests.yml)
10
+ <br />
7
11
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
8
- [![Coverage](https://img.shields.io/badge/coverage-85.63%25-brightgreen.svg)](https://github.com/axisj/beautiful-grid/actions/workflows/tests.yml)
12
+ [![TypeScript](https://img.shields.io/npm/types/beautiful-grid?logo=typescript&logoColor=white)](https://www.npmjs.com/package/beautiful-grid)
13
+ [![React](https://img.shields.io/badge/React-%5E19.0.0-61DAFB?logo=react&logoColor=black)](https://react.dev/)
14
+ [![Node](https://img.shields.io/badge/node-%3E%3D22-339933?logo=node.js&logoColor=white)](https://nodejs.org)
15
+ [![Last commit](https://img.shields.io/github/last-commit/axisj/beautiful-grid?logo=git)](https://github.com/axisj/beautiful-grid/commits/main)
16
+ <br />
17
+ [![GitHub stars](https://img.shields.io/github/stars/axisj/beautiful-grid?logo=github)](https://github.com/axisj/beautiful-grid/stargazers)
18
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/axisj/beautiful-grid/pulls)
19
+ [![Docs](https://img.shields.io/badge/docs-bgrid.axisj.com-blue?logo=googlechrome&logoColor=white)](https://bgrid.axisj.com)
9
20
 
10
- BeautifulGrid is a high-performance, feature-packed, and beautifully designed open-source React Data Grid for data-heavy business applications. It combines zero-runtime-CSS styling with virtual scrolling, spreadsheet-like cell selection and clipboard operations, built-in and plugin cell editing, multi-level grouped headers, filtering & sorting toolboxes, server/client pagination, pivot table transforms, row reordering, and flexible theming.
21
+ BeautifulGrid is a high-performance, feature-packed, and beautifully designed open-source React Data Grid for data-heavy business applications. It combines zero-runtime-CSS styling with virtual scrolling, spreadsheet-like cell selection and clipboard operations, built-in and plugin cell editing, multi-level grouped headers, filtering & sorting toolboxes, recoverable column visibility, server/client pagination, pivot table transforms, row reordering, and flexible theming.
11
22
 
12
23
  Explore live interactive examples and in-depth documentation at [bgrid.axisj.com](https://bgrid.axisj.com).
13
24
 
@@ -33,6 +44,7 @@ Explore live interactive examples and in-depth documentation at [bgrid.axisj.com
33
44
  - [11. Summary Row](#11-summary-row)
34
45
  - [12. Cell Merging](#12-cell-merging)
35
46
  - [13. Pivot Table](#13-pivot-table)
47
+ - [14. Column Visibility](#14-column-visibility)
36
48
  - [Props Reference](#props-reference)
37
49
  - [BGridProps](#bgridprops)
38
50
  - [BGridColumn](#bgridcolumn)
@@ -846,6 +858,35 @@ const pivotConfig: BGridProps<SalesRecord>['pivot'] = {
846
858
 
847
859
  ---
848
860
 
861
+ ### 14. Column Visibility
862
+
863
+ Available since BeautifulGrid `1.0.6`.
864
+
865
+ Enable recoverable column hiding through the existing header toolbox. Use controlled state to persist a user's visible-column preferences.
866
+
867
+ ```typescript jsx
868
+ function OrdersGrid({ data, columns }) {
869
+ const [hiddenColumnIds, setHiddenColumnIds] = React.useState(['owner']);
870
+
871
+ return (
872
+ <BGrid
873
+ width={800}
874
+ height={420}
875
+ data={data}
876
+ columns={columns}
877
+ columnVisibility={{
878
+ hiddenColumnIds,
879
+ onChange: setHiddenColumnIds,
880
+ }}
881
+ />
882
+ );
883
+ }
884
+ ```
885
+
886
+ Set `hideable: false` on columns that must remain available. The final visible column cannot be hidden, and active sort/filter conditions remain intact while their column is hidden.
887
+
888
+ ---
889
+
849
890
  ## Props Reference
850
891
 
851
892
  ### BGridProps
@@ -919,6 +960,7 @@ Below is a categorized reference of `<BGrid>` props. For exact TypeScript types,
919
960
  | `summary` | `{ position: 'top' \| 'bottom'; columns: BGridSummaryColumn<T>[] }` | Static summary row configuration. |
920
961
  | `cellMergeOptions` | `{ columnsMap: Record<number, BGridCellMergeColumn> }` | Vertical cell merge rules. |
921
962
  | `pivot` | `BGridPivotOptions<T>` | Pivot table dimensions, aggregation rules, and metrics. |
963
+ | `columnVisibility` | `boolean \| BGridColumnVisibilityOptions<T>` | Enables controlled or uncontrolled column hiding and restore controls (since `1.0.6`). |
922
964
  | `loading` | `boolean` | Displays full-grid loading overlay. |
923
965
  | `spinning` | `boolean` | Displays body-area spinner. |
924
966
  | `msg` | `{ emptyList?: string }` | Custom empty state text. |
@@ -950,6 +992,7 @@ Below is a categorized reference of `<BGrid>` props. For exact TypeScript types,
950
992
  | `searchable` | `boolean` | Whether this column participates in grid search (defaults to `true`). |
951
993
  | `getSearchText` | `(params: BGridSearchCellParams<T>) => unknown` | Custom string extractor for grid search matching. |
952
994
  | `toolbox` | `boolean \| BGridToolboxConfig<T>` | Enables header sort/filter toolbox popup. |
995
+ | `hideable` | `boolean` | Allows this column to be hidden through the visibility menu (defaults to `true`, since `1.0.6`). |
953
996
  | `filter` | `false \| BGridColumnFilterConfig<T>` | Column filter configuration (`type: 'values' \| 'text' \| 'number'`). |
954
997
  | `sortComparator` | `(a, b, params) => number` | Custom comparator function for sorting. |
955
998
 
package/cjs/BGrid.js CHANGED
@@ -77,10 +77,28 @@ var React = __importStar(require("react"));
77
77
  var Table_1 = __importDefault(require("./components/Table"));
78
78
  var utils_1 = require("./utils");
79
79
  var store_1 = require("./store");
80
+ function computeModelColumns(columns, frozenColumnIndex, duplicateToolboxColumnIds) {
81
+ var left = 0;
82
+ var previousWidth = 0;
83
+ return columns.map(function (column, columnIndex) {
84
+ var _a, _b;
85
+ var columnId = (0, utils_1.getColumnId)(column);
86
+ if (columnIndex >= frozenColumnIndex) {
87
+ left += previousWidth;
88
+ previousWidth = (_a = column.width) !== null && _a !== void 0 ? _a : 100;
89
+ }
90
+ return __assign(__assign({}, column), { columnId: columnId, keyToken: (0, utils_1.getColumnKeyToken)(column.key), toolbox: duplicateToolboxColumnIds.has(columnId) ? false : column.toolbox, left: columnIndex < frozenColumnIndex ? -1 : left, width: (_b = column.width) !== null && _b !== void 0 ? _b : 100 });
91
+ });
92
+ }
80
93
  function BGrid(_a) {
81
94
  var _b, _c, _d;
82
- var ref = _a.ref, width = _a.width, height = _a.height, _e = _a.headerHeight, headerHeight = _e === void 0 ? 30 : _e, footerHeight = _a.footerHeight, _f = _a.summaryHeight, summaryHeight = _f === void 0 ? 30 : _f, _g = _a.itemHeight, itemHeight = _g === void 0 ? 15 : _g, _h = _a.itemPadding, itemPadding = _h === void 0 ? 7 : _h, columns = _a.columns, columnsGroup = _a.columnsGroup, columnGroups = _a.columnGroups, onChangeColumns = _a.onChangeColumns, _j = _a.frozenColumnIndex, frozenColumnIndex = _j === void 0 ? 0 : _j, _k = _a.frozenRowCount, frozenRowCount = _k === void 0 ? 0 : _k, _l = _a.data, data = _l === void 0 ? [] : _l, page = _a.page, scrollbar = _a.scrollbar, status = _a.status, pagination = _a.pagination, bottomBarHeight = _a.bottomBarHeight, _m = _a.scrollTop, scrollTop = _m === void 0 ? 0 : _m, _o = _a.scrollLeft, scrollLeft = _o === void 0 ? 0 : _o, className = _a.className, style = _a.style, rowChecked = _a.rowChecked, sort = _a.sort, onClick = _a.onClick, _p = _a.loading, loading = _p === void 0 ? false : _p, spinning = _a.spinning, rowKey = _a.rowKey, selectedRowKey = _a.selectedRowKey, editable = _a.editable, onChangeData = _a.onChangeData, showLineNumber = _a.showLineNumber, msg = _a.msg, getRowClassName = _a.getRowClassName, _q = _a.editTrigger, editTrigger = _q === void 0 ? 'dblclick' : _q, cellMergeOptions = _a.cellMergeOptions, cellSelectionOptions = _a.cellSelectionOptions, cellNavigationOptions = _a.cellNavigationOptions, variant = _a.variant, summary = _a.summary, columnSortable = _a.columnSortable, reorder = _a.reorder, pivot = _a.pivot, dataControl = _a.dataControl, icons = _a.icons, searchOptions = _a.searchOptions, contextMenuOptions = _a.contextMenuOptions;
83
- var warnedSearchControlledRef = React.useRef({ open: false, query: false, pivotContextMenu: false });
95
+ var ref = _a.ref, width = _a.width, height = _a.height, _e = _a.headerHeight, headerHeight = _e === void 0 ? 30 : _e, footerHeight = _a.footerHeight, _f = _a.summaryHeight, summaryHeight = _f === void 0 ? 30 : _f, _g = _a.itemHeight, itemHeight = _g === void 0 ? 15 : _g, _h = _a.itemPadding, itemPadding = _h === void 0 ? 7 : _h, columns = _a.columns, columnsGroup = _a.columnsGroup, columnGroups = _a.columnGroups, onChangeColumns = _a.onChangeColumns, _j = _a.frozenColumnIndex, frozenColumnIndex = _j === void 0 ? 0 : _j, _k = _a.frozenRowCount, frozenRowCount = _k === void 0 ? 0 : _k, _l = _a.data, data = _l === void 0 ? [] : _l, page = _a.page, scrollbar = _a.scrollbar, status = _a.status, pagination = _a.pagination, bottomBarHeight = _a.bottomBarHeight, _m = _a.scrollTop, scrollTop = _m === void 0 ? 0 : _m, _o = _a.scrollLeft, scrollLeft = _o === void 0 ? 0 : _o, className = _a.className, style = _a.style, rowChecked = _a.rowChecked, sort = _a.sort, onClick = _a.onClick, _p = _a.loading, loading = _p === void 0 ? false : _p, spinning = _a.spinning, rowKey = _a.rowKey, selectedRowKey = _a.selectedRowKey, editable = _a.editable, onChangeData = _a.onChangeData, showLineNumber = _a.showLineNumber, msg = _a.msg, getRowClassName = _a.getRowClassName, _q = _a.editTrigger, editTrigger = _q === void 0 ? 'dblclick' : _q, cellMergeOptions = _a.cellMergeOptions, cellSelectionOptions = _a.cellSelectionOptions, cellNavigationOptions = _a.cellNavigationOptions, variant = _a.variant, summary = _a.summary, columnSortable = _a.columnSortable, reorder = _a.reorder, pivot = _a.pivot, dataControl = _a.dataControl, icons = _a.icons, columnVisibility = _a.columnVisibility, searchOptions = _a.searchOptions, contextMenuOptions = _a.contextMenuOptions;
96
+ var warnedSearchControlledRef = React.useRef({
97
+ open: false,
98
+ query: false,
99
+ pivotContextMenu: false,
100
+ columnVisibility: false,
101
+ });
84
102
  var pivotData = React.useMemo(function () {
85
103
  return (0, utils_1.createPivotData)({
86
104
  data: data,
@@ -88,26 +106,63 @@ function BGrid(_a) {
88
106
  });
89
107
  }, [data, pivot]);
90
108
  var pivotEnabled = !!pivotData;
91
- var resolvedColumns = (_b = pivotData === null || pivotData === void 0 ? void 0 : pivotData.columns) !== null && _b !== void 0 ? _b : columns;
109
+ var resolvedColumns = ((_b = pivotData === null || pivotData === void 0 ? void 0 : pivotData.columns) !== null && _b !== void 0 ? _b : columns);
110
+ var visibilityOptions = typeof columnVisibility === 'object' ? columnVisibility : undefined;
111
+ var visibilityEnabled = columnVisibility === true || (visibilityOptions !== undefined && visibilityOptions.enabled !== false);
112
+ var _r = __read(React.useState(function () { var _a; return Array.from(new Set((_a = visibilityOptions === null || visibilityOptions === void 0 ? void 0 : visibilityOptions.defaultHiddenColumnIds) !== null && _a !== void 0 ? _a : [])); }), 2), uncontrolledHiddenColumnIds = _r[0], setUncontrolledHiddenColumnIds = _r[1];
113
+ var hiddenColumnIds = React.useMemo(function () {
114
+ var _a;
115
+ if (!visibilityEnabled)
116
+ return [];
117
+ var requestedIds = Array.from(new Set((_a = visibilityOptions === null || visibilityOptions === void 0 ? void 0 : visibilityOptions.hiddenColumnIds) !== null && _a !== void 0 ? _a : uncontrolledHiddenColumnIds));
118
+ if (resolvedColumns.length > 0 &&
119
+ resolvedColumns.every(function (column) { return requestedIds.includes((0, utils_1.getColumnId)(column)); })) {
120
+ var firstColumnId_1 = (0, utils_1.getColumnId)(resolvedColumns[0]);
121
+ return requestedIds.filter(function (columnId) { return columnId !== firstColumnId_1; });
122
+ }
123
+ return requestedIds;
124
+ }, [resolvedColumns, uncontrolledHiddenColumnIds, visibilityEnabled, visibilityOptions === null || visibilityOptions === void 0 ? void 0 : visibilityOptions.hiddenColumnIds]);
125
+ var hiddenColumnIdSet = React.useMemo(function () { return new Set(hiddenColumnIds); }, [hiddenColumnIds]);
92
126
  var resolvedColumnGroups = React.useMemo(function () { return (pivotEnabled ? [] : columnGroups !== null && columnGroups !== void 0 ? columnGroups : []); }, [columnGroups, pivotEnabled]);
93
127
  var resolvedColumnsGroup = React.useMemo(function () { var _a; return (_a = pivotData === null || pivotData === void 0 ? void 0 : pivotData.columnsGroup) !== null && _a !== void 0 ? _a : (resolvedColumnGroups.length ? [] : columnsGroup !== null && columnsGroup !== void 0 ? columnsGroup : []); }, [columnsGroup, pivotData === null || pivotData === void 0 ? void 0 : pivotData.columnsGroup, resolvedColumnGroups.length]);
128
+ var visibilityProjection = React.useMemo(function () {
129
+ return (0, utils_1.projectColumnVisibility)({
130
+ columns: resolvedColumns,
131
+ hiddenColumnIds: hiddenColumnIdSet,
132
+ frozenColumnIndex: pivotEnabled ? 0 : frozenColumnIndex,
133
+ columnsGroup: resolvedColumnsGroup,
134
+ columnGroups: resolvedColumnGroups,
135
+ cellMergeOptions: pivotEnabled ? undefined : cellMergeOptions,
136
+ summary: pivotEnabled ? undefined : summary,
137
+ });
138
+ }, [
139
+ cellMergeOptions,
140
+ frozenColumnIndex,
141
+ hiddenColumnIdSet,
142
+ pivotEnabled,
143
+ resolvedColumnGroups,
144
+ resolvedColumns,
145
+ resolvedColumnsGroup,
146
+ summary,
147
+ ]);
94
148
  var resolvedData = (_c = pivotData === null || pivotData === void 0 ? void 0 : pivotData.data) !== null && _c !== void 0 ? _c : data;
95
149
  var resolvedPage = pivotEnabled ? undefined : page;
96
- var resolvedFrozenColumnIndex = pivotEnabled ? 0 : frozenColumnIndex;
150
+ var resolvedFrozenColumnIndex = visibilityProjection.frozenColumnIndex;
97
151
  var resolvedRowChecked = pivotEnabled ? undefined : rowChecked;
98
152
  var resolvedSort = pivotEnabled ? undefined : sort;
99
153
  var resolvedOnClick = pivotEnabled ? undefined : onClick;
100
- var resolvedOnChangeColumns = pivotEnabled ? undefined : onChangeColumns;
154
+ var baseOnChangeColumns = pivotEnabled ? undefined : onChangeColumns;
101
155
  var resolvedOnChangeData = pivotEnabled ? undefined : onChangeData;
102
156
  var resolvedRowKey = pivotEnabled ? undefined : rowKey;
103
157
  var resolvedSelectedRowKey = pivotEnabled ? undefined : selectedRowKey;
104
158
  var resolvedEditable = pivotEnabled ? false : editable;
105
159
  var resolvedShowLineNumber = pivotEnabled ? false : showLineNumber;
106
160
  var resolvedGetRowClassName = pivotEnabled ? undefined : getRowClassName;
107
- var resolvedCellMergeOptions = pivotEnabled ? undefined : cellMergeOptions;
161
+ var resolvedCellMergeOptions = visibilityProjection.cellMergeOptions;
108
162
  var resolvedCellSelectionOptions = cellSelectionOptions;
109
- var resolvedSummary = pivotEnabled ? undefined : summary;
110
- var resolvedColumnSortable = pivotEnabled ? false : columnSortable;
163
+ var resolvedSummary = visibilityProjection.summary;
164
+ var hasHiddenColumns = visibilityProjection.columns.length < resolvedColumns.length;
165
+ var resolvedColumnSortable = pivotEnabled || hasHiddenColumns ? false : columnSortable;
111
166
  var resolvedDataControl = pivotEnabled ? undefined : dataControl;
112
167
  var resolvedSearchOptions = pivotEnabled ? undefined : searchOptions;
113
168
  var resolvedContextMenuOptions = pivotEnabled ? undefined : contextMenuOptions;
@@ -148,6 +203,15 @@ function BGrid(_a) {
148
203
  warnedSearchControlledRef.current.pivotContextMenu = true;
149
204
  console.warn('[BGrid] contextMenuOptions is disabled while pivot mode is active.');
150
205
  }
206
+ if (hasHiddenColumns && columnSortable) {
207
+ console.warn('[BGrid] Column reordering is disabled while columns are hidden.');
208
+ }
209
+ if ((visibilityOptions === null || visibilityOptions === void 0 ? void 0 : visibilityOptions.hiddenColumnIds) !== undefined &&
210
+ !visibilityOptions.onChange &&
211
+ !warnedSearchControlledRef.current.columnVisibility) {
212
+ warnedSearchControlledRef.current.columnVisibility = true;
213
+ console.warn('[BGrid] Controlled columnVisibility.hiddenColumnIds requires onChange to respond to user actions.');
214
+ }
151
215
  if ((searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.open) !== undefined &&
152
216
  !searchOptions.onOpenChange &&
153
217
  !warnedSearchControlledRef.current.open) {
@@ -173,8 +237,18 @@ function BGrid(_a) {
173
237
  resolvedSort,
174
238
  contextMenuOptions,
175
239
  searchOptions,
240
+ columnSortable,
241
+ hasHiddenColumns,
242
+ visibilityOptions === null || visibilityOptions === void 0 ? void 0 : visibilityOptions.hiddenColumnIds,
243
+ visibilityOptions === null || visibilityOptions === void 0 ? void 0 : visibilityOptions.onChange,
176
244
  ]);
177
- var duplicateToolboxColumnIds = React.useMemo(function () { return (0, utils_1.findDuplicateColumnIds)(resolvedColumns, true); }, [resolvedColumns]);
245
+ var duplicateToolboxColumnIds = React.useMemo(function () {
246
+ var duplicates = (0, utils_1.findDuplicateColumnIds)(resolvedColumns, true);
247
+ if (visibilityEnabled) {
248
+ (0, utils_1.findDuplicateColumnIds)(resolvedColumns).forEach(function (columnId) { return duplicates.add(columnId); });
249
+ }
250
+ return duplicates;
251
+ }, [resolvedColumns, visibilityEnabled]);
178
252
  var warnedDuplicateIdsRef = React.useRef(new Set());
179
253
  React.useEffect(function () {
180
254
  if (process.env.NODE_ENV === 'production')
@@ -183,30 +257,82 @@ function BGrid(_a) {
183
257
  if (newDuplicateIds.length === 0)
184
258
  return;
185
259
  newDuplicateIds.forEach(function (id) { return warnedDuplicateIdsRef.current.add(id); });
186
- console.warn("[BGrid] Duplicate column IDs detected: ".concat(newDuplicateIds.join(', '), ". Toolbox is disabled for those columns; specify an explicit unique 'id'."));
187
- }, [duplicateToolboxColumnIds]);
260
+ console.warn("[BGrid] Duplicate column IDs detected: ".concat(newDuplicateIds.join(', '), ". Toolbox").concat(visibilityEnabled ? ' and column visibility are' : ' is', " disabled for those columns; specify an explicit unique 'id'."));
261
+ }, [duplicateToolboxColumnIds, visibilityEnabled]);
262
+ var requestColumnVisibilityChange = React.useCallback(function (nextHiddenColumnIds, event) {
263
+ var _a;
264
+ var uniqueIds = Array.from(new Set(nextHiddenColumnIds));
265
+ if (event.type === 'hide') {
266
+ var visibleCount = resolvedColumns.reduce(function (count, column) { return count + (uniqueIds.includes((0, utils_1.getColumnId)(column)) ? 0 : 1); }, 0);
267
+ if (visibleCount === 0)
268
+ return;
269
+ }
270
+ if ((visibilityOptions === null || visibilityOptions === void 0 ? void 0 : visibilityOptions.hiddenColumnIds) === undefined) {
271
+ setUncontrolledHiddenColumnIds(uniqueIds);
272
+ }
273
+ (_a = visibilityOptions === null || visibilityOptions === void 0 ? void 0 : visibilityOptions.onChange) === null || _a === void 0 ? void 0 : _a.call(visibilityOptions, uniqueIds, event);
274
+ }, [resolvedColumns, visibilityOptions]);
275
+ var columnVisibilityState = React.useMemo(function () {
276
+ return visibilityEnabled
277
+ ? {
278
+ items: resolvedColumns.map(function (column) {
279
+ var columnId = (0, utils_1.getColumnId)(column);
280
+ return {
281
+ column: column,
282
+ columnId: columnId,
283
+ hidden: hiddenColumnIdSet.has(columnId),
284
+ hideable: column.hideable !== false && !duplicateToolboxColumnIds.has(columnId),
285
+ };
286
+ }),
287
+ hiddenColumnIds: hiddenColumnIds,
288
+ onChange: requestColumnVisibilityChange,
289
+ }
290
+ : undefined;
291
+ }, [
292
+ duplicateToolboxColumnIds,
293
+ hiddenColumnIdSet,
294
+ hiddenColumnIds,
295
+ requestColumnVisibilityChange,
296
+ resolvedColumns,
297
+ visibilityEnabled,
298
+ ]);
188
299
  var computedColumns = React.useMemo(function () {
189
- var left = 0;
190
- var prevWidth = 0;
191
- return __spreadArray(__spreadArray([], __read(resolvedColumns.slice(0, resolvedFrozenColumnIndex).map(function (column) {
192
- var _a;
193
- var columnId = (0, utils_1.getColumnId)(column);
194
- return __assign(__assign({}, column), { columnId: columnId, keyToken: (0, utils_1.getColumnKeyToken)(column.key), toolbox: duplicateToolboxColumnIds.has(columnId) ? false : column.toolbox, left: -1, width: (_a = column.width) !== null && _a !== void 0 ? _a : 100 });
195
- })), false), __read(resolvedColumns.slice(resolvedFrozenColumnIndex).map(function (column) {
196
- var _a, _b;
197
- left += prevWidth;
198
- prevWidth = (_a = column.width) !== null && _a !== void 0 ? _a : 100;
199
- var columnId = (0, utils_1.getColumnId)(column);
200
- return __assign(__assign({}, column), { columnId: columnId, keyToken: (0, utils_1.getColumnKeyToken)(column.key), toolbox: duplicateToolboxColumnIds.has(columnId) ? false : column.toolbox, left: left, width: (_b = column.width) !== null && _b !== void 0 ? _b : 100 });
201
- })), false);
202
- }, [duplicateToolboxColumnIds, resolvedColumns, resolvedFrozenColumnIndex]);
300
+ return computeModelColumns(visibilityProjection.columns, resolvedFrozenColumnIndex, duplicateToolboxColumnIds);
301
+ }, [duplicateToolboxColumnIds, resolvedFrozenColumnIndex, visibilityProjection.columns]);
302
+ var queryColumns = React.useMemo(function () { return computeModelColumns(resolvedColumns, pivotEnabled ? 0 : frozenColumnIndex, duplicateToolboxColumnIds); }, [duplicateToolboxColumnIds, frozenColumnIndex, pivotEnabled, resolvedColumns]);
303
+ var projectedOnChangeColumns = React.useCallback(function (visibleColumnIndex, info) {
304
+ var _a;
305
+ if (!baseOnChangeColumns)
306
+ return;
307
+ if (!hasHiddenColumns) {
308
+ baseOnChangeColumns(visibleColumnIndex, info);
309
+ return;
310
+ }
311
+ var nextColumns = __spreadArray([], __read(resolvedColumns), false);
312
+ visibilityProjection.visibleOriginalIndexes.forEach(function (originalIndex, visibleIndex) {
313
+ var updatedColumn = info.columns[visibleIndex];
314
+ if (updatedColumn)
315
+ nextColumns[originalIndex] = updatedColumn;
316
+ });
317
+ baseOnChangeColumns(visibleColumnIndex === null
318
+ ? null
319
+ : (_a = visibilityProjection.visibleOriginalIndexes[visibleColumnIndex]) !== null && _a !== void 0 ? _a : null, __assign(__assign({}, info), { columns: nextColumns, columnsGroup: resolvedColumnsGroup, columnGroups: resolvedColumnGroups }));
320
+ }, [
321
+ baseOnChangeColumns,
322
+ hasHiddenColumns,
323
+ resolvedColumnGroups,
324
+ resolvedColumns,
325
+ resolvedColumnsGroup,
326
+ visibilityProjection.visibleOriginalIndexes,
327
+ ]);
328
+ var resolvedOnChangeColumns = baseOnChangeColumns ? projectedOnChangeColumns : undefined;
203
329
  var headerMatrixDiagnostics = React.useMemo(function () {
204
330
  return (0, utils_1.buildHeaderMatrix)({
205
331
  columns: computedColumns,
206
- columnsGroup: resolvedColumnsGroup,
207
- columnGroups: resolvedColumnGroups,
332
+ columnsGroup: visibilityProjection.columnsGroup,
333
+ columnGroups: visibilityProjection.columnGroups,
208
334
  });
209
- }, [computedColumns, resolvedColumnGroups, resolvedColumnsGroup]);
335
+ }, [computedColumns, visibilityProjection.columnGroups, visibilityProjection.columnsGroup]);
210
336
  React.useEffect(function () {
211
337
  if (process.env.NODE_ENV === 'production')
212
338
  return;
@@ -221,9 +347,9 @@ function BGrid(_a) {
221
347
  var unknownQueryColumnIds = React.useMemo(function () {
222
348
  if (!resolvedDataControl)
223
349
  return [];
224
- var knownIds = new Set(computedColumns.map(function (column) { return column.columnId; }));
350
+ var knownIds = new Set(queryColumns.map(function (column) { return column.columnId; }));
225
351
  return Array.from(new Set(__spreadArray(__spreadArray([], __read(resolvedDataControl.query.sortParams.map(function (param) { var _a; return (_a = param.columnId) !== null && _a !== void 0 ? _a : param.key; })), false), __read(resolvedDataControl.query.filterParams.map(function (param) { return param.columnId; })), false).filter(function (id) { return !!id && !knownIds.has(id); })));
226
- }, [computedColumns, resolvedDataControl]);
352
+ }, [queryColumns, resolvedDataControl]);
227
353
  var warnedUnknownQueryIdsRef = React.useRef(new Set());
228
354
  React.useEffect(function () {
229
355
  if (process.env.NODE_ENV === 'production')
@@ -257,7 +383,7 @@ function BGrid(_a) {
257
383
  if ((resolvedDataControl === null || resolvedDataControl === void 0 ? void 0 : resolvedDataControl.mode) === 'client') {
258
384
  return (0, utils_1.processDataQuery)({
259
385
  data: resolvedData,
260
- columns: computedColumns,
386
+ columns: queryColumns,
261
387
  query: resolvedDataQuery,
262
388
  rowKey: resolvedRowKey,
263
389
  includeRows: false,
@@ -271,7 +397,7 @@ function BGrid(_a) {
271
397
  sourceIndexByVisibleIndex: sourceIndexByVisibleIndex,
272
398
  visibleIndexBySourceIndex: visibleIndexBySourceIndex,
273
399
  };
274
- }, [computedColumns, resolvedData, resolvedDataControl === null || resolvedDataControl === void 0 ? void 0 : resolvedDataControl.mode, resolvedDataQuery, resolvedRowKey]);
400
+ }, [queryColumns, resolvedData, resolvedDataControl === null || resolvedDataControl === void 0 ? void 0 : resolvedDataControl.mode, resolvedDataQuery, resolvedRowKey]);
275
401
  var displayData = processedResult.data;
276
402
  var resolvedFrozenRowCount = pivotEnabled
277
403
  ? 0
@@ -376,8 +502,8 @@ function BGrid(_a) {
376
502
  reorderable: (_a = resolvedReorder === null || resolvedReorder === void 0 ? void 0 : resolvedReorder.enabled) !== null && _a !== void 0 ? _a : false,
377
503
  }),
378
504
  columns: computedColumns,
379
- columnsGroup: resolvedColumnsGroup,
380
- columnGroups: resolvedColumnGroups,
505
+ columnsGroup: visibilityProjection.columnsGroup,
506
+ columnGroups: visibilityProjection.columnGroups,
381
507
  data: displayData,
382
508
  sourceData: resolvedData,
383
509
  sourceIndexByVisibleIndex: processedResult.sourceIndexByVisibleIndex,
@@ -392,6 +518,7 @@ function BGrid(_a) {
392
518
  dataQuery: resolvedDataQuery,
393
519
  dataControl: resolvedDataControl,
394
520
  icons: icons,
521
+ columnVisibilityState: columnVisibilityState,
395
522
  searchOptions: resolvedSearchOptions,
396
523
  contextMenuOptions: resolvedContextMenuOptions,
397
524
  page: resolvedPage,
@@ -445,13 +572,14 @@ function BGrid(_a) {
445
572
  resolvedRowChecked,
446
573
  computedColumns,
447
574
  resolvedReorder,
448
- resolvedColumnsGroup,
449
- resolvedColumnGroups,
575
+ visibilityProjection.columnsGroup,
576
+ visibilityProjection.columnGroups,
450
577
  resolvedSort,
451
578
  sortParams,
452
579
  resolvedDataQuery,
453
580
  resolvedDataControl,
454
581
  icons,
582
+ columnVisibilityState,
455
583
  resolvedSearchOptions,
456
584
  resolvedContextMenuOptions,
457
585
  loading,
@@ -476,15 +604,15 @@ function BGrid(_a) {
476
604
  ]);
477
605
  return (React.createElement(store_1.AppStoreProvider, { initialState: initialStoreState },
478
606
  React.createElement(Table_1.default, { ref: ref, columns: computedColumns,
479
- columnsGroup: resolvedColumnsGroup,
480
- columnGroups: resolvedColumnGroups,
607
+ columnsGroup: visibilityProjection.columnsGroup,
608
+ columnGroups: visibilityProjection.columnGroups,
481
609
  onChangeColumns: resolvedOnChangeColumns, width: width, height: height, className: className, style: style, loading: loading, spinning: spinning, scrollLeft: scrollLeft, scrollTop: scrollTop, headerHeight: headerHeight, footerHeight: footerHeight, bottomBarHeight: resolvedBottomBarHeight,
482
610
  scrollbar: resolvedScrollbar,
483
611
  status: resolvedStatus,
484
612
  pagination: resolvedPagination, summaryHeight: summaryHeight, itemHeight: itemHeight, itemPadding: itemPadding, frozenColumnIndex: resolvedFrozenColumnIndex,
485
613
  frozenRowCount: resolvedFrozenRowCount,
486
614
  rowChecked: resolvedRowChecked, checkedIndexesMap: checkedIndexesMap, sort: resolvedSort, sortParams: sortParams, dataQuery: resolvedDataQuery,
487
- dataControl: resolvedDataControl, icons: icons, searchOptions: resolvedSearchOptions,
615
+ dataControl: resolvedDataControl, icons: icons, columnVisibilityState: columnVisibilityState, searchOptions: resolvedSearchOptions,
488
616
  contextMenuOptions: resolvedContextMenuOptions,
489
617
  page: resolvedPage,
490
618
  data: displayData,