Description
🐛 Bug Report
Background:
useDrag
uses useDescription
to render a hidden div with a description (i.e. Click to start dragging.) that it can refer to via aria-describedby
. On modality change, this messages is updated (i.e. Press Enter to start dragging.)
Problem:
Currently, when this message is changed (i.e. modality change), the description div is removed and a new one is created with a new id. As a result, all draggable items are re-rendered since they all refer to this div. We should be able to improve this and avoid unnecessary re-renders.
A previous attempt at fixing this was to only re-render the draggable item that has focus. However this may cause issues with out of date/inaccurate descriptions for screen readers since focus may not change when moving the screen reader cursor around. A new approach is to not rely on re-rendering the draggable items and instead update the description divs when modality changes
Found via investigation into #2403.
🤔 Expected Behavior
Description text should update without causing every draggable item to re-render.
😯 Current Behavior
useDescription causes every draggable item to re-render on modality change.
💁 Possible Solution
A few possible solutions we could look into after discussion with @devongovett and @LFDanLu:
-
Add an alternate
useDescription
that returns a setter to update the description div text. If ref count for the description div falls to 0, don't remove the div but store it for future reuse -
Instantiate and update descriptions at the collection-level. Possible cons: what about standalone draggable items that are using useDrag only
-
Handle within DragManager at page-level. Possible cons: might be hard to clean up those divs if it is unaware of unmount.
🔦 Context
useDescription use via useDrag
💻 Code Sample
Can be seen in https://codesandbox.io/s/intelligent-sun-pyg93 via #2403
🌍 Your Environment
Software | Version(s) |
---|---|
react-spectrum | |
Browser | |
Operating System |