Skip to content

Commit

Permalink
[DataGridPro] Implement header filter height (mui#12666)
Browse files Browse the repository at this point in the history
Signed-off-by: Rom Grk <[email protected]>
Co-authored-by: Bilal Shafi <[email protected]>
  • Loading branch information
romgrk and MBilalShafi authored Apr 16, 2024
1 parent d42fae1 commit 9c27168
Show file tree
Hide file tree
Showing 23 changed files with 92 additions and 45 deletions.
9 changes: 9 additions & 0 deletions docs/data/data-grid/filtering/header-filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ Additionally, `slots.headerFilterMenu` could also be used to customize the menu

{{"demo": "CustomHeaderFilterDataGridPro.js", "bg": "inline", "defaultCodeOpen": false}}

### Custom header filter height

By default, the height of the header filter row is the same as the header row (represented by `columnHeaderHeight` prop).
You can customize the height of the header filter cell using the `headerFilterHeight` prop.

```tsx
<DataGridPro {...data} headerFilterHeight={52} />
```

## Ignore diacritics (accents)

You can ignore diacritics (accents) when filtering the rows. See [Quick filter - Ignore diacritics (accents)](/x/react-data-grid/filtering/quick-filter/#ignore-diacritics-accents).
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/data-grid-premium.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
}
},
"groupingColDef": { "type": { "name": "union", "description": "func<br>&#124;&nbsp;object" } },
"headerFilterHeight": { "type": { "name": "number" } },
"headerFilters": { "type": { "name": "bool" }, "default": "false" },
"hideFooter": { "type": { "name": "bool" }, "default": "false" },
"hideFooterPagination": { "type": { "name": "bool" }, "default": "false" },
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
}
},
"groupingColDef": { "type": { "name": "union", "description": "func<br>&#124;&nbsp;object" } },
"headerFilterHeight": { "type": { "name": "number" } },
"headerFilters": { "type": { "name": "bool" }, "default": "false" },
"hideFooter": { "type": { "name": "bool" }, "default": "false" },
"hideFooterPagination": { "type": { "name": "bool" }, "default": "false" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
}
},
"groupingColDef": { "description": "The grouping column used by the tree data." },
"headerFilterHeight": { "description": "Override the height of the header filters." },
"headerFilters": {
"description": "If <code>true</code>, enables the data grid filtering on header feature."
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
}
},
"groupingColDef": { "description": "The grouping column used by the tree data." },
"headerFilterHeight": { "description": "Override the height of the header filters." },
"headerFilters": {
"description": "If <code>true</code>, enables the data grid filtering on header feature."
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,10 @@ DataGridPremiumRaw.propTypes = {
* The grouping column used by the tree data.
*/
groupingColDef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
/**
* Override the height of the header filters.
*/
headerFilterHeight: PropTypes.number,
/**
* If `true`, enables the data grid filtering on header feature.
* @default false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const useGridCellSelection = (
const autoScrollRAF = React.useRef<number | null>();
const sortedRowIds = useGridSelector(apiRef, gridSortedRowIdsSelector);
const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
const totalHeaderHeight = getTotalHeaderHeight(apiRef, props.columnHeaderHeight);
const totalHeaderHeight = getTotalHeaderHeight(apiRef, props);

const ignoreValueFormatterProp = props.ignoreValueFormatterDuringExport;
const ignoreValueFormatter =
Expand Down
4 changes: 4 additions & 0 deletions packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,10 @@ DataGridProRaw.propTypes = {
* The grouping column used by the tree data.
*/
groupingColDef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
/**
* Override the height of the header filters.
*/
headerFilterHeight: PropTypes.number,
/**
* If `true`, enables the data grid filtering on header feature.
* @default false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => {
<rootProps.slots.headerFilterCell
colIndex={columnIndex}
key={`${colDef.field}-filter`}
height={dimensions.headerHeight}
height={dimensions.headerFilterHeight}
width={colDef.computedWidth}
colDef={colDef}
hasFocus={hasFocus}
Expand Down
8 changes: 5 additions & 3 deletions packages/x-data-grid-pro/src/models/dataGridProProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
DataGridPropsWithComplexDefaultValueBeforeProcessing,
GridPinnedColumnFields,
DataGridProSharedPropsWithDefaultValue,
DataGridProSharedPropsWithoutDefaultValue,
} from '@mui/x-data-grid/internals';
import type { GridPinnedRowsProp } from '../hooks/features/rowPinning';
import { GridApiPro } from './gridApiPro';
Expand Down Expand Up @@ -138,9 +139,10 @@ export interface DataGridProPropsWithDefaultValue<R extends GridValidRowModel =

export interface DataGridProPropsWithoutDefaultValue<R extends GridValidRowModel = any>
extends Omit<
DataGridPropsWithoutDefaultValue<R>,
'initialState' | 'componentsProps' | 'slotProps'
> {
DataGridPropsWithoutDefaultValue<R>,
'initialState' | 'componentsProps' | 'slotProps'
>,
DataGridProSharedPropsWithoutDefaultValue {
/**
* The ref object that allows grid manipulation. Can be instantiated with `useGridApiRef()`.
*/
Expand Down
16 changes: 16 additions & 0 deletions packages/x-data-grid-pro/src/tests/layout.DataGridPro.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,22 @@ describe('<DataGridPro /> - Layout', () => {
});
});

it('should work with `headerFilterHeight` prop', () => {
render(
<div style={{ width: 300, height: 300 }}>
<DataGridPro
{...baselineProps}
autoHeight
headerFilters
columnHeaderHeight={20}
headerFilterHeight={32}
rowHeight={20}
/>
</div>,
);
expect(grid('main')!.clientHeight).to.equal(baselineProps.rows.length * 20 + 20 + 32);
});

it('should support translations in the theme', () => {
render(
<ThemeProvider theme={createTheme({}, ptBR)}>
Expand Down
1 change: 1 addition & 0 deletions packages/x-data-grid/src/components/GridRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ GridRow.propTypes = {
}).isRequired,
hasScrollX: PropTypes.bool.isRequired,
hasScrollY: PropTypes.bool.isRequired,
headerFilterHeight: PropTypes.number.isRequired,
headerHeight: PropTypes.number.isRequired,
headersTotalHeight: PropTypes.number.isRequired,
isReady: PropTypes.bool.isRequired,
Expand Down
2 changes: 1 addition & 1 deletion packages/x-data-grid/src/components/GridScrollArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function GridScrollAreaRaw(props: ScrollAreaProps) {
const rootProps = useGridRootProps();
const ownerState = { ...rootProps, scrollDirection };
const classes = useUtilityClasses(ownerState);
const totalHeaderHeight = getTotalHeaderHeight(apiRef, rootProps.columnHeaderHeight);
const totalHeaderHeight = getTotalHeaderHeight(apiRef, rootProps);
const headerHeight = Math.floor(rootProps.columnHeaderHeight * densityFactor);

const style: React.CSSProperties = {
Expand Down
7 changes: 2 additions & 5 deletions packages/x-data-grid/src/components/cell/GridCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { gridFocusCellSelector } from '../../hooks/features/focus/gridFocusStateSelector';
import { MissingRowIdError } from '../../hooks/features/rows/useGridParamsApi';
import type {
DataGridProcessedProps,
DataGridProcessedPropsWithShared,
} from '../../models/props/DataGridProps';
import type { DataGridProcessedProps } from '../../models/props/DataGridProps';
import { shouldCellShowLeftBorder, shouldCellShowRightBorder } from '../../utils/cellBorderUtils';
import { GridPinnedColumnPosition } from '../../hooks/features/columns/gridColumnsInterfaces';

Expand Down Expand Up @@ -182,7 +179,7 @@ const GridCell = React.forwardRef<HTMLDivElement, GridCellProps>((props, ref) =>
} = props;

const apiRef = useGridApiContext();
const rootProps = useGridRootProps() as DataGridProcessedPropsWithShared;
const rootProps = useGridRootProps();

const field = column.field;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export const GridColumnHeaderRow = styled('div', {
overridesResolver: (_, styles) => styles.columnHeaderRow,
})<{ ownerState: OwnerState }>({
display: 'flex',
height: 'var(--DataGrid-headerHeight)',
});

export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
GRID_STRING_COL_DEF,
getGridDefaultColumnTypes,
} from '../../../colDef';
import { DataGridProcessedProps } from '../../../models/props/DataGridProps';
import { GridApiCommunity } from '../../../models/api/gridApiCommunity';
import { GridColDef, GridStateColDef } from '../../../models/colDef/gridColDef';
import { gridColumnsStateSelector, gridColumnVisibilityModelSelector } from './gridColumnsSelector';
Expand Down Expand Up @@ -431,11 +432,16 @@ export function getFirstNonSpannedColumnToRender({

export function getTotalHeaderHeight(
apiRef: React.MutableRefObject<GridApiCommunity>,
headerHeight: number,
props: Pick<DataGridProcessedProps, 'columnHeaderHeight' | 'headerFilterHeight'>,
) {
const densityFactor = gridDensityFactorSelector(apiRef);
const maxDepth = gridColumnGroupsHeaderMaxDepthSelector(apiRef);
const isHeaderFilteringEnabled = gridHeaderFilteringEnabledSelector(apiRef);
const multiplicationFactor = isHeaderFilteringEnabled ? 2 : 1;
return Math.floor(headerHeight * densityFactor) * ((maxDepth ?? 0) + multiplicationFactor);

const columnHeadersHeight = Math.floor(props.columnHeaderHeight * densityFactor);
const filterHeadersHeight = isHeaderFilteringEnabled
? Math.floor((props.headerFilterHeight ?? props.columnHeaderHeight) * densityFactor)
: 0;

return columnHeadersHeight * (1 + (maxDepth ?? 0)) + filterHeadersHeight;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,13 @@ export interface GridDimensions {
*/
rightPinnedWidth: number;
/**
* Height of one headers.
* Height of one column header.
*/
headerHeight: number;
/**
* Height of header filters.
*/
headerFilterHeight: number;
/**
* Height of all the column headers.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type RootProps = Pick<
| 'rowHeight'
| 'resizeThrottleMs'
| 'columnHeaderHeight'
| 'headerFilterHeight'
>;

export type GridDimensionsState = GridDimensions;
Expand All @@ -58,6 +59,7 @@ const EMPTY_DIMENSIONS: GridDimensions = {
hasScrollY: false,
scrollbarSize: 0,
headerHeight: 0,
headerFilterHeight: 0,
rowWidth: 0,
rowHeight: 0,
columnsTotalWidth: 0,
Expand Down Expand Up @@ -89,8 +91,11 @@ export function useGridDimensions(
const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
const rowHeight = Math.floor(props.rowHeight * densityFactor);
const headerHeight = Math.floor(props.columnHeaderHeight * densityFactor);
const headerFilterHeight = Math.floor(
(props.headerFilterHeight ?? props.columnHeaderHeight) * densityFactor,
);
const columnsTotalWidth = roundToDecimalPlaces(gridColumnsTotalWidthSelector(apiRef), 6);
const headersTotalHeight = getTotalHeaderHeight(apiRef, props.columnHeaderHeight);
const headersTotalHeight = getTotalHeaderHeight(apiRef, props);

const leftPinnedWidth = pinnedColumns.left.reduce((w, col) => w + col.computedWidth, 0);
const rightPinnedWidth = pinnedColumns.right.reduce((w, col) => w + col.computedWidth, 0);
Expand Down Expand Up @@ -244,6 +249,7 @@ export function useGridDimensions(
hasScrollY,
scrollbarSize,
headerHeight,
headerFilterHeight,
rowWidth,
rowHeight,
columnsTotalWidth,
Expand Down Expand Up @@ -273,6 +279,7 @@ export function useGridDimensions(
rowsMeta.currentPageTotalHeight,
rowHeight,
headerHeight,
headerFilterHeight,
columnsTotalWidth,
headersTotalHeight,
leftPinnedWidth,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function buildPrintWindow(title?: string): HTMLIFrameElement {
*/
export const useGridPrintExport = (
apiRef: React.MutableRefObject<GridPrivateApiCommunity>,
props: Pick<DataGridProcessedProps, 'pagination' | 'columnHeaderHeight'>,
props: Pick<DataGridProcessedProps, 'pagination' | 'columnHeaderHeight' | 'headerFilterHeight'>,
): void => {
const logger = useGridLogger(apiRef, 'useGridPrintExport');
const doc = React.useRef<Document | null>(null);
Expand Down Expand Up @@ -160,7 +160,7 @@ export const useGridPrintExport = (
// Expand container height to accommodate all rows
const computedTotalHeight =
rowsMeta.currentPageTotalHeight +
getTotalHeaderHeight(apiRef, props.columnHeaderHeight) +
getTotalHeaderHeight(apiRef, props) +
gridToolbarElementHeight +
gridFooterElementHeight;
gridClone.style.height = `${computedTotalHeight}px`;
Expand Down Expand Up @@ -256,7 +256,7 @@ export const useGridPrintExport = (
});
}
},
[apiRef, doc, props.columnHeaderHeight],
[apiRef, doc, props],
);

const handlePrintWindowAfterPrint = React.useCallback(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity';
import { DataGridProcessedPropsWithShared } from '../../../models/props/DataGridProps';
import { DataGridProcessedProps } from '../../../models/props/DataGridProps';
import { GridHeaderFilteringState } from '../../../models/gridHeaderFilteringModel';
import { useGridApiMethod } from '../../utils/useGridApiMethod';
import { GridStateInitializer } from '../../utils/useGridInitializeState';
Expand All @@ -17,15 +17,15 @@ import {

export const headerFilteringStateInitializer: GridStateInitializer = (
state,
props: DataGridProcessedPropsWithShared,
props: DataGridProcessedProps,
) => ({
...state,
headerFiltering: { enabled: props.headerFilters ?? false, editing: null, menuOpen: null },
});

export const useGridHeaderFiltering = (
apiRef: React.MutableRefObject<GridPrivateApiCommunity>,
props: Pick<DataGridProcessedPropsWithShared, 'signature' | 'headerFilters'>,
props: Pick<DataGridProcessedProps, 'signature' | 'headerFilters'>,
) => {
const logger = useGridLogger(apiRef, 'useGridHeaderFiltering');
const setHeaderFilterState = React.useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { GridCellParams } from '../../../models/params/gridCellParams';
import { gridVisibleColumnDefinitionsSelector } from '../columns/gridColumnsSelector';
import { useGridLogger } from '../../utils/useGridLogger';
import { useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
import { DataGridProcessedPropsWithShared } from '../../../models/props/DataGridProps';
import { DataGridProcessedProps } from '../../../models/props/DataGridProps';
import { gridExpandedSortedRowEntriesSelector } from '../filter/gridFilterSelector';
import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../../../colDef/gridCheckboxSelectionColDef';
Expand Down Expand Up @@ -92,7 +92,7 @@ const getRightColumnIndex = ({
export const useGridKeyboardNavigation = (
apiRef: React.MutableRefObject<GridPrivateApiCommunity>,
props: Pick<
DataGridProcessedPropsWithShared,
DataGridProcessedProps,
| 'pagination'
| 'paginationMode'
| 'getRowId'
Expand Down
10 changes: 1 addition & 9 deletions packages/x-data-grid/src/internals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,7 @@ export { useGridVisibleRows, getVisibleRows } from '../hooks/utils/useGridVisibl
export { useGridInitializeState } from '../hooks/utils/useGridInitializeState';
export type { GridStateInitializer } from '../hooks/utils/useGridInitializeState';

export type {
DataGridProSharedPropsWithDefaultValue,
DataGridPremiumSharedPropsWithDefaultValue,
GridExperimentalFeatures,
DataGridPropsWithoutDefaultValue,
DataGridPropsWithDefaultValues,
DataGridPropsWithComplexDefaultValueAfterProcessing,
DataGridPropsWithComplexDefaultValueBeforeProcessing,
} from '../models/props/DataGridProps';
export type * from '../models/props/DataGridProps';

export { getColumnsToExport, defaultGetRowsToExport } from '../hooks/features/export/utils';
export * from '../utils/createControllablePromise';
Expand Down
24 changes: 13 additions & 11 deletions packages/x-data-grid/src/models/props/DataGridProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,6 @@ export type DataGridProps<R extends GridValidRowModel = any> = Omit<
pagination?: true;
};

/**
* The props of the `DataGrid` component after the pre-processing phase.
*/
export interface DataGridProcessedProps<R extends GridValidRowModel = any>
extends DataGridPropsWithDefaultValues,
DataGridPropsWithComplexDefaultValueAfterProcessing,
DataGridPropsWithoutDefaultValue<R> {}

/**
* The props of the `DataGrid` component after the pre-processing phase that the user should not be able to override.
* Those are usually used in feature-hook for which the pro-plan has more advanced features (eg: multi-sorting, multi-filtering, ...).
Expand Down Expand Up @@ -799,6 +791,13 @@ export interface DataGridProSharedPropsWithDefaultValue {
headerFilters: boolean;
}

export interface DataGridProSharedPropsWithoutDefaultValue {
/**
* Override the height of the header filters.
*/
headerFilterHeight?: number;
}

export interface DataGridPremiumSharedPropsWithDefaultValue {
/**
* If `true`, the cell selection mode is enabled.
Expand All @@ -808,9 +807,12 @@ export interface DataGridPremiumSharedPropsWithDefaultValue {
}

/**
* Contains the commercial packages' props shared in the MIT version.
* The props of the `DataGrid` component after the pre-processing phase.
*/
export interface DataGridProcessedPropsWithShared
extends DataGridProcessedProps,
export interface DataGridProcessedProps<R extends GridValidRowModel = any>
extends DataGridPropsWithDefaultValues,
DataGridPropsWithComplexDefaultValueAfterProcessing,
DataGridPropsWithoutDefaultValue<R>,
DataGridProSharedPropsWithoutDefaultValue,
Partial<DataGridProSharedPropsWithDefaultValue>,
Partial<DataGridPremiumSharedPropsWithDefaultValue> {}

0 comments on commit 9c27168

Please sign in to comment.