web-components icon indicating copy to clipboard operation
web-components copied to clipboard

ComboBoi/MultiSelectComboBox focus behavior when clicking label is different than Select/DatePicker

Open TatuLund opened this issue 1 year ago • 2 comments

Description

We have multiple field components which have dropdown popup. These differ in focus / blur behavior when clicking the label while the dropdown is open.

In case of ComboBox and MultiSelectComboBox when the dropdown is open and one clicks the label of the component, the blur event is fired and focus event is fired after that.

In case of Select and DatePicker clicking label will not emit blur event and hence no focus event is fired either.

Expected outcome

I would expect the behavior of these components to be consistent. I.e. they would fire focus and blur events in similar fashion.

Furthermore I think Select and DatePicker behavior is more correct.

Minimal reproducible example

@Route(value = "combo-focus", layout = MainLayout.class)
public class ComboFocusView extends VerticalLayout {

    public ComboFocusView() {
        setSpacing(true);
        setPadding(true);
        List<String> items = new ArrayList<>();
        for (int i = 0; i < 40; i++) {
            items.add("Item " + i);
        }
        ComboBox<String> comboBox = new ComboBox<>("ComboBox");
        comboBox.addBlurListener(
                event -> System.out.println("Combo: Blur event fired!"));
        comboBox.addFocusListener(
                event -> System.out.println("Combo: Focus event fired!"));
        comboBox.setItems(items);

        MultiSelectComboBox<String> multiComboBox = new MultiSelectComboBox<>(
                "MultiSelectComboBox");
        multiComboBox.addBlurListener(
                event -> System.out.println("Multi: Blur event fired!"));
        multiComboBox.addFocusListener(
                event -> System.out.println("Multi: Focus event fired!"));
        multiComboBox.setItems(items);

        Select<String> select = new Select<>();
        select.setLabel("Select");
        select.addBlurListener(
                event -> System.out.println("Select: Blur event fired!"));
        select.addFocusListener(
                event -> System.out.println("Select: Focus event fired!"));
        select.setItems(items);

        DatePicker picker = new DatePicker("DatePicker");
        picker.addBlurListener(
                event -> System.out.println("DatePicker: Blur event fired!"));
        picker.addFocusListener(
                event -> System.out.println("DatePicker: Focus event fired!"));

        add(comboBox, multiComboBox, select, picker);
    }
}

Steps to reproduce

  • Click the field -> Popup opens
  • Click the field label
  • Observe console output

Environment

Vaadin version(s): Vaadin 24.4.11

Browsers

No response

TatuLund avatar Sep 18 '24 06:09 TatuLund

Note: we should also ensure that TimePicker and MultiSelectComboBox work consistently. Currently, these components do not open overlay on label click, unlike ComboBox and DatePicker (which have that handled by _onHostClick).

web-padawan avatar Sep 18 '24 08:09 web-padawan

Here is another observation. If I click on the DatePicker's label while the dropdown is open, focus goes to an unknown place, and the dropdown remains open, which is weird.

Private Zenhub Video

https://vaadin.com/docs/latest/example?path=component/datepicker/date-picker-basic.ts

vursen avatar Sep 19 '24 13:09 vursen

Currently the components work differently due to how they are implemented:

  • vaadin-combo-box has _onHostClick() logic that specifically opens on label click. Clicking the label while opened causes the overlay to close (as it's considered "outside click") and then re-open. As the mousedown event is prevented, focus stays in the input field after reopening,
  • vaadin-date-picker also has _onHostClick() but it doesn't get closed due to the fact that vaadin-overlay-close is specifically prevented in case of click event originating from the date-picker itself. The mousedown event is still prevented, so focus stays in the input field,
  • vaadin-time-picker doesn't have _onHostClick() and the internal combo-box implementation doesn't take the label into account, so clicking the label doesn't open overlay. When it's opened, the overlay is closes as per any outside click (mousedown is prevented from combo-box).
  • vaadin-multi-select-combo-box behave the same as the time-picker (as it also uses internal combo-box implementation) - clicking the label doesn't open overlay, but closes it in case it's already open.
  • vaadin-select has _onClick() listener on both label and input container. Clicking the label opens overlay when not opened and closes it when opened (similar to how toggle button works in other components).

I'm not 100% sure what the correct behavior should be (whether label should work as in the select or date-picker). But it's clear that at least time-picker and multil-select-combo-box need to be updated to use correct logic.

Regarding blur events, that's a slightly separate problem that was already fixed by preventing mousedown on outside click as part of https://github.com/vaadin/web-components/pull/7846 which also covered label click. We might want to add separate tests for label clicks.

web-padawan avatar Dec 02 '24 14:12 web-padawan

Actually, since the original issue is about focus / blur events and that was fixed, I'll close it and create a new one instead.

web-padawan avatar Dec 03 '24 08:12 web-padawan