@ceed/cds 1.40.3-next.7 → 1.40.3-next.8

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
@@ -2620,8 +2620,8 @@ function computeAutoFitWidth(params) {
2620
2620
  if (!isNaN(maxPx) && maxPx > 0) finalWidth = Math.min(finalWidth, maxPx);
2621
2621
  return finalWidth;
2622
2622
  }
2623
- function getHeaderCellId(tableId, columnId) {
2624
- return `${tableId}_header_${columnId}`;
2623
+ function getHeaderCellId(tableId, field) {
2624
+ return `${tableId}_header_${sanitizeColumnId(field)}`;
2625
2625
  }
2626
2626
  function sanitizeColumnId(field) {
2627
2627
  return String(field).trim().replace(/\s+/g, "_");
@@ -3569,8 +3569,7 @@ var HeadCell = (props) => {
3569
3569
  tableColRef,
3570
3570
  headerClassName,
3571
3571
  headerLineClamp,
3572
- onAutoFit,
3573
- columnId
3572
+ onAutoFit
3574
3573
  } = props;
3575
3574
  const theme = (0, import_joy33.useTheme)();
3576
3575
  const ref = headerRef;
@@ -3581,7 +3580,7 @@ var HeadCell = (props) => {
3581
3580
  }, [ref]);
3582
3581
  const [isHovered, setIsHovered] = (0, import_react26.useState)(false);
3583
3582
  const sortable = type === "actions" ? false : _sortable;
3584
- const headId = (0, import_react26.useMemo)(() => getHeaderCellId(tableId, columnId), [tableId, columnId]);
3583
+ const headId = (0, import_react26.useMemo)(() => getHeaderCellId(tableId, field), [tableId, field]);
3585
3584
  const isResizingRef = (0, import_react26.useRef)(false);
3586
3585
  const resizer = (0, import_react26.useMemo)(
3587
3586
  () => resizable ?? true ? Resizer(
@@ -3590,9 +3589,9 @@ var HeadCell = (props) => {
3590
3589
  (isResizing) => {
3591
3590
  isResizingRef.current = isResizing;
3592
3591
  },
3593
- onAutoFit ? () => onAutoFit(columnId) : void 0
3592
+ onAutoFit ? () => onAutoFit(field) : void 0
3594
3593
  ) : null,
3595
- [resizable, ref, colRef, onAutoFit, columnId]
3594
+ [resizable, ref, colRef, onAutoFit, field]
3596
3595
  );
3597
3596
  const style = (0, import_react26.useMemo)(
3598
3597
  () => ({
@@ -3862,7 +3861,7 @@ var BodyCell = (props) => {
3862
3861
  {
3863
3862
  ref: cellRef,
3864
3863
  key: field,
3865
- headers: getHeaderCellId(tableId, props.columnId),
3864
+ headers: getHeaderCellId(tableId, field),
3866
3865
  sx: {
3867
3866
  textAlign: getTextAlign({ type }),
3868
3867
  verticalAlign: editMode ? "top" : "middle",
@@ -3928,7 +3927,7 @@ var VirtualizedTableRow = (0, import_react26.memo)(StyledTableRow2, (prevProps,
3928
3927
 
3929
3928
  // src/components/DataTable/hooks.ts
3930
3929
  var import_react27 = require("react");
3931
- function useColumnWidths(columnsById) {
3930
+ function useColumnWidths(columnsByField) {
3932
3931
  const [widths, setWidths] = (0, import_react27.useState)({});
3933
3932
  const roRef = (0, import_react27.useRef)();
3934
3933
  (0, import_react27.useLayoutEffect)(() => {
@@ -3938,11 +3937,11 @@ function useColumnWidths(columnsById) {
3938
3937
  let changed = false;
3939
3938
  const next = { ...prev };
3940
3939
  entries.forEach((entry) => {
3941
- const columnId = entry.target.dataset.hdsColumnId;
3940
+ const field = entry.target.dataset.field;
3942
3941
  const w = Math.round(entry.target.getBoundingClientRect().width);
3943
3942
  if (w === 0) return;
3944
- if (next[columnId] !== w) {
3945
- next[columnId] = w;
3943
+ if (next[field] !== w) {
3944
+ next[field] = w;
3946
3945
  changed = true;
3947
3946
  }
3948
3947
  });
@@ -3950,13 +3949,12 @@ function useColumnWidths(columnsById) {
3950
3949
  });
3951
3950
  });
3952
3951
  const measured = {};
3953
- Object.entries(columnsById).forEach(([columnId, def]) => {
3952
+ Object.entries(columnsByField).forEach(([field, def]) => {
3954
3953
  const el = def.headerRef.current;
3955
3954
  if (el) {
3956
- el.dataset.hdsColumnId = columnId;
3957
- el.dataset.field = String(def.field);
3955
+ el.dataset.field = field;
3958
3956
  const w = Math.round(el.getBoundingClientRect().width);
3959
- if (w > 0) measured[columnId] = w;
3957
+ if (w > 0) measured[field] = w;
3960
3958
  roRef.current.observe(el);
3961
3959
  }
3962
3960
  });
@@ -3966,7 +3964,7 @@ function useColumnWidths(columnsById) {
3966
3964
  return same ? prev : { ...prev, ...measured };
3967
3965
  });
3968
3966
  return () => roRef.current?.disconnect();
3969
- }, [columnsById]);
3967
+ }, [columnsByField]);
3970
3968
  return widths;
3971
3969
  }
3972
3970
  function useDataTableRenderer({
@@ -3998,6 +3996,13 @@ function useDataTableRenderer({
3998
3996
  "You cannot use both `pinnedColumns` and `columnGroupingModel` at the same time. Please choose one of them."
3999
3997
  );
4000
3998
  }
3999
+ const duplicatedField = (0, import_react27.useMemo)(() => {
4000
+ const ids = columnsProp.map((column) => sanitizeColumnId(column.field));
4001
+ const index = ids.findIndex((id, i) => ids.indexOf(id) !== i);
4002
+ return index === -1 ? void 0 : columnsProp[index].field;
4003
+ }, [columnsProp]);
4004
+ if (duplicatedField !== void 0)
4005
+ throw new Error(`DataTable: column \`field\` must be unique. Duplicated: "${String(duplicatedField)}"`);
4001
4006
  const onSelectionModelChangeRef = (0, import_react27.useRef)(onSelectionModelChange);
4002
4007
  onSelectionModelChangeRef.current = onSelectionModelChange;
4003
4008
  const [focusedRowId, setFocusedRowId] = (0, import_react27.useState)(null);
@@ -4019,16 +4024,9 @@ function useDataTableRenderer({
4019
4024
  if (!columnGroupingModel) return columnsProp;
4020
4025
  return reorderColumnsByGroupingModel(columnsProp, columnGroupingModel);
4021
4026
  }, [columnsProp, columnGroupingModel]);
4022
- const visibleColumnIndexes = (0, import_react27.useMemo)(
4023
- () => reorderedColumns.reduce((acc, col, index) => {
4024
- if (visibilityModel[col.field] !== false) acc.push(index);
4025
- return acc;
4026
- }, []),
4027
- [reorderedColumns, visibilityModel]
4028
- );
4029
4027
  const visibleColumns = (0, import_react27.useMemo)(
4030
- () => visibleColumnIndexes.map((index) => reorderedColumns[index]),
4031
- [visibleColumnIndexes, reorderedColumns]
4028
+ () => reorderedColumns.filter((col) => visibilityModel[col.field] !== false),
4029
+ [reorderedColumns, visibilityModel]
4032
4030
  );
4033
4031
  const visibleFieldSet = (0, import_react27.useMemo)(() => new Set(visibleColumns.map((c) => c.field)), [visibleColumns]);
4034
4032
  const tableMinWidth = (0, import_react27.useMemo)(() => {
@@ -4049,29 +4047,10 @@ function useDataTableRenderer({
4049
4047
  ),
4050
4048
  [reorderedColumns]
4051
4049
  );
4052
- const allColumnIds = (0, import_react27.useMemo)(() => {
4053
- const taken = new Set(reorderedColumns.map((column) => sanitizeColumnId(column.field)));
4054
- const assigned = /* @__PURE__ */ new Set();
4055
- return reorderedColumns.map((column) => {
4056
- const field = sanitizeColumnId(column.field);
4057
- if (!assigned.has(field)) {
4058
- assigned.add(field);
4059
- return field;
4060
- }
4061
- let n = 2;
4062
- while (taken.has(`${field}__${n}`)) n += 1;
4063
- taken.add(`${field}__${n}`);
4064
- return `${field}__${n}`;
4065
- });
4066
- }, [reorderedColumns]);
4067
- const columnIds = (0, import_react27.useMemo)(
4068
- () => visibleColumnIndexes.map((index) => allColumnIds[index]),
4069
- [visibleColumnIndexes, allColumnIds]
4070
- );
4071
- const visibleColumnsById = (0, import_react27.useMemo)(
4050
+ const visibleColumnsByField = (0, import_react27.useMemo)(
4072
4051
  () => Object.fromEntries(
4073
- visibleColumns.map((column, index) => [
4074
- columnIds[index],
4052
+ visibleColumns.map((column) => [
4053
+ column.field,
4075
4054
  {
4076
4055
  ...column,
4077
4056
  headerRef: (0, import_react27.createRef)(),
@@ -4079,7 +4058,7 @@ function useDataTableRenderer({
4079
4058
  }
4080
4059
  ])
4081
4060
  ),
4082
- [visibleColumns, columnIds]
4061
+ [visibleColumns]
4083
4062
  );
4084
4063
  const sortComparator = (0, import_react27.useCallback)(
4085
4064
  (rowA, rowB) => {
@@ -4172,18 +4151,12 @@ function useDataTableRenderer({
4172
4151
  () => _isTotalSelected ?? (selectableRowCount > 0 && (selectionModel?.length || 0) === selectableRowCount),
4173
4152
  [_isTotalSelected, selectionModel, selectableRowCount]
4174
4153
  );
4175
- const columnWidths = useColumnWidths(visibleColumnsById);
4176
- const measuredWidthByField = (0, import_react27.useMemo)(
4177
- () => Object.fromEntries(
4178
- Object.entries(visibleColumnsById).map(([columnId, column]) => [column.field, columnWidths[columnId]])
4179
- ),
4180
- [visibleColumnsById, columnWidths]
4181
- );
4154
+ const columnWidths = useColumnWidths(visibleColumnsByField);
4182
4155
  const getWidth = (0, import_react27.useCallback)(
4183
4156
  // 반환값은 pinned offset으로 더해지므로 반드시 숫자여야 한다. width/minWidth는 '500px' 같은 문자열.
4184
- (f) => measuredWidthByField[f] ?? parsePxValue(allColumnsByField[f]?.width) ?? // Column prop 으로 지정된 width
4157
+ (f) => columnWidths[f] ?? parsePxValue(allColumnsByField[f]?.width) ?? // Column prop 으로 지정된 width
4185
4158
  parsePxValue(allColumnsByField[f]?.minWidth) ?? 0,
4186
- [measuredWidthByField, allColumnsByField]
4159
+ [columnWidths, allColumnsByField]
4187
4160
  );
4188
4161
  const processedColumnGroups = (0, import_react27.useMemo)(() => {
4189
4162
  if (!columnGroupingModel) return null;
@@ -4203,16 +4176,14 @@ function useDataTableRenderer({
4203
4176
  const baseColumns = visibleColumns.length > 0 ? visibleColumns : reorderedColumns.length > 0 ? [] : inferredFields.map((key) => ({
4204
4177
  field: key
4205
4178
  }));
4206
- return baseColumns.map((column, index) => {
4207
- const columnId = columnIds[index] ?? sanitizeColumnId(column.field);
4179
+ return baseColumns.map((column) => {
4208
4180
  const isLeftPinned = effectivePinnedLeft?.includes(column.field);
4209
4181
  const isRightPinned = effectivePinnedRight?.includes(column.field);
4210
4182
  const isPinned = isLeftPinned || isRightPinned;
4211
4183
  return {
4212
4184
  ...column,
4213
- columnId,
4214
- headerRef: visibleColumnsById[columnId]?.headerRef,
4215
- tableColRef: visibleColumnsById[columnId]?.tableColRef,
4185
+ headerRef: visibleColumnsByField[column.field]?.headerRef,
4186
+ tableColRef: visibleColumnsByField[column.field]?.tableColRef,
4216
4187
  isCellEditable: editMode && (typeof column.isCellEditable === "function" ? column.isCellEditable : column.isCellEditable ?? true),
4217
4188
  sort: sortModel.find((sort) => sort.field === column.field)?.sort,
4218
4189
  sortOrder: allColumnsByField[column.field]?.sortOrder || sortOrder,
@@ -4229,8 +4200,7 @@ function useDataTableRenderer({
4229
4200
  inferredFields,
4230
4201
  effectivePinnedLeft,
4231
4202
  effectivePinnedRight,
4232
- columnIds,
4233
- visibleColumnsById,
4203
+ visibleColumnsByField,
4234
4204
  allColumnsByField,
4235
4205
  editMode,
4236
4206
  sortModel,
@@ -4290,8 +4260,8 @@ function useDataTableRenderer({
4290
4260
  }
4291
4261
  }, [_rows]);
4292
4262
  const handleAutoFit = (0, import_react27.useCallback)(
4293
- (columnId) => {
4294
- const colDef = visibleColumnsById[columnId];
4263
+ (field) => {
4264
+ const colDef = visibleColumnsByField[field];
4295
4265
  if (!colDef?.headerRef.current) return;
4296
4266
  const columnType = "type" in colDef ? colDef.type : void 0;
4297
4267
  if (columnType === "actions") return;
@@ -4305,7 +4275,7 @@ function useDataTableRenderer({
4305
4275
  colDef.headerRef.current.style.width = widthPx;
4306
4276
  if (colDef.tableColRef.current) colDef.tableColRef.current.style.width = widthPx;
4307
4277
  },
4308
- [visibleColumnsById, dataInPage]
4278
+ [visibleColumnsByField, dataInPage]
4309
4279
  );
4310
4280
  return {
4311
4281
  rowCount,
@@ -4992,7 +4962,7 @@ function Component(props, apiRef) {
4992
4962
  "col",
4993
4963
  {
4994
4964
  ref: c.tableColRef,
4995
- key: c.columnId,
4965
+ key: c.field.toString(),
4996
4966
  style: {
4997
4967
  width: c.width,
4998
4968
  minWidth: c.minWidth ?? "50px"
@@ -5048,7 +5018,7 @@ function Component(props, apiRef) {
5048
5018
  HeadCell2,
5049
5019
  {
5050
5020
  tableId,
5051
- key: c.columnId,
5021
+ key: c.field.toString(),
5052
5022
  stickyHeader: props.stickyHeader,
5053
5023
  editMode: !!c.isCellEditable,
5054
5024
  onSortChange: handleSortChange,
package/dist/index.js CHANGED
@@ -2491,8 +2491,8 @@ function computeAutoFitWidth(params) {
2491
2491
  if (!isNaN(maxPx) && maxPx > 0) finalWidth = Math.min(finalWidth, maxPx);
2492
2492
  return finalWidth;
2493
2493
  }
2494
- function getHeaderCellId(tableId, columnId) {
2495
- return `${tableId}_header_${columnId}`;
2494
+ function getHeaderCellId(tableId, field) {
2495
+ return `${tableId}_header_${sanitizeColumnId(field)}`;
2496
2496
  }
2497
2497
  function sanitizeColumnId(field) {
2498
2498
  return String(field).trim().replace(/\s+/g, "_");
@@ -3454,8 +3454,7 @@ var HeadCell = (props) => {
3454
3454
  tableColRef,
3455
3455
  headerClassName,
3456
3456
  headerLineClamp,
3457
- onAutoFit,
3458
- columnId
3457
+ onAutoFit
3459
3458
  } = props;
3460
3459
  const theme = useTheme();
3461
3460
  const ref = headerRef;
@@ -3466,7 +3465,7 @@ var HeadCell = (props) => {
3466
3465
  }, [ref]);
3467
3466
  const [isHovered, setIsHovered] = useState8(false);
3468
3467
  const sortable = type === "actions" ? false : _sortable;
3469
- const headId = useMemo10(() => getHeaderCellId(tableId, columnId), [tableId, columnId]);
3468
+ const headId = useMemo10(() => getHeaderCellId(tableId, field), [tableId, field]);
3470
3469
  const isResizingRef = useRef6(false);
3471
3470
  const resizer = useMemo10(
3472
3471
  () => resizable ?? true ? Resizer(
@@ -3475,9 +3474,9 @@ var HeadCell = (props) => {
3475
3474
  (isResizing) => {
3476
3475
  isResizingRef.current = isResizing;
3477
3476
  },
3478
- onAutoFit ? () => onAutoFit(columnId) : void 0
3477
+ onAutoFit ? () => onAutoFit(field) : void 0
3479
3478
  ) : null,
3480
- [resizable, ref, colRef, onAutoFit, columnId]
3479
+ [resizable, ref, colRef, onAutoFit, field]
3481
3480
  );
3482
3481
  const style = useMemo10(
3483
3482
  () => ({
@@ -3747,7 +3746,7 @@ var BodyCell = (props) => {
3747
3746
  {
3748
3747
  ref: cellRef,
3749
3748
  key: field,
3750
- headers: getHeaderCellId(tableId, props.columnId),
3749
+ headers: getHeaderCellId(tableId, field),
3751
3750
  sx: {
3752
3751
  textAlign: getTextAlign({ type }),
3753
3752
  verticalAlign: editMode ? "top" : "middle",
@@ -3813,7 +3812,7 @@ var VirtualizedTableRow = memo(StyledTableRow2, (prevProps, nextProps) => {
3813
3812
 
3814
3813
  // src/components/DataTable/hooks.ts
3815
3814
  import { useState as useState9, useLayoutEffect as useLayoutEffect2, useRef as useRef7, useMemo as useMemo11, useCallback as useCallback12, useEffect as useEffect6, createRef } from "react";
3816
- function useColumnWidths(columnsById) {
3815
+ function useColumnWidths(columnsByField) {
3817
3816
  const [widths, setWidths] = useState9({});
3818
3817
  const roRef = useRef7();
3819
3818
  useLayoutEffect2(() => {
@@ -3823,11 +3822,11 @@ function useColumnWidths(columnsById) {
3823
3822
  let changed = false;
3824
3823
  const next = { ...prev };
3825
3824
  entries.forEach((entry) => {
3826
- const columnId = entry.target.dataset.hdsColumnId;
3825
+ const field = entry.target.dataset.field;
3827
3826
  const w = Math.round(entry.target.getBoundingClientRect().width);
3828
3827
  if (w === 0) return;
3829
- if (next[columnId] !== w) {
3830
- next[columnId] = w;
3828
+ if (next[field] !== w) {
3829
+ next[field] = w;
3831
3830
  changed = true;
3832
3831
  }
3833
3832
  });
@@ -3835,13 +3834,12 @@ function useColumnWidths(columnsById) {
3835
3834
  });
3836
3835
  });
3837
3836
  const measured = {};
3838
- Object.entries(columnsById).forEach(([columnId, def]) => {
3837
+ Object.entries(columnsByField).forEach(([field, def]) => {
3839
3838
  const el = def.headerRef.current;
3840
3839
  if (el) {
3841
- el.dataset.hdsColumnId = columnId;
3842
- el.dataset.field = String(def.field);
3840
+ el.dataset.field = field;
3843
3841
  const w = Math.round(el.getBoundingClientRect().width);
3844
- if (w > 0) measured[columnId] = w;
3842
+ if (w > 0) measured[field] = w;
3845
3843
  roRef.current.observe(el);
3846
3844
  }
3847
3845
  });
@@ -3851,7 +3849,7 @@ function useColumnWidths(columnsById) {
3851
3849
  return same ? prev : { ...prev, ...measured };
3852
3850
  });
3853
3851
  return () => roRef.current?.disconnect();
3854
- }, [columnsById]);
3852
+ }, [columnsByField]);
3855
3853
  return widths;
3856
3854
  }
3857
3855
  function useDataTableRenderer({
@@ -3883,6 +3881,13 @@ function useDataTableRenderer({
3883
3881
  "You cannot use both `pinnedColumns` and `columnGroupingModel` at the same time. Please choose one of them."
3884
3882
  );
3885
3883
  }
3884
+ const duplicatedField = useMemo11(() => {
3885
+ const ids = columnsProp.map((column) => sanitizeColumnId(column.field));
3886
+ const index = ids.findIndex((id, i) => ids.indexOf(id) !== i);
3887
+ return index === -1 ? void 0 : columnsProp[index].field;
3888
+ }, [columnsProp]);
3889
+ if (duplicatedField !== void 0)
3890
+ throw new Error(`DataTable: column \`field\` must be unique. Duplicated: "${String(duplicatedField)}"`);
3886
3891
  const onSelectionModelChangeRef = useRef7(onSelectionModelChange);
3887
3892
  onSelectionModelChangeRef.current = onSelectionModelChange;
3888
3893
  const [focusedRowId, setFocusedRowId] = useState9(null);
@@ -3904,16 +3909,9 @@ function useDataTableRenderer({
3904
3909
  if (!columnGroupingModel) return columnsProp;
3905
3910
  return reorderColumnsByGroupingModel(columnsProp, columnGroupingModel);
3906
3911
  }, [columnsProp, columnGroupingModel]);
3907
- const visibleColumnIndexes = useMemo11(
3908
- () => reorderedColumns.reduce((acc, col, index) => {
3909
- if (visibilityModel[col.field] !== false) acc.push(index);
3910
- return acc;
3911
- }, []),
3912
- [reorderedColumns, visibilityModel]
3913
- );
3914
3912
  const visibleColumns = useMemo11(
3915
- () => visibleColumnIndexes.map((index) => reorderedColumns[index]),
3916
- [visibleColumnIndexes, reorderedColumns]
3913
+ () => reorderedColumns.filter((col) => visibilityModel[col.field] !== false),
3914
+ [reorderedColumns, visibilityModel]
3917
3915
  );
3918
3916
  const visibleFieldSet = useMemo11(() => new Set(visibleColumns.map((c) => c.field)), [visibleColumns]);
3919
3917
  const tableMinWidth = useMemo11(() => {
@@ -3934,29 +3932,10 @@ function useDataTableRenderer({
3934
3932
  ),
3935
3933
  [reorderedColumns]
3936
3934
  );
3937
- const allColumnIds = useMemo11(() => {
3938
- const taken = new Set(reorderedColumns.map((column) => sanitizeColumnId(column.field)));
3939
- const assigned = /* @__PURE__ */ new Set();
3940
- return reorderedColumns.map((column) => {
3941
- const field = sanitizeColumnId(column.field);
3942
- if (!assigned.has(field)) {
3943
- assigned.add(field);
3944
- return field;
3945
- }
3946
- let n = 2;
3947
- while (taken.has(`${field}__${n}`)) n += 1;
3948
- taken.add(`${field}__${n}`);
3949
- return `${field}__${n}`;
3950
- });
3951
- }, [reorderedColumns]);
3952
- const columnIds = useMemo11(
3953
- () => visibleColumnIndexes.map((index) => allColumnIds[index]),
3954
- [visibleColumnIndexes, allColumnIds]
3955
- );
3956
- const visibleColumnsById = useMemo11(
3935
+ const visibleColumnsByField = useMemo11(
3957
3936
  () => Object.fromEntries(
3958
- visibleColumns.map((column, index) => [
3959
- columnIds[index],
3937
+ visibleColumns.map((column) => [
3938
+ column.field,
3960
3939
  {
3961
3940
  ...column,
3962
3941
  headerRef: createRef(),
@@ -3964,7 +3943,7 @@ function useDataTableRenderer({
3964
3943
  }
3965
3944
  ])
3966
3945
  ),
3967
- [visibleColumns, columnIds]
3946
+ [visibleColumns]
3968
3947
  );
3969
3948
  const sortComparator = useCallback12(
3970
3949
  (rowA, rowB) => {
@@ -4057,18 +4036,12 @@ function useDataTableRenderer({
4057
4036
  () => _isTotalSelected ?? (selectableRowCount > 0 && (selectionModel?.length || 0) === selectableRowCount),
4058
4037
  [_isTotalSelected, selectionModel, selectableRowCount]
4059
4038
  );
4060
- const columnWidths = useColumnWidths(visibleColumnsById);
4061
- const measuredWidthByField = useMemo11(
4062
- () => Object.fromEntries(
4063
- Object.entries(visibleColumnsById).map(([columnId, column]) => [column.field, columnWidths[columnId]])
4064
- ),
4065
- [visibleColumnsById, columnWidths]
4066
- );
4039
+ const columnWidths = useColumnWidths(visibleColumnsByField);
4067
4040
  const getWidth = useCallback12(
4068
4041
  // 반환값은 pinned offset으로 더해지므로 반드시 숫자여야 한다. width/minWidth는 '500px' 같은 문자열.
4069
- (f) => measuredWidthByField[f] ?? parsePxValue(allColumnsByField[f]?.width) ?? // Column prop 으로 지정된 width
4042
+ (f) => columnWidths[f] ?? parsePxValue(allColumnsByField[f]?.width) ?? // Column prop 으로 지정된 width
4070
4043
  parsePxValue(allColumnsByField[f]?.minWidth) ?? 0,
4071
- [measuredWidthByField, allColumnsByField]
4044
+ [columnWidths, allColumnsByField]
4072
4045
  );
4073
4046
  const processedColumnGroups = useMemo11(() => {
4074
4047
  if (!columnGroupingModel) return null;
@@ -4088,16 +4061,14 @@ function useDataTableRenderer({
4088
4061
  const baseColumns = visibleColumns.length > 0 ? visibleColumns : reorderedColumns.length > 0 ? [] : inferredFields.map((key) => ({
4089
4062
  field: key
4090
4063
  }));
4091
- return baseColumns.map((column, index) => {
4092
- const columnId = columnIds[index] ?? sanitizeColumnId(column.field);
4064
+ return baseColumns.map((column) => {
4093
4065
  const isLeftPinned = effectivePinnedLeft?.includes(column.field);
4094
4066
  const isRightPinned = effectivePinnedRight?.includes(column.field);
4095
4067
  const isPinned = isLeftPinned || isRightPinned;
4096
4068
  return {
4097
4069
  ...column,
4098
- columnId,
4099
- headerRef: visibleColumnsById[columnId]?.headerRef,
4100
- tableColRef: visibleColumnsById[columnId]?.tableColRef,
4070
+ headerRef: visibleColumnsByField[column.field]?.headerRef,
4071
+ tableColRef: visibleColumnsByField[column.field]?.tableColRef,
4101
4072
  isCellEditable: editMode && (typeof column.isCellEditable === "function" ? column.isCellEditable : column.isCellEditable ?? true),
4102
4073
  sort: sortModel.find((sort) => sort.field === column.field)?.sort,
4103
4074
  sortOrder: allColumnsByField[column.field]?.sortOrder || sortOrder,
@@ -4114,8 +4085,7 @@ function useDataTableRenderer({
4114
4085
  inferredFields,
4115
4086
  effectivePinnedLeft,
4116
4087
  effectivePinnedRight,
4117
- columnIds,
4118
- visibleColumnsById,
4088
+ visibleColumnsByField,
4119
4089
  allColumnsByField,
4120
4090
  editMode,
4121
4091
  sortModel,
@@ -4175,8 +4145,8 @@ function useDataTableRenderer({
4175
4145
  }
4176
4146
  }, [_rows]);
4177
4147
  const handleAutoFit = useCallback12(
4178
- (columnId) => {
4179
- const colDef = visibleColumnsById[columnId];
4148
+ (field) => {
4149
+ const colDef = visibleColumnsByField[field];
4180
4150
  if (!colDef?.headerRef.current) return;
4181
4151
  const columnType = "type" in colDef ? colDef.type : void 0;
4182
4152
  if (columnType === "actions") return;
@@ -4190,7 +4160,7 @@ function useDataTableRenderer({
4190
4160
  colDef.headerRef.current.style.width = widthPx;
4191
4161
  if (colDef.tableColRef.current) colDef.tableColRef.current.style.width = widthPx;
4192
4162
  },
4193
- [visibleColumnsById, dataInPage]
4163
+ [visibleColumnsByField, dataInPage]
4194
4164
  );
4195
4165
  return {
4196
4166
  rowCount,
@@ -4877,7 +4847,7 @@ function Component(props, apiRef) {
4877
4847
  "col",
4878
4848
  {
4879
4849
  ref: c.tableColRef,
4880
- key: c.columnId,
4850
+ key: c.field.toString(),
4881
4851
  style: {
4882
4852
  width: c.width,
4883
4853
  minWidth: c.minWidth ?? "50px"
@@ -4933,7 +4903,7 @@ function Component(props, apiRef) {
4933
4903
  HeadCell2,
4934
4904
  {
4935
4905
  tableId,
4936
- key: c.columnId,
4906
+ key: c.field.toString(),
4937
4907
  stickyHeader: props.stickyHeader,
4938
4908
  editMode: !!c.isCellEditable,
4939
4909
  onSortChange: handleSortChange,