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

[Drawer] Close persistent drawer on Escape keydown #12188

Closed
2 tasks done
mctep opened this issue Jul 18, 2018 · 6 comments
Closed
2 tasks done

[Drawer] Close persistent drawer on Escape keydown #12188

mctep opened this issue Jul 18, 2018 · 6 comments
Assignees
Labels
component: modal This is the name of the generic UI component, not the React module! discussion

Comments

@mctep
Copy link
Contributor

mctep commented Jul 18, 2018

Hi!

I want to make right persistent drawer (like in three pane interfaces). Also I want to close right pane by Escape pressed. But this keypress works only for temporary drawers based on Modal components.

  • This is a v1.x issue.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior

I could add my own keydown listener and close my drawer, but I cannot to check that some Modal is opened for properly closing (Escape closes my drawer and opened modal).

I cannot use temporary drawer for this because it creates fixed div that fill whole page and blocks other elements on page.

Expected Behavior

As the simplest solution I would to suggest to export default ModalManager singleton from @material-ui/core/Modal (Modal.defaultProps.manager) and add to it some method like hasModals().

Examples

import * as React from 'react';
import { manager } from '@material-ui/core/Modal';
import Drawer from '@material-ui/core/Drawer';
import * as EventListener from 'react-event-listener';

interface Props {}

interface State {
  drawerOpen: boolean;
}

class MyComponent extends React.Component<Props, State> {
  public state: State = {
    drawerOpen: false,
  };

  private handleDocumentKeyDown = (event: KeyboardEvent) => {
    if (event.key === 'Escape' && !manager.hasModal()) {
      this.setState({ drawerOpen: false });
    }
  };

  public render() {
    return (
      <React.Fragment>
        <EventListener target="document" onKeydown={this.handleDocumentKeyDown}/>
        <Drawer variant="persistent" open={this.state.drawerOpen} />
      </React.Fragment>
    );
  }
}
@oliviertassinari oliviertassinari added support: question Community support but can be turned into an improvement component: modal This is the name of the generic UI component, not the React module! discussion and removed support: question Community support but can be turned into an improvement labels Jul 18, 2018
@oliviertassinari
Copy link
Member

oliviertassinari commented Jul 18, 2018

@mctep I would suggest you to use a custom modalManager instance, providing it to all the modals you are using (you can use theme for that). Then, you can use the isTopModal() method to know if you have to handle the Escape event.

Also, I'm wondering if we should be checking event.defaultPrevented in the Modal keyboard handler to prune the handler?

@mctep
Copy link
Contributor Author

mctep commented Jul 19, 2018

@oliviertassinari Thank you for the answer! So I need to wrap all components that use Modal component. It is Popover, Menu, Drawer. I see it is OK but a bit of a hassle 😬. Is it probably better to add special ModalManagerProvider?

Also, I'm wondering if we should be checking event.defaultPrevented in the Modal keyboard handler to prune the handler?

Sorry, but I do not understand. How does it help with the issue? I do not need to prune the Modal handler. I need to prune my handler. Or do you mean to call preventDefault in the Modal handler? But there is no guaranty that handlers will be called in the right order.

@oliviertassinari
Copy link
Member

Is it probably better to add special ModalManagerProvider?

Yes, as I was saying it earlier, you can use the theme for that: (theme.props.MuiModal.modalManager).

Sorry, but I do not understand. How does it help with the issue?

You could be listening for the Escape on your custom drawer component. You could prevent the default event behavior, then the Material-UI's Modal could check if the event default behavior is prevented and skip the close logic.

@mctep
Copy link
Contributor Author

mctep commented Jul 19, 2018

theme.props.MuiModal.modalManager

Awesome! I didn't know about this API. I'll try it. Thank you.

Modal could check if the event default behavior is prevented and skip the close logic.

Modal's property disableEscapeKeyDown is used for this purpose, isn't it?

@oliviertassinari oliviertassinari self-assigned this Jul 19, 2018
@mctep
Copy link
Contributor Author

mctep commented Jul 19, 2018

Theme works like a charm! ✨

The best library ever!

@sabotag
Copy link

sabotag commented Nov 4, 2022

@oliviertassinari, hi, how about for mui v5? Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: modal This is the name of the generic UI component, not the React module! discussion
Projects
None yet
Development

No branches or pull requests

3 participants