fix(ui): lift theme popover out of header stacking context to appear above modals

This commit is contained in:
Will Miao
2026-06-18 22:19:36 +08:00
parent 3012a7aef3
commit a617487a43
3 changed files with 71 additions and 54 deletions

View File

@@ -329,16 +329,14 @@
.theme-popover {
display: none;
position: absolute;
top: calc(100% + 8px);
right: -8px;
position: fixed;
background: var(--surface-base, #ffffff);
border: 1px solid var(--border-base, #e0e0e0);
border-radius: var(--radius-md, 8px);
box-shadow: var(--shadow-xl, 0 4px 16px rgba(0, 0, 0, 0.15));
padding: 12px;
min-width: 220px;
z-index: var(--z-dropdown, 200);
z-index: calc(var(--z-overlay) + 1);
animation: theme-popover-in 0.15s ease-out;
}

View File

@@ -121,11 +121,11 @@ export class HeaderManager {
this.updatePopoverActiveStates(currentTheme, currentPreset);
themeToggle.addEventListener('click', (e) => {
if (e.target.closest('.theme-popover')) return;
e.stopPropagation();
const isOpen = themePopover.classList.contains('active');
this.closeAllPopovers();
if (!isOpen) {
this.positionThemePopover();
themePopover.classList.add('active');
}
});
@@ -149,6 +149,13 @@ export class HeaderManager {
themePopover.classList.remove('active');
}
});
// Reposition on resize while popover is active
window.addEventListener('resize', () => {
if (themePopover.classList.contains('active')) {
this.positionThemePopover();
}
});
}
closeAllPopovers() {
@@ -158,6 +165,17 @@ export class HeaderManager {
}
}
positionThemePopover() {
const themeToggle = document.querySelector('.theme-toggle');
const themePopover = document.getElementById('themePopover');
if (!themeToggle || !themePopover) return;
const rect = themeToggle.getBoundingClientRect();
// Guard: toggle may be hidden on narrow viewports (≤950px CSS hides .header-controls)
if (rect.width === 0 || rect.height === 0) return;
themePopover.style.top = (rect.bottom + 8) + 'px';
themePopover.style.right = (window.innerWidth - rect.right - 8) + 'px';
}
setThemeMode(mode) {
setStorageItem('theme', mode);
const htmlElement = document.documentElement;