@mui/x-data-grid-generator 8.26.0 → 8.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/columns/commodities.columns.d.ts +1 -1
  3. package/columns/commodities.columns.js +2 -0
  4. package/columns/employees.columns.d.ts +1 -1
  5. package/columns/employees.columns.js +1 -0
  6. package/constants/prompts.d.ts +1 -1
  7. package/esm/columns/commodities.columns.d.ts +1 -1
  8. package/esm/columns/commodities.columns.js +3 -1
  9. package/esm/columns/employees.columns.d.ts +1 -1
  10. package/esm/columns/employees.columns.js +2 -1
  11. package/esm/constants/prompts.d.ts +1 -1
  12. package/esm/hooks/serverUtils.d.ts +1 -1
  13. package/esm/hooks/useBasicDemoData.d.ts +1 -1
  14. package/esm/hooks/useDemoData.d.ts +4 -4
  15. package/esm/hooks/useEditDropdownState.d.ts +39 -0
  16. package/esm/hooks/useEditDropdownState.js +158 -0
  17. package/esm/hooks/useMockServer.d.ts +1 -1
  18. package/esm/hooks/useMovieData.d.ts +1 -1
  19. package/esm/hooks/useQuery.d.ts +2 -2
  20. package/esm/hooks/useRowEditHandlers.d.ts +25 -0
  21. package/esm/hooks/useRowEditHandlers.js +84 -0
  22. package/esm/index.js +1 -1
  23. package/esm/renderer/index.d.ts +2 -1
  24. package/esm/renderer/index.js +2 -1
  25. package/esm/renderer/renderAvatar.d.ts +1 -1
  26. package/esm/renderer/renderCountry.d.ts +2 -2
  27. package/esm/renderer/renderEditBoolean.d.ts +2 -0
  28. package/esm/renderer/renderEditBoolean.js +56 -0
  29. package/esm/renderer/renderEditCountry.d.ts +2 -2
  30. package/esm/renderer/renderEditCountry.js +68 -48
  31. package/esm/renderer/renderEditCurrency.d.ts +1 -1
  32. package/esm/renderer/renderEditCurrency.js +67 -47
  33. package/esm/renderer/renderEditIncoterm.d.ts +1 -1
  34. package/esm/renderer/renderEditIncoterm.js +30 -27
  35. package/esm/renderer/renderEditProgress.d.ts +1 -1
  36. package/esm/renderer/renderEditProgress.js +3 -2
  37. package/esm/renderer/renderEditRating.d.ts +1 -1
  38. package/esm/renderer/renderEditRating.js +3 -2
  39. package/esm/renderer/renderEditStatus.d.ts +1 -1
  40. package/esm/renderer/renderEditStatus.js +30 -28
  41. package/esm/renderer/renderEmail.d.ts +1 -1
  42. package/esm/renderer/renderIncoterm.d.ts +1 -1
  43. package/esm/renderer/renderLink.d.ts +1 -1
  44. package/esm/renderer/renderPnl.d.ts +1 -1
  45. package/esm/renderer/renderProgress.d.ts +1 -1
  46. package/esm/renderer/renderRating.d.ts +1 -1
  47. package/esm/renderer/renderStatus.d.ts +1 -1
  48. package/esm/renderer/renderTotalPrice.d.ts +1 -1
  49. package/esm/services/basic-data-service.d.ts +1 -1
  50. package/esm/services/gridColDefGenerator.d.ts +1 -1
  51. package/esm/services/prompt-resolver.d.ts +1 -1
  52. package/esm/services/random-generator.d.ts +1 -1
  53. package/esm/services/real-data-service.d.ts +2 -2
  54. package/esm/services/tree-data-generator.d.ts +2 -2
  55. package/hooks/serverUtils.d.ts +1 -1
  56. package/hooks/useBasicDemoData.d.ts +1 -1
  57. package/hooks/useDemoData.d.ts +4 -4
  58. package/hooks/useEditDropdownState.d.ts +39 -0
  59. package/hooks/useEditDropdownState.js +165 -0
  60. package/hooks/useMockServer.d.ts +1 -1
  61. package/hooks/useMovieData.d.ts +1 -1
  62. package/hooks/useQuery.d.ts +2 -2
  63. package/hooks/useRowEditHandlers.d.ts +25 -0
  64. package/hooks/useRowEditHandlers.js +90 -0
  65. package/index.js +1 -1
  66. package/package.json +5 -5
  67. package/renderer/index.d.ts +2 -1
  68. package/renderer/index.js +11 -0
  69. package/renderer/renderAvatar.d.ts +1 -1
  70. package/renderer/renderCountry.d.ts +2 -2
  71. package/renderer/renderEditBoolean.d.ts +2 -0
  72. package/renderer/renderEditBoolean.js +63 -0
  73. package/renderer/renderEditCountry.d.ts +2 -2
  74. package/renderer/renderEditCountry.js +67 -48
  75. package/renderer/renderEditCurrency.d.ts +1 -1
  76. package/renderer/renderEditCurrency.js +66 -47
  77. package/renderer/renderEditIncoterm.d.ts +1 -1
  78. package/renderer/renderEditIncoterm.js +30 -27
  79. package/renderer/renderEditProgress.d.ts +1 -1
  80. package/renderer/renderEditProgress.js +3 -2
  81. package/renderer/renderEditRating.d.ts +1 -1
  82. package/renderer/renderEditRating.js +3 -2
  83. package/renderer/renderEditStatus.d.ts +1 -1
  84. package/renderer/renderEditStatus.js +30 -28
  85. package/renderer/renderEmail.d.ts +1 -1
  86. package/renderer/renderIncoterm.d.ts +1 -1
  87. package/renderer/renderLink.d.ts +1 -1
  88. package/renderer/renderPnl.d.ts +1 -1
  89. package/renderer/renderProgress.d.ts +1 -1
  90. package/renderer/renderRating.d.ts +1 -1
  91. package/renderer/renderStatus.d.ts +1 -1
  92. package/renderer/renderTotalPrice.d.ts +1 -1
  93. package/services/basic-data-service.d.ts +1 -1
  94. package/services/gridColDefGenerator.d.ts +1 -1
  95. package/services/prompt-resolver.d.ts +1 -1
  96. package/services/random-generator.d.ts +1 -1
  97. package/services/real-data-service.d.ts +2 -2
  98. package/services/tree-data-generator.d.ts +2 -2
package/CHANGELOG.md CHANGED
@@ -5,6 +5,106 @@
5
5
  All notable changes to this project will be documented in this file.
6
6
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
7
7
 
8
+ ## v8.27.0
9
+
10
+ _Feb 2, 2026_
11
+
12
+ We'd like to extend a big thank you to the 8 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 📝 Data Grid supports new `longText` [column type](https://mui.com/x/react-data-grid/column-definition/#column-types)
15
+
16
+ The following team members contributed to this release:
17
+ @alexfauquette, @arminmeh, @bernardobelchior, @cherniavskii, @flaviendelangle, @JCQuintas, @MBilalShafi, @siriwatknp
18
+
19
+ ### Data Grid
20
+
21
+ #### `@mui/x-data-grid@8.27.0`
22
+
23
+ - [DataGrid] Fix virtualization crash by preventing out-of-bounds `focusedVirtualCell` indices (#21123) @cherniavskii
24
+ - [DataGrid] Fix focus steal issue with `<Dialog />` (#21106) @MBilalShafi
25
+ - [DataGrid] Add new `longText` column type (#21103) @siriwatknp
26
+
27
+ #### `@mui/x-data-grid-pro@8.27.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
28
+
29
+ Same changes as in `@mui/x-data-grid@8.27.0`.
30
+
31
+ #### `@mui/x-data-grid-premium@8.27.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
32
+
33
+ Same changes as in `@mui/x-data-grid-pro@8.27.0`, plus:
34
+
35
+ - [DataGridPremium] Fix focus retention when undo/redo operations are done on the same cell (#21110) @arminmeh
36
+
37
+ ### Date and Time Pickers
38
+
39
+ #### `@mui/x-date-pickers@8.27.0`
40
+
41
+ Internal changes.
42
+
43
+ #### `@mui/x-date-pickers-pro@8.27.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
44
+
45
+ Same changes as in `@mui/x-date-pickers@8.27.0`.
46
+
47
+ ### Charts
48
+
49
+ #### `@mui/x-charts@8.27.0`
50
+
51
+ - [charts] Deprecate `AxisId` class in favour of to `data-axis-id` attribute (#21048) @JCQuintas
52
+
53
+ #### `@mui/x-charts-pro@8.27.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
54
+
55
+ Same changes as in `@mui/x-charts@8.27.0`, plus:
56
+
57
+ - [charts-pro] Add `onItemClick` to the heatmap (#20817) (#21030) @alexfauquette
58
+
59
+ #### `@mui/x-charts-premium@8.27.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
60
+
61
+ Same changes as in `@mui/x-charts-pro@8.27.0`, plus:
62
+
63
+ - [charts-premium] Fix wrong `defaultSlots` in premium charts (#21052) @bernardobelchior
64
+
65
+ ### Tree View
66
+
67
+ #### `@mui/x-tree-view@8.27.0`
68
+
69
+ Internal changes.
70
+
71
+ #### `@mui/x-tree-view-pro@8.27.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
72
+
73
+ Same changes as in `@mui/x-tree-view@8.27.0`, plus:
74
+
75
+ - [RichTreeViewPro] Do not export `useSimpleTreeViewApiRef()` and `useRichTreeViewApiRef()` from pro package (#21145) @flaviendelangle
76
+
77
+ ### Codemod
78
+
79
+ #### `@mui/x-codemod@8.27.0`
80
+
81
+ Internal changes.
82
+
83
+ ### Docs
84
+
85
+ - [docs] Fix DataGrid's cell edit renderers (@arminmeh) (#21041) @github-actions[bot]
86
+
87
+ ### Core
88
+
89
+ - [code-infra] Add `consistent-type-imports` rule to the grid packages (#21119) @arminmeh
90
+ - [code-infra] Allow user to select target branch if it exists for current major (#21005) @JCQuintas
91
+ - [code-infra] Fix the target branch condition in the release script (#21051) @arminmeh
92
+ - [code-infra] Update docs deploy script to fetch from `v8.x` (#21013) @arminmeh
93
+
94
+ ## 8.26.1
95
+
96
+ _Jan 23, 2026_
97
+
98
+ Release highlight ✨:
99
+
100
+ - 🐞 Hotfix for Data Grid Premium type imports
101
+
102
+ ### Data Grid
103
+
104
+ #### `@mui/x-data-grid-premium@8.26.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
105
+
106
+ - [DataGridPremium] Fix type import (#21033) @arminmeh
107
+
8
108
  ## 8.26.0
9
109
 
10
110
  _Jan 22, 2026_
@@ -1,2 +1,2 @@
1
- import { GridColDefGenerator } from "../services/gridColDefGenerator.js";
1
+ import type { GridColDefGenerator } from "../services/gridColDefGenerator.js";
2
2
  export declare const getCommodityColumns: (editable?: boolean) => GridColDefGenerator[];
@@ -61,6 +61,7 @@ const getCommodityColumns = (editable = false) => [{
61
61
  generateData: _services.generateIsFilled,
62
62
  type: 'boolean',
63
63
  width: 80,
64
+ renderEditCell: _renderer.renderEditBoolean,
64
65
  editable
65
66
  }, {
66
67
  field: 'status',
@@ -168,6 +169,7 @@ const getCommodityColumns = (editable = false) => [{
168
169
  type: 'singleSelect',
169
170
  generateData: _services.randomCountry,
170
171
  renderCell: _renderer.renderCountry,
172
+ renderEditCell: _renderer.renderEditCountry,
171
173
  valueOptions: _staticData.COUNTRY_ISO_OPTIONS_SORTED,
172
174
  valueParser: value => {
173
175
  if (typeof value === 'string') {
@@ -1,2 +1,2 @@
1
- import { GridColDefGenerator } from "../services/gridColDefGenerator.js";
1
+ import type { GridColDefGenerator } from "../services/gridColDefGenerator.js";
2
2
  export declare const getEmployeeColumns: () => GridColDefGenerator[];
@@ -127,6 +127,7 @@ const getEmployeeColumns = () => [{
127
127
  generateData: _services.randomBoolean,
128
128
  type: 'boolean',
129
129
  width: 150,
130
+ renderEditCell: _renderer.renderEditBoolean,
130
131
  editable: true
131
132
  }, {
132
133
  field: 'salary',
@@ -1,2 +1,2 @@
1
- import { PromptResponse } from '@mui/x-data-grid-premium';
1
+ import type { PromptResponse } from '@mui/x-data-grid-premium';
2
2
  export declare const mockPrompts: Map<string, PromptResponse>;
@@ -1,2 +1,2 @@
1
- import { GridColDefGenerator } from "../services/gridColDefGenerator.js";
1
+ import type { GridColDefGenerator } from "../services/gridColDefGenerator.js";
2
2
  export declare const getCommodityColumns: (editable?: boolean) => GridColDefGenerator[];
@@ -1,6 +1,6 @@
1
1
  import { gridStringOrNumberComparator } from '@mui/x-data-grid-premium';
2
2
  import { randomCommodity, randomDesk, randomEmail, randomFeeRate, generateFilledQuantity, randomId, randomIncoterm, generateIsFilled, randomQuantity, randomTraderName, randomUnitPrice, randomUnitPriceCurrency, randomStatusOptions, randomPnL, randomTradeDate, randomMaturityDate, randomBrokerId, randomCompanyName, randomCountry, randomCurrency, randomAddress, randomCity, randomUpdatedDate, randomCreatedDate, randomRateType, randomContractType, randomTaxCode } from "../services/index.js";
3
- import { renderCountry, renderEmail, renderIncoterm, renderPnl, renderProgress, renderStatus, renderTotalPrice, renderEditCurrency, renderEditProgress, renderEditStatus, renderEditIncoterm } from "../renderer/index.js";
3
+ import { renderCountry, renderEmail, renderIncoterm, renderPnl, renderProgress, renderStatus, renderTotalPrice, renderEditCurrency, renderEditProgress, renderEditStatus, renderEditIncoterm, renderEditBoolean, renderEditCountry } from "../renderer/index.js";
4
4
  import { CONTRACT_TYPE_OPTIONS, COUNTRY_ISO_OPTIONS_SORTED, CURRENCY_OPTIONS, INCOTERM_OPTIONS, RATE_TYPE_OPTIONS, STATUS_OPTIONS, TAXCODE_OPTIONS } from "../services/static-data.js";
5
5
  export const getCommodityColumns = (editable = false) => [{
6
6
  field: 'id',
@@ -55,6 +55,7 @@ export const getCommodityColumns = (editable = false) => [{
55
55
  generateData: generateIsFilled,
56
56
  type: 'boolean',
57
57
  width: 80,
58
+ renderEditCell: renderEditBoolean,
58
59
  editable
59
60
  }, {
60
61
  field: 'status',
@@ -162,6 +163,7 @@ export const getCommodityColumns = (editable = false) => [{
162
163
  type: 'singleSelect',
163
164
  generateData: randomCountry,
164
165
  renderCell: renderCountry,
166
+ renderEditCell: renderEditCountry,
165
167
  valueOptions: COUNTRY_ISO_OPTIONS_SORTED,
166
168
  valueParser: value => {
167
169
  if (typeof value === 'string') {
@@ -1,2 +1,2 @@
1
- import { GridColDefGenerator } from "../services/gridColDefGenerator.js";
1
+ import type { GridColDefGenerator } from "../services/gridColDefGenerator.js";
2
2
  export declare const getEmployeeColumns: () => GridColDefGenerator[];
@@ -1,6 +1,6 @@
1
1
  import { gridStringOrNumberComparator } from '@mui/x-data-grid-premium';
2
2
  import { randomCity, randomCompanyName, randomCountry, randomCreatedDate, randomEmail, randomId, randomJobTitle, randomPhoneNumber, randomRating, randomUpdatedDate, randomUrl, randomUserName, randomBoolean, randomName, randomColor, randomInt } from "../services/index.js";
3
- import { renderAvatar, renderCountry, renderEmail, renderLink, renderRating, renderEditRating, renderEditCountry } from "../renderer/index.js";
3
+ import { renderAvatar, renderCountry, renderEmail, renderLink, renderRating, renderEditRating, renderEditCountry, renderEditBoolean } from "../renderer/index.js";
4
4
  import { COUNTRY_ISO_OPTIONS_SORTED } from "../services/static-data.js";
5
5
  export const getEmployeeColumns = () => [{
6
6
  field: 'id',
@@ -121,6 +121,7 @@ export const getEmployeeColumns = () => [{
121
121
  generateData: randomBoolean,
122
122
  type: 'boolean',
123
123
  width: 150,
124
+ renderEditCell: renderEditBoolean,
124
125
  editable: true
125
126
  }, {
126
127
  field: 'salary',
@@ -1,2 +1,2 @@
1
- import { PromptResponse } from '@mui/x-data-grid-premium';
1
+ import type { PromptResponse } from '@mui/x-data-grid-premium';
2
2
  export declare const mockPrompts: Map<string, PromptResponse>;
@@ -1,4 +1,4 @@
1
- import { GridRowModel, GridFilterModel, GridSortModel, GridColDef, GridRowId, GridPaginationModel, GridValidRowModel, GridAggregationModel, GridPivotModel, GridGetRowsResponse } from '@mui/x-data-grid-premium';
1
+ import { type GridRowModel, type GridFilterModel, type GridSortModel, type GridColDef, type GridRowId, type GridPaginationModel, type GridValidRowModel, type GridAggregationModel, type GridPivotModel, type GridGetRowsResponse } from '@mui/x-data-grid-premium';
2
2
  export interface FakeServerResponse {
3
3
  returnedRows: GridRowModel[];
4
4
  aggregateRow?: GridValidRowModel;
@@ -1,2 +1,2 @@
1
- import { GridBasicData } from "../services/index.js";
1
+ import { type GridBasicData } from "../services/index.js";
2
2
  export declare const useBasicDemoData: (nbRows: number, nbCols: number) => GridBasicData;
@@ -1,7 +1,7 @@
1
- import { GridColumnVisibilityModel } from '@mui/x-data-grid-premium';
2
- import { GridDemoData } from "../services/real-data-service.js";
3
- import { GridColDefGenerator } from "../services/gridColDefGenerator.js";
4
- import { AddPathToDemoDataOptions, DemoTreeDataValue } from "../services/tree-data-generator.js";
1
+ import type { GridColumnVisibilityModel } from '@mui/x-data-grid-premium';
2
+ import { type GridDemoData } from "../services/real-data-service.js";
3
+ import type { GridColDefGenerator } from "../services/gridColDefGenerator.js";
4
+ import { type AddPathToDemoDataOptions, type DemoTreeDataValue } from "../services/tree-data-generator.js";
5
5
  export type DemoDataReturnType = {
6
6
  data: DemoTreeDataValue;
7
7
  loading: boolean;
@@ -0,0 +1,39 @@
1
+ import * as React from 'react';
2
+ import { type GridRowId } from '@mui/x-data-grid-premium';
3
+ interface UseEditDropdownStateParams {
4
+ id: GridRowId;
5
+ field: string;
6
+ hasFocus: boolean;
7
+ }
8
+ /**
9
+ * Hook that manages dropdown state and keyboard handling for custom edit cells
10
+ * with dropdowns (Select, Autocomplete).
11
+ *
12
+ * Provides:
13
+ * - Auto-open on mount if cell had focus when edit started
14
+ * - Focus management when tabbing into the cell
15
+ * - Keyboard handlers for Tab, Enter, Escape that work in both cell and row edit modes
16
+ * - Handlers for Select and Autocomplete components
17
+ */
18
+ export declare function useEditDropdownState(params: UseEditDropdownStateParams): {
19
+ open: boolean;
20
+ setOpen: React.Dispatch<React.SetStateAction<boolean>>;
21
+ inputRef: React.RefObject<HTMLInputElement | null>;
22
+ shouldAutoOpen: boolean;
23
+ handleSelectKeyDown: (event: React.KeyboardEvent) => void;
24
+ handleSelectMenuClose: (event: object, reason: "escapeKeyDown" | "backdropClick" | "tabKeyDown") => void;
25
+ handleSelectMenuListKeyDown: (event: React.KeyboardEvent) => void;
26
+ createSelectChangeHandler: (getValue: (event: {
27
+ target: {
28
+ value: unknown;
29
+ };
30
+ }) => unknown) => (event: {
31
+ target: {
32
+ value: unknown;
33
+ };
34
+ }) => Promise<void>;
35
+ handleAutocompleteInputKeyDown: (event: React.KeyboardEvent) => void;
36
+ handleAutocompleteWrapperKeyDown: (event: React.KeyboardEvent) => void;
37
+ createAutocompleteChangeHandler: <T>(transformValue?: (value: T) => unknown) => (event: React.SyntheticEvent, newValue: T) => Promise<void>;
38
+ };
39
+ export {};
@@ -0,0 +1,158 @@
1
+ 'use client';
2
+
3
+ import _extends from "@babel/runtime/helpers/esm/extends";
4
+ import * as React from 'react';
5
+ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
6
+ import { GridCellEditStopReasons, GridEditModes, useGridApiContext, useGridRootProps } from '@mui/x-data-grid-premium';
7
+ import { useRowEditHandlers } from "./useRowEditHandlers.js";
8
+ /**
9
+ * Hook that manages dropdown state and keyboard handling for custom edit cells
10
+ * with dropdowns (Select, Autocomplete).
11
+ *
12
+ * Provides:
13
+ * - Auto-open on mount if cell had focus when edit started
14
+ * - Focus management when tabbing into the cell
15
+ * - Keyboard handlers for Tab, Enter, Escape that work in both cell and row edit modes
16
+ * - Handlers for Select and Autocomplete components
17
+ */
18
+ export function useEditDropdownState(params) {
19
+ const {
20
+ id,
21
+ field,
22
+ hasFocus
23
+ } = params;
24
+ const apiRef = useGridApiContext();
25
+ const rootProps = useGridRootProps();
26
+ const inputRef = React.useRef(null);
27
+
28
+ // Only auto-open if this cell had focus when edit started
29
+ const shouldAutoOpen = React.useRef(hasFocus).current;
30
+ const [open, setOpen] = React.useState(shouldAutoOpen);
31
+
32
+ // Track open state in a ref for event handlers that need current value
33
+ const openRef = React.useRef(open);
34
+ openRef.current = open;
35
+ const isRowEditMode = rootProps.editMode === GridEditModes.Row;
36
+ const closeMenu = React.useCallback(() => setOpen(false), []);
37
+ const {
38
+ handleTabKeyDown,
39
+ handleMenuKeyDown
40
+ } = useRowEditHandlers({
41
+ id,
42
+ field,
43
+ onClose: closeMenu
44
+ });
45
+
46
+ // Focus input when hasFocus becomes true (e.g., when tabbing into this cell)
47
+ useEnhancedEffect(() => {
48
+ if (hasFocus) {
49
+ inputRef.current?.focus();
50
+ }
51
+ }, [hasFocus]);
52
+
53
+ /**
54
+ * Handler for Select's onKeyDown - handles Tab when menu is closed
55
+ */
56
+ const handleSelectKeyDown = React.useCallback(event => {
57
+ if (event.key === 'Tab') {
58
+ handleTabKeyDown(event);
59
+ }
60
+ }, [handleTabKeyDown]);
61
+
62
+ /**
63
+ * Handler for Select's MenuProps.onClose - closes menu and exits cell edit on backdrop click
64
+ */
65
+ const handleSelectMenuClose = React.useCallback((event, reason) => {
66
+ setOpen(false);
67
+ if (reason === 'backdropClick' && rootProps.editMode === GridEditModes.Cell && apiRef.current.getCellMode(id, field) === 'edit') {
68
+ const cellParams = apiRef.current.getCellParams(id, field);
69
+ apiRef.current.publishEvent('cellEditStop', _extends({}, cellParams, {
70
+ reason: GridCellEditStopReasons.cellFocusOut
71
+ }));
72
+ }
73
+ }, [apiRef, id, field, rootProps.editMode]);
74
+
75
+ /**
76
+ * Creates a change handler for Select that closes menu and optionally exits edit mode
77
+ */
78
+ const createSelectChangeHandler = React.useCallback(getValue => {
79
+ return async event => {
80
+ // Close menu after selection
81
+ setOpen(false);
82
+ const newValue = getValue(event);
83
+ const isValid = await apiRef.current.setEditCellValue({
84
+ id,
85
+ field,
86
+ value: newValue
87
+ }, event);
88
+
89
+ // In cell edit mode, selecting closes the menu and exits edit mode
90
+ // In row edit mode, selecting only closes the menu (already done above)
91
+ // Check if still in edit mode to avoid double-exit when Enter key also triggers grid's handler
92
+ if (isValid && !isRowEditMode && apiRef.current.getCellMode(id, field) === 'edit') {
93
+ const cellParams = apiRef.current.getCellParams(id, field);
94
+ apiRef.current.publishEvent('cellEditStop', _extends({}, cellParams, {
95
+ reason: GridCellEditStopReasons.enterKeyDown
96
+ }));
97
+ }
98
+ };
99
+ }, [apiRef, id, field, isRowEditMode]);
100
+
101
+ /**
102
+ * Handler for Autocomplete's InputBase onKeyDown - handles Tab
103
+ */
104
+ const handleAutocompleteInputKeyDown = React.useCallback(event => {
105
+ if (event.key === 'Tab') {
106
+ handleTabKeyDown(event);
107
+ }
108
+ }, [handleTabKeyDown]);
109
+
110
+ /**
111
+ * Handler for Autocomplete's wrapper div - stops Enter/Escape only when dropdown is open
112
+ */
113
+ const handleAutocompleteWrapperKeyDown = React.useCallback(event => {
114
+ if (isRowEditMode && openRef.current && (event.key === 'Enter' || event.key === 'Escape')) {
115
+ event.stopPropagation();
116
+ }
117
+ }, [isRowEditMode]);
118
+
119
+ /**
120
+ * Creates a change handler for Autocomplete that optionally exits edit mode
121
+ */
122
+ const createAutocompleteChangeHandler = React.useCallback(transformValue => {
123
+ return async (event, newValue) => {
124
+ const valueToSet = transformValue ? transformValue(newValue) : newValue;
125
+ await apiRef.current.setEditCellValue({
126
+ id,
127
+ field,
128
+ value: valueToSet
129
+ }, event);
130
+
131
+ // In cell edit mode, selecting exits edit mode
132
+ // In row edit mode, selecting only closes the dropdown (Autocomplete handles this)
133
+ // Check if still in edit mode to avoid double-exit when Enter key also triggers grid's handler
134
+ if (!isRowEditMode && apiRef.current.getCellMode(id, field) === 'edit') {
135
+ apiRef.current.stopCellEditMode({
136
+ id,
137
+ field
138
+ });
139
+ }
140
+ };
141
+ }, [apiRef, id, field, isRowEditMode]);
142
+ return {
143
+ // State
144
+ open,
145
+ setOpen,
146
+ inputRef,
147
+ shouldAutoOpen,
148
+ // Select handlers
149
+ handleSelectKeyDown,
150
+ handleSelectMenuClose,
151
+ handleSelectMenuListKeyDown: handleMenuKeyDown,
152
+ createSelectChangeHandler,
153
+ // Autocomplete handlers
154
+ handleAutocompleteInputKeyDown,
155
+ handleAutocompleteWrapperKeyDown,
156
+ createAutocompleteChangeHandler
157
+ };
158
+ }
@@ -1,5 +1,5 @@
1
1
  import { type GridGetRowsResponse, type GridRowId, type GridRowModel, type GridColDef, type GridInitialState } from '@mui/x-data-grid-premium';
2
- import { AddPathToDemoDataOptions } from "../services/tree-data-generator.js";
2
+ import { type AddPathToDemoDataOptions } from "../services/tree-data-generator.js";
3
3
  import type { ServerOptions } from "./serverUtils.js";
4
4
  export declare const BASE_URL = "https://mui.com/x/api/data-grid";
5
5
  type UseMockServerResponse<T> = {
@@ -1,4 +1,4 @@
1
- import { GridColDef, GridRowModel } from '@mui/x-data-grid-premium';
1
+ import type { GridColDef, GridRowModel } from '@mui/x-data-grid-premium';
2
2
  export type Movie = {
3
3
  id: number;
4
4
  title: string;
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { GridRowModel } from '@mui/x-data-grid-pro';
3
- import { UseDemoDataOptions } from "./useDemoData.js";
2
+ import { type GridRowModel } from '@mui/x-data-grid-pro';
3
+ import { type UseDemoDataOptions } from "./useDemoData.js";
4
4
  import type { ServerOptions, QueryOptions, PageInfo } from "./serverUtils.js";
5
5
  export declare const createFakeServer: (dataSetOptions?: Partial<UseDemoDataOptions>, serverOptions?: ServerOptions) => {
6
6
  columns: import("../index.js").GridColDefGenerator[];
@@ -0,0 +1,25 @@
1
+ import * as React from 'react';
2
+ import { type GridRowId } from '@mui/x-data-grid-premium';
3
+ interface UseRowEditHandlersParams {
4
+ id: GridRowId;
5
+ field: string;
6
+ onClose?: () => void;
7
+ }
8
+ /**
9
+ * Hook that provides keyboard event handlers for custom edit cells
10
+ * to work correctly in both cell and row edit modes.
11
+ *
12
+ * In row edit mode:
13
+ * - Tab moves focus to the next/previous editable cell
14
+ * - Enter/Escape are stopped from propagating to prevent exiting row edit
15
+ *
16
+ * In cell edit mode:
17
+ * - Default behavior is preserved
18
+ */
19
+ export declare function useRowEditHandlers(params: UseRowEditHandlersParams): {
20
+ handleTabKeyDown: (event: React.KeyboardEvent) => void;
21
+ handleEnterEscapeKeyDown: (event: React.KeyboardEvent) => void;
22
+ handleMenuKeyDown: (event: React.KeyboardEvent) => void;
23
+ moveFocusToNextCell: (shiftKey: boolean) => void;
24
+ };
25
+ export {};
@@ -0,0 +1,84 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { GridEditModes, useGridApiContext, useGridRootProps } from '@mui/x-data-grid-premium';
5
+ /**
6
+ * Hook that provides keyboard event handlers for custom edit cells
7
+ * to work correctly in both cell and row edit modes.
8
+ *
9
+ * In row edit mode:
10
+ * - Tab moves focus to the next/previous editable cell
11
+ * - Enter/Escape are stopped from propagating to prevent exiting row edit
12
+ *
13
+ * In cell edit mode:
14
+ * - Default behavior is preserved
15
+ */
16
+ export function useRowEditHandlers(params) {
17
+ const {
18
+ id,
19
+ field,
20
+ onClose
21
+ } = params;
22
+ const apiRef = useGridApiContext();
23
+ const rootProps = useGridRootProps();
24
+ const isRowEditMode = rootProps.editMode === GridEditModes.Row;
25
+ const moveFocusToNextCell = React.useCallback(shiftKey => {
26
+ const editableFields = apiRef.current.getVisibleColumns().filter(column => column.type === 'actions' || apiRef.current.isCellEditable(apiRef.current.getCellParams(id, column.field))).map(column => column.field);
27
+ const currentIndex = editableFields.indexOf(field);
28
+ if (currentIndex === -1) {
29
+ return;
30
+ }
31
+ const nextIndex = shiftKey ? currentIndex - 1 : currentIndex + 1;
32
+ if (nextIndex < 0 || nextIndex >= editableFields.length) {
33
+ // At boundary - exit row edit mode
34
+ apiRef.current.stopRowEditMode({
35
+ id,
36
+ field,
37
+ cellToFocusAfter: shiftKey ? 'left' : 'right'
38
+ });
39
+ return;
40
+ }
41
+ apiRef.current.setCellFocus(id, editableFields[nextIndex]);
42
+ }, [apiRef, id, field]);
43
+
44
+ /**
45
+ * Handle Tab key in row edit mode.
46
+ * Closes any open popup and moves focus to the next/previous editable cell.
47
+ */
48
+ const handleTabKeyDown = React.useCallback(event => {
49
+ if (!isRowEditMode || event.key !== 'Tab') {
50
+ return;
51
+ }
52
+ event.preventDefault();
53
+ event.stopPropagation();
54
+ onClose?.();
55
+ moveFocusToNextCell(event.shiftKey);
56
+ }, [isRowEditMode, onClose, moveFocusToNextCell]);
57
+
58
+ /**
59
+ * Prevent Enter/Escape from bubbling in row edit mode.
60
+ * This prevents the grid from exiting row edit when selecting from a dropdown.
61
+ */
62
+ const handleEnterEscapeKeyDown = React.useCallback(event => {
63
+ if (!isRowEditMode) {
64
+ return;
65
+ }
66
+ if (event.key === 'Enter' || event.key === 'Escape') {
67
+ event.stopPropagation();
68
+ }
69
+ }, [isRowEditMode]);
70
+
71
+ /**
72
+ * Combined handler for menus/listboxes that need to handle both Tab and Enter/Escape.
73
+ */
74
+ const handleMenuKeyDown = React.useCallback(event => {
75
+ handleEnterEscapeKeyDown(event);
76
+ handleTabKeyDown(event);
77
+ }, [handleEnterEscapeKeyDown, handleTabKeyDown]);
78
+ return {
79
+ handleTabKeyDown,
80
+ handleEnterEscapeKeyDown,
81
+ handleMenuKeyDown,
82
+ moveFocusToNextCell
83
+ };
84
+ }
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-generator v8.26.0
2
+ * @mui/x-data-grid-generator v8.27.0
3
3
  *
4
4
  * @license UNLICENSED
5
5
  * This source code is licensed under the UNLICENSED license found in the
@@ -13,4 +13,5 @@ export * from "./renderEditProgress.js";
13
13
  export * from "./renderEditStatus.js";
14
14
  export * from "./renderEditIncoterm.js";
15
15
  export * from "./renderEditRating.js";
16
- export * from "./renderEditCountry.js";
16
+ export * from "./renderEditCountry.js";
17
+ export * from "./renderEditBoolean.js";
@@ -13,4 +13,5 @@ export * from "./renderEditProgress.js";
13
13
  export * from "./renderEditStatus.js";
14
14
  export * from "./renderEditIncoterm.js";
15
15
  export * from "./renderEditRating.js";
16
- export * from "./renderEditCountry.js";
16
+ export * from "./renderEditCountry.js";
17
+ export * from "./renderEditBoolean.js";
@@ -1,4 +1,4 @@
1
- import { GridRenderCellParams } from '@mui/x-data-grid-premium';
1
+ import type { GridRenderCellParams } from '@mui/x-data-grid-premium';
2
2
  export declare function renderAvatar(params: GridRenderCellParams<{
3
3
  name: string;
4
4
  color: string;
@@ -1,3 +1,3 @@
1
- import { GridRenderCellParams } from '@mui/x-data-grid-premium';
2
- import { CountryIsoOption } from "../services/static-data.js";
1
+ import { type GridRenderCellParams } from '@mui/x-data-grid-premium';
2
+ import type { CountryIsoOption } from "../services/static-data.js";
3
3
  export declare function renderCountry(params: GridRenderCellParams<CountryIsoOption, any, any>): any;
@@ -0,0 +1,2 @@
1
+ import { type GridRenderEditCellParams } from '@mui/x-data-grid-premium';
2
+ export declare function renderEditBoolean(params: GridRenderEditCellParams<any, boolean>): import("react/jsx-runtime").JSX.Element;