Skip to content
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

[data grid] The filter panel in custom toolbar steal the focus from an input #7044

Open
sasa5195 opened this issue Nov 30, 2022 · 12 comments
Open
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! design This is about UI or UX design, please involve a designer external dependency Blocked by external dependency, we can’t do anything about it

Comments

@sasa5195
Copy link

sasa5195 commented Nov 30, 2022

Steps to reproduce 🕹

Link to live example: https://codesandbox.io/s/tender-shannon-2o3hv7

https://www.loom.com/share/eb4bd147cdb043139c30a055f0f9f842

Browser - Chrome, Firefox

  • Case 1
    Steps:
  1. Click on the filter button on the data grid toolbar,
  2. Then, click on the start text field/ end text field of the date range picker
  • Case 2
    Steps:
  1. Click on the column button on the data grid toolbar,
  2. Then, click on the start text field/ end text field of the date range picker

Current behavior 😯

Opening the date range picker after the filter panel or column panel closes the date range picker automatically for the first time.

But this doesn't happens when density menu appears and date range picker is being opened

Expected behavior 🤔

Opening the date range picker after the filter panel or column panel should not close the date range picker automatically. It should behave the same way as when we toggle between different panels like filter, column, density, etc.

Context 🔦

I need to add a date range filter which is not related to the columns of the data grid. So inorder to achieve that i am using the date range picker component and placing it in the data grid toolbar.

Your environment 🌎

npx @mui/envinfo
System:
    OS: macOS 12.6.1
  Binaries:
    Node: 18.10.0 - ~/.nvm/versions/node/v18.10.0/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 8.19.2 - ~/.nvm/versions/node/v18.10.0/bin/npm
  Browsers:
    Chrome: 106.0.5249.119
    Edge: Not Found
    Firefox: 106.0.5
    Safari: 16.1
  npmPackages:
    @emotion/react: ^11.10.4 => 11.10.5 
    @emotion/styled: ^11.10.4 => 11.10.5 
    @mui/base:  5.0.0-alpha.103 
    @mui/core-downloads-tracker:  5.10.11 
    @mui/icons-material: ^5.10.6 => 5.10.9 
    @mui/material: ^5.10.6 => 5.10.11 
    @mui/private-theming:  5.10.9 
    @mui/styled-engine:  5.10.8 
    @mui/system:  5.10.10 
    @mui/types:  7.2.0 
    @mui/utils:  5.10.9 
    @mui/x-data-grid:  5.17.8 
    @mui/x-data-grid-pro: ^5.17.4 => 5.17.8 
    @mui/x-date-pickers:  5.0.9 
    @mui/x-date-pickers-pro: ^5.0.9 => 5.0.9 
    @mui/x-license-pro:  5.17.0 
    @types/react: ^18.0.20 => 18.0.24 
    react: ^18.2.0 => 18.2.0 
    react-dom: ^18.2.0 => 18.2.0 
    typescript: ^4.8.3 => 4.8.4 

Order ID 💳 (optional)

No response

@sasa5195 sasa5195 added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Nov 30, 2022
@zannager zannager added component: pickers This is the name of the generic UI component, not the React module! plan: Pro Impact at least one Pro user labels Nov 30, 2022
@sasa5195 sasa5195 changed the title The filter panel in custom toolbar closes the date range picker in the custom toolbar [data grid] The filter panel in custom toolbar closes the date range picker in the custom toolbar Nov 30, 2022
@sasa5195 sasa5195 changed the title [data grid] The filter panel in custom toolbar closes the date range picker in the custom toolbar [pickers] [data grid] The filter panel in custom toolbar closes the date range picker in the custom toolbar Nov 30, 2022
@m4theushw m4theushw removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Nov 30, 2022
@m4theushw m4theushw changed the title [pickers] [data grid] The filter panel in custom toolbar closes the date range picker in the custom toolbar [data grid] The filter panel in custom toolbar closes the date range picker in the custom toolbar Nov 30, 2022
@m4theushw m4theushw added component: data grid This is the name of the generic UI component, not the React module! and removed component: pickers This is the name of the generic UI component, not the React module! labels Nov 30, 2022
@m4theushw
Copy link
Member

The filter panel is based on the FocusTrap, previously named TrapFocus. When you click the filter button to open the panel, this component stores which element is focused (the button), then once the panel is closed it tries to restore the focus to the element it had saved. What is happening here is that when the date range picker input is focused, the filter panel understands that a click outside occurred and it should be closed. When it closes, FocusTrap restores the focus to the button, which for the date range picker means that the input lost focus and the calendar should be closed. A solution would be to use the disableRestoreFocus prop to disable the logic that restores the focus. The downside is that accessibility will be affected, as the active element once the panel is closed will be document.body and, e.g. pressing Tab, will focus a complete random element.

If this is acceptable, then we need to give the possibility of passing props to the FocusTrap used by the panel. This can be done with:

diff --git a/packages/grid/x-data-grid/src/components/panel/GridPanelWrapper.tsx b/packages/grid/x-data-grid/src/components/panel/GridPanelWrapper.tsx
index f738196ce..4701aa1bf 100644
--- a/packages/grid/x-data-grid/src/components/panel/GridPanelWrapper.tsx
+++ b/packages/grid/x-data-grid/src/components/panel/GridPanelWrapper.tsx
@@ -1,6 +1,6 @@
 import * as React from 'react';
 import clsx from 'clsx';
-import TrapFocus from '@mui/material/Unstable_TrapFocus';
+import TrapFocus, { TrapFocusProps } from '@mui/material/Unstable_TrapFocus';
 import { styled, Theme } from '@mui/material/styles';
 import { MUIStyledCommonProps } from '@mui/system';
 import { unstable_composeClasses as composeClasses } from '@mui/utils';
@@ -36,18 +36,20 @@ const GridPanelWrapperRoot = styled('div', {
 const isEnabled = () => true;
 
 export interface GridPanelWrapperProps
-  extends React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>,
+  extends React.PropsWithChildren<
+      React.HTMLAttributes<HTMLDivElement> & { TrapFocusProps: Omit<TrapFocusProps, 'open'> }
+    >,
     MUIStyledCommonProps<Theme> {}
 
 const GridPanelWrapper = React.forwardRef<HTMLDivElement, GridPanelWrapperProps>(
   function GridPanelWrapper(props, ref) {
-    const { className, ...other } = props;
+    const { className, TrapFocusProps: TrapFocusPropsProps, ...other } = props;
     const rootProps = useGridRootProps();
     const ownerState = { classes: rootProps.classes };
     const classes = useUtilityClasses(ownerState);
 
     return (
-      <TrapFocus open disableEnforceFocus isEnabled={isEnabled}>
+      <TrapFocus open disableEnforceFocus isEnabled={isEnabled} {...TrapFocusPropsProps}>
         <GridPanelWrapperRoot
           ref={ref}
           tabIndex={-1}

Then, disableRestoreFocus will be able to be used with:

<DataGrid
  componentsProps={{ filterPanel: { TrapFocusProps: { disableRestoreFocus: true } } }}
/>

Do you want to submit a PR with the diff above?

@m4theushw m4theushw added good first issue Great for first contributions. Enable to learn the contribution process. dx Related to developers' experience and removed plan: Pro Impact at least one Pro user labels Nov 30, 2022
@Vivek-Prajapatii

This comment was marked as outdated.

@m4theushw
Copy link
Member

@Vivek-Prajapatii Yes, you can find more information in https://github.com/mui/material-ui/blob/HEAD/CONTRIBUTING.md. When opening the PR make sure to set the target branch to next.

@ayushcs
Copy link

ayushcs commented Jan 27, 2023

@m4theushw @Vivek-Prajapatii @sasa5195 Is this solution is available in the MUI or still needs to be updated ? Do we have a workaround solution to fix this?

@Vivek-Prajapatii

This comment was marked as outdated.

@oliviertassinari oliviertassinari changed the title [data grid] The filter panel in custom toolbar closes the date range picker in the custom toolbar [data grid] The filter panel in custom toolbar steal the focus from an input Jan 28, 2023
@oliviertassinari
Copy link
Member

oliviertassinari commented Jan 28, 2023

I have simplified the problem a bit more in https://codesandbox.io/s/date-range-picker-issue-in-data-grid-inside-cutom-toolbar-forked-smx7j4?file=/demo.js so that we can consider the issue without the date pickers, a basic <input> is enough:

Screen.Recording.2023-01-28.at.20.00.16.mov

Overall, I think that it's more a FocusTrap bug than a data grid one. For example in https://www.w3.org/WAI/ARIA/apg/example-index/menu-button/menu-button-links.html the focus is only restored to the button if the modality that triggered the close of the popup is the keyboard, nothing happens if its the mouse. So overall, we have a few options:

  1. Use Popover to block all clicks interactions on the page (what's done by Notion & GitHub)
  2. Extend the FocusTrap so that the focus is only restored for keyboard, e.g. clickOutsideDeactivates https://focus-trap.github.io/focus-trap/
  3. Replace the FocusTrap to implement the restore focus on keyboard action on our own (least preferred option)

I have noticed the same bug on this demo: https://mui.com/material-ui/react-menu/#menulist-composition, 2. could be its solution)

@oliviertassinari oliviertassinari added design: ux bug 🐛 Something doesn't work and removed dx Related to developers' experience good first issue Great for first contributions. Enable to learn the contribution process. labels Jan 28, 2023
@m4theushw
Copy link
Member

Overall, I think that it's more a FocusTrap bug than a data grid one.

@oliviertassinari I also agree but we can't wait for the Core to properly fix this bug (if there's a proper fix available). My proposal here is to at least allow a workaround.

Extend the FocusTrap so that the focus is only restored for keyboard, e.g. clickOutsideDeactivates https://focus-trap.github.io/focus-trap/

I've proposed a more customizable solution in mui/material-ui#35307

@m4theushw
Copy link
Member

#7733 is merged and it will be included in the next release. For now, the following workaround can be used:

<DataGrid
  componentsProps={{
    filterPanel: {
      slotProps: {
        TrapFocus: {
          disableRestoreFocus: true,
        },
      },
    },
  }}
/>

@oliviertassinari
Copy link
Member

@m4theushw I'm reopening as the UX is broken by default; It's great that we have a workaround 👍

@ayushcs
Copy link

ayushcs commented Feb 13, 2023

@m4theushw @oliviertassinari On which version we can use this workaround I have tried 5.17.23 and even 6.0.0-beta.3 #7696 issue is still happening

Codesandbox
https://codesandbox.io/s/customfilterpanelposition-demo-mui-x-forked-gw96fs?file=/demo.tsx:600-615

@m4theushw
Copy link
Member

@ayushcs It will be available in the version we're going to release this week, probably on Thursday.

@oliviertassinari oliviertassinari added the external dependency Blocked by external dependency, we can’t do anything about it label Feb 13, 2023
@oliviertassinari oliviertassinari added design This is about UI or UX design, please involve a designer and removed design: ux labels Aug 18, 2023
@DiegoAndai
Copy link
Member

Hey @cherniavskii, we had another report of this issue: mui/material-ui#45150.

The workaround suggested in #7044 (comment) works as well, although it throws a typescript error as filterPanel.slotProps is not included in the GridFilterPanelProps type.

I'll close the duplicate issue in favor of this one so the discussion can continue here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! design This is about UI or UX design, please involve a designer external dependency Blocked by external dependency, we can’t do anything about it
Projects
None yet
Development

No branches or pull requests

7 participants