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
477 stars 67 forks source link

[HxSidebar] Sidebar remains collapsed horizontally when the window is resized #532

Open TPIvan opened 1 year ago

TPIvan commented 1 year ago

When a Sidebar is horizontally collapsed by toggler and then the window is made narrower which causes the Sidebar to collapse vertically to its header and then the Sidebar is expanded vertically by the hamburger expader it remain collapsed horizontally. There is no way how to expand the sidebar horizontally in this situation (the toggler is hidden). image

Steps to reproduce

  1. Open the documentation site https://havit.blazor.eu/
  2. Toggle the Sidebar
  3. Make the window narrower to make Sidebar to collapse to up
  4. Expand the Sidebar

Solution

A solution is probably quite simple the navbar toggler (hx-sidebar-navbar-toggler) should expand the sidebar also horizontally. The onclick is added:

          <HxButton OnClick=@(async () => await SetCollapsed(false))
                CssClass="@CssClassHelper.Combine("hx-sidebar-navbar-toggler ms-auto", GetResponsiveCssClass("d-??-none"))"

and the function:

   private async Task SetCollapsed(bool state)
    {
    Collapsed =state;
    await InvokeCollapsedChangedAsync(Collapsed);
    }
hakenr commented 1 year ago

@crdo Can you please check the proposed solution?

crdo commented 1 year ago

That is unfortunately not enough. We need to get rid of the collapsed class on HxSidebar and if this is suppose to be a real solution, it has to happen on the window resize event and also take in an account the responsive settings of the Sidebar. That being said makes it a way more complicated than the proposed solution

TPIvan commented 1 year ago

The presence of collapsed css class is controlled by Collapsed property.

    private string GetCollapsedCssClass() => Collapsed ? "collapsed" : null;

and onclik handler sets the property whenever the hamburger button is pressed. Afte the window resize sidebar is horizontally collapsed (disapears) and shows only after clicking the hamburger button which expands it horizontally too and there is no need for reaction to window resize.

I apologize - it is difficult to explain it clearly.

crdo commented 1 year ago

I think there is a better solution. Working on it...

crdo commented 1 year ago

@hakenr i decided to link WIP PR as I am not making any progress.

1) cleaned some CSS and moved utility classes to CSS isolation 2) implemented what @TPIvan is suggesting, but I consider it to be more a work-around than a real fix as it has some known issues (SidebarBrand text shows after clicking on hamburger menu, not after resizing window, collapse animation of mobile menu is not happening on the first click) 3) moved some logic of showing/hiding of elements when collapsed/expanded from CSS to Blazor using CascadingParamterer

From my POV, points 1 and 3 are merging worthy. Not sure about the 2. Real solution as I see it after messing around with the implementation for couple of hours is to separate rendering of SidebarItems in desktop and mobile view. Yes, it would duplicate presence of the items in the DOM, but it would solve this issue and simplify the implementaiton.

crdo commented 1 year ago

... I was hoping for a CSS only solution, but the with the possibility to set Responsivity of rendering the desktop/mobile version in Blazor and with missing SASS maps in the CSS isolation, it is simply not possible.

TPIvan commented 1 year ago

I think that a CSS only solution will be difficult (if possible), because after the sidebar is horizontally collapsed its state is changed and this state has to be responsively ignored. I agree that proposed solution is more a workaround than a solution, but it respects the changed state and reverts it after pressing the vertical expand button.

StefanOverHaevgRZ commented 1 month ago

@crdo Do you have any idea for a permanent solution? We're currently thinking about overriding all the sidebar css classes with media queries in our SCSS. So basically inverting the root classes to have no width limitation on the collapsed state, and for the media query classes to have a set width instead.

crdo commented 1 month ago

That is only a half of the problem. Even if you remove the fixed width of the collapsed Sidebar, fixing the layout problem, you end up with correct layout but still missing the content of the SidebarItems, which is not rendered at all if ParentSidebar.Collapsed == true.

image

I have an idea of permanent solution which is to separate rendering of the nav content for mobile/desktop.

The mobile item is a simple NavItem with no logic whatsoever contrary to desktop item that has tooltips, dropdowns, expanded/collapsed variant etc.

I am giving you guys a hads-up that we are currently focused on activities related to Havit.Blazor.Premium as part of our monetisation efforts tracked in #798 so if anyone giving it a shot I can support you with my ideas.

TPIvan commented 1 month ago

@crdo: I believe that categorizing navigation strictly into mobile and desktop views might be a bit limiting. For instance, a desktop window can be resized to a narrow width, and mobile devices can switch orientations, altering their display between mobile and desktop views.

crdo commented 1 month ago

@TPIvan what I propose is that both of the views will be always rendered in the DOM and its visibility will be managed by responsive utility classes set on the Sidebar. The key take-away is that the mobile nav would not be anyhow affected by the collapse state of the desktop nav.

StefanOverHaevgRZ commented 3 weeks ago

@crdo Sounds like the best approach to be honest. I had a look at the Bootstrap 5.3 docs page, and they handle this issue similiar, but a bit different (the menu becomes an offcanvas there).

Some design questions regarding the proposed solution:

  1. How should the files/classes/components be organized? Separate components for the "sidebar" and "topbar" states, or everything in HxSidebar?
  2. For the small screen size: should it always be a "topbar", or optional the "offcanvas" approach?

There are probably multiple ways to approach this, either with breaking changes or without.