Compare commits
2 Commits
985c655f6a
...
1aa1486d88
| Author | SHA1 | Date | |
|---|---|---|---|
| 1aa1486d88 | |||
| aaf1f79519 |
@@ -48,15 +48,16 @@ export function ProfileSheet({ open, onOpenChange }: ProfileSheetProps) {
|
|||||||
const savedName = name.trim()
|
const savedName = name.trim()
|
||||||
const savedCompany = company.trim() || undefined
|
const savedCompany = company.trim() || undefined
|
||||||
|
|
||||||
// Cerramos el Sheet PRIMERO para que Radix inicie la animación de cierre en un
|
// Cerramos el Sheet primero. updateUser() se difiere 350ms — más que la animación
|
||||||
// render limpio. updateUser() se difiere al siguiente macrotask para evitar que
|
// de cierre de Radix (duration-300 = 300ms) — para que el cleanup de
|
||||||
// el re-render de AuthContext (ancestor) interfiera con la animación: si ambas
|
// @radix-ui/react-remove-scroll restaure pointer-events:none del body ANTES
|
||||||
// actualizaciones ocurren en el mismo tick, React las batchea pero Radix puede
|
// de que el re-render de AuthContext vuelva a procesar el Sheet. Si updateUser
|
||||||
// recibir un render intermedio con open=true que deja el overlay en el DOM.
|
// corre durante la animación, Radix no ejecuta el cleanup y body queda con
|
||||||
|
// pointer-events:none permanente, bloqueando toda interacción fuera del canvas BPMN.
|
||||||
onOpenChange(false)
|
onOpenChange(false)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
updateUser({ name: savedName, company: savedCompany })
|
updateUser({ name: savedName, company: savedCompany })
|
||||||
}, 0)
|
}, 350)
|
||||||
|
|
||||||
// Persistir en Supabase en background — fire & forget.
|
// Persistir en Supabase en background — fire & forget.
|
||||||
// Usamos raw fetch (no el cliente Supabase) para evitar contención con processLock.
|
// Usamos raw fetch (no el cliente Supabase) para evitar contención con processLock.
|
||||||
|
|||||||
@@ -4,7 +4,30 @@ import { cva, type VariantProps } from 'class-variance-authority'
|
|||||||
import { X } from 'lucide-react'
|
import { X } from 'lucide-react'
|
||||||
import { cn } from '@/lib/utils'
|
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 SheetTrigger = SheetPrimitive.Trigger
|
||||||
const SheetClose = SheetPrimitive.Close
|
const SheetClose = SheetPrimitive.Close
|
||||||
const SheetPortal = SheetPrimitive.Portal
|
const SheetPortal = SheetPrimitive.Portal
|
||||||
|
|||||||
Reference in New Issue
Block a user