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

Can't use keydown on components which use portals #68

Closed
mmsbrggr opened this issue Aug 24, 2017 · 9 comments
Closed

Can't use keydown on components which use portals #68

mmsbrggr opened this issue Aug 24, 2017 · 9 comments

Comments

@mmsbrggr
Copy link

Hey :)
I have a modal component which renders some markup in a portal (so it overlays the whole body). I wanted to use react-keydown to close the overlay when the ESC key is pressed. This is not working. I believe that the problem is that react-keydown only listens on keydowns which happen inside the component. Through react-portal the overlay jumps out of the current component. What would be needed is to somehow listen to all keydowns of the whole window.

@salmanm
Copy link
Contributor

salmanm commented Aug 24, 2017

I may be wrong, but looking at your code here, it seems to me if you decorate your ModalBox component, it should work.

I don't know how react-portal works, but I assume it would pull out ModalBox component to document.body. So if you decorate ModalBox and create a function in it which does the following then it should work!

@keydown('escape')
onClose() {
  this.props.onRequestClose();
}

Let me know if it makes sense

@mmsbrggr
Copy link
Author

mmsbrggr commented Aug 24, 2017

Thank's for your reply :). That sounds reasonable and could work. I'll try it tomorrow. Nevertheless it would be great to also be able to use react-keydown on components which use portals. The expected behavior in my opinion would be, that the methods in the component receive all keydown events of the window.

@salmanm
Copy link
Contributor

salmanm commented Aug 24, 2017

Appreciate the feedback. However, IMHO I don't think that's the purpose of react-keydown, capturing global document events is straightforward using native javascript code.

WDYT @glortho

@glortho
Copy link
Owner

glortho commented Aug 24, 2017

i agree that @salmanm's suggestion above should work: #68 (comment)

i also agree about global event binding. one of the main inspirations/use-cases of react-keydown is shifting scopes. for example, you may want to use navigational arrow keys to navigate lots of different lists/grids in your app. setting up global bindings for that can get complex quickly. react-keydown tries to make an educated guess at which context should get dibs on otherwise duplicate keybindings based on where the user appears to have been most active most recently.

if you really do want global keybindings that are active all the time, you can indeed set up your own bindings with addEventListener, or you can decorate the root component of your app with @keydown( 'esc' ), which will inject props.keydown to do with as you please. though if portal renders your component outside of your root mount node, you're out of luck with that approach.

@glortho glortho closed this as completed Aug 24, 2017
@mmsbrggr
Copy link
Author

@salmanm @glortho. The solution in #68 (comment) works perfectly. Thank you. I really appreciate your work and really like react-keydown. Do you think it's not suitable for the library to include some kind of mechanism to listen to all keydowns of the window. Maybe including an additional decorator @keydownGlobal? What's your opinion on that?

@glortho
Copy link
Owner

glortho commented Aug 25, 2017

that's not a bad idea @mmsbrggr . what do you think @salmanm ?

it's starting to seem like we need to accept options. { debounce: 200 } along the lines of what you suggested in the other issue @salmanm, and we could also do { global: true }, which i guess would trigger in all cases as long as the decorated component was mounted and there was no duplicate keybinding that would otherwise be active.

then again, you don't really want global to be dependent on whether a particular component is mounted in the DOM. but it would be unintuitive to have a keybinding inside a component that fires whether or not the component is mounted. open to thoughts/suggestions.

@salmanm
Copy link
Contributor

salmanm commented Aug 26, 2017

Hmmm if it is to avoid binding and unbinding in cWM & cWU then yes its a cleaner API. But I think for this a clear distinction would be better, as @mmsbrggr suggested keydownGlobal.

Also, finding conflicting keybindings could be tricky. So I think if we just keep it stupid simple and call all handlers registered as global bindings that could work.

@glortho
Copy link
Owner

glortho commented Aug 28, 2017

Okay sounds good -- I'll create an issue. Feel free to tackle it if you have time @salmanm or @mmsbrggr . Otherwise I'll get to it before long.

@sheldonrong
Copy link

@glortho any progress on this #69 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants