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

Aperta
#10,897 4 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
Mezza giornata
Idoneità per principianti
55/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
react, typescript
Ambito
frontend

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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

Lingua principale
TypeScript
Stelle
16k
Fork
1.6k
Merge medio
2g 17h
PR unite (30g)
41

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di adobe/react-spectrum

Tutte le issue di adobe/react-spectrum

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.