vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
619 stars 167 forks source link

As a user I expect to still be able to type when there is a keyboard shortcut bound to a letter key #5473

Open brp-benjamin opened 5 years ago

brp-benjamin commented 5 years ago

As a user I expect to still be able to type when there is a keyboard shortcut bound to a letter key

If the application has a shortcut registered to for example 'a' then the shortcut will trigger even when typing in an input field. This is unexpected behavior from a user perspective

Example scenario

You are Anders Andersson are going through a multi step wizard. To go to the next step the button n is bound as a shortcut to the next button. However, one of the input steps contains a input field asking for your name, you start input An and the shortcut triggers unexpectedly.

We could solve this if we had some way of telling the shortcut api not to trigger based on where the event originated, this could even be hard-coded for typeable dom elements (input, textarea, elements with the attribute [contenteditable=true]).

ujoni commented 5 years ago

Hello @brp-benjamin and thank you for another great suggestion!

We'll take this under consideration. Meanwhile, if you need something quick and dirty to get around this issue, you can use something like

    public static Registration excludeFromShortcuts(Component component) {
        return ComponentUtil.addListener(component, KeyDownEvent.class, event -> {},
                domListenerRegistration -> domListenerRegistration.setFilter(
                        "event.stopPropagation()"));
    }

    // usage example
    TextField field = new TextField("Enter name:");
    excludeFromShortcuts(field);

It will catch all the KeyDown events from the component (i.e. TextField) and block the key down events from propagating upwards. This excludes the component from all shortcuts that are not directly listening on the component. Since the `"event.stopPropagation()" is set as the filter, no round-trips will be generated, since the filter value will be false-y for all events.

Note that if you are listening for key down events higher in the DOM tree, this trick will exclude the component from that, too.

brp-benjamin commented 5 years ago

Thanks for the tip @ujoni , we actually had a lot of scenarios where using ComponentUtil.addListener with a filter was more convenient than the keyboard shortcuts api. May I suggest you mention it in the tutorial as an alternative way to handle keyboard interactions.