-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
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
[MenuUnstyled] Accept callbacks in componentsProps #32997
Merged
Merged
Changes from 2 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
e19c84a
Accept function in Menu's componentsProps
michaldudak 8757572
Accept functions in MenuItemUnstyled's componentsProps
michaldudak 40bc050
Create and use the useSlotProps hook
michaldudak c971a38
Merge remote-tracking branch 'upstream/master' into componentsProps/menu
michaldudak e87d050
Merge remote-tracking branch 'upstream/master' into componentsProps/menu
michaldudak 3efae41
Add useSlotProps tests
michaldudak a24c5b2
Merge remote-tracking branch 'upstream/master' into componentsProps/menu
michaldudak File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import * as React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import clsx from 'clsx'; | ||
import { HTMLElementType, refType } from '@mui/utils'; | ||
import { HTMLElementType, refType, unstable_useForkRef as useForkRef } from '@mui/utils'; | ||
import appendOwnerState from '../utils/appendOwnerState'; | ||
import MenuUnstyledContext, { MenuUnstyledContextType } from './MenuUnstyledContext'; | ||
import { | ||
|
@@ -15,6 +15,7 @@ import useMenu from './useMenu'; | |
import composeClasses from '../composeClasses'; | ||
import PopperUnstyled from '../PopperUnstyled'; | ||
import { WithOptionalOwnerState } from '../utils'; | ||
import resolveComponentProps from '../utils/resolveComponentProps'; | ||
|
||
function getUtilityClasses(ownerState: MenuUnstyledOwnerState) { | ||
const { open } = ownerState; | ||
|
@@ -48,6 +49,7 @@ const MenuUnstyled = React.forwardRef(function MenuUnstyled( | |
components = {}, | ||
componentsProps = {}, | ||
keepMounted = false, | ||
listboxId, | ||
onClose, | ||
open = false, | ||
...other | ||
|
@@ -64,8 +66,7 @@ const MenuUnstyled = React.forwardRef(function MenuUnstyled( | |
} = useMenu({ | ||
open, | ||
onClose, | ||
listboxRef: componentsProps.listbox?.ref, | ||
listboxId: componentsProps.listbox?.id, | ||
listboxId, | ||
}); | ||
|
||
React.useImperativeHandle( | ||
|
@@ -85,6 +86,7 @@ const MenuUnstyled = React.forwardRef(function MenuUnstyled( | |
const classes = getUtilityClasses(ownerState); | ||
|
||
const Popper = component ?? components.Root ?? PopperUnstyled; | ||
const popperComponentProps = resolveComponentProps(componentsProps.root, ownerState); | ||
const popperProps: MenuUnstyledRootSlotProps = appendOwnerState( | ||
Popper, | ||
{ | ||
|
@@ -93,19 +95,23 @@ const MenuUnstyled = React.forwardRef(function MenuUnstyled( | |
open, | ||
keepMounted, | ||
role: undefined, | ||
...componentsProps.root, | ||
className: clsx(classes.root, className, componentsProps.root?.className), | ||
...popperComponentProps, | ||
className: clsx(classes.root, className, popperComponentProps?.className), | ||
ref: useForkRef(popperComponentProps?.ref, forwardedRef), | ||
}, | ||
ownerState, | ||
) as MenuUnstyledRootSlotProps; | ||
|
||
const Listbox = components.Listbox ?? 'ul'; | ||
const listboxComponentProps = resolveComponentProps(componentsProps.listbox, ownerState); | ||
const propsFromHook = getListboxProps(); | ||
const listboxProps: WithOptionalOwnerState<MenuUnstyledListboxSlotProps> = appendOwnerState( | ||
Listbox, | ||
{ | ||
...componentsProps.listbox, | ||
...getListboxProps(), | ||
className: clsx(classes.listbox, componentsProps.listbox?.className), | ||
...propsFromHook, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like that this was resolved previously it helps with readability :) |
||
...listboxComponentProps, | ||
className: clsx(classes.listbox, listboxComponentProps?.className), | ||
ref: useForkRef(propsFromHook.ref, listboxComponentProps?.ref), | ||
}, | ||
ownerState, | ||
); | ||
|
@@ -170,8 +176,8 @@ MenuUnstyled.propTypes /* remove-proptypes */ = { | |
* @ignore | ||
*/ | ||
componentsProps: PropTypes.shape({ | ||
listbox: PropTypes.object, | ||
root: PropTypes.object, | ||
listbox: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), | ||
root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), | ||
}), | ||
/** | ||
* Always keep the menu in the DOM. | ||
|
@@ -180,6 +186,10 @@ MenuUnstyled.propTypes /* remove-proptypes */ = { | |
* @default false | ||
*/ | ||
keepMounted: PropTypes.bool, | ||
/** | ||
* @ignore | ||
*/ | ||
listboxId: PropTypes.string, | ||
/** | ||
* Triggered when focus leaves the menu and the menu should close. | ||
*/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
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.
hmm why was the order changed? Shouldn't the
getRootProps()
comes last as they are adding some event handlers?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 way devs are able to override whatever the hook is setting. But I see there's a problem with event handlers. I suppose the order should be as following:
...other
) with removed event handlers - only for the root slotcomponentsProps.<slot name>
with removed event handlersclassName
- merged fromclassName
prop,componentsProps.*.className
and slot-specific classesref
- if necessaryDevelopers would be able to override whatever prop they need and if they provide an event handler, it would be chained with the hook's handlers.
We could use a function that would encapsulate this logic and ensure this works consistently across our components.
What do you think?
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.
Yep, let's do this 👍
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 created a
useSlotProps
function that takes care of everything needed to resolve, merge and supplement the props with ownerState. The preparation of the slots' props in the components is much cleaner now.