Prevent TAB going into Popover?

I have a Popover anchored to my TextField. When focus is in the TextField and the Popover is open, TAB goes to the Popover instead of to the next TextField. Is there any way to change that?

I notice that the Popover panel has tabIndex=“0”. I can’t set it from code, but even if I set tabindex=“-1” in the browser DevTools, it still gets focus.

So far, the only “fix” I can think of is to add a TAB keypress handler to this field and an Shift-TAB keypress handler to the next one, which will be awkward, especially since I dynamically show/hide fields.

I see the tooltip example in the doc has the same issue, making it a bit useless:
I’ve added that to my example below; Tab to Field3, wait a bit for the tooltip. Tab again and the tooltip gets focus. Bad UX…

@Route("TestPopoverTab")
public class TestPopoverTab extends VerticalLayout {
    
    public TestPopoverTab() {
        
        setSizeFull();

        var field1 = new TextField("Field1");
        var field2 = new TextField("Field2");
        var field3 = new TextField("Field3");
        var field4 = new TextField("Field4");
        
        field1.setTabIndex(1);
        field2.setTabIndex(2);
        field3.setTabIndex(3);
        field4.setTabIndex(4);

        addDropdown(field2);
        addToolTip(field3);
                
        var row = new HorizontalLayout(field1, field2, field3, field4);
        row.setWidthFull();
        add(row);
        
    }

    void addDropdown(TextField textField) {
        var popover = new Popover();
        popover.setTarget(textField);
        popover.setOpenOnClick(false);
        popover.setPosition(PopoverPosition.BOTTOM_START);
        popover.setCloseOnEsc(false);
        
        var opener = new Button(VaadinIcon.COG.create());
        opener.addThemeVariants(ButtonVariant.LUMO_ICON, ButtonVariant.LUMO_TERTIARY_INLINE);
        opener.setTabIndex(-1);

        opener.addClickListener(event -> {
            popover.setOpened(!popover.isOpened());
        });

        textField.setSuffixComponent(opener);
        
        var popoverLayout = new VerticalLayout();
        popoverLayout.setWidth("300px");
        popoverLayout.setHeight("300px");
        popover.add(popoverLayout);

        popoverLayout.add(new TextField("Inside popover"));
        
    }
    
    void addToolTip(TextField textField) {

        Popover popover = new Popover();
        popover.addThemeVariants(PopoverVariant.ARROW);
        popover.setPosition(PopoverPosition.TOP);
        popover.setOpenOnClick(false);
        popover.setOpenOnHover(true);
        popover.setOpenOnFocus(true);

        H3 header = new H3("Card Verification Value");
        header.setId("cvv-heading");
        header.getStyle().set("margin", "0");
        header.getStyle().set("font-size", "1rem");

        Div content = new Div(
                "A three or four digit code, usually printed on the back of the card, "
                        + "next to, or at the end of, the signature strip.");
        content.getStyle().set("max-width", "300px");

        Anchor link = new Anchor("https://www.cvvnumber.com/cvv.html",
                "See where to find CVV on different cards", AnchorTarget.BLANK);

        popover.add(header, content, link);
        popover.setAriaLabelledBy("cvv-heading");
        popover.setTarget(textField);

    }
    
}

This is by design – if tabbing doesn’t move focus to the popover, how do you reach the popover by keyboard at all?

(If you don’t have interactive content in the Popover, and thus don’t need keyboard focus to go there, you might be better off with a Tooltip instead.)

For my case, which is a Combobox replacement, arrow-down goes into it.
TAB doesn’t go down into Combobox either.

I assume Combobox still doesn’t use Popover, but IMHO it is what Popover is made for, and if you changed Combobox to use Popover, you’d get the same poor UX as my Combobox replacement.

You didn’t say if it was by Vaadin’s design, or by the standard itself.
I see the “Accessibility” section of this is saying the same as you: Using the Popover API - Web APIs | MDN

I don’t like it, but then there is not much point arguing about it. :slight_smile:

Yes, that is the native behavior of html popovers.

However, now that I think about it, I don’t remember if we are actually using the popovertarget attribute on the Popover component, or instead handle the opening and focus behavior with javascript, mimicing that native popovertarget behavior. I recall that we decided that should be the default behavior partially because of the popover html spec, but also because it is the desired behavior for most popovers.

ComboBoxes and such are not the use case Popover is made for, but it’s certainly a completely valid use case (and one which we definitely want to support with the component), and those should indeed not have that focus behavior.

I’ll have a look next week at the implementation to see if that behavior is JS-based, in which case it should not be too difficult to provide an API for opting out of it.

Ok, confirmed that: we are emulating the native behavior with JS, so we could provide an opt-out for it (which shouldn’t be too difficult).

Could you make a ticket about it in GitHub · Where software is built and provide your use case as an example where it would be useful?

Thanks Rolf, I’ve registered: