fix: RangeCalendar range selection in shadow DOM - #10347
Closed
AKnassa wants to merge 2 commits into
Closed
Conversation
The window-level pointerup listener in useRangeCalendar read the raw
e.target, which is retargeted to the shadow host for events originating
inside a shadow root. nodeContains() then always reported the release
as outside the calendar, committing {start === end} on the first click.
Resolve the real target with the shadow-safe getEventTarget() helper.
Fixes adobe#10330
Extend the shadow DOM describe with paths the first regression test did
not reach, all of which fail without the getEventTarget() fix: drag
selection (onChange fired twice), the month navigation buttons (the
closest('button') branch), commitBehavior "clear", and nested shadow
roots.
Add guards on the inverse paths so a later change cannot over-correct:
releasing outside the calendar but inside the same shadow root, and
committing when focus leaves the shadow root.
Share the per-test setup through a renderInShadowRoot() helper, and note
that enableShadowDOM() is a one way flag so this describe must stay last.
Member
|
Just noticed I have this covered in chore: additional shadow dom tests and fixes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #10330
When a
RangeCalendar(including the calendar insideDateRangePicker) is rendered inside a shadow root withenableShadowDOM(), clicking a single date immediately committed a range wherestart === end, so a multi-day range could never be selected by clicking. Dragging a range had a second symptom from the same cause:onChangefired twice, once from the early commit and once from the cell's own press.The window-level
pointeruplistener inuseRangeCalendarread the rawe.target. For events coming from inside a shadow root the browser retargets that to the shadow host, so the calendar always believed the pointer was released outside of it and committed the in-progress selection on every click. The listener now resolves the real target with the existing shadow-safegetEventTarget()helper, as suggested by @snowystinger in the issue.Resolving the real target also feeds the
closest('button, [role="button"]')check on the line below, which is what stops the month navigation buttons from committing an in-progress selection. That path was broken inside a shadow root too, and is now covered.Nested shadow roots work as well — the window listener only ever sees the outermost host, and
composedPath()[0]resolves through every boundary. One known limit, unchanged by this PR and shared withuseInteractOutside/useToastRegion:closest()does not pierce shadow boundaries, so it would still miss a navigation button living in a deeper shadow root than the calendar itself. That looked like a separate, wider change rather than something to fold in here.✅ Pull Request Checklist:
📝 Test Instructions:
yarn jest packages/react-aria-components/test/RangeCalendar.test.tsx— the newshadow DOMdescribe has eight tests. Five of them fail onmainand pass with the fix:onChangefires withstart === endon the first clickonChangefires twicecommitBehavior="clear"— the first click wipes the selection instead of anchoring itThe other three pass with and without the fix and are there as guards on the inverse paths, so a future change can't over-correct: releasing outside the calendar, releasing outside the calendar but inside the same shadow root, and committing when focus leaves the shadow root.
Manual: call
enableShadowDOM()from@react-stately/flags, render aRangeCalendarinside an open shadow root, and click two dates — the range commits only on the second click, matching light DOM behavior.🧢 Your Project:
No response