Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Autocomplete] Fix option grouping (#19109)
Browse files Browse the repository at this point in the history
liangchunn committed Jan 7, 2020
1 parent c99bd0d commit d490f77
Showing 2 changed files with 49 additions and 10 deletions.
27 changes: 27 additions & 0 deletions packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
Original file line number Diff line number Diff line change
@@ -955,4 +955,31 @@ describe('<Autocomplete />', () => {
expect(options).to.have.length(3);
});
});

describe('prop: groupBy', () => {
it('correctly groups options and preserves option order in each group', () => {
const data = [
{ group: 1, value: 'A' },
{ group: 2, value: 'D' },
{ group: 2, value: 'E' },
{ group: 1, value: 'B' },
{ group: 3, value: 'G' },
{ group: 2, value: 'F' },
{ group: 1, value: 'C' },
];
const { getAllByRole } = render(
<Autocomplete
options={data}
getOptionLabel={option => option.value}
renderInput={params => <TextField {...params} autoFocus />}
open
groupBy={option => option.group}
/>,
);

const options = getAllByRole('option').map(el => el.textContent);
expect(options).to.have.length(7);
expect(options).to.deep.equal(['A', 'B', 'C', 'D', 'E', 'F', 'G']);
});
});
});
32 changes: 22 additions & 10 deletions packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
@@ -782,21 +782,33 @@ export default function useAutocomplete(props) {

let groupedOptions = filteredOptions;
if (groupBy) {
groupedOptions = filteredOptions.reduce((acc, option, index) => {
const key = groupBy(option);
const result = [];

if (acc.length > 0 && acc[acc.length - 1].key === key) {
acc[acc.length - 1].options.push(option);
} else {
acc.push({
// used to keep track of key and indexes in the result array
const indexByKey = new Map();
let currentResultIndex = 0;

filteredOptions.forEach(option => {
const key = groupBy(option);
if (indexByKey.get(key) === undefined) {
indexByKey.set(key, currentResultIndex);
result.push({
key,
index,
options: [option],
options: [],
});
currentResultIndex += 1;
}
result[indexByKey.get(key)].options.push(option);
});

// now we can add the `index` property based on the options length
let indexCounter = 0;
result.forEach(option => {
option.index = indexCounter;
indexCounter += option.options.length;
});

return acc;
}, []);
groupedOptions = result;
}

return {

0 comments on commit d490f77

Please sign in to comment.