Skip to content

Commit

Permalink
[DataGrid] Refactor: create base Select (#16394)
Browse files Browse the repository at this point in the history
  • Loading branch information
romgrk authored Feb 7, 2025
1 parent fc6cd07 commit d259518
Show file tree
Hide file tree
Showing 9 changed files with 287 additions and 280 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { GridColumnMenuItemProps, useGridSelector } from '@mui/x-data-grid-pro';
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import { unstable_useId as useId } from '@mui/utils';
import { SelectChangeEvent } from '@mui/material/Select';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import {
Expand Down Expand Up @@ -55,7 +52,7 @@ function GridColumnMenuAggregationItem(props: GridColumnMenuItemProps) {
return '';
}, [rootProps.aggregationFunctions, rootProps.unstable_dataSource, aggregationModel, colDef]);

const handleAggregationItemChange = (event: SelectChangeEvent<unknown>) => {
const handleAggregationItemChange = (event: React.ChangeEvent<unknown>) => {
const newAggregationItem = (event.target as HTMLSelectElement | null)?.value || undefined;
const currentModel = gridAggregationModelSelector(apiRef);
const { [colDef.field]: columnItem, ...otherColumnItems } = currentModel;
Expand Down Expand Up @@ -88,53 +85,49 @@ function GridColumnMenuAggregationItem(props: GridColumnMenuItemProps) {
iconStart={<rootProps.slots.columnMenuAggregationIcon fontSize="small" />}
onKeyDown={handleMenuItemKeyDown}
>
<FormControl size="small" fullWidth sx={{ minWidth: 150 }}>
<InputLabel id={`${id}-label`} htmlFor={`${id}-input`}>
{label}
</InputLabel>
<rootProps.slots.baseSelect
labelId={`${id}-label`}
inputRef={inputRef}
id={`${id}-input`}
value={selectedAggregationRule}
label={label}
color="primary"
onChange={handleAggregationItemChange}
MenuProps={{
PaperProps: {
onKeyDown: handleSelectKeyDown,
},
}}
onBlur={(event) => event.stopPropagation()}
<rootProps.slots.baseSelect
labelId={`${id}-label`}
id={`${id}-input`}
value={selectedAggregationRule}
label={label}
onChange={handleAggregationItemChange}
onKeyDown={handleSelectKeyDown}
onBlur={(event) => event.stopPropagation()}
native={isBaseSelectNative}
fullWidth
size="small"
style={{ minWidth: 150 }}
slotProps={{
htmlInput: {
ref: inputRef,
},
}}
{...baseSelectProps}
>
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
native={isBaseSelectNative}
fullWidth
{...baseSelectProps}
value=""
>
...
</rootProps.slots.baseSelectOption>
{availableAggregationFunctions.map((aggFunc) => (
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
key={aggFunc}
value={aggFunc}
native={isBaseSelectNative}
value=""
>
...
{getAggregationFunctionLabel({
apiRef,
aggregationRule: {
aggregationFunctionName: aggFunc,
aggregationFunction: rootProps.aggregationFunctions[aggFunc],
},
})}
</rootProps.slots.baseSelectOption>
{availableAggregationFunctions.map((aggFunc) => (
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
key={aggFunc}
value={aggFunc}
native={isBaseSelectNative}
>
{getAggregationFunctionLabel({
apiRef,
aggregationRule: {
aggregationFunctionName: aggFunc,
aggregationFunction: rootProps.aggregationFunctions[aggFunc],
},
})}
</rootProps.slots.baseSelectOption>
))}
</rootProps.slots.baseSelect>
</FormControl>
))}
</rootProps.slots.baseSelect>
</rootProps.slots.baseMenuItem>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function GridEditSingleSelectCell(props: GridEditSingleSelectCellProps) {
error,
onValueChange,
initialOpen = rootProps.editMode === GridEditModes.Cell,
slotProps,
...other
} = props;

Expand All @@ -64,7 +65,6 @@ function GridEditSingleSelectCell(props: GridEditSingleSelectCellProps) {

const baseSelectProps = rootProps.slotProps?.baseSelect || {};
const isSelectNative = baseSelectProps.native ?? false;
const { MenuProps, ...otherBaseSelectProps } = rootProps.slotProps?.baseSelect || {};

useEnhancedEffect(() => {
if (hasFocus) {
Expand All @@ -84,7 +84,7 @@ function GridEditSingleSelectCell(props: GridEditSingleSelectCellProps) {
const getOptionValue = colDef.getOptionValue!;
const getOptionLabel = colDef.getOptionLabel!;

const handleChange: SelectProps['onChange'] = async (event) => {
const handleChange: React.ChangeEventHandler<HTMLInputElement> = async (event) => {
if (!isSingleSelectColDef(colDef) || !valueOptions) {
return;
}
Expand Down Expand Up @@ -136,20 +136,22 @@ function GridEditSingleSelectCell(props: GridEditSingleSelectCellProps) {
return (
<rootProps.slots.baseSelect
ref={ref}
inputRef={inputRef}
value={valueProp}
onChange={handleChange}
onChange={handleChange as any}
open={open}
onOpen={handleOpen}
MenuProps={{
onClose: handleClose,
...MenuProps,
}}
onClose={handleClose}
error={error}
native={isSelectNative}
fullWidth
slotProps={{
htmlInput: {
ref: inputRef,
},
}}
{...other}
{...otherBaseSelectProps}
{...slotProps?.root}
{...rootProps.slotProps?.baseSelect}
>
{valueOptions.map((valueOption) => {
const value = getOptionValue(valueOption);
Expand Down
185 changes: 70 additions & 115 deletions packages/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ const GridFilterForm = forwardRef<HTMLDivElement, GridFilterFormProps>(
const baseSelectProps = rootProps.slotProps?.baseSelect || {};
const isBaseSelectNative = baseSelectProps.native ?? false;

const baseInputLabelProps = rootProps.slotProps?.baseInputLabel || {};
const baseSelectOptionProps = rootProps.slotProps?.baseSelectOption || {};

const { InputComponentProps, ...valueInputPropsOther } = valueInputProps;
Expand Down Expand Up @@ -445,11 +444,7 @@ const GridFilterForm = forwardRef<HTMLDivElement, GridFilterFormProps>(
</rootProps.slots.baseIconButton>
</FilterFormDeleteIcon>
<FilterFormLogicOperatorInput
variant="outlined"
size="small"
as={rootProps.slots.baseFormControl}
{...baseFormControlProps}
{...logicOperatorInputProps}
as={rootProps.slots.baseSelect}
sx={[
hasLogicOperatorColumn
? {
Expand All @@ -465,137 +460,97 @@ const GridFilterForm = forwardRef<HTMLDivElement, GridFilterFormProps>(
: {
visibility: 'hidden',
},
baseFormControlProps.sx,
logicOperatorInputProps.sx,
]}
className={clsx(
classes.logicOperatorInput,
baseFormControlProps.className,
logicOperatorInputProps.className,
)}
className={clsx(classes.logicOperatorInput, logicOperatorInputProps.className)}
ownerState={rootProps}
>
<rootProps.slots.baseSelect
inputProps={{
{...logicOperatorInputProps}
size="small"
slotProps={{
htmlInput: {
'aria-label': apiRef.current.getLocaleText('filterPanelLogicOperator'),
}}
value={multiFilterOperator ?? ''}
onChange={changeLogicOperator}
disabled={!!disableMultiFilterOperator || logicOperators.length === 1}
native={isBaseSelectNative}
{...rootProps.slotProps?.baseSelect}
>
{logicOperators.map((logicOperator) => (
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
native={isBaseSelectNative}
key={logicOperator.toString()}
value={logicOperator.toString()}
>
{apiRef.current.getLocaleText(getLogicOperatorLocaleKey(logicOperator))}
</rootProps.slots.baseSelectOption>
))}
</rootProps.slots.baseSelect>
},
}}
value={multiFilterOperator ?? ''}
onChange={changeLogicOperator}
disabled={!!disableMultiFilterOperator || logicOperators.length === 1}
native={isBaseSelectNative}
{...rootProps.slotProps?.baseSelect}
>
{logicOperators.map((logicOperator) => (
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
native={isBaseSelectNative}
key={logicOperator.toString()}
value={logicOperator.toString()}
>
{apiRef.current.getLocaleText(getLogicOperatorLocaleKey(logicOperator))}
</rootProps.slots.baseSelectOption>
))}
</FilterFormLogicOperatorInput>
<FilterFormColumnInput
variant="outlined"
size="small"
as={rootProps.slots.baseFormControl}
{...baseFormControlProps}
as={rootProps.slots.baseSelect}
{...columnInputProps}
className={clsx(
classes.columnInput,
baseFormControlProps.className,
columnInputProps.className,
)}
className={clsx(classes.columnInput, columnInputProps.className)}
ownerState={rootProps}
size="small"
labelId={columnSelectLabelId}
id={columnSelectId}
label={apiRef.current.getLocaleText('filterPanelColumns')}
value={selectedField ?? ''}
onChange={changeColumn}
native={isBaseSelectNative}
disabled={readOnly}
{...rootProps.slotProps?.baseSelect}
>
<rootProps.slots.baseInputLabel
{...baseInputLabelProps}
htmlFor={columnSelectId}
id={columnSelectLabelId}
>
{apiRef.current.getLocaleText('filterPanelColumns')}
</rootProps.slots.baseInputLabel>
<rootProps.slots.baseSelect
labelId={columnSelectLabelId}
id={columnSelectId}
label={apiRef.current.getLocaleText('filterPanelColumns')}
value={selectedField ?? ''}
onChange={changeColumn}
native={isBaseSelectNative}
disabled={readOnly}
{...rootProps.slotProps?.baseSelect}
>
{sortedFilteredColumns.map((col) => (
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
native={isBaseSelectNative}
key={col.field}
value={col.field}
>
{getColumnLabel(col)}
</rootProps.slots.baseSelectOption>
))}
</rootProps.slots.baseSelect>
{sortedFilteredColumns.map((col) => (
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
native={isBaseSelectNative}
key={col.field}
value={col.field}
>
{getColumnLabel(col)}
</rootProps.slots.baseSelectOption>
))}
</FilterFormColumnInput>
<FilterFormOperatorInput
variant="outlined"
size="small"
as={rootProps.slots.baseFormControl}
{...baseFormControlProps}
as={rootProps.slots.baseSelect}
{...operatorInputProps}
className={clsx(
classes.operatorInput,
baseFormControlProps.className,
operatorInputProps.className,
)}
className={clsx(classes.operatorInput, operatorInputProps.className)}
ownerState={rootProps}
labelId={operatorSelectLabelId}
label={apiRef.current.getLocaleText('filterPanelOperator')}
id={operatorSelectId}
value={item.operator}
onChange={changeOperator}
native={isBaseSelectNative}
inputRef={filterSelectorRef}
disabled={readOnly}
{...rootProps.slotProps?.baseSelect}
>
<rootProps.slots.baseInputLabel
{...baseInputLabelProps}
htmlFor={operatorSelectId}
id={operatorSelectLabelId}
>
{apiRef.current.getLocaleText('filterPanelOperator')}
</rootProps.slots.baseInputLabel>
<rootProps.slots.baseSelect
labelId={operatorSelectLabelId}
label={apiRef.current.getLocaleText('filterPanelOperator')}
id={operatorSelectId}
value={item.operator}
onChange={changeOperator}
native={isBaseSelectNative}
inputRef={filterSelectorRef}
disabled={readOnly}
{...rootProps.slotProps?.baseSelect}
>
{currentColumn?.filterOperators?.map((operator) => (
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
native={isBaseSelectNative}
key={operator.value}
value={operator.value}
>
{operator.label ||
apiRef.current.getLocaleText(
`filterOperator${capitalize(operator.value)}` as 'filterOperatorContains',
)}
</rootProps.slots.baseSelectOption>
))}
</rootProps.slots.baseSelect>
{currentColumn?.filterOperators?.map((operator) => (
<rootProps.slots.baseSelectOption
{...baseSelectOptionProps}
native={isBaseSelectNative}
key={operator.value}
value={operator.value}
>
{operator.label ||
apiRef.current.getLocaleText(
`filterOperator${capitalize(operator.value)}` as 'filterOperatorContains',
)}
</rootProps.slots.baseSelectOption>
))}
</FilterFormOperatorInput>
<FilterFormValueInput
variant="outlined"
size="small"
as={rootProps.slots.baseFormControl}
{...baseFormControlProps}
{...valueInputPropsOther}
className={clsx(
classes.valueInput,
baseFormControlProps.className,
valueInputPropsOther.className,
)}
className={clsx(classes.valueInput, valueInputPropsOther.className)}
ownerState={rootProps}
>
{currentOperator?.InputComponent ? (
Expand Down
Loading

0 comments on commit d259518

Please sign in to comment.