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

Dialog element is not removed when closed in playwright & firefox environment #3369

Open
nozaq opened this issue Jul 7, 2024 · 7 comments
Open

Comments

@nozaq
Copy link

nozaq commented Jul 7, 2024

What package within Headless UI are you using?

@headlessui/react

What version of that package are you using?

2.1.2

What browser are you using?

Firefox with Playwright

  • Playwright version: 1.45.1 (the latest version as of this writing)
  • Firefox version: 127.0 (the version Playwright 1.45.1 uses)

Reproduction URL

https://github.com/nozaq/headlessui-dialog-poc

README explains how to run PoC code.

Describe your issue

PoC code contains three Playwright test cases and each test case is executed on three different browser, i.e. Chromium, Firefox and Webkit.

  1. Show dialog w/ transition. Wait for the dialog element to be visible before closing it (source).
  2. Show dialog w/ transition. Wait for the dialog element to be opacity 1.0 before closing it (source).
  3. Show dialog w/o transition (source).

Test results are shown below. The issue here is that Test Case 1 fails with Firefox browser.

Test Case Chromium Firefox Webkit
1 PASS FAIL PASS
2 PASS PASS PASS
3 PASS PASS PASS

The test fails because <Dialog> element with transition attribute is not removed from the portal node( <div data-headlessui-portal> node ) after the transition completes, resulting in the page becoming unresponsive since the dialog element remains covering the whole screen. The test case 1 fails at this line with the following error message.

  - expect.toBeHidden with timeout 5000ms
  - waiting for getByRole('dialog')
  -   locator resolved to <div data-open="" data-enter="" role="dialog" tabindex="-1" aria-modal="true" data-transition="" id="headlessui-dialog-:r0:" data-headlessui-state="open" class="fixed inset-0 flex w-screen items-center justify-center bg-black/30 p-4 transition duration-300 ease-out data-[closed]:opacity-0">…</div>
  -   unexpected value "visible"

The test passes when explicitly waiting the opacity of the dialog element to be 1.0 before closing it. This is confirmed by the test case 2.

I wonder if transition does not finish as expected when <Dialog> is closed in the middle of the entering transition from the following reason.

  • The difference between test case 1 and 2 is that the later waits until the enter transition finishes while the former not.
  • From the error message above, the dialog element still has data-enter attribute when the dialog element is supposed to be unmounted.

Additional Information

Please let me know if any additional information/clarification is needed.

@crissadriana
Copy link

Similarly is happening to me with Dialog as well as Combobox listbox - passing tests on Chromium and Webkit, but failing on Firefox

@HendrikGrobler
Copy link

This is a pretty serious issue for me, it's actually causing everything to be unclickable when closing a dialog with a backdrop before the animation completes (only in Firefox). Setting transition to false does seem to "fix" it for the time being, but it's not ideal.

@ben-maclaurin
Copy link

I'm also experiencing this issue with multiple tests (all Firefox).

@lucajung
Copy link

I have this problem too. The problem often (but not always) occurs in Firefox, but occasionally also in Chrome. The website becomes unusable every time because the background filter hides everything. The actual dialogue has opacity=0, but is on top of everything because of the z-index. Is there a version I can downgrade to that doesn't have this problem?

@nozaq
Copy link
Author

nozaq commented Aug 23, 2024

@lucajung The issue started from v2.1.0, which introduced major changes around transition API, in our environment. I believe downgrading before v2.1.0, v2.0.4 for example, would solve the issue.

@lucajung
Copy link

@nozaq Thanks, but I have the same problem with v2.0.4 (but less often)

@lucajung
Copy link

This may be helpful for debugging purposes. Due to the opacity-0 only the blurred background is visible, but no content.
This value was defined before in the React code as following:

<TransitionChild
    as={Fragment}
    enter="ease-out duration-300"
    enterFrom="opacity-0"
    enterTo="opacity-100"
    leave="ease-in duration-200"
    leaveFrom="opacity-100"
    leaveTo="opacity-0"
>

The broken state in HTML looks like this:

<div data-headlessui-portal="">
    <button type="button" data-headlessui-focus-guard="true" aria-hidden="true" style="position: fixed; top: 1px; left: 1px; width: 1px; height: 0px; padding: 0px; margin: -1px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; border-width: 0px;"></button>
    <div>
        <div class="relative z-50" id="headlessui-dialog-:ra:" role="dialog" tabindex="-1" aria-modal="true"
            data-headlessui-state="open" data-open="" aria-labelledby="headlessui-dialog-title-:ri:">
            <div class="ease-out duration-300 opacity-0" data-enter="" data-transition="" style="" data-closed="">
                <div class="fixed inset-0 w-screen bg-black bg-opacity-25"></div>
            </div>
            <div class="fixed inset-0 overflow-y-auto backdrop-blur-sm">
                <div class="flex items-center justify-center p-4 text-center h-full ease-out duration-300 opacity-0 scale-95"
                    data-enter="" data-transition="" style="" data-closed="">
                    <div class="w-auto max-h-full flex flex-col transform rounded-2xl bg-white dark:bg-slate-800 p-6 text-left align-middle shadow-xl transition-all"
                        id="headlessui-dialog-panel-:rh:" data-headlessui-state="open" data-open="">
                        <h3 class="text-lg font-medium leading-6 text-slate-900 dark:text-white pb-2 break-words"
                            id="headlessui-dialog-title-:ri:" data-headlessui-state="open" data-open=""></h3>
                        <div>
                            Content
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <button type="button" data-headlessui-focus-guard="true" aria-hidden="true" style="position: fixed; top: 1px; left: 1px; width: 1px; height: 0px; padding: 0px; margin: -1px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; border-width: 0px;"></button>
</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants