vaadin / web-components

A set of high-quality standards based web components for enterprise web applications. Part of Vaadin 20+
https://vaadin.com/docs/latest/components
464 stars 83 forks source link

[dialog] Modeless dialog does not honor close on outside click #7778

Open knoobie opened 1 month ago

knoobie commented 1 month ago

Description

Using modeless (setModal(false) does not honor closeOnOutsideClick and stays open.

Expected outcome

Dialog closes when clicking outside.

Minimal reproducible example


        var dialog = new Dialog();
        dialog.setModal(false);
        dialog.setCloseOnOutsideClick(true);
        dialog.add(new Paragraph("Lorem Ipsum"));
        dialog.open();

Environment

Vaadin version(s): 24.4.10

Browsers

All

web-padawan commented 1 month ago

This is kind of by design as the "modeless" overlay doesn't use global outside click / Esc key listeners:

https://github.com/vaadin/web-components/blob/d665940d99599dc6005aecff2107687e4aeb1430/packages/overlay/src/vaadin-overlay-mixin.js#L244-L252

We did have to add some workarounds for it especially custom outside click listener for vaadin-context-menu.

knoobie commented 1 month ago

If this is not a bug.. it probably has to be documented on the flow side on either modal or closeOnOutsideClick - I was kinda suprised by this :) We use setModal(false) often because of the "problems" with server-side modality; which renders the closeOnOutsideClick flag "useless".

TatuLund commented 1 month ago

Note, you can have modal dialog and disable the server side modality using API in UI class.

sissbruecker commented 1 month ago

Something is wrong if people start using non-modal dialogs to work around server-side modality. Maybe there should be a more obvious API on the component level to disable it.

Right now disabling it is not straightforward:

For comparison, this works:

add(dialog);
dialog.open();
ui.setChildComponentModal(dialog, false);

And these don't:

dialog.open();
ui.setChildComponentModal(dialog, false);
add(dialog);
ui.setChildComponentModal(dialog, false);
dialog.open();