v1.8.34: fix dropdown — portal to body with fixed positioning, no overlap possible

This commit is contained in:
2026-05-28 23:12:57 +00:00
parent 43d72c757d
commit 97653ef882
+26 -11
View File
@@ -181,15 +181,21 @@
if (!r.ok) { localStorage.removeItem('rag_token'); initHeaderAuth(); return; } if (!r.ok) { localStorage.removeItem('rag_token'); initHeaderAuth(); return; }
const user = await r.json(); const user = await r.json();
const isAdmin = user.role === 'admin'; const isAdmin = user.role === 'admin';
// Button only in nav-auth
nav.innerHTML = ` nav.innerHTML = `
<div class="relative" id="uh-wrap"> <button id="uh-btn" class="glass glass-hover flex items-center gap-2 px-3 py-2 rounded-xl text-xs transition-colors">
<button onclick="document.getElementById('uh-drop').classList.toggle('hidden')"
class="glass glass-hover flex items-center gap-2 px-3 py-2 rounded-xl text-xs transition-colors">
<span class="msym text-base text-primary">person</span> <span class="msym text-base text-primary">person</span>
<span class="hidden sm:inline max-w-[80px] truncate">${user.name}</span> <span class="hidden sm:inline max-w-[80px] truncate">${user.name}</span>
<span class="msym text-sm text-on-surface-variant">expand_more</span> <span class="msym text-sm text-on-surface-variant">expand_more</span>
</button> </button>`;
<div id="uh-drop" class="hidden absolute top-full mt-1 glass rounded-xl p-2 w-44 z-50 shadow-xl" style="left:0;max-width:calc(100vw - 4rem)">
// Dropdown portaled to body — no overlap possible
const existingDrop = document.getElementById('uh-drop');
if (existingDrop) existingDrop.remove();
const drop = document.createElement('div');
drop.id = 'uh-drop';
drop.className = 'hidden fixed glass rounded-xl p-2 w-44 z-[9999] shadow-xl';
drop.innerHTML = `
<div class="px-3 py-2 border-b border-outline-variant/30 mb-1"> <div class="px-3 py-2 border-b border-outline-variant/30 mb-1">
<p class="text-xs font-bold">${user.name}</p> <p class="text-xs font-bold">${user.name}</p>
<p class="text-[10px] text-primary">${user.role}</p> <p class="text-[10px] text-primary">${user.role}</p>
@@ -197,13 +203,22 @@
${isAdmin ? '<a href="/admin" class="flex items-center gap-2 px-3 py-2 rounded-lg text-xs text-on-surface-variant hover:text-primary hover:bg-primary/5"><span class="msym text-sm">admin_panel_settings</span>Admin</a>' : ''} ${isAdmin ? '<a href="/admin" class="flex items-center gap-2 px-3 py-2 rounded-lg text-xs text-on-surface-variant hover:text-primary hover:bg-primary/5"><span class="msym text-sm">admin_panel_settings</span>Admin</a>' : ''}
<button onclick="uhLogout()" class="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-xs text-error hover:bg-red-900/10"> <button onclick="uhLogout()" class="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-xs text-error hover:bg-red-900/10">
<span class="msym text-sm">logout</span>خروج <span class="msym text-sm">logout</span>خروج
</button> </button>`;
</div> document.body.appendChild(drop);
</div>`;
document.addEventListener('click', e => { document.getElementById('uh-btn').addEventListener('click', e => {
const w = document.getElementById('uh-wrap'); e.stopPropagation();
if (w && !w.contains(e.target)) document.getElementById('uh-drop')?.classList.add('hidden'); const btn = document.getElementById('uh-btn');
const rect = btn.getBoundingClientRect();
drop.style.top = (rect.bottom + 6) + 'px';
drop.style.left = rect.left + 'px';
// Keep within viewport
const rightEdge = rect.left + 176;
if (rightEdge > window.innerWidth - 8) drop.style.left = (window.innerWidth - 184) + 'px';
drop.classList.toggle('hidden');
}); });
document.addEventListener('click', () => drop.classList.add('hidden'));
} catch (e) {} } catch (e) {}
} }