dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.39k stars 10k forks source link

components-reconnect-modal appears underneath <dialog> elements #58486

Open mrpmorris opened 1 week ago

mrpmorris commented 1 week ago

Is there an existing issue for this?

Describe the bug

When a Blazor server app loses connectivity, the components-reconnect-modal obscurer doesn't obscure <dialog> elements that have had .showModal() called on them.

Expected Behavior

It should also obscure <dialog> elements - perhaps convert it into a <dialog> that is shown modally?

Steps To Reproduce

  1. New Blazor Server App
  2. Add wwwroot/index.js
    window.showModal = function (id) {
    const elem = document.getElementById(id);
    elem.showModal();
    }
  3. In App.razor, after the <script src="_framework/blazor.web.js"></script> add <script src="/index.js"></script>
  4. Change Home.razor to the following
    
    @page "/"
    @inject IJSRuntime JSRuntime
Home

Hello, world!

Welcome to your new app.

Hello

@code { protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (firstRender) await JSRuntime.InvokeVoidAsync("showModal", "modal"); } }


5. Run the app using `dotnet watch`
6. Wait for the app to start and for the dialog to appear.
7. Close the `dotnet watch` app and watch the page show it has lost its connection.

### Exceptions (if any)

_No response_

### .NET Version

8.0.36

### Anything else?

![Image](https://github.com/user-attachments/assets/5d69860d-c1df-4b86-a2f8-1877df46a33b)
javiercn commented 1 week ago

@mrpmorris thanks for contacting us.

I imagine this is "by design" as this component predates the dialog element and dialog elements contain special logic to render on top of everything else, which makes solving this hard/impossible.

I don't think we can make the UI a dialog element itself because I doubt it'll render if another modal dialog is already opened.

mkArtakMSFT commented 1 week ago

Thanks @javiercn. @mrpmorris I'm going to park this in the Backlog for now. Doesn't seem to be too critical for now.

mrpmorris commented 1 week ago

With the creation of <dialog> and the number of years it has now been in all the browsers perhaps this should now be a feature request?

If a dialog is open and you call showDialog on another then it will show on top, so there is no problem there.

I think even having a class "blazor-circuit-disconnected" added to the would be sufficient, because then I could use CSS

In the meantime, I have this workaround...

body.blazor-server-disconnected dialog {
   opacity: 0;
}
new MutationObserver(() => {
   const modal = document.getElementById("components-reconnect-modal");
   if (modal) {
      document.body.classList.add("blazor-server-disconnected");
   } else {
      document.body.classList.remove("blazor-server-disconnected");
   }
})
.observe(document.body, { childList: true, subtree: false });