From e6c629e2337131be447bb06245ecf29df973e483 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Mon, 9 Dec 2024 15:40:02 +0000 Subject: [PATCH 01/16] change header filter variant and update styling --- .../headerFiltering/GridHeaderFilterCell.tsx | 13 +++++++++---- .../GridHeaderFilterClearButton.tsx | 9 ++++++--- .../GridHeaderFilterMenuContainer.tsx | 4 +--- .../panel/filterPanel/GridFilterInputBoolean.tsx | 14 ++------------ .../filterPanel/GridFilterInputSingleSelect.tsx | 14 ++------------ .../panel/filterPanel/GridFilterInputValue.tsx | 12 ++++++++---- 6 files changed, 28 insertions(+), 38 deletions(-) diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx index bd8aca4630ed1..83c028401a380 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx @@ -88,9 +88,9 @@ const useUtilityClasses = (ownerState: OwnerState) => { return composeClasses(slots, getDataGridUtilityClass, classes); }; -const dateSx = { - [`& input[value=""]:not(:focus)`]: { color: 'transparent' }, -}; +const inputSx = { flex: 1, mr: 0.5 }; +const dateSx = { [`& input[value=""]:not(:focus)`]: { color: 'transparent' } }; + const defaultInputComponents: { [key in GridColType]: React.JSXElementConstructor | null } = { string: GridFilterInputValue, number: GridFilterInputValue, @@ -374,10 +374,15 @@ const GridHeaderFilterCell = React.forwardRef ) : null } + variant="outlined" + size="small" disabled={isFilterReadOnly || isNoInputOperator} tabIndex={-1} InputLabelProps={null} - sx={colDef.type === 'date' || colDef.type === 'dateTime' ? dateSx : undefined} + sx={[ + inputSx, + colDef.type === 'date' || colDef.type === 'dateTime' ? dateSx : undefined, + ]} {...(isNoInputOperator ? { value: '' } : {})} {...currentOperator?.InputComponentProps} {...InputComponentProps} diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterClearButton.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterClearButton.tsx index 1c4ad36c7c588..3ab17406a9c50 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterClearButton.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterClearButton.tsx @@ -1,11 +1,10 @@ import * as React from 'react'; import { IconButtonProps } from '@mui/material/IconButton'; +import { inputBaseClasses } from '@mui/material/InputBase'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; interface GridHeaderFilterClearIconProps extends IconButtonProps {} -const sx = { padding: '2px' }; - function GridHeaderFilterClearButton(props: GridHeaderFilterClearIconProps) { const rootProps = useGridRootProps(); return ( @@ -13,7 +12,11 @@ function GridHeaderFilterClearButton(props: GridHeaderFilterClearIconProps) { tabIndex={-1} aria-label="Clear filter" size="small" - sx={sx} + sx={{ + [`.${inputBaseClasses.root} &`]: { + mx: -0.5, + }, + }} {...props} {...rootProps.slotProps?.baseIconButton} > diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx index a09f307355e91..5c7dc5cab2aaf 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx @@ -12,9 +12,7 @@ import { gridHeaderFilteringMenuSelector } from '@mui/x-data-grid/internals'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; const sx = { - width: 22, - height: 22, - margin: 'auto 0 10px 5px', + marginRight: -0.75, }; function GridHeaderFilterMenuContainer(props: { diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx index c0f6ae6818ddf..87a4ceddedeab 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { TextFieldProps } from '@mui/material/TextField'; import { refType, unstable_useId as useId } from '@mui/utils'; -import { styled } from '@mui/material/styles'; import { GridFilterInputValueProps } from './GridFilterInputValueProps'; import { useGridRootProps } from '../../../hooks/utils/useGridRootProps'; @@ -26,15 +25,6 @@ export const sanitizeFilterItemValue = (value: any): boolean | undefined => { return undefined; }; -const BooleanOperatorContainer = styled('div')({ - display: 'flex', - alignItems: 'center', - width: '100%', - [`& button`]: { - margin: 'auto 0px 5px 5px', - }, -}); - function GridFilterInputBoolean(props: GridFilterInputBooleanProps) { const { item, @@ -79,7 +69,7 @@ function GridFilterInputBoolean(props: GridFilterInputBooleanProps) { const label = labelProp ?? apiRef.current.getLocaleText('filterPanelInputLabel'); return ( - + {clearButton} - + ); } diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx index d88468fb9cd1b..e5c827b14a7a6 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import { TextFieldProps } from '@mui/material/TextField'; import { SelectChangeEvent } from '@mui/material/Select'; import { unstable_useId as useId } from '@mui/utils'; -import { styled } from '@mui/material/styles'; import { GridFilterInputValueProps } from './GridFilterInputValueProps'; import { GridSingleSelectColDef } from '../../../models/colDef/gridColDef'; import { useGridRootProps } from '../../../hooks/utils/useGridRootProps'; @@ -46,15 +45,6 @@ const renderSingleSelectOptions = ({ }); }; -const SingleSelectOperatorContainer = styled('div')({ - display: 'flex', - alignItems: 'flex-end', - width: '100%', - [`& button`]: { - margin: 'auto 0px 5px 5px', - }, -}); - export type GridFilterInputSingleSelectProps = GridFilterInputValueProps & TextFieldProps & { clearButton?: React.ReactNode | null; @@ -122,7 +112,7 @@ function GridFilterInputSingleSelect(props: GridFilterInputSingleSelectProps) { const label = labelProp ?? apiRef.current.getLocaleText('filterPanelInputLabel'); return ( - + {clearButton} - + ); } diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx index 4391eed4166d3..f00ebcfb5f43a 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx @@ -79,10 +79,14 @@ function GridFilterInputValue(props: GridTypeFilterInputValueProps) { InputProps={{ ...(applying || clearButton ? { - endAdornment: applying ? ( - - ) : ( - clearButton + endAdornment: ( + + {applying ? ( + + ) : ( + clearButton + )} + ), } : {}), From 73bcdde964462e66530b5a38365fff88063133a6 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Wed, 11 Dec 2024 17:10:35 +0000 Subject: [PATCH 02/16] small inputs --- .../headerFiltering/GridHeaderFilterCell.tsx | 133 ++++++++++-------- .../GridHeaderFilterClearButton.tsx | 7 +- .../GridHeaderFilterMenuContainer.tsx | 8 +- .../filterPanel/GridFilterInputBoolean.tsx | 2 + .../GridFilterInputSingleSelect.tsx | 92 ++++++------ 5 files changed, 131 insertions(+), 111 deletions(-) diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx index 83c028401a380..b3074742dafc7 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx @@ -33,6 +33,7 @@ import { shouldCellShowLeftBorder, shouldCellShowRightBorder, } from '@mui/x-data-grid/internals'; +import { SxProps } from '@mui/system'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; import { DataGridProProcessedProps } from '../../models/dataGridProProps'; import { GridHeaderFilterMenuContainer } from './GridHeaderFilterMenuContainer'; @@ -88,8 +89,14 @@ const useUtilityClasses = (ownerState: OwnerState) => { return composeClasses(slots, getDataGridUtilityClass, classes); }; -const inputSx = { flex: 1, mr: 0.5 }; -const dateSx = { [`& input[value=""]:not(:focus)`]: { color: 'transparent' } }; +const inputSx: SxProps = { + flex: 1, + '.MuiOutlinedInput-root': { px: 1.25 }, + '.MuiOutlinedInput-input': { fontSize: 14 }, + '.MuiInputLabel-outlined': { transform: 'translate(12px, -9px) scale(0.75)' }, + '.MuiOutlinedInput-notchedOutline': { px: 0.75 }, +}; +const dateSx: SxProps = { [`& input[value=""]:not(:focus)`]: { color: 'transparent' } }; const defaultInputComponents: { [key in GridColType]: React.JSXElementConstructor | null } = { string: GridFilterInputValue, @@ -331,6 +338,7 @@ const GridHeaderFilterCell = React.forwardRef {headerFilterComponent} {InputComponent && headerFilterComponent === undefined ? ( - - apiRef.current.startHeaderFilterEditMode(colDef.field)} - onBlur={(event: React.FocusEvent) => { - apiRef.current.stopHeaderFilterEditMode(); - // Blurring an input element should reset focus state only if `relatedTarget` is not the header filter cell - if (!event.relatedTarget?.className.includes('columnHeader')) { - apiRef.current.setState((state) => ({ - ...state, - focus: { - cell: null, - columnHeader: null, - columnHeaderFilter: null, - columnGroupHeader: null, - }, - })); - } - }} - label={capitalize(label)} - placeholder="" - isFilterActive={isFilterActive} - clearButton={ - showClearIcon && isApplied ? ( - apiRef.current.startHeaderFilterEditMode(colDef.field)} + onBlur={(event: React.FocusEvent) => { + apiRef.current.stopHeaderFilterEditMode(); + // Blurring an input element should reset focus state only if `relatedTarget` is not the header filter cell + if (!event.relatedTarget?.className.includes('columnHeader')) { + apiRef.current.setState((state) => ({ + ...state, + focus: { + cell: null, + columnHeader: null, + columnHeaderFilter: null, + columnGroupHeader: null, + }, + })); + } + }} + label={capitalize(label)} + placeholder="" + isFilterActive={isFilterActive} + variant="outlined" + size="small" + disabled={isFilterReadOnly || isNoInputOperator} + tabIndex={-1} + InputLabelProps={null} + InputProps={{ + startAdornment: ( + + - ) : null - } - variant="outlined" - size="small" - disabled={isFilterReadOnly || isNoInputOperator} - tabIndex={-1} - InputLabelProps={null} - sx={[ - inputSx, - colDef.type === 'date' || colDef.type === 'dateTime' ? dateSx : undefined, - ]} - {...(isNoInputOperator ? { value: '' } : {})} - {...currentOperator?.InputComponentProps} - {...InputComponentProps} - /> - - + + ), + endAdornment: + showClearIcon && isApplied ? ( + + + + ) : null, + }} + sx={[ + inputSx, + colDef.type === 'date' || colDef.type === 'dateTime' ? dateSx : undefined, + ]} + clearButton={ + showClearIcon && isApplied ? ( + + ) : null + } + {...(isNoInputOperator ? { value: '' } : {})} + {...currentOperator?.InputComponentProps} + {...InputComponentProps} + /> ) : null} ); diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterClearButton.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterClearButton.tsx index 3ab17406a9c50..4ee23436fd039 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterClearButton.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterClearButton.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import { IconButtonProps } from '@mui/material/IconButton'; -import { inputBaseClasses } from '@mui/material/InputBase'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; interface GridHeaderFilterClearIconProps extends IconButtonProps {} @@ -12,11 +11,7 @@ function GridHeaderFilterClearButton(props: GridHeaderFilterClearIconProps) { tabIndex={-1} aria-label="Clear filter" size="small" - sx={{ - [`.${inputBaseClasses.root} &`]: { - mx: -0.5, - }, - }} + edge="end" {...props} {...rootProps.slotProps?.baseIconButton} > diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx index 5c7dc5cab2aaf..38e080bdab3c3 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx @@ -11,10 +11,6 @@ import { refType, unstable_useId as useId } from '@mui/utils'; import { gridHeaderFilteringMenuSelector } from '@mui/x-data-grid/internals'; import { useGridRootProps } from '../../hooks/utils/useGridRootProps'; -const sx = { - marginRight: -0.75, -}; - function GridHeaderFilterMenuContainer(props: { operators: GridFilterOperator[]; field: GridColDef['field']; @@ -66,12 +62,12 @@ function GridHeaderFilterMenuContainer(props: { aria-haspopup="true" tabIndex={-1} size="small" + edge="start" onClick={handleClick} - sx={sx} disabled={disabled} {...rootProps.slotProps?.baseIconButton} > - + - - - {label} - - - {renderSingleSelectOptions({ - column: resolvedColumn, - OptionComponent: rootProps.slots.baseSelectOption, - getOptionLabel, - getOptionValue, - isSelectNative, - baseSelectOptionProps: rootProps.slotProps?.baseSelectOption, - })} - - - {clearButton} - + + + {label} + + + {clearButton} + + } + inputProps={{ + tabIndex, + ref: focusElementRef, + placeholder: placeholder ?? apiRef.current.getLocaleText('filterPanelInputPlaceholder'), + }} + native={isSelectNative} + notched={variant === 'outlined' ? true : undefined} + { + ...(others as any) /* FIXME: typing error */ + } + {...rootProps.slotProps?.baseSelect} + > + {renderSingleSelectOptions({ + column: resolvedColumn, + OptionComponent: rootProps.slots.baseSelectOption, + getOptionLabel, + getOptionValue, + isSelectNative, + baseSelectOptionProps: rootProps.slotProps?.baseSelectOption, + })} + + ); } From ebea8b3c80f5a7445cfb4a2004b45007a46d2cd6 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Mon, 23 Dec 2024 15:59:14 +0000 Subject: [PATCH 03/16] update clear button design --- .../CustomHeaderFilterOperatorDataGridPro.tsx | 29 ++-- .../CustomHeaderFilterSingleDataGridPro.tsx | 7 +- docs/data/data-grid/localization/data.json | 140 +++++++++--------- .../x/api/data-grid/data-grid-premium.json | 6 + docs/pages/x/api/data-grid/data-grid-pro.json | 6 + docs/pages/x/api/data-grid/data-grid.json | 6 + .../data-grid-premium/data-grid-premium.json | 1 + .../data-grid-pro/data-grid-pro.json | 1 + .../data-grid/data-grid/data-grid.json | 1 + .../headerFiltering/GridHeaderFilterCell.tsx | 54 +++---- .../GridHeaderFilterClearButton.tsx | 4 +- .../headerFiltering/GridHeaderFilterMenu.tsx | 32 +++- .../GridHeaderFilterMenuContainer.tsx | 14 +- .../filterPanel/GridFilterInputBoolean.tsx | 8 +- .../panel/filterPanel/GridFilterInputDate.tsx | 71 ++++----- .../GridFilterInputMultipleSingleSelect.tsx | 2 +- .../GridFilterInputMultipleValue.tsx | 2 +- .../GridFilterInputSingleSelect.tsx | 98 ++++++------ .../filterPanel/GridFilterInputValue.tsx | 73 +++++---- .../src/constants/localeTextConstants.ts | 1 + packages/x-data-grid/src/locales/arSD.ts | 1 + packages/x-data-grid/src/locales/beBY.ts | 1 + packages/x-data-grid/src/locales/bgBG.ts | 1 + packages/x-data-grid/src/locales/csCZ.ts | 1 + packages/x-data-grid/src/locales/daDK.ts | 1 + packages/x-data-grid/src/locales/deDE.ts | 1 + packages/x-data-grid/src/locales/elGR.ts | 1 + packages/x-data-grid/src/locales/esES.ts | 1 + packages/x-data-grid/src/locales/faIR.ts | 1 + packages/x-data-grid/src/locales/fiFI.ts | 1 + packages/x-data-grid/src/locales/frFR.ts | 1 + packages/x-data-grid/src/locales/heIL.ts | 1 + packages/x-data-grid/src/locales/hrHR.ts | 1 + packages/x-data-grid/src/locales/huHU.ts | 1 + packages/x-data-grid/src/locales/isIS.ts | 1 + packages/x-data-grid/src/locales/itIT.ts | 1 + packages/x-data-grid/src/locales/jaJP.ts | 1 + packages/x-data-grid/src/locales/koKR.ts | 1 + packages/x-data-grid/src/locales/nbNO.ts | 1 + packages/x-data-grid/src/locales/nlNL.ts | 1 + packages/x-data-grid/src/locales/nnNO.ts | 1 + packages/x-data-grid/src/locales/plPL.ts | 1 + packages/x-data-grid/src/locales/ptBR.ts | 1 + packages/x-data-grid/src/locales/ptPT.ts | 1 + packages/x-data-grid/src/locales/roRO.ts | 1 + packages/x-data-grid/src/locales/ruRU.ts | 1 + packages/x-data-grid/src/locales/skSK.ts | 1 + packages/x-data-grid/src/locales/svSE.ts | 1 + packages/x-data-grid/src/locales/trTR.ts | 1 + packages/x-data-grid/src/locales/ukUA.ts | 1 + packages/x-data-grid/src/locales/urPK.ts | 1 + packages/x-data-grid/src/locales/viVN.ts | 1 + packages/x-data-grid/src/locales/zhCN.ts | 1 + packages/x-data-grid/src/locales/zhHK.ts | 1 + packages/x-data-grid/src/locales/zhTW.ts | 1 + packages/x-data-grid/src/material/index.tsx | 1 + .../src/models/api/gridLocaleTextApi.ts | 1 + .../src/models/gridIconSlotsComponent.ts | 5 + 58 files changed, 339 insertions(+), 259 deletions(-) diff --git a/docs/data/data-grid/filtering/CustomHeaderFilterOperatorDataGridPro.tsx b/docs/data/data-grid/filtering/CustomHeaderFilterOperatorDataGridPro.tsx index 0276f0e9e4299..9725cf6185bc6 100644 --- a/docs/data/data-grid/filtering/CustomHeaderFilterOperatorDataGridPro.tsx +++ b/docs/data/data-grid/filtering/CustomHeaderFilterOperatorDataGridPro.tsx @@ -32,28 +32,17 @@ function RatingInputValue( }; return ( - + + {headerFilterMenu} - - - {clearButton} - + ); } diff --git a/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx b/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx index ecd9ccf8be2a1..0cdf6f9fe6e36 100644 --- a/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx +++ b/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx @@ -43,7 +43,12 @@ function AdminFilter(props: GridRenderHeaderFilterProps) { const label = !value ? 'Filter' : 'Is admin'; return ( - + {label} None diff --git a/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx b/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx index 0cdf6f9fe6e36..5c14abbdf7862 100644 --- a/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx +++ b/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx @@ -43,12 +43,7 @@ function AdminFilter(props: GridRenderHeaderFilterProps) { const label = !value ? 'Filter' : 'Is admin'; return ( - + {label} None diff --git a/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx b/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx index 5c14abbdf7862..4dc9ec6bde046 100644 --- a/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx +++ b/docs/data/data-grid/filtering/CustomHeaderFilterSingleDataGridPro.tsx @@ -44,7 +44,9 @@ function AdminFilter(props: GridRenderHeaderFilterProps) { return ( - {label} + + {label} +