Skip to content

Commit

Permalink
Improve the condition to correctly check whether element is focussabl…
Browse files Browse the repository at this point in the history
…e or not
  • Loading branch information
Divyam Madhok committed Jul 22, 2023
1 parent dfc4ffd commit 00a31cd
Showing 1 changed file with 51 additions and 1 deletion.
52 changes: 51 additions & 1 deletion packages/mui-material/src/MenuList/MenuList.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,51 @@ import getScrollbarSize from '../utils/getScrollbarSize';
import useForkRef from '../utils/useForkRef';
import useEnhancedEffect from '../utils/useEnhancedEffect';

/**
* This function dictates whether the element passed can receive focus when tabbed by checking from an array
* if it's a legal child.
*/
function isElementTabbableMenuChild(reactElement) {
/**
* If the element passed is not a valid React Element OR it does not have a type associated with
* it then early exit the function with `false` since it should not be tabbable.
*/
if (!React.isValidElement(reactElement) || !reactElement.type) {
return false;
}

// This contains illegal child that should not get focussed through tab.
const illegalTabbableChildNames = ['Divider'];

/**
* If the element is a native HTML element like p, div, span then we can directly
* check if reactElement.type is in the array of illegal children.
*
* - if yes, return false that it should not be tabbable otherwise return true
*/
if (typeof reactElement.type === 'string') {
return !illegalTabbableChildNames.includes(reactElement.type);
}

/**
* If the element is a custom user defined component like - Divider, Button, Accordion etc
* then we can directly access the element.type.name to check its name.
*/
if (typeof reactElement.type === 'function') {
return !illegalTabbableChildNames.includes(reactElement.type.name);
}

/**
* It's possible that the element passes is wrapped with forwardRef, in that case we can
* just check the element.type.render.name as these properties are listed down in the render key.
*/
if (reactElement.type.render) {
return !illegalTabbableChildNames.includes(reactElement.type.render.name);
}

return false;
}

function nextItem(list, item, disableListWrap) {
if (list === item) {
return list.firstChild;
Expand Down Expand Up @@ -259,7 +304,12 @@ const MenuList = React.forwardRef(function MenuList(props, ref) {
if (autoFocusItem) {
newChildProps.autoFocus = true;
}
if (child.props.tabIndex === undefined && variant === 'selectedMenu') {

if (
child.props.tabIndex === undefined &&
variant === 'selectedMenu' &&
isElementTabbableMenuChild(child)
) {
newChildProps.tabIndex = 0;
}

Expand Down

0 comments on commit 00a31cd

Please sign in to comment.