diff --git a/docs/data/data-grid/filtering/CustomFilterPanelPosition.js b/docs/data/data-grid/filtering/CustomFilterPanelPositionNoSnap.js similarity index 95% rename from docs/data/data-grid/filtering/CustomFilterPanelPosition.js rename to docs/data/data-grid/filtering/CustomFilterPanelPositionNoSnap.js index dfb4f68770c9d..022b087f60bf5 100644 --- a/docs/data/data-grid/filtering/CustomFilterPanelPosition.js +++ b/docs/data/data-grid/filtering/CustomFilterPanelPositionNoSnap.js @@ -23,7 +23,7 @@ function CustomToolbar({ setFilterButtonEl }) { ); } -export default function CustomFilterPanelPosition() { +export default function CustomFilterPanelPositionNoSnap() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, diff --git a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx b/docs/data/data-grid/filtering/CustomFilterPanelPositionNoSnap.tsx similarity index 96% rename from docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx rename to docs/data/data-grid/filtering/CustomFilterPanelPositionNoSnap.tsx index a2ac5a8db49eb..ad2bb1b6ee132 100644 --- a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx +++ b/docs/data/data-grid/filtering/CustomFilterPanelPositionNoSnap.tsx @@ -32,7 +32,7 @@ function CustomToolbar({ setFilterButtonEl }: GridSlotProps['toolbar']) { ); } -export default function CustomFilterPanelPosition() { +export default function CustomFilterPanelPositionNoSnap() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, diff --git a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx.preview b/docs/data/data-grid/filtering/CustomFilterPanelPositionNoSnap.tsx.preview similarity index 100% rename from docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx.preview rename to docs/data/data-grid/filtering/CustomFilterPanelPositionNoSnap.tsx.preview diff --git a/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.js b/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.js new file mode 100644 index 0000000000000..bd2b7734264c6 --- /dev/null +++ b/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.js @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { DataGrid } from '@mui/x-data-grid'; +import { useDemoData } from '@mui/x-data-grid-generator'; + +const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; + +export default function FilterPanelPlacementColumnHeadersNoSnap() { + const { data, loading } = useDemoData({ + dataSet: 'Employee', + visibleFields: VISIBLE_FIELDS, + rowLength: 100, + }); + + const columnHeadersRef = React.useRef(null); + + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.tsx b/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.tsx new file mode 100644 index 0000000000000..f6f0716d4984e --- /dev/null +++ b/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.tsx @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { DataGrid } from '@mui/x-data-grid'; +import { useDemoData } from '@mui/x-data-grid-generator'; + +const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; + +export default function FilterPanelPlacementColumnHeadersNoSnap() { + const { data, loading } = useDemoData({ + dataSet: 'Employee', + visibleFields: VISIBLE_FIELDS, + rowLength: 100, + }); + + const columnHeadersRef = React.useRef(null); + + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.tsx.preview b/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.tsx.preview new file mode 100644 index 0000000000000..bd1274aa277ff --- /dev/null +++ b/docs/data/data-grid/filtering/FilterPanelPlacementColumnHeadersNoSnap.tsx.preview @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/docs/data/data-grid/filtering/customization.md b/docs/data/data-grid/filtering/customization.md index 1d4a676e5e535..081fd5a3ba97c 100644 --- a/docs/data/data-grid/filtering/customization.md +++ b/docs/data/data-grid/filtering/customization.md @@ -177,9 +177,17 @@ To pass props directly to the `InputComponent` and not its wrapper, you can use ### Customize the filter panel position +#### Toolbar button anchor + The demo below shows how to anchor the filter panel to the toolbar button instead of the column header. -{{"demo": "CustomFilterPanelPosition.js", "bg": "inline", "defaultCodeOpen": false}} +{{"demo": "CustomFilterPanelPositionNoSnap.js", "bg": "inline", "defaultCodeOpen": false}} + +#### Column headers anchor + +The following demo shows how to make panels always appear on the bottom-left under the column headers mimicking the default behavior of Data Grid v7. + +{{"demo": "FilterPanelPlacementColumnHeadersNoSnap.js", "bg": "inline", "defaultCodeOpen": false}} ## API diff --git a/packages/x-data-grid/src/components/panel/GridPanel.tsx b/packages/x-data-grid/src/components/panel/GridPanel.tsx index acdbf781ad54c..404e88b308972 100644 --- a/packages/x-data-grid/src/components/panel/GridPanel.tsx +++ b/packages/x-data-grid/src/components/panel/GridPanel.tsx @@ -23,10 +23,7 @@ export interface GridPanelClasses { paper: string; } -export interface GridPanelProps extends Pick< - GridSlotProps['basePopper'], - 'id' | 'className' | 'target' | 'flip' -> { +export interface GridPanelProps extends Omit { ref?: React.Ref; children?: React.ReactNode; /** @@ -134,11 +131,48 @@ GridPanel.propTypes = { */ classes: PropTypes.object, className: PropTypes.string, + clickAwayMouseEvent: PropTypes.oneOf([ + 'onClick', + 'onMouseDown', + 'onMouseUp', + 'onPointerDown', + 'onPointerUp', + false, + ]), + clickAwayTouchEvent: PropTypes.oneOf(['onTouchEnd', 'onTouchStart', false]), flip: PropTypes.bool, + focusTrap: PropTypes.bool, id: PropTypes.string, + onClickAway: PropTypes.func, onClose: PropTypes.func, + onDidHide: PropTypes.func, + onDidShow: PropTypes.func, + onExited: PropTypes.func, open: PropTypes.bool.isRequired, + /** + * @default 'bottom' + */ + placement: PropTypes.oneOf([ + 'auto-end', + 'auto-start', + 'auto', + 'bottom-end', + 'bottom-start', + 'bottom', + 'left-end', + 'left-start', + 'left', + 'right-end', + 'right-start', + 'right', + 'top-end', + 'top-start', + 'top', + ]), + role: PropTypes.string, + style: PropTypes.object, target: PropTypes /* @typescript-to-proptypes-ignore */.any, + transition: PropTypes.bool, } as any; export { GridPanel };