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

UI - Input: Hook up <Input /> element to Focus #290

Open
bryphe opened this issue Jan 30, 2019 · 7 comments
Open

UI - Input: Hook up <Input /> element to Focus #290

bryphe opened this issue Jan 30, 2019 · 7 comments
Labels
A-components Area: Consumer-exposed components providing some convenience over the primitives enhancement New feature or request

Comments

@bryphe
Copy link
Member

bryphe commented Jan 30, 2019

Issue: Our current <Input /> element, introduced in #205 , directly hooks to the window.onKeyPress/window.onKeyDown events. This works, but means that <Input /> elements have to cooperatively manage who has focus, and ignore input events if they don't currently have focus.

We also have a concept of Focus introduced in #199 - but currently the Focus / <Input /> element are not in sync.

The design I'd like to look investigate is, instead of each <Input /> listening directly to window events - only the focus manager listens to them at the top-level (the focus manager), and the focus manager will dispatch those events to the focused item. This will be important in terms of managing focus across multiple components (for example, tabbing between inputs/buttons/etc), since the concept of focus is broader than just the <Input /> elements.

This is sort of like how we handle mouse events right now - we have the Mouse module that listens to window-level events, and then the Mouse module, based on the position/z-index, decides which component to actually dispatch the event to, instead of every element listening to window mouse events.

Likewise, for Focus, it's similiar, and actually even more straightforward - the focus manager knows which element has focus and can dispatch keydown/keypress/keyup events directly to that element.

A few scenarios this would enable:

  • Programmatically calling focus on an <Input /> should enable it to receive key presses
  • Items like Buttons should be able to handle key presses (ie, space/enter to commit)
  • We should be able to tab through form elements via a tabIndex
@bryphe bryphe added the enhancement New feature or request label Jan 30, 2019
@akinsho akinsho mentioned this issue Feb 6, 2019
5 tasks
@faisalil
Copy link
Contributor

faisalil commented Feb 9, 2019

Planning to take a stab at this next.

@faisalil
Copy link
Contributor

So @bryphe , I spent sometime looking at the Focus and Mouse module to see how they handle the events for mouse events and one simple way I was able to think about to resolve the keyboard events for the Input elements was the following:

  • In the start of the application (in Revery_UI), I can subscribe to the keyboard events.
  • In the handler, the logic is simple: get the current Focused element (Using the Focus.focused global state) and fire the keyboard events handlers on it if it is listening to those. Any thoughts?

@faisalil
Copy link
Contributor

The outline solution above was implemented in #324

@bryphe
Copy link
Member Author

bryphe commented Feb 11, 2019

@faisalil - sorry for the slow reply!

I just checked out #324 - looks great - the solution you outlined above is perfect 👍

The only thing I think we're missing is (potentially) bubbling the key events - but that should be tracked as another issue. Thanks for putting together the scaffolding for this.

@faisalil
Copy link
Contributor

@bryphe , what do you mean by bubbling key events? What I am doing right now is sending the event to the element that has focus, should it be sent to some other element?

@bryphe
Copy link
Member Author

bryphe commented Feb 11, 2019

@bryphe , what do you mean by bubbling key events? What I am doing right now is sending the event to the element that has focus, should it be sent to some other element?

I believe that, by default, the key events 'bubble up' (as long as stopPropagation isn't called on the event). So that means that, potentially, an ancestor node in the hierarchy could listen for a key event, too - like:

<View onKeyDown={(evt) => print_endline(string_of_int(evt.scancode)}>
    <Input />
</View>

So if input had focus, and a key was down, and evt.stopPropagation wasn't called - it would bubble up to handlers in the hierarchy too.

We actually have a utility to do this 'bubbling':

let bubble = (node, event: event) => {

If this is the expected behavior, it might be as simple as calling bubble(node, event).

@glennsl
Copy link
Member

glennsl commented Nov 15, 2019

I'm not entirely convinced that bubbling is a good idea for keyboard events, but should this be closed in favor of a separate issue for bubbling? It's also not entirely clear to me whether there's anything else keeping this issue open.

@glennsl glennsl added the A-components Area: Consumer-exposed components providing some convenience over the primitives label Nov 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-components Area: Consumer-exposed components providing some convenience over the primitives enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants