-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[TreeView] New API method: setItemExpansion
#12595
Conversation
@@ -2,10 +2,20 @@ import * as React from 'react'; | |||
import { DefaultizedProps, TreeViewPluginSignature } from '../../models'; | |||
import { UseTreeViewItemsSignature } from '../useTreeViewItems'; | |||
|
|||
export interface UseTreeViewExpansionInstance { | |||
export interface UseTreeViewExpansionPublicAPI { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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 🤔
There was a problem hiding this comment.
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(() => { |
There was a problem hiding this comment.
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).
setItemExpansion
const value = model.isControlled | ||
? props[modelName as keyof DefaultizedParams] | ||
: modelsState[modelName]; | ||
const value = props[modelName as keyof DefaultizedParams] ?? modelsState[modelName]; |
There was a problem hiding this comment.
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.
@@ -177,13 +187,14 @@ const innerDescribeTreeView = <TPlugin extends TreeViewAnyPluginSignature>( | |||
); | |||
|
|||
const result = render( | |||
<SimpleTreeView slots={slots} {...other}> | |||
<SimpleTreeView slots={slots} apiRef={apiRef} {...other}> |
There was a problem hiding this comment.
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
There was a problem hiding this 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; |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvement! 👍
docs/data/tree-view/rich-tree-view/expansion/ChangeItemExpansion.tsx
Outdated
Show resolved
Hide resolved
docs/data/tree-view/rich-tree-view/expansion/ChangeItemExpansion.js
Outdated
Show resolved
Hide resolved
docs/data/tree-view/simple-tree-view/expansion/ChangeItemExpansion.js
Outdated
Show resolved
Hide resolved
docs/data/tree-view/simple-tree-view/expansion/ChangeItemExpansion.tsx
Outdated
Show resolved
Hide resolved
packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts
Show resolved
Hide resolved
…on.tsx Co-authored-by: Lukas <[email protected]> Signed-off-by: Flavien DELANGLE <[email protected]>
…on.js Co-authored-by: Lukas <[email protected]> Signed-off-by: Flavien DELANGLE <[email protected]>
Co-authored-by: Lukas <[email protected]> Signed-off-by: Flavien DELANGLE <[email protected]>
Co-authored-by: Lukas <[email protected]> Signed-off-by: Flavien DELANGLE <[email protected]>
…sion.tsx Co-authored-by: Lukas <[email protected]> Signed-off-by: Flavien DELANGLE <[email protected]>
…sion.js Co-authored-by: Lukas <[email protected]> Signed-off-by: Flavien DELANGLE <[email protected]>
Signed-off-by: Flavien DELANGLE <[email protected]> Co-authored-by: Lukas <[email protected]>
Signed-off-by: Flavien DELANGLE <[email protected]> Co-authored-by: Lukas <[email protected]>
Closes #9960
I would like to merge #12428 to write the new tests in the right place instead of moving them in 2 days