-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DataGrid] Enable using non-native Select in filter panel #4361
Conversation
These are the results for the performance tests:
|
c39f5b1
to
756d28a
Compare
756d28a
to
632457b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Supporting both native and non-native select seems to be a pain due to the switch between <option />
and <MenuItem />
What would you think about adding a helper component to switch between them more easily
const SelectOption = ({ isNative, ...props }) => isNative ? <option {...props} /> : <MenuItem {...props} />
packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx
Outdated
Show resolved
Hide resolved
@@ -137,6 +137,7 @@ function GridEditSingleSelectCell(props: GridRenderEditCellParams & Omit<SelectP | |||
fullWidth | |||
{...other} | |||
{...rootProps.componentsProps?.baseSelect} | |||
native={false} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the default value. I do not think users prop should be overridden
A solution could be to send a warning if other.native || rootProps.componentsProps?.baseSelect?.native
explaining that EditSingleSelectCell
does not support native select
Here is an example of a warning message:
mui-x/packages/grid/x-data-grid/src/hooks/features/columns/gridColumnsUtils.ts
Lines 295 to 305 in 3d2ff09
if (process.env.NODE_ENV !== 'production') { | |
if (!columnTypeWarnedOnce && !columnTypes[type]) { | |
console.warn( | |
[ | |
`MUI: The column type "${type}" you are using is not supported.`, | |
`Column type "string" is being used instead.`, | |
].join('\n'), | |
); | |
columnTypeWarnedOnce = true; | |
} | |
} |
Another solution is to support native select by adding an argument isNative
to renderSingleSelectOptions
such that it can switch between <MenuItem/>
and <option />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another solution is to support native select by adding an argument isNative to renderSingleSelectOptions such that it can switch between and
+1 for this option. It will be odd to have all selects working with native=false
and only this one that doesn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chose the latter solution(support native select).
I tested the change using Storybook, and I found that NativeSelect
casts the value to a string.
To fix that issue, I copied the util getValueFromValueOptions
from filterPanelUtils
and formatted the value.
const handleChange = async (event: React.KeyboardEvent<HTMLInputElement>) => {
setOpen(false);
const target = event.target as HTMLInputElement;
// NativeSelect casts the value to a string.
const formattedTargetValue = getValueFromValueOptions(target.value, valueOptionsFormatted);
const isValid = await api.setEditCellValue({ id, field, value: formattedTargetValue }, event);
...
packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job! I only think we could go one step further and reduce the amount of code duplicated. Sometimes only one or two props change.
))} | ||
{linkOperators.map((linkOperator) => | ||
isBaseSelectNative ? ( | ||
<option key={linkOperator.toString()} value={linkOperator.toString()}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The props are the same for MenuItem
and option
. You could store in an OptionComponent
variable which option component to use, then do:
const OptionComponent = ...
linkOperators.map((linkOperator) => (
<OptionComponent key={...} value={...} />
))
Same for the other components. This reduce code duplication.
packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx
Outdated
Show resolved
Hide resolved
@alexfauquette @m4theushw |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look nice. Maybe putting the SelectOption
in a dedicated file to avoid duplicated code, and for me it will be good.
packages/grid/x-data-grid/src/components/cell/GridEditSingleSelectCell.tsx
Outdated
Show resolved
Hide resolved
interface SelectOptionProps { | ||
isNative: boolean; | ||
children: React.ReactNode; | ||
value: string; | ||
} | ||
|
||
const SelectOption = ({ isNative, children, value, ...props }: SelectOptionProps) => | ||
isNative ? ( | ||
<option value={value} {...props}> | ||
{children} | ||
</option> | ||
) : ( | ||
<MenuItem value={value} {...props}> | ||
{children} | ||
</MenuItem> | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this code is duplicated, maybe a dedicated file components/SelectOption.tsx
could be more appropriate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed a4110eb simplifying the way we choose which component to use for the options. I think we were duplicating too much code. What do you think now?
@@ -12,17 +12,21 @@ import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; | |||
import { GridEditModes } from '../../models/gridEditRowModel'; | |||
import { GridEvents } from '../../models/events/gridEvents'; | |||
import { GridColDef, ValueOptions } from '../../models/colDef/gridColDef'; | |||
import { getValueFromValueOptions } from './editCellUtils'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we reuse the functions from filterPanelUtils.ts
?
It looks simpler than my first version. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a commit to change import helpers from the single select
Just spot a typo, otherwise it looks good
packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx
Show resolved
Hide resolved
Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com>
Preview: https://codesandbox.io/s/columntypesgrid-material-demo-forked-ll8bmp?file=/demo.tsx
Closes #4127
This PR resolves the issue that
Select
component inFilter Panel
only usesnative UI
.Following the suggestion, I made 3 changes.
ClickAwayListener
inFilter Panel
usesonMouseUp
mouseEvent.When
rootProps.componentsProps?.baseSelect.native
is set to false,baseSelect
component uses MUI component andMenuItem
component is used instead ofoption
tag.rootProps.componentsProps?.baseSelect
is passed toInputComponent
whenSelect
Component is used.NOTE. To avoid breaking change, I set default
native
to true.Before
2022-04-05.12.59.42.mov
After
2022-04-05.12.25.22.mov