소스 검색

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 1 개월 전
부모
커밋
fe194e7003
3개의 변경된 파일과 24개의 추가작업 그리고 10개의 파일을 삭제
  1. 0 0
      netbox/project-static/dist/netbox.js
  2. 0 0
      netbox/project-static/dist/netbox.js.map
  3. 24 10
      netbox/project-static/src/sidenav.ts

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
netbox/project-static/dist/netbox.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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));
       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());
     window.addEventListener('resize', () => this.onResize());
 
 
     this.base.addEventListener('mouseenter', () => this.onEnter());
     this.base.addEventListener('mouseenter', () => this.onEnter());
     this.base.addEventListener('mouseleave', () => this.onLeave());
     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.
    * If the sidenav is shown, expand active nav links. Otherwise, collapse them.
    */
    */
@@ -153,12 +165,14 @@ class SideNav {
         switch (action) {
         switch (action) {
           case 'expand':
           case 'expand':
             groupLink.setAttribute('aria-expanded', 'true');
             groupLink.setAttribute('aria-expanded', 'true');
+            groupLink.classList.add('show');
             groupItem.classList.add('active');
             groupItem.classList.add('active');
             dropdownMenu.classList.add('show');
             dropdownMenu.classList.add('show');
             link.classList.add('active');
             link.classList.add('active');
             break;
             break;
           case 'collapse':
           case 'collapse':
             groupLink.setAttribute('aria-expanded', 'false');
             groupLink.setAttribute('aria-expanded', 'false');
+            groupLink.classList.remove('show');
             groupItem.classList.remove('active');
             groupItem.classList.remove('active');
             dropdownMenu.classList.remove('show');
             dropdownMenu.classList.remove('show');
             link.classList.remove('active');
             link.classList.remove('active');

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.