Guarantee DOM sort order when performing actions #1168
Merged
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.
We already fixed a bug in the past where the order of DOM nodes wasn't stored in the correct order when performing operations (e.g.: using your keyboard to go to the next option).
We fixed this by ensuring that when we register/unregister an option/item, that we sorted the list properly. This worked fine, until we introduced the Combobox components. This is because items in a Combobox are continuously filtered and because of that moved around.
Moving a DOM node to a new position doesn't require a full unmount/remount. This means that the sort gets messed up and the order is wrong when moving around again.
To fix this, we will always perform a sort when performing actions. This could have performance drawbacks, but the alternative is to re-sort when the component gets updated. The bad part is that you can update a component via many ways (like changes on the parent), in those scenario's you probably don't care to properly re-order the internal list. Instead we do it while performing an action (
goToOption
/goToItem
).To make things a bit more efficient, instead of querying the DOM all the time using
document.querySelectorAll
, we will keep track of the underlying DOM node instead. This does increase memory usage a bit but I think that this is a fine trade-off.Performance wise this could also be a bottleneck to perform the sorting if you have a lot of data. But this problem already exists today, therefore I consider this a complete new problem instead to solve. Maybe we don't solve it in Headless UI itself, but figure out a way to make it composable with existing virtualization libraries.