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
This commit is contained in:
parent
88f90dc8ca
commit
fe194e7003
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -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');
|
||||
|
|
|
|||
Loading…
Reference in New Issue