diff --git a/packages/grid/x-data-grid/src/components/panel/GridColumnsPanel.tsx b/packages/grid/x-data-grid/src/components/panel/GridColumnsPanel.tsx index 30ab1314ffd0..39c98609f340 100644 --- a/packages/grid/x-data-grid/src/components/panel/GridColumnsPanel.tsx +++ b/packages/grid/x-data-grid/src/components/panel/GridColumnsPanel.tsx @@ -19,8 +19,8 @@ import { GridPanelWrapper, GridPanelWrapperProps } from './GridPanelWrapper'; import { GRID_EXPERIMENTAL_ENABLED } from '../../constants/envConstants'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; import { DataGridProcessedProps } from '../../models/props/DataGridProps'; +import type { GridStateColDef } from '../../models/colDef/gridColDef'; import { getDataGridUtilityClass } from '../../constants/gridClasses'; -import { GridStateColDef } from '../../models/colDef/gridColDef'; type OwnerState = { classes: DataGridProcessedProps['classes'] }; @@ -67,6 +67,13 @@ export interface GridColumnsPanelProps extends GridPanelWrapperProps { */ sort?: 'asc' | 'desc'; searchPredicate?: (column: GridStateColDef, searchValue: string) => boolean; + /* + * If `true`, the column search field will be focused automatically. + * If `false`, the first column switch input will be focused automatically. + * This helps to avoid input keyboard panel to popup automatically on touch devices. + * @default true + */ + autoFocusSearchField?: boolean; } const collator = new Intl.Collator(); @@ -88,7 +95,12 @@ function GridColumnsPanel(props: GridColumnsPanelProps) { const ownerState = { classes: rootProps.classes }; const classes = useUtilityClasses(ownerState); - const { sort, searchPredicate = defaultSearchPredicate, ...other } = props; + const { + sort, + searchPredicate = defaultSearchPredicate, + autoFocusSearchField = true, + ...other + } = props; const sortedColumns = React.useMemo(() => { switch (sort) { @@ -155,9 +167,24 @@ function GridColumnsPanel(props: GridColumnsPanelProps) { return sortedColumns.filter((column) => searchPredicate(column, searchValueToCheck)); }, [sortedColumns, searchValue, searchPredicate]); + const firstSwitchRef = React.useRef(null); + React.useEffect(() => { - searchInputRef.current!.focus(); - }, []); + if (autoFocusSearchField) { + searchInputRef.current!.focus(); + } else if (firstSwitchRef.current && typeof firstSwitchRef.current.focus === 'function') { + firstSwitchRef.current.focus(); + } + }, [autoFocusSearchField]); + + let firstHideableColumnFound = false; + const isFirstHideableColumn = (column: GridStateColDef) => { + if (firstHideableColumnFound === false && column.hideable !== false) { + firstHideableColumnFound = true; + return true; + } + return false; + }; return ( @@ -185,6 +212,7 @@ function GridColumnsPanel(props: GridColumnsPanelProps) { onClick={toggleColumn} name={column.field} size="small" + inputRef={isFirstHideableColumn(column) ? firstSwitchRef : undefined} {...rootProps.componentsProps?.baseSwitch} /> } @@ -228,6 +256,7 @@ GridColumnsPanel.propTypes = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- + autoFocusSearchField: PropTypes.bool, searchPredicate: PropTypes.func, sort: PropTypes.oneOf(['asc', 'desc']), } as any; diff --git a/packages/grid/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx index a2414a03f981..b4b9184f861d 100644 --- a/packages/grid/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx @@ -259,4 +259,23 @@ describe(' - Columns Visibility', () => { expect(getColumnHeadersTextContent()).to.deep.equal(['id', 'idBis']); }); }); + + it('should autofocus the first switch element in columns panel when `autoFocusSearchField` disabled', () => { + render( + , + ); + + fireEvent.click(screen.getByRole('button', { name: 'Select columns' })); + + expect(screen.getByRole('checkbox', { name: columns[0].field })).toHaveFocus(); + }); });