Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TreeView] Rework the selection internals #12703

Merged
merged 10 commits into from Apr 23, 2024

Conversation

flaviendelangle
Copy link
Member

@flaviendelangle flaviendelangle commented Apr 8, 2024

Part of #10300

Goal

  • Improve the performances of the selection by removing linear or even quadratic complexity whenever possible
  • Improve the readability of the codebase by getting rid of the TreeViewItemRange interface (understanding what was going on was a pain with this object of 4 optional properties)

Behavior change

This PR includes a very small behavior change when using the Home or End key.
Before, when pressing Home, the focus was moving to the first navigable item and when pressing End the focus was moving to the last navigable item.
Additionally, if you pressed Home then End, the end selection was all the items below the item originally focus.

For me this is inconsistent, either:

  1. We move the focus and when pressing Home then End, all the items are selected since we pressed End while focusing the first item
Screencast.2024-04-11.15.36.29.mp4
  1. We don't move the focus and when pressing Home then End, only the items below the item originally focus (which is still focused) are selected
Screencast.2024-04-11.15.34.57.mp4

Here is what the ARIA spec says:

Control + Shift + Home (Optional): Selects the node with focus and all nodes up to the first node. Optionally, moves focus to the first node.

Control + Shift + End (Optional): Selects the node with focus and all nodes down to the last node. Optionally, moves focus to the last node.

I went for 2., but both are clearly totally valid

@flaviendelangle flaviendelangle self-assigned this Apr 8, 2024
@flaviendelangle flaviendelangle added performance component: tree view TreeView, TreeItem. This is the name of the generic UI component, not the React module! labels Apr 8, 2024
@mui-bot
Copy link

mui-bot commented Apr 8, 2024

Deploy preview: https://deploy-preview-12703--material-ui-x.netlify.app/

Generated by 🚫 dangerJS against c52985c

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 8, 2024
Copy link

github-actions bot commented Apr 8, 2024

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 8, 2024
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 8, 2024
Copy link

github-actions bot commented Apr 8, 2024

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 9, 2024
Copy link

github-actions bot commented Apr 9, 2024

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 11, 2024
itemId: string,
keepExistingSelection?: boolean,
) => void;
/**
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I split the API into several methods instead of a single selectRange
That way each one can receive the parameters it needs AND we can apply some optimization (selectAllNavigableItems is a lot cheaper now, no need to try to reconcile the old and the new model, you just select everything).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes a lot more sense like this! 👌 The previous API felt a little bit like mental gymnastics to me, this feels a lot more coherent 💯

* @param {string} currentItemId The id of the active item before the keyboard navigation.
* @param {string} nextItemId The id of the active item after the keyboard navigation.
*/
selectItemFromArrowNavigation: (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge fan of this abstraction, I would prefer useTreeViewKeyboardNavigation to only use methods that are not explicitly related to keyboard navigation.
But the selection behavior of the arrows require stuff that is inside useTreeViewSelection and I don't see how to name this method differently 😬

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the selection behavior of the arrows require stuff that is inside useTreeViewSelection

makes sense to me. I think the naming is fine here tbh 🤔

@flaviendelangle flaviendelangle marked this pull request as ready for review April 11, 2024 14:04
Copy link
Contributor

@noraleonte noraleonte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work 👌 🎉
The changes make a lot of sense to me, and the API is much better now IMO 💯

Regarding the behavior change when pressing Home then Enter, I think the approach you went with is the most logical. I would be ok with 1 too, but personally prefer 2

itemId: string,
keepExistingSelection?: boolean,
) => void;
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes a lot more sense like this! 👌 The previous API felt a little bit like mental gymnastics to me, this feels a lot more coherent 💯

* @param {string} currentItemId The id of the active item before the keyboard navigation.
* @param {string} nextItemId The id of the active item after the keyboard navigation.
*/
selectItemFromArrowNavigation: (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the selection behavior of the arrows require stuff that is inside useTreeViewSelection

makes sense to me. I think the naming is fine here tbh 🤔

@flaviendelangle flaviendelangle merged commit ece6641 into mui:master Apr 23, 2024
17 checks passed
@flaviendelangle flaviendelangle deleted the selection-refacto branch April 23, 2024 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: tree view TreeView, TreeItem. This is the name of the generic UI component, not the React module! performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants