havit / Havit.Blazor

Free Bootstrap 5 components for ASP.NET Blazor + optional enterprise-level stack for Blazor development (gRPC code-first, layered architecture, localization, auth, ...)
https://havit.blazor.eu
MIT License
490 stars 67 forks source link

[HxModal] and [HxOffcanvas] disable main scrolling on remove/close #110

Open stayboy opened 2 years ago

stayboy commented 2 years ago

For scrolling pages, HxModal and HxOffCanvax on pop, set body style to overflow = hidden. And does not remove style on either component HideAsync action

hakenr commented 2 years ago

@crdo Can you take a look at this, please?

crdo commented 2 years ago

@stayboy I am not able to reproduce the described behaviour. The documentation page is scrollable and the overflow: hidden; on the body element is removed as soon as the dialog is closed. May I please ask you to provide some minimal repository reproducing your issue?

stayboy commented 2 years ago

@stayboy I am not able to reproduce the described behaviour. The documentation page is scrollable and the overflow: hidden; on the body element is removed as soon as the dialog is closed. May I please ask you to provide some minimal repository reproducing your issue?

Try the backdrop sample here image

crdo commented 2 years ago

Tried, working as expected...

stayboy commented 2 years ago

Tried, working as expected...

I saw the problem. When you hit to show the Canvax, rather than close it, hit the source Tab from the picture I sent, and the scrolls will go off forever. My guess is, when HxOffCanvax is not closed and State changes someway or the other that forces HxOffCanvax to hide by itself, You are locked out of ever seeing your scroll bars. Just try it.

image

crdo commented 2 years ago

OK, I get it.

  1. Open the Offcanvas w/o backdrop
  2. Click the Source tab
  3. The content of the Demo tab is removed from the DOM and the css inlined to the body element is not cleaned up

I guess this is not a real world scenario, but we can have a look into it. Cc @hakenr

stayboy commented 2 years ago

OK, I get it.

  1. Open the Offcanvas w/o backdrop
  2. Click the Source tab
  3. The content of the Demo tab is removed from the DOM and the css inlined to the body element is not cleaned up

I guess this is not a real world scenario, but we can have a look into it. Cc @hakenr

Well, You cannot say that. It's a big issue at a top company we are using for. What we figured out, is dont Change any state or call StateHasChanged when these two controls are showing. Else the user must refresh whole screen to bring back the scroll bars. We are trying so hard to minimize their use. For HxOffCanvas, Enabling Scrollbars seems to fix it. But we think, that is a hack, not a fix

crdo commented 2 years ago

You simply cannot remove the whole Offcanvas/Modal component from the DOM while it is open and scrolling is disabled. If you do it, overflow: hidden remains set on the body and you cannot scroll.

This is a wrong application design rather than issue of Havit.Blazor. If you do the same with Bootstrap only, you will get exactly the same result.

If you still believe that it is somehow related to changing state or calling StateHasChanged, please submit a repository reproducing your issue.

stayboy commented 2 years ago

You simply cannot remove the whole Offcanvas/Modal component from the DOM while it is open and scrolling is disabled. If you do it, overflow: hidden remains set on the body and you cannot scroll.

This is a wrong application design rather than issue of Havit.Blazor. If you do the same with Bootstrap only, you will get exactly the same result.

If you still believe that it is somehow related to changing state or calling StateHasChanged, please submit a repository reproducing your issue.

Kindly Refer to earlier Chat on how to reproduce similar on your Sample Page. I showed you a Picture. Hit the button to show HxCanvax, dont close the HxCanvax and mistakenly, like every user does, click the Source Tab for the Example

hakenr commented 2 years ago

We are calling offcanvas.dispose() and we believe the dispose should do the cleanup. Will try to create a simple repro for Bootstrap and report to them. (@Harvey1214)

Harvey1214 commented 2 years ago

This should be addressed in v5.2.0-beta1. Stable release is coming soon.

Refer to https://github.com/twbs/bootstrap/issues/36397

skruis commented 2 years ago

This may not be related specifically to OP's situation but I'm experiencing a non scrollable body after using a modal as well. In my example, I have a modal wrapped in an EditForm. I'm using an HxSubmit's OnValidClick method to call a save routine which then kicks off some other methods that cause their own DOM updates. If however I replace the EditForm's model with a new Model(), the modal is removed from the DOM (without calling HideAsync), the body is non scrollable and the js throws the '_element is null' error in the console. If I leave the current instance of the model or merely update it's properties, the modal is left in the DOM until I call HideAsync at which time the close operation functions properly and I'm able to scroll the body again.

*EDIT - Seems EditForm's specifically destroy and rebuild their contents when the model changes which I think ties into crdo's comment on April 12th. Please ignore.

hakenr commented 2 years ago

Unfortunately, Bootstrap 5.2.0 does not seem to resolve the issue. Our bug-report https://github.com/twbs/bootstrap/issues/36397 was closed as not planned even though it was originally commented with

This should be addressed in v5.2.0-beta1. Stable release is coming soon.

@crdo Can you please verify and try to reactivate the issue on Bootstrap side?

hakenr commented 1 year ago

It seems that sometimes our dispose() function gets called while the offcanvas/modal hiding transition is still running. The transition-complete callback which clean-ups the body fails in such case.

This can be reproduced in our HxListLayout component when I change nesting and make the HxOffcanvas to be inside of HxFilterForm instead of having the HxFilterForm inside the HxOffcanvas.Body. Then, when you click Apply button in the HxListLayout filter-offcanvas footer, this error occurs:

offcanvas.js:146  Uncaught TypeError: Cannot read properties of null (reading 'classList')
    at offcanvas.js:146:21
    at g (index.js:226:51)
    at HTMLDivElement.a (index.js:247:5)
    at s (index.js:71:11)
    at index.js:253:7

Where it is line 146 in hide() where the callback does not find the classList any more (as the dispose() already took place): image

I will try to add some defensive logic to HxOffcanvas and HxModal to postpone our dispose() to onHidden event handler if it gets called while hiding is still in progress.

hakenr commented 8 months ago

Issue persists in Bootstrap; reverting to waiting status.

Bootstrap's dispose() method fails to reset scrollbars, leaving overflow: hidden on the body element intact. Neither Offcanvas.js:dispose() nor Modal.js:dispose() invoke ScrollBarHelper().reset(). Currently, this reset is only triggered in the hide() logic of Bootstrap's Offcanvas/Modal. However, this approach is ineffective for us because Blazor removes elements from the DOM, causing the hide() call to fail before reset() can be executed.

hakenr commented 8 months ago

Reported at twbs/bootstrap#36397 (attempting to reopen the issue). If reopening is unsuccessful, we will proceed to create a new ticket.