fix(sprint-5/etapa-4h): safety net en Sheet — body queda con pointer-events:none stuck tras cerrar
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled
Bug de Radix/react-remove-scroll: el cleanup que restaura pointer-events del body al cerrar un Dialog/Sheet puede no ejecutarse (race con re-renders externos durante la animación de salida). Resultado: toda la página queda no interactiva hasta refrescar manualmente — confirmado en producción tras guardar perfil pese al defer de 350ms ya aplicado en ProfileSheet (mitigaba una causa, no era estructural). Fix a nivel del primitivo Sheet (cubre todos los usos, no solo ProfileSheet): al cerrar, espera 400ms (> 300ms de la animación) y si no queda ningún [role="dialog"][data-state="open"] en el DOM pero el body sigue con pointer-events:none, lo limpia explícitamente. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,30 @@ import { cva, type VariantProps } from 'class-variance-authority'
|
||||
import { X } from 'lucide-react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const Sheet = SheetPrimitive.Root
|
||||
// Bug conocido de Radix/react-remove-scroll: si un re-render externo coincide con la
|
||||
// animación de cierre, el cleanup que restaura `pointer-events` del body no se ejecuta
|
||||
// — toda la página queda no interactiva hasta refrescar manualmente. El defer de 350ms
|
||||
// en algunos callers (ej. ProfileSheet) mitiga UNA causa, pero no es estructural: este
|
||||
// fallback corrige el estado real del DOM sin asumir cuál fue la causa de la falla.
|
||||
// 400ms > duración de la animación de salida (300ms, ver sheetVariants).
|
||||
function Sheet({ onOpenChange, ...props }: React.ComponentPropsWithoutRef<typeof SheetPrimitive.Root>) {
|
||||
return (
|
||||
<SheetPrimitive.Root
|
||||
onOpenChange={(open) => {
|
||||
onOpenChange?.(open)
|
||||
if (!open) {
|
||||
window.setTimeout(() => {
|
||||
const stillHasOpenDialog = document.querySelector('[role="dialog"][data-state="open"]')
|
||||
if (!stillHasOpenDialog && document.body.style.pointerEvents === 'none') {
|
||||
document.body.style.pointerEvents = ''
|
||||
}
|
||||
}, 400)
|
||||
}
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
const SheetTrigger = SheetPrimitive.Trigger
|
||||
const SheetClose = SheetPrimitive.Close
|
||||
const SheetPortal = SheetPrimitive.Portal
|
||||
|
||||
Reference in New Issue
Block a user