Skip to content

Commit 7baf780

Browse files
committed
fix(autocomplete): top option group not scrolled into view when going up
Fixes the case where the user won't be able to see the top option group when reaching the first option via the arrow keys.
1 parent 6a7fc81 commit 7baf780

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

src/material/autocomplete/autocomplete-trigger.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -481,14 +481,21 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnChanges,
481481
const labelCount = _countGroupLabelsBeforeOption(index,
482482
this.autocomplete.options, this.autocomplete.optionGroups);
483483

484-
const newScrollPosition = _getOptionScrollPosition(
485-
index + labelCount,
486-
AUTOCOMPLETE_OPTION_HEIGHT,
487-
this.autocomplete._getScrollTop(),
488-
AUTOCOMPLETE_PANEL_HEIGHT
489-
);
490-
491-
this.autocomplete._setScrollTop(newScrollPosition);
484+
if (index === 0 && labelCount === 1) {
485+
// If we've got one group label before the option and we're at the top option,
486+
// scroll the list to the top. This is better UX than scrolling the list to the
487+
// top of the option, because it allows the user to read the top group's label.
488+
this.autocomplete._setScrollTop(0);
489+
} else {
490+
const newScrollPosition = _getOptionScrollPosition(
491+
index + labelCount,
492+
AUTOCOMPLETE_OPTION_HEIGHT,
493+
this.autocomplete._getScrollTop(),
494+
AUTOCOMPLETE_PANEL_HEIGHT
495+
);
496+
497+
this.autocomplete._setScrollTop(newScrollPosition);
498+
}
492499
}
493500

494501
/**

src/material/autocomplete/autocomplete.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,28 @@ describe('MatAutocomplete', () => {
12721272
expect(container.scrollTop)
12731273
.toBe(96, 'Expected panel to scroll up when option is above panel.');
12741274
}));
1275+
1276+
it('should scroll back to the top when reaching the first option with preceding group label',
1277+
fakeAsync(() => {
1278+
fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT);
1279+
tick();
1280+
fixture.detectChanges();
1281+
expect(container.scrollTop).toBe(0, 'Expected the panel not to scroll.');
1282+
1283+
// Press the down arrow five times.
1284+
[1, 2, 3, 4, 5].forEach(() => {
1285+
fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT);
1286+
tick();
1287+
});
1288+
1289+
// Press the up arrow five times.
1290+
[1, 2, 3, 4, 5].forEach(() => {
1291+
fixture.componentInstance.trigger._handleKeydown(UP_ARROW_EVENT);
1292+
tick();
1293+
});
1294+
1295+
expect(container.scrollTop).toBe(0, 'Expected panel to be scrolled to the top.');
1296+
}));
12751297
});
12761298

12771299
describe('aria', () => {

0 commit comments

Comments
 (0)