Skip to content

Commit 50ec408

Browse files
authored
fix(Dropdown): compute proper selectedIndex in multiple (#4006)
1 parent 28eee26 commit 50ec408

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

src/modules/Dropdown/utils/getSelectedIndex.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default function getSelectedIndex(config) {
2727
multiple,
2828
search,
2929
})
30-
const enabledIndicies = _.reduce(
30+
const enabledIndexes = _.reduce(
3131
menuOptions,
3232
(memo, item, index) => {
3333
if (!item.disabled) memo.push(index)
@@ -40,30 +40,32 @@ export default function getSelectedIndex(config) {
4040

4141
// update the selected index
4242
if (!selectedIndex || selectedIndex < 0) {
43-
const firstIndex = enabledIndicies[0]
43+
const firstIndex = enabledIndexes[0]
4444

4545
// Select the currently active item, if none, use the first item.
4646
// Multiple selects remove active items from the list,
4747
// their initial selected index should be 0.
4848
newSelectedIndex = multiple
4949
? firstIndex
50-
: _.findIndex(menuOptions, ['value', value]) || enabledIndicies[0]
50+
: _.findIndex(menuOptions, ['value', value]) || enabledIndexes[0]
5151
} else if (multiple) {
52+
newSelectedIndex = _.find(enabledIndexes, (index) => index >= selectedIndex)
53+
5254
// multiple selects remove options from the menu as they are made active
5355
// keep the selected index within range of the remaining items
5456
if (selectedIndex >= menuOptions.length - 1) {
55-
newSelectedIndex = enabledIndicies[enabledIndicies.length - 1]
57+
newSelectedIndex = enabledIndexes[enabledIndexes.length - 1]
5658
}
5759
} else {
5860
const activeIndex = _.findIndex(menuOptions, ['value', value])
5961

6062
// regular selects can only have one active item
6163
// set the selected index to the currently active item
62-
newSelectedIndex = _.includes(enabledIndicies, activeIndex) ? activeIndex : undefined
64+
newSelectedIndex = _.includes(enabledIndexes, activeIndex) ? activeIndex : undefined
6365
}
6466

6567
if (!newSelectedIndex || newSelectedIndex < 0) {
66-
newSelectedIndex = enabledIndicies[0]
68+
newSelectedIndex = enabledIndexes[0]
6769
}
6870

6971
return newSelectedIndex

test/specs/modules/Dropdown/Dropdown-test.js

+31
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,37 @@ describe('Dropdown', () => {
15211521
wrapper.should.have.exactly(options.length - 1).descendants('DropdownItem')
15221522
wrapper.find('DropdownItem').last().should.have.prop('selected', true)
15231523
})
1524+
it('keeps the selection on the same index', () => {
1525+
wrapperMount(<Dropdown options={options} selection multiple />)
1526+
1527+
wrapper.simulate('click')
1528+
dropdownMenuIsOpen()
1529+
1530+
wrapper.simulate('keydown', { key: 'ArrowDown' })
1531+
wrapper.find('DropdownItem').at(1).should.have.prop('selected', true)
1532+
1533+
wrapper.simulate('keydown', { key: 'Enter' })
1534+
wrapper.find('DropdownItem').at(1).should.have.prop('selected', true)
1535+
})
1536+
it('skips disabled items in selection', () => {
1537+
const testOptions = [
1538+
{ value: 'foo', key: 'foo', text: 'foo' },
1539+
{ value: 'bar', key: 'bar', text: 'bar' },
1540+
{ value: 'baz', key: 'baz', text: 'baz', disabled: true },
1541+
{ value: 'qux', key: 'qux', text: 'qux' },
1542+
]
1543+
1544+
wrapperMount(<Dropdown options={testOptions} selection multiple />)
1545+
1546+
wrapper.simulate('click')
1547+
dropdownMenuIsOpen()
1548+
1549+
wrapper.simulate('keydown', { key: 'ArrowDown' })
1550+
wrapper.find('DropdownItem').at(1).should.have.prop('selected', true)
1551+
1552+
wrapper.simulate('keydown', { key: 'Enter' })
1553+
wrapper.find('DropdownItem').at(2).should.have.prop('selected', true)
1554+
})
15241555
it('has labels with delete icons', () => {
15251556
// add a value so we have a label
15261557
const value = [_.head(options).value]

0 commit comments

Comments
 (0)