fix(match-list): scope drag ids to response areas so re-used answer choices behave independently PIE-965 - #3115
Merged
Merged
Conversation
…hoices behave independently PIE-965 dnd-kit keys its draggable registry, its isDragging flag and its drag transform off the id it is given, and match-list named a placed answer after the choice it held. With config.duplicates enabled the same choice can occupy several response areas, so all of those tiles registered under one id and collapsed into a single registry entry: they animated together, the last-registered tile's data resolved as the drag payload so the wrong response area changed, and unmounting any one of them deleted the entry the still-mounted siblings depended on, leaving a tile that was focusable but no longer draggable or reachable by the keyboard sensor. A placed answer is now identified by its response area; pool choices stay keyed by choice id, since the pool renders each choice once. Also fills in a missing branch in placeAnswer: with duplicates enabled, moving a placed answer onto an occupied response area matched neither the swap branch, which requires duplicates to be off, nor the move branch, which requires an empty target, and was a silent no-op. It now takes the target and vacates its source, matching the choice-onto-occupied-target path. The screen-reader label helpers recovered the dragged choice by regex-stripping the drag id, which the new id shape breaks; they read the tile's drag data instead. Rows are keyed by prompt id rather than index, now that each row owns a promptId-derived registration. dnd-kit is mocked repo-wide in __mocks__/@dnd-kit/core.js with useDraggable stubbed to a constant, so no existing test could observe the collision. The new tests assert the ids handed to dnd-kit; 9 fail against the old id scheme and 2 against the old reducer.
CarlaCostea
requested review from
PatriciaRomaniuc,
andreeimiron and
arimieandreea
September 4, 2026 10:50
PatriciaRomaniuc
approved these changes
Sep 4, 2026
andreeimiron
approved these changes
Sep 4, 2026
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.
The issue was caused by duplicate placed answers sharing the same dnd-kit id. Since dnd-kit uses that id for its draggable registry, state, and transform, multiple tiles collapsed into a single entry. This caused them to animate together, sometimes update the wrong response area, and in some cases become focusable but no longer draggable.
Placed answers now use their response area as the draggable id, while pool choices keep using the choice id since each appears only once.
I also fixed a missing
placeAnswercase: with duplicates enabled, moving a placed answer onto an occupied response area was previously a no-op. It now replaces the target and clears the source as expected.Screen-reader helpers now get the dragged choice from the drag data instead of parsing the id, and rows are keyed by
promptId.Existing tests couldn't catch the id collision because
useDraggableis mocked globally. New tests now verify the ids passed to dnd-kit and cover the reducer case as well.https://illuminate.atlassian.net/browse/PIE-965