Jelajahi Sumber

fix(ui): Reconcile sidebar state when crossing the responsive breakpoint

SideNav classified the viewport only during construction. Resizing past
the `lg` breakpoint therefore left the desktop sidebar in its previous
mobile state, and the menu group containing the current page remained
collapsed until the pointer entered the sidebar.

Use the existing desktop media query as an event source. Apply the
persisted pin preference directly to the body attributes during
initialization and on each breakpoint transition, then reinitialize the
active menu section.

Avoid calling `pin()` or `unpin()` during responsive transitions so
Bootstrap retains ownership of its collapse state and the stored
preference is not rewritten unnecessarily.

Also remove the `show` class from a menu group toggle when collapsing
its section to keep the toggle and menu state synchronized.

Fixes #23035
Martin Hauser 12 jam lalu
induk
melakukan
fe194e7003

File diff ditekan karena terlalu besar
+ 0 - 0
netbox/project-static/dist/netbox.js


File diff ditekan karena terlalu besar
+ 0 - 0
netbox/project-static/dist/netbox.js.map


+ 24 - 10
netbox/project-static/src/sidenav.ts

@@ -66,22 +66,34 @@ class SideNav {
       toggler.addEventListener('click', event => this.onMobileToggle(event));
     }
 
-    if (window.matchMedia(SIDENAV_DESKTOP_MEDIA).matches) {
-      if (this.state.get('pinned')) {
-        this.pin();
-      } else {
-        this.unpin();
-      }
-    } else {
-      this.bodyRemove('hide');
-      this.bodyAdd('hidden');
-    }
+    const desktopMedia = window.matchMedia(SIDENAV_DESKTOP_MEDIA);
+    this.setResponsiveState(desktopMedia.matches);
+    desktopMedia.addEventListener('change', event => {
+      this.setResponsiveState(event.matches);
+      this.initLinks();
+    });
+
     window.addEventListener('resize', () => this.onResize());
 
     this.base.addEventListener('mouseenter', () => this.onEnter());
     this.base.addEventListener('mouseleave', () => this.onLeave());
   }
 
+  /**
+   * Apply the appropriate sidenav state for the current responsive layout.
+   */
+  private setResponsiveState(isDesktop: boolean): void {
+    this.bodyRemove('hide');
+
+    if (isDesktop && this.state.get('pinned')) {
+      this.bodyRemove('hidden');
+      this.bodyAdd('show', 'pinned');
+    } else {
+      this.bodyRemove('show', 'pinned');
+      this.bodyAdd('hidden');
+    }
+  }
+
   /**
    * If the sidenav is shown, expand active nav links. Otherwise, collapse them.
    */
@@ -153,12 +165,14 @@ class SideNav {
         switch (action) {
           case 'expand':
             groupLink.setAttribute('aria-expanded', 'true');
+            groupLink.classList.add('show');
             groupItem.classList.add('active');
             dropdownMenu.classList.add('show');
             link.classList.add('active');
             break;
           case 'collapse':
             groupLink.setAttribute('aria-expanded', 'false');
+            groupLink.classList.remove('show');
             groupItem.classList.remove('active');
             dropdownMenu.classList.remove('show');
             link.classList.remove('active');

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini