Sheet stays exiting when the IntersectionObserver batches the ratio 0 entry behind another

Abierto
#10,897 4 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
Medio día
Aptitud para principiantes
55/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
react, typescript
Área
frontend

Línea de trabajo

The bug lives in SheetOverlay, which reads entries[0] from the IntersectionObserver callback for [data-sheet-content]. Start there and find every place the entry is read (setExpanded, isVisible, and the close check). Switch to the last entry, then reproduce by wrapping IntersectionObserver to deliver a ratio>0 and a ratio 0 entry in one callback. Done when the sheet unmounts and react-aria-sheet-close fires in that case.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Provide a general summary of the issue here

This is the root cause of #10813, which was closed because we didn't know why the observer's last report goes missing. It isn't missing. On a slow frame the IntersectionObserver delivers two entries for the sheet content in one callback, and SheetOverlay only reads entries[0]. The ratio 0 entry is the second one, so the sheet stays data-exiting over the page.

🤔 Expected Behavior?

The sheet unmounts once its content has left the viewport.

😯 Current Behavior

The content slides out, the scroller rests at the exit position (scrollTop 0 for a bottom sheet) and fires scrollend, but react-aria-sheet-close never fires. The overlay stays in the DOM with data-exiting and blocks clicks on the page.

Logging the observer's entries for [data-sheet-content] (ms after the sheet opens), in a run that got stuck:

observe       @146
r=0.00 top=884   @211   initial, off screen
r=0.06 top=732   @299   entering
r=1.00 top=117   @653   entered
r=0.01 top=759   @2023  exiting  <- entries[0], read
r=0.00 top=771   @2023  gone     <- entries[1], ignored

Both exit entries arrive in the same callback. The sheet doesn't move after that, so no other report arrives.

💁 Possible Solution

Read the last entry for the target instead of the first:

let entry = entries[entries.length - 1];

This covers setExpanded, isVisible, and the close check. Since only one element is observed, the last entry is always the latest state.

🔦 Context

We build a Drawer on Sheet. Our date-picker tests on GitHub Actions kept failing at random with the drawer stuck after a backdrop tap. Locally we can reproduce it with CPU throttling: 10 of 40 runs got stuck. For now we work around it by dispatching react-aria-sheet-close ourselves on scrollend when the panel is off screen, which brought it to 40 of 40.

🖥️ Steps to Reproduce
  1. Open a bottom Sheet and let it fully enter.
  2. Throttle the CPU in Chrome (Emulation.setCPUThrottlingRate with rate: 6 over CDP, or DevTools > Performance > CPU 6x).
  3. Close it, for example by tapping the backdrop. Repeat a few times.
  4. Sometimes the sheet stays data-exiting at the exit position. Wrapping IntersectionObserver to log entries shows two entries in one callback, as above.

To simulate it without throttling, wrap IntersectionObserver so the callback gets the last ratio>0 report and the ratio 0 report together in one array.

Version

react-aria-components 1.22.1 (same code in 3.0.0-nightly-2691598d3-261008)

What browsers are you seeing the problem on?

Chrome

If other, please specify.

No response

What operating system are you using?

macOS 26 (locally, with CPU throttling) and Ubuntu (GitHub Actions)

🕷 Tracking Issue

#10813

Lenguaje dominante
TypeScript
Estrellas
16k
Forks
1.6k
Merge medio
2 d 17 h
PR fusionados (30 d)
41

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de adobe/react-spectrum

Todos los issues de adobe/react-spectrum

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.