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] New API method: setItemExpansion #12595

Merged

Conversation

flaviendelangle
Copy link
Member

@flaviendelangle flaviendelangle commented Mar 28, 2024

Closes #9960

I would like to merge #12428 to write the new tests in the right place instead of moving them in 2 days

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

mui-bot commented Mar 28, 2024

@@ -2,10 +2,20 @@ import * as React from 'react';
import { DefaultizedProps, TreeViewPluginSignature } from '../../models';
import { UseTreeViewItemsSignature } from '../useTreeViewItems';

export interface UseTreeViewExpansionInstance {
export interface UseTreeViewExpansionPublicAPI {
Copy link
Member Author

Choose a reason for hiding this comment

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

@noraleonte I propose you to switch the logic for the definition of the instance / publicAPI and to instead define the method on XXXPublicAPI and use extend on XXXInstance.
That way it's easy to be sure that every public method has a good JSDoc.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's probably a much better way to do it 👍

* @param {string} itemId The id of the item to modify.
* @param {boolean} isExpanded The new expansion status of the given item.
*/
setItemExpansion: (event: React.SyntheticEvent, itemId: string, isExpanded: 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.

The main DX question here is about the event

Do we require the user to pass an event? This is needed right now to call the onItemExpansionToggle prop.
If we don't, do we only call onItemExpansionToggle when the event is defined or do we make the event nullable on onItemExpansionToggle?

Copy link
Contributor

@noraleonte noraleonte Apr 3, 2024

Choose a reason for hiding this comment

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

Do we require the user to pass an event

I personally don't see a problem with keeping the event required here 🤔 I'm trying to think of a scenario where users would want to specifically avoid passing the event here 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

We could imagine scenarios where there is no event (expand an item when receiving some data from the server for instance).
But I'd be in favor of keeping the event mandatory and making it nullable if we have feedback of valid use-cases that ask for it.

params,
models,
}) => {
const expandedItemsMap = React.useMemo(() => {
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 took the opportunity to do this performance improvement now because in order to avoid code duplication between toggleItemExpansion and setItemExpansion, I need to check the expansion status twice and doing it with a linear complexity with awefull.

@romgrk do you have a preference on the data structure to use for this model? Knowing that for now it's purely internal and we keep the array for the expandedItems prop (we can reconsider in the future).

@flaviendelangle flaviendelangle changed the title [TreeView] New API method: setItemExpansion [TreeView] New API method: setItemExpansion Mar 28, 2024
const value = model.isControlled
? props[modelName as keyof DefaultizedParams]
: modelsState[modelName];
const value = props[modelName as keyof DefaultizedParams] ?? modelsState[modelName];
Copy link
Member Author

Choose a reason for hiding this comment

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

This change makes sure that if we switch a model from controlled to uncontrolled, we will still have a valid value on the model.
This is a bad pattern and a warning will be shown (defined below in this file), but at least it does not crash with in some random place of the code and people can understand what is the problem.

@flaviendelangle flaviendelangle marked this pull request as ready for review March 29, 2024 07:23
@@ -177,13 +187,14 @@ const innerDescribeTreeView = <TPlugin extends TreeViewAnyPluginSignature>(
);

const result = render(
<SimpleTreeView slots={slots} {...other}>
<SimpleTreeView slots={slots} apiRef={apiRef} {...other}>
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 don't want to add ! on every single test when we know the ref will never be undefined

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.

Nice work, LGTM 👍 🎉

* @param {string} itemId The id of the item to modify.
* @param {boolean} isExpanded The new expansion status of the given item.
*/
setItemExpansion: (event: React.SyntheticEvent, itemId: string, isExpanded: boolean) => void;
Copy link
Contributor

@noraleonte noraleonte Apr 3, 2024

Choose a reason for hiding this comment

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

Do we require the user to pass an event

I personally don't see a problem with keeping the event required here 🤔 I'm trying to think of a scenario where users would want to specifically avoid passing the event here 🤔

@@ -2,10 +2,20 @@ import * as React from 'react';
import { DefaultizedProps, TreeViewPluginSignature } from '../../models';
import { UseTreeViewItemsSignature } from '../useTreeViewItems';

export interface UseTreeViewExpansionInstance {
export interface UseTreeViewExpansionPublicAPI {
Copy link
Contributor

Choose a reason for hiding this comment

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

That's probably a much better way to do it 👍

Copy link
Member

@LukasTy LukasTy left a comment

Choose a reason for hiding this comment

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

Nice improvement! 👍

flaviendelangle and others added 6 commits April 3, 2024 16:37
…on.tsx

Co-authored-by: Lukas <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
…on.js

Co-authored-by: Lukas <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
Co-authored-by: Lukas <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
Co-authored-by: Lukas <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
…sion.tsx

Co-authored-by: Lukas <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
…sion.js

Co-authored-by: Lukas <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
@flaviendelangle flaviendelangle merged commit b44c954 into mui:master Apr 3, 2024
15 checks passed
@flaviendelangle flaviendelangle deleted the publicAPI-setItemExpansion branch April 3, 2024 14:59
@flaviendelangle flaviendelangle mentioned this pull request Apr 5, 2024
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!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[TreeView] Expand control at TreeItem level
4 participants