fix(client): keep confirmation dialogs above sheets

Raise shared confirmation layers above sheet overlays so mouse input reaches privilege-change prompts.

Fixes #1502
This commit is contained in:
neon
2026-09-23 01:40:28 +00:00
parent bc10ebcc33
commit 27cfdc2028
3 changed files with 36 additions and 2 deletions
+2 -2
View File
@@ -50,10 +50,10 @@ function handleCancel() {
<template>
<DialogRoot :open="open" @update:open="handleOpenChange">
<DialogPortal>
<DialogOverlay class="fixed inset-0 z-50 bg-foreground/50" />
<DialogOverlay class="fixed inset-0 z-[70] bg-foreground/50" />
<DialogContent
aria-modal="true"
class="fixed left-1/2 top-1/2 z-50 w-[calc(100%-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg border border-border bg-card p-6 shadow-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
class="fixed left-1/2 top-1/2 z-[70] w-[calc(100%-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg border border-border bg-card p-6 shadow-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
<div class="flex items-start gap-3">
<div v-if="destructive" class="flex size-10 shrink-0 items-center justify-center rounded-full bg-destructive/10">
@@ -78,4 +78,36 @@ describe('ConfirmDialog', () => {
expect(confirmButton()?.disabled).toBe(true)
wrapper.unmount()
})
it('elevates its stacking layer to z-[70] so it renders above drawers and sheets', async () => {
const wrapper = mountDialog()
await flushPromises()
const content = document.body.querySelector<HTMLDivElement>('[role="dialog"]')
const overlay = document.body.querySelector<HTMLDivElement>('.fixed.inset-0')
expect(content?.className).toContain('z-[70]')
expect(overlay?.className).toContain('z-[70]')
wrapper.unmount()
})
it('can be confirmed when rendered alongside a sheet overlay', async () => {
// Simulate an underlying drawer/sheet overlay rendered at z-50
const sheetOverlay = document.createElement('div')
sheetOverlay.setAttribute('data-slot', 'sheet-overlay')
sheetOverlay.className = 'fixed inset-0 z-50 bg-black/15'
document.body.appendChild(sheetOverlay)
const wrapper = mountDialog()
await flushPromises()
confirmButton()?.click()
await flushPromises()
expect(wrapper.emitted('confirm')).toHaveLength(1)
wrapper.unmount()
sheetOverlay.remove()
})
})
@@ -485,6 +485,8 @@ describe('UsersPage superuser access', () => {
await flushPromises()
expect(document.body.textContent).toContain('Grant Ada Lovelace unrestricted server access.')
const dialog = document.body.querySelector('[role="dialog"]')
expect(dialog?.className).toContain('z-[70]')
const confirm = Array.from(document.body.querySelectorAll('button'))
.filter((button) => button.textContent?.trim() === 'Promote to superuser')
.at(-1)