@ceed/ads 1.26.0 → 1.27.0

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.
package/dist/index.cjs CHANGED
@@ -2134,14 +2134,15 @@ function reorderColumnsByGroupingModel(columns, columnGroupingModel) {
2134
2134
  }
2135
2135
  return reorderedColumns;
2136
2136
  }
2137
- function flattenColumnGroups(items, groupPath = [], columnIndex = { current: 0 }) {
2137
+ function flattenColumnGroups(items, groupPath = [], columnIndex = { current: 0 }, visibleFields) {
2138
2138
  const result = [];
2139
2139
  for (const item of items) {
2140
2140
  if ("groupId" in item) {
2141
2141
  const newPath = [...groupPath, item.groupId];
2142
2142
  const children = Array.isArray(item.children) ? item.children : [item.children];
2143
- result.push(...flattenColumnGroups(children, newPath, columnIndex));
2143
+ result.push(...flattenColumnGroups(children, newPath, columnIndex, visibleFields));
2144
2144
  } else {
2145
+ if (visibleFields && !visibleFields.has(item.field)) continue;
2145
2146
  result.push({
2146
2147
  ...item,
2147
2148
  groupPath,
@@ -2151,9 +2152,9 @@ function flattenColumnGroups(items, groupPath = [], columnIndex = { current: 0 }
2151
2152
  }
2152
2153
  return result;
2153
2154
  }
2154
- function calculateColumnGroups(columnGroupingModel, columns) {
2155
+ function calculateColumnGroups(columnGroupingModel, columns, visibleFields) {
2155
2156
  const fieldsInGroupingModel = extractFieldsFromGroupingModel(columnGroupingModel);
2156
- const flattenedColumns = flattenColumnGroups(columnGroupingModel);
2157
+ const flattenedColumns = flattenColumnGroups(columnGroupingModel, [], { current: 0 }, visibleFields);
2157
2158
  const columnIndexMap = new Map(flattenedColumns.map((col) => [col.field, col.columnIndex]));
2158
2159
  const processedGroups = /* @__PURE__ */ new Map();
2159
2160
  const groupsByLevel = [];
@@ -2201,7 +2202,9 @@ function calculateColumnGroups(columnGroupingModel, columns) {
2201
2202
  groupsByLevel.forEach((level) => {
2202
2203
  level.sort((a, b) => a.startIndex - b.startIndex);
2203
2204
  });
2204
- return { groups: groupsByLevel, maxLevel, fieldsInGroupingModel };
2205
+ const filteredGroupsByLevel = groupsByLevel.map((level) => level.filter((g) => g.colspan > 0)).filter((level) => level.length > 0);
2206
+ const correctedMaxLevel = filteredGroupsByLevel.length > 0 ? filteredGroupsByLevel.length - 1 : -1;
2207
+ return { groups: filteredGroupsByLevel, maxLevel: correctedMaxLevel, fieldsInGroupingModel };
2205
2208
  }
2206
2209
  function getTextAlign(props) {
2207
2210
  return !props.editMode && ["number", "date", "currency"].includes(props.type || "") ? "end" : "start";
@@ -3365,7 +3368,9 @@ function useDataTableRenderer({
3365
3368
  getId: _getId,
3366
3369
  isTotalSelected: _isTotalSelected,
3367
3370
  isRowSelectable,
3368
- columnGroupingModel
3371
+ columnGroupingModel,
3372
+ columnVisibilityModel,
3373
+ onColumnVisibilityModelChange
3369
3374
  }) {
3370
3375
  if (pinnedColumns && columnGroupingModel) {
3371
3376
  throw new Error(
@@ -3381,12 +3386,35 @@ function useDataTableRenderer({
3381
3386
  initialState?.sorting?.sortModel ?? [],
3382
3387
  (0, import_react25.useCallback)((sortModel2) => onSortModelChange?.(sortModel2), [onSortModelChange])
3383
3388
  );
3389
+ const [visibilityModel] = useControlledState(
3390
+ columnVisibilityModel,
3391
+ initialState?.columns?.columnVisibilityModel ?? {},
3392
+ (0, import_react25.useCallback)(
3393
+ (model) => onColumnVisibilityModelChange?.(model),
3394
+ [onColumnVisibilityModelChange]
3395
+ )
3396
+ );
3384
3397
  const reorderedColumns = (0, import_react25.useMemo)(() => {
3385
3398
  if (!columnGroupingModel) return columnsProp;
3386
3399
  return reorderColumnsByGroupingModel(columnsProp, columnGroupingModel);
3387
3400
  }, [columnsProp, columnGroupingModel]);
3388
- const columnsByField = (0, import_react25.useMemo)(
3401
+ const visibleColumns = (0, import_react25.useMemo)(
3402
+ () => reorderedColumns.filter((col) => visibilityModel[col.field] !== false),
3403
+ [reorderedColumns, visibilityModel]
3404
+ );
3405
+ const visibleFieldSet = (0, import_react25.useMemo)(() => new Set(visibleColumns.map((c) => c.field)), [visibleColumns]);
3406
+ const allColumnsByField = (0, import_react25.useMemo)(
3389
3407
  () => reorderedColumns.reduce(
3408
+ (acc, curr) => ({
3409
+ ...acc,
3410
+ [curr.field]: curr
3411
+ }),
3412
+ {}
3413
+ ),
3414
+ [reorderedColumns]
3415
+ );
3416
+ const visibleColumnsByField = (0, import_react25.useMemo)(
3417
+ () => visibleColumns.reduce(
3390
3418
  (acc, curr) => ({
3391
3419
  ...acc,
3392
3420
  [curr.field]: {
@@ -3397,7 +3425,7 @@ function useDataTableRenderer({
3397
3425
  }),
3398
3426
  {}
3399
3427
  ),
3400
- [reorderedColumns]
3428
+ [visibleColumns]
3401
3429
  );
3402
3430
  const sortComparator = (0, import_react25.useCallback)(
3403
3431
  (rowA, rowB) => {
@@ -3405,7 +3433,8 @@ function useDataTableRenderer({
3405
3433
  const { field, sort: direction } = sort;
3406
3434
  const a = rowA[field];
3407
3435
  const b = rowB[field];
3408
- const column = columnsByField[field];
3436
+ const column = allColumnsByField[field];
3437
+ if (!column) continue;
3409
3438
  let comparison = 0;
3410
3439
  if (column.sortComparator) {
3411
3440
  comparison = column.sortComparator({
@@ -3425,7 +3454,7 @@ function useDataTableRenderer({
3425
3454
  }
3426
3455
  return 0;
3427
3456
  },
3428
- [sortModel, columnsByField]
3457
+ [sortModel, allColumnsByField]
3429
3458
  );
3430
3459
  const rows = (0, import_react25.useMemo)(
3431
3460
  () => sortModel.length ? [..._rows].sort(sortComparator) : _rows,
@@ -3489,44 +3518,54 @@ function useDataTableRenderer({
3489
3518
  () => _isTotalSelected ?? (selectableRowCount > 0 && (selectionModel?.length || 0) === selectableRowCount),
3490
3519
  [_isTotalSelected, selectionModel, selectableRowCount]
3491
3520
  );
3492
- const columnWidths = useColumnWidths(columnsByField);
3521
+ const columnWidths = useColumnWidths(visibleColumnsByField);
3493
3522
  const getWidth = (0, import_react25.useCallback)(
3494
- (f) => columnWidths[f] ?? columnsByField[f].width ?? // Column prop 으로 지정된 width
3495
- columnsByField[f].minWidth ?? 0,
3496
- [columnWidths, columnsByField]
3523
+ (f) => columnWidths[f] ?? allColumnsByField[f]?.width ?? // Column prop 으로 지정된 width
3524
+ allColumnsByField[f]?.minWidth ?? 0,
3525
+ [columnWidths, allColumnsByField]
3497
3526
  );
3498
3527
  const processedColumnGroups = (0, import_react25.useMemo)(() => {
3499
3528
  if (!columnGroupingModel) return null;
3500
- return calculateColumnGroups(columnGroupingModel, reorderedColumns);
3501
- }, [columnGroupingModel, reorderedColumns]);
3529
+ return calculateColumnGroups(columnGroupingModel, visibleColumns, visibleFieldSet);
3530
+ }, [columnGroupingModel, visibleColumns, visibleFieldSet]);
3531
+ const effectivePinnedLeft = (0, import_react25.useMemo)(
3532
+ () => pinnedColumns?.left?.filter((f) => visibleFieldSet.has(f)),
3533
+ [pinnedColumns?.left, visibleFieldSet]
3534
+ );
3535
+ const effectivePinnedRight = (0, import_react25.useMemo)(
3536
+ () => pinnedColumns?.right?.filter((f) => visibleFieldSet.has(f)),
3537
+ [pinnedColumns?.right, visibleFieldSet]
3538
+ );
3502
3539
  const columns = (0, import_react25.useMemo)(() => {
3503
- const baseColumns = reorderedColumns.length > 0 ? reorderedColumns : Object.keys(rows[0] || {}).map((key) => ({
3540
+ const baseColumns = visibleColumns.length > 0 ? visibleColumns : reorderedColumns.length > 0 ? [] : Object.keys(rows[0] || {}).map((key) => ({
3504
3541
  field: key
3505
3542
  }));
3506
3543
  return baseColumns.map((column) => {
3507
- const isLeftPinned = pinnedColumns?.left?.includes(column.field);
3508
- const isRightPinned = pinnedColumns?.right?.includes(column.field);
3544
+ const isLeftPinned = effectivePinnedLeft?.includes(column.field);
3545
+ const isRightPinned = effectivePinnedRight?.includes(column.field);
3509
3546
  const isPinned = isLeftPinned || isRightPinned;
3510
3547
  return {
3511
3548
  ...column,
3512
- headerRef: columnsByField[column.field].headerRef,
3513
- tableColRef: columnsByField[column.field].tableColRef,
3549
+ headerRef: visibleColumnsByField[column.field]?.headerRef,
3550
+ tableColRef: visibleColumnsByField[column.field]?.tableColRef,
3514
3551
  isCellEditable: editMode && (typeof column.isCellEditable === "function" ? column.isCellEditable : column.isCellEditable ?? true),
3515
3552
  sort: sortModel.find((sort) => sort.field === column.field)?.sort,
3516
- sortOrder: columnsByField[column.field]?.sortOrder || sortOrder,
3553
+ sortOrder: allColumnsByField[column.field]?.sortOrder || sortOrder,
3517
3554
  isPinned,
3518
- isLastStartPinnedColumn: isLeftPinned && [...pinnedColumns?.left || []].pop() === column.field,
3519
- isLastEndPinnedColumn: isRightPinned && (pinnedColumns?.right?.[0] ?? null) === column.field,
3520
- pinnedStartPosition: pinnedColumns?.left?.slice(0, isLeftPinned ? pinnedColumns.left.indexOf(column.field) : pinnedColumns.left.length).reduce((acc, curr) => acc + getWidth(curr), 0),
3521
- pinnedEndPosition: pinnedColumns?.right?.slice(isRightPinned ? pinnedColumns.right.indexOf(column.field) + 1 : 0).reduce((acc, curr) => acc + getWidth(curr), 0)
3555
+ isLastStartPinnedColumn: isLeftPinned && [...effectivePinnedLeft || []].pop() === column.field,
3556
+ isLastEndPinnedColumn: isRightPinned && (effectivePinnedRight?.[0] ?? null) === column.field,
3557
+ pinnedStartPosition: effectivePinnedLeft?.slice(0, isLeftPinned ? effectivePinnedLeft.indexOf(column.field) : effectivePinnedLeft.length).reduce((acc, curr) => acc + getWidth(curr), 0),
3558
+ pinnedEndPosition: effectivePinnedRight?.slice(isRightPinned ? effectivePinnedRight.indexOf(column.field) + 1 : 0).reduce((acc, curr) => acc + getWidth(curr), 0)
3522
3559
  };
3523
3560
  });
3524
3561
  }, [
3562
+ visibleColumns,
3525
3563
  reorderedColumns,
3526
3564
  rows,
3527
- pinnedColumns?.left,
3528
- pinnedColumns?.right,
3529
- columnsByField,
3565
+ effectivePinnedLeft,
3566
+ effectivePinnedRight,
3567
+ visibleColumnsByField,
3568
+ allColumnsByField,
3530
3569
  editMode,
3531
3570
  sortModel,
3532
3571
  sortOrder,
@@ -3542,8 +3581,8 @@ function useDataTableRenderer({
3542
3581
  const handleSortChange = (0, import_react25.useCallback)(
3543
3582
  (props) => {
3544
3583
  const { field, currentSort, multiple } = props;
3545
- const column = columnsByField[field];
3546
- const columnSortOrder = column.sortOrder || sortOrder;
3584
+ const column = allColumnsByField[field];
3585
+ const columnSortOrder = column?.sortOrder || sortOrder;
3547
3586
  if (currentSort !== void 0) {
3548
3587
  const currentOrderIndex = columnSortOrder.indexOf(currentSort);
3549
3588
  const nextSortOrderIndex = (currentOrderIndex + 1) % columnSortOrder.length;
@@ -3560,7 +3599,7 @@ function useDataTableRenderer({
3560
3599
  setSortModel(newSortModel);
3561
3600
  }
3562
3601
  },
3563
- [sortOrder, columnsByField, sortModel, setSortModel]
3602
+ [sortOrder, allColumnsByField, sortModel, setSortModel]
3564
3603
  );
3565
3604
  (0, import_react25.useEffect)(() => {
3566
3605
  if (!paginationModel) {
@@ -3986,6 +4025,10 @@ function Component(props, apiRef) {
3986
4025
  loading,
3987
4026
  columnGroupingModel: _________________,
3988
4027
  // columnGroupingModel is used in useDataTableRenderer
4028
+ columnVisibilityModel: __________________,
4029
+ // columnVisibilityModel is used in useDataTableRenderer
4030
+ onColumnVisibilityModelChange: ___________________,
4031
+ // onColumnVisibilityModelChange is used in useDataTableRenderer
3989
4032
  slots: {
3990
4033
  checkbox: RenderCheckbox = Checkbox_default,
3991
4034
  toolbar: Toolbar,
@@ -4225,7 +4268,7 @@ function Component(props, apiRef) {
4225
4268
  width: c.width
4226
4269
  }
4227
4270
  }
4228
- ))), /* @__PURE__ */ import_react28.default.createElement("thead", null, processedColumnGroups && processedColumnGroups.groups.map((levelGroups, level) => /* @__PURE__ */ import_react28.default.createElement("tr", { key: `group-level-${level}` }, checkboxSelection && level === 0 && /* @__PURE__ */ import_react28.default.createElement(
4271
+ ))), /* @__PURE__ */ import_react28.default.createElement("thead", null, processedColumnGroups && processedColumnGroups.groups.length > 0 && processedColumnGroups.groups.map((levelGroups, level) => /* @__PURE__ */ import_react28.default.createElement("tr", { key: `group-level-${level}` }, checkboxSelection && level === 0 && /* @__PURE__ */ import_react28.default.createElement(
4229
4272
  "th",
4230
4273
  {
4231
4274
  rowSpan: processedColumnGroups.maxLevel + 2,
@@ -4245,7 +4288,7 @@ function Component(props, apiRef) {
4245
4288
  ...checkboxProps
4246
4289
  }
4247
4290
  )
4248
- ), level > 0 && Array.from({ length: levelGroups[0]?.startIndex || 0 }).map((_2, i) => /* @__PURE__ */ import_react28.default.createElement("th", { key: `empty-${level}-${i}` })), levelGroups.map((group, groupIndex) => {
4291
+ ), level > 0 && Array.from({ length: levelGroups[0]?.startIndex || 0 }).map((_2, i) => /* @__PURE__ */ import_react28.default.createElement("th", { key: `empty-${level}-${i}` })), levelGroups.filter((g) => g.colspan > 0).map((group, groupIndex) => {
4249
4292
  const nextGroup = levelGroups[groupIndex + 1];
4250
4293
  const emptyCells = nextGroup ? nextGroup.startIndex - (group.startIndex + group.colspan) : columns.length - (group.startIndex + group.colspan);
4251
4294
  const params = { groupId: group.groupId };
@@ -4263,7 +4306,7 @@ function Component(props, apiRef) {
4263
4306
  },
4264
4307
  group.headerName ?? group.groupId
4265
4308
  ), emptyCells > 0 && Array.from({ length: emptyCells }).map((_2, i) => /* @__PURE__ */ import_react28.default.createElement("th", { key: `empty-between-${level}-${groupIndex}-${i}`, colSpan: 1 })));
4266
- }))), /* @__PURE__ */ import_react28.default.createElement("tr", null, !processedColumnGroups && checkboxSelection && /* @__PURE__ */ import_react28.default.createElement(
4309
+ }))), /* @__PURE__ */ import_react28.default.createElement("tr", null, (!processedColumnGroups || processedColumnGroups.groups.length === 0) && checkboxSelection && /* @__PURE__ */ import_react28.default.createElement(
4267
4310
  "th",
4268
4311
  {
4269
4312
  style: {
package/dist/index.js CHANGED
@@ -2000,14 +2000,15 @@ function reorderColumnsByGroupingModel(columns, columnGroupingModel) {
2000
2000
  }
2001
2001
  return reorderedColumns;
2002
2002
  }
2003
- function flattenColumnGroups(items, groupPath = [], columnIndex = { current: 0 }) {
2003
+ function flattenColumnGroups(items, groupPath = [], columnIndex = { current: 0 }, visibleFields) {
2004
2004
  const result = [];
2005
2005
  for (const item of items) {
2006
2006
  if ("groupId" in item) {
2007
2007
  const newPath = [...groupPath, item.groupId];
2008
2008
  const children = Array.isArray(item.children) ? item.children : [item.children];
2009
- result.push(...flattenColumnGroups(children, newPath, columnIndex));
2009
+ result.push(...flattenColumnGroups(children, newPath, columnIndex, visibleFields));
2010
2010
  } else {
2011
+ if (visibleFields && !visibleFields.has(item.field)) continue;
2011
2012
  result.push({
2012
2013
  ...item,
2013
2014
  groupPath,
@@ -2017,9 +2018,9 @@ function flattenColumnGroups(items, groupPath = [], columnIndex = { current: 0 }
2017
2018
  }
2018
2019
  return result;
2019
2020
  }
2020
- function calculateColumnGroups(columnGroupingModel, columns) {
2021
+ function calculateColumnGroups(columnGroupingModel, columns, visibleFields) {
2021
2022
  const fieldsInGroupingModel = extractFieldsFromGroupingModel(columnGroupingModel);
2022
- const flattenedColumns = flattenColumnGroups(columnGroupingModel);
2023
+ const flattenedColumns = flattenColumnGroups(columnGroupingModel, [], { current: 0 }, visibleFields);
2023
2024
  const columnIndexMap = new Map(flattenedColumns.map((col) => [col.field, col.columnIndex]));
2024
2025
  const processedGroups = /* @__PURE__ */ new Map();
2025
2026
  const groupsByLevel = [];
@@ -2067,7 +2068,9 @@ function calculateColumnGroups(columnGroupingModel, columns) {
2067
2068
  groupsByLevel.forEach((level) => {
2068
2069
  level.sort((a, b) => a.startIndex - b.startIndex);
2069
2070
  });
2070
- return { groups: groupsByLevel, maxLevel, fieldsInGroupingModel };
2071
+ const filteredGroupsByLevel = groupsByLevel.map((level) => level.filter((g) => g.colspan > 0)).filter((level) => level.length > 0);
2072
+ const correctedMaxLevel = filteredGroupsByLevel.length > 0 ? filteredGroupsByLevel.length - 1 : -1;
2073
+ return { groups: filteredGroupsByLevel, maxLevel: correctedMaxLevel, fieldsInGroupingModel };
2071
2074
  }
2072
2075
  function getTextAlign(props) {
2073
2076
  return !props.editMode && ["number", "date", "currency"].includes(props.type || "") ? "end" : "start";
@@ -3240,7 +3243,9 @@ function useDataTableRenderer({
3240
3243
  getId: _getId,
3241
3244
  isTotalSelected: _isTotalSelected,
3242
3245
  isRowSelectable,
3243
- columnGroupingModel
3246
+ columnGroupingModel,
3247
+ columnVisibilityModel,
3248
+ onColumnVisibilityModelChange
3244
3249
  }) {
3245
3250
  if (pinnedColumns && columnGroupingModel) {
3246
3251
  throw new Error(
@@ -3256,12 +3261,35 @@ function useDataTableRenderer({
3256
3261
  initialState?.sorting?.sortModel ?? [],
3257
3262
  useCallback10((sortModel2) => onSortModelChange?.(sortModel2), [onSortModelChange])
3258
3263
  );
3264
+ const [visibilityModel] = useControlledState(
3265
+ columnVisibilityModel,
3266
+ initialState?.columns?.columnVisibilityModel ?? {},
3267
+ useCallback10(
3268
+ (model) => onColumnVisibilityModelChange?.(model),
3269
+ [onColumnVisibilityModelChange]
3270
+ )
3271
+ );
3259
3272
  const reorderedColumns = useMemo9(() => {
3260
3273
  if (!columnGroupingModel) return columnsProp;
3261
3274
  return reorderColumnsByGroupingModel(columnsProp, columnGroupingModel);
3262
3275
  }, [columnsProp, columnGroupingModel]);
3263
- const columnsByField = useMemo9(
3276
+ const visibleColumns = useMemo9(
3277
+ () => reorderedColumns.filter((col) => visibilityModel[col.field] !== false),
3278
+ [reorderedColumns, visibilityModel]
3279
+ );
3280
+ const visibleFieldSet = useMemo9(() => new Set(visibleColumns.map((c) => c.field)), [visibleColumns]);
3281
+ const allColumnsByField = useMemo9(
3264
3282
  () => reorderedColumns.reduce(
3283
+ (acc, curr) => ({
3284
+ ...acc,
3285
+ [curr.field]: curr
3286
+ }),
3287
+ {}
3288
+ ),
3289
+ [reorderedColumns]
3290
+ );
3291
+ const visibleColumnsByField = useMemo9(
3292
+ () => visibleColumns.reduce(
3265
3293
  (acc, curr) => ({
3266
3294
  ...acc,
3267
3295
  [curr.field]: {
@@ -3272,7 +3300,7 @@ function useDataTableRenderer({
3272
3300
  }),
3273
3301
  {}
3274
3302
  ),
3275
- [reorderedColumns]
3303
+ [visibleColumns]
3276
3304
  );
3277
3305
  const sortComparator = useCallback10(
3278
3306
  (rowA, rowB) => {
@@ -3280,7 +3308,8 @@ function useDataTableRenderer({
3280
3308
  const { field, sort: direction } = sort;
3281
3309
  const a = rowA[field];
3282
3310
  const b = rowB[field];
3283
- const column = columnsByField[field];
3311
+ const column = allColumnsByField[field];
3312
+ if (!column) continue;
3284
3313
  let comparison = 0;
3285
3314
  if (column.sortComparator) {
3286
3315
  comparison = column.sortComparator({
@@ -3300,7 +3329,7 @@ function useDataTableRenderer({
3300
3329
  }
3301
3330
  return 0;
3302
3331
  },
3303
- [sortModel, columnsByField]
3332
+ [sortModel, allColumnsByField]
3304
3333
  );
3305
3334
  const rows = useMemo9(
3306
3335
  () => sortModel.length ? [..._rows].sort(sortComparator) : _rows,
@@ -3364,44 +3393,54 @@ function useDataTableRenderer({
3364
3393
  () => _isTotalSelected ?? (selectableRowCount > 0 && (selectionModel?.length || 0) === selectableRowCount),
3365
3394
  [_isTotalSelected, selectionModel, selectableRowCount]
3366
3395
  );
3367
- const columnWidths = useColumnWidths(columnsByField);
3396
+ const columnWidths = useColumnWidths(visibleColumnsByField);
3368
3397
  const getWidth = useCallback10(
3369
- (f) => columnWidths[f] ?? columnsByField[f].width ?? // Column prop 으로 지정된 width
3370
- columnsByField[f].minWidth ?? 0,
3371
- [columnWidths, columnsByField]
3398
+ (f) => columnWidths[f] ?? allColumnsByField[f]?.width ?? // Column prop 으로 지정된 width
3399
+ allColumnsByField[f]?.minWidth ?? 0,
3400
+ [columnWidths, allColumnsByField]
3372
3401
  );
3373
3402
  const processedColumnGroups = useMemo9(() => {
3374
3403
  if (!columnGroupingModel) return null;
3375
- return calculateColumnGroups(columnGroupingModel, reorderedColumns);
3376
- }, [columnGroupingModel, reorderedColumns]);
3404
+ return calculateColumnGroups(columnGroupingModel, visibleColumns, visibleFieldSet);
3405
+ }, [columnGroupingModel, visibleColumns, visibleFieldSet]);
3406
+ const effectivePinnedLeft = useMemo9(
3407
+ () => pinnedColumns?.left?.filter((f) => visibleFieldSet.has(f)),
3408
+ [pinnedColumns?.left, visibleFieldSet]
3409
+ );
3410
+ const effectivePinnedRight = useMemo9(
3411
+ () => pinnedColumns?.right?.filter((f) => visibleFieldSet.has(f)),
3412
+ [pinnedColumns?.right, visibleFieldSet]
3413
+ );
3377
3414
  const columns = useMemo9(() => {
3378
- const baseColumns = reorderedColumns.length > 0 ? reorderedColumns : Object.keys(rows[0] || {}).map((key) => ({
3415
+ const baseColumns = visibleColumns.length > 0 ? visibleColumns : reorderedColumns.length > 0 ? [] : Object.keys(rows[0] || {}).map((key) => ({
3379
3416
  field: key
3380
3417
  }));
3381
3418
  return baseColumns.map((column) => {
3382
- const isLeftPinned = pinnedColumns?.left?.includes(column.field);
3383
- const isRightPinned = pinnedColumns?.right?.includes(column.field);
3419
+ const isLeftPinned = effectivePinnedLeft?.includes(column.field);
3420
+ const isRightPinned = effectivePinnedRight?.includes(column.field);
3384
3421
  const isPinned = isLeftPinned || isRightPinned;
3385
3422
  return {
3386
3423
  ...column,
3387
- headerRef: columnsByField[column.field].headerRef,
3388
- tableColRef: columnsByField[column.field].tableColRef,
3424
+ headerRef: visibleColumnsByField[column.field]?.headerRef,
3425
+ tableColRef: visibleColumnsByField[column.field]?.tableColRef,
3389
3426
  isCellEditable: editMode && (typeof column.isCellEditable === "function" ? column.isCellEditable : column.isCellEditable ?? true),
3390
3427
  sort: sortModel.find((sort) => sort.field === column.field)?.sort,
3391
- sortOrder: columnsByField[column.field]?.sortOrder || sortOrder,
3428
+ sortOrder: allColumnsByField[column.field]?.sortOrder || sortOrder,
3392
3429
  isPinned,
3393
- isLastStartPinnedColumn: isLeftPinned && [...pinnedColumns?.left || []].pop() === column.field,
3394
- isLastEndPinnedColumn: isRightPinned && (pinnedColumns?.right?.[0] ?? null) === column.field,
3395
- pinnedStartPosition: pinnedColumns?.left?.slice(0, isLeftPinned ? pinnedColumns.left.indexOf(column.field) : pinnedColumns.left.length).reduce((acc, curr) => acc + getWidth(curr), 0),
3396
- pinnedEndPosition: pinnedColumns?.right?.slice(isRightPinned ? pinnedColumns.right.indexOf(column.field) + 1 : 0).reduce((acc, curr) => acc + getWidth(curr), 0)
3430
+ isLastStartPinnedColumn: isLeftPinned && [...effectivePinnedLeft || []].pop() === column.field,
3431
+ isLastEndPinnedColumn: isRightPinned && (effectivePinnedRight?.[0] ?? null) === column.field,
3432
+ pinnedStartPosition: effectivePinnedLeft?.slice(0, isLeftPinned ? effectivePinnedLeft.indexOf(column.field) : effectivePinnedLeft.length).reduce((acc, curr) => acc + getWidth(curr), 0),
3433
+ pinnedEndPosition: effectivePinnedRight?.slice(isRightPinned ? effectivePinnedRight.indexOf(column.field) + 1 : 0).reduce((acc, curr) => acc + getWidth(curr), 0)
3397
3434
  };
3398
3435
  });
3399
3436
  }, [
3437
+ visibleColumns,
3400
3438
  reorderedColumns,
3401
3439
  rows,
3402
- pinnedColumns?.left,
3403
- pinnedColumns?.right,
3404
- columnsByField,
3440
+ effectivePinnedLeft,
3441
+ effectivePinnedRight,
3442
+ visibleColumnsByField,
3443
+ allColumnsByField,
3405
3444
  editMode,
3406
3445
  sortModel,
3407
3446
  sortOrder,
@@ -3417,8 +3456,8 @@ function useDataTableRenderer({
3417
3456
  const handleSortChange = useCallback10(
3418
3457
  (props) => {
3419
3458
  const { field, currentSort, multiple } = props;
3420
- const column = columnsByField[field];
3421
- const columnSortOrder = column.sortOrder || sortOrder;
3459
+ const column = allColumnsByField[field];
3460
+ const columnSortOrder = column?.sortOrder || sortOrder;
3422
3461
  if (currentSort !== void 0) {
3423
3462
  const currentOrderIndex = columnSortOrder.indexOf(currentSort);
3424
3463
  const nextSortOrderIndex = (currentOrderIndex + 1) % columnSortOrder.length;
@@ -3435,7 +3474,7 @@ function useDataTableRenderer({
3435
3474
  setSortModel(newSortModel);
3436
3475
  }
3437
3476
  },
3438
- [sortOrder, columnsByField, sortModel, setSortModel]
3477
+ [sortOrder, allColumnsByField, sortModel, setSortModel]
3439
3478
  );
3440
3479
  useEffect6(() => {
3441
3480
  if (!paginationModel) {
@@ -3861,6 +3900,10 @@ function Component(props, apiRef) {
3861
3900
  loading,
3862
3901
  columnGroupingModel: _________________,
3863
3902
  // columnGroupingModel is used in useDataTableRenderer
3903
+ columnVisibilityModel: __________________,
3904
+ // columnVisibilityModel is used in useDataTableRenderer
3905
+ onColumnVisibilityModelChange: ___________________,
3906
+ // onColumnVisibilityModelChange is used in useDataTableRenderer
3864
3907
  slots: {
3865
3908
  checkbox: RenderCheckbox = Checkbox_default,
3866
3909
  toolbar: Toolbar,
@@ -4100,7 +4143,7 @@ function Component(props, apiRef) {
4100
4143
  width: c.width
4101
4144
  }
4102
4145
  }
4103
- ))), /* @__PURE__ */ React25.createElement("thead", null, processedColumnGroups && processedColumnGroups.groups.map((levelGroups, level) => /* @__PURE__ */ React25.createElement("tr", { key: `group-level-${level}` }, checkboxSelection && level === 0 && /* @__PURE__ */ React25.createElement(
4146
+ ))), /* @__PURE__ */ React25.createElement("thead", null, processedColumnGroups && processedColumnGroups.groups.length > 0 && processedColumnGroups.groups.map((levelGroups, level) => /* @__PURE__ */ React25.createElement("tr", { key: `group-level-${level}` }, checkboxSelection && level === 0 && /* @__PURE__ */ React25.createElement(
4104
4147
  "th",
4105
4148
  {
4106
4149
  rowSpan: processedColumnGroups.maxLevel + 2,
@@ -4120,7 +4163,7 @@ function Component(props, apiRef) {
4120
4163
  ...checkboxProps
4121
4164
  }
4122
4165
  )
4123
- ), level > 0 && Array.from({ length: levelGroups[0]?.startIndex || 0 }).map((_2, i) => /* @__PURE__ */ React25.createElement("th", { key: `empty-${level}-${i}` })), levelGroups.map((group, groupIndex) => {
4166
+ ), level > 0 && Array.from({ length: levelGroups[0]?.startIndex || 0 }).map((_2, i) => /* @__PURE__ */ React25.createElement("th", { key: `empty-${level}-${i}` })), levelGroups.filter((g) => g.colspan > 0).map((group, groupIndex) => {
4124
4167
  const nextGroup = levelGroups[groupIndex + 1];
4125
4168
  const emptyCells = nextGroup ? nextGroup.startIndex - (group.startIndex + group.colspan) : columns.length - (group.startIndex + group.colspan);
4126
4169
  const params = { groupId: group.groupId };
@@ -4138,7 +4181,7 @@ function Component(props, apiRef) {
4138
4181
  },
4139
4182
  group.headerName ?? group.groupId
4140
4183
  ), emptyCells > 0 && Array.from({ length: emptyCells }).map((_2, i) => /* @__PURE__ */ React25.createElement("th", { key: `empty-between-${level}-${groupIndex}-${i}`, colSpan: 1 })));
4141
- }))), /* @__PURE__ */ React25.createElement("tr", null, !processedColumnGroups && checkboxSelection && /* @__PURE__ */ React25.createElement(
4184
+ }))), /* @__PURE__ */ React25.createElement("tr", null, (!processedColumnGroups || processedColumnGroups.groups.length === 0) && checkboxSelection && /* @__PURE__ */ React25.createElement(
4142
4185
  "th",
4143
4186
  {
4144
4187
  style: {