fix(@react-aria/datepicker): don't steal focus into a date segment from selectionchange (Firefox) (#10260)
* fix(@react-aria/datepicker): don't steal focus into a date segment from selectionchange while another element is focused
In Firefox, the caret inside a sibling <input> is not reflected in the
document selection, so a stale anchor can remain inside a date segment
after focus moves away. useDateSegment's document-level 'selectionchange'
listener then calls Selection.collapse(segment), and in Firefox collapsing
onto a contentEditable node moves focus to it -- stealing focus into the
segment while the user types in a neighbouring input.
Gate the collapse on the segment actually being the active element. This
preserves the Android-Chrome composition behaviour the handler was written
for (which only applies while the segment is focused) and removes the
cross-element focus steal.
Fixes #10259
* test: make DateField selectionchange focus-steal test fail without the fix
The previous test relied on a stale selection anchor surviving inside the
segment after focus moved to a sibling input, but Chromium/WebKit collapse
the document selection on focus change so the guarded branch was never
reached -- the test passed with and without the fix.
Reproduce the guarded precondition deterministically instead: keep genuine
focus on a sibling element (so getActiveElement() !== the segment) and stub
window.getSelection for a single selectionchange so the anchor is inside the
segment, then assert the handler does not call Selection.collapse onto it.
Now fails in every browser without the active-element guard.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore: fix formatting in DateField.browser.test.tsx
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test: move DateField focus-steal regression test to jsdom
The selectionchange focus steal is Firefox-specific browser behaviour, but the
logic the fix changed -- whether the handler calls Selection.collapse onto the
segment while another element is focused -- is environment independent. A real
browser can't reproduce the steal through synthetic events anyway, so replace
the browser test with a focused jsdom unit test that stubs window.getSelection
to model the stale Firefox anchor and asserts collapse is not called.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore: trim comment on selectionchange focus-steal guard
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* ci: retrigger CI (s2-docs parcel-resolver panic)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Robert Snow <rsnow@adobe.com>