Skip to content

Commit eb747f0

Browse files
While navigating context menu via keyboard, skip disabled items
1 parent 69fbda1 commit eb747f0

File tree

1 file changed

+42
-13
lines changed

1 file changed

+42
-13
lines changed

src/AbstractMenu.js

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ export default class AbstractMenu extends Component {
7979
selectChildren = (forward) => {
8080
const { selectedItem } = this.state;
8181
const children = [];
82-
const childCollector = (child) => {
82+
let disabledChildrenCount = 0;
83+
let disabledChildIndexes = {};
84+
85+
const childCollector = (child, index) => {
8386
// child can be empty in case you do conditional rendering of components, in which
8487
// case it should not be accounted for as a real child
8588
if (!child) {
@@ -90,24 +93,50 @@ export default class AbstractMenu extends Component {
9093
// Maybe the MenuItem or SubMenu is capsuled in a wrapper div or something else
9194
React.Children.forEach(child.props.children, childCollector);
9295
} else if (!child.props.divider) {
96+
if (child.props.disabled) {
97+
++disabledChildrenCount;
98+
disabledChildIndexes[index] = true;
99+
}
100+
93101
children.push(child);
94102
}
95103
};
104+
96105
React.Children.forEach(this.props.children, childCollector);
106+
if (disabledChildrenCount === children.length) {
107+
// All menu items are disabled, so none can be selected, don't do anything
108+
return;
109+
}
110+
111+
function findNextEnabledChildIndex(currentIndex) {
112+
let i = currentIndex;
113+
let incrementCounter = () => {
114+
if (forward) {
115+
--i;
116+
} else {
117+
++i;
118+
}
119+
120+
if (i < 0) {
121+
i = children.length - 1;
122+
} else if (i >= children.length) {
123+
i = 0;
124+
}
125+
};
126+
127+
do {
128+
incrementCounter();
129+
} while (i !== currentIndex && disabledChildIndexes[i]);
130+
131+
return i === currentIndex ? null : i;
132+
}
133+
97134
const currentIndex = children.indexOf(selectedItem);
98-
if (currentIndex < 0) {
99-
this.setState({
100-
selectedItem: forward ? children[children.length - 1] : children[0],
101-
forceSubMenuOpen: false
102-
});
103-
} else if (forward) {
104-
this.setState({
105-
selectedItem: children[currentIndex - 1 < 0 ? children.length - 1 : currentIndex - 1],
106-
forceSubMenuOpen: false
107-
});
108-
} else {
135+
const nextEnabledChildIndex = findNextEnabledChildIndex(currentIndex);
136+
137+
if (nextEnabledChildIndex !== null) {
109138
this.setState({
110-
selectedItem: children[currentIndex + 1 < children.length ? currentIndex + 1 : 0],
139+
selectedItem: children[nextEnabledChildIndex],
111140
forceSubMenuOpen: false
112141
});
113142
}

0 commit comments

Comments
 (0)