@@ -9,13 +9,25 @@ import {ConnectedPositionStrategy} from '../core/overlay/position/connected-posi
99import { Observable } from 'rxjs/Observable' ;
1010import { MdOptionSelectEvent , MdOption } from '../core/option/option' ;
1111import { ActiveDescendantKeyManager } from '../core/a11y/activedescendant-key-manager' ;
12- import { ENTER } from '../core/keyboard/keycodes' ;
12+ import { ENTER , UP_ARROW , DOWN_ARROW } from '../core/keyboard/keycodes' ;
1313import { Subscription } from 'rxjs/Subscription' ;
1414import 'rxjs/add/observable/merge' ;
1515import { Dir } from '../core/rtl/dir' ;
1616import 'rxjs/add/operator/startWith' ;
1717import 'rxjs/add/operator/switchMap' ;
1818
19+ /**
20+ * The following style constants are necessary to save here in order
21+ * to properly calculate the scrollTop of the panel. Because we are not
22+ * actually focusing the active item, scroll must be handled manually.
23+ */
24+
25+ /** The height of each autocomplete option. */
26+ export const AUTOCOMPLETE_OPTION_HEIGHT = 48 ;
27+
28+ /** The total height of the autocomplete panel. */
29+ export const AUTOCOMPLETE_PANEL_HEIGHT = 256 ;
30+
1931@Directive ( {
2032 selector : 'input[mdAutocomplete], input[matAutocomplete]' ,
2133 host : {
@@ -117,9 +129,25 @@ export class MdAutocompleteTrigger implements AfterContentInit, OnDestroy {
117129 } else {
118130 this . openPanel ( ) ;
119131 this . _keyManager . onKeydown ( event ) ;
132+ if ( event . keyCode === UP_ARROW || event . keyCode === DOWN_ARROW ) {
133+ this . _scrollToOption ( ) ;
134+ }
120135 }
121136 }
122137
138+ /**
139+ * Given that we are not actually focusing active options, we must manually adjust scroll
140+ * to reveal options below the fold. First, we find the offset of the option from the top
141+ * of the panel. The new scrollTop will be that offset - the panel height + the option
142+ * height, so the active option will be just visible at the bottom of the panel.
143+ */
144+ private _scrollToOption ( ) : void {
145+ const optionOffset = this . _keyManager . activeItemIndex * AUTOCOMPLETE_OPTION_HEIGHT ;
146+ const newScrollTop =
147+ Math . max ( 0 , optionOffset - AUTOCOMPLETE_PANEL_HEIGHT + AUTOCOMPLETE_OPTION_HEIGHT ) ;
148+ this . autocomplete . _setScrollTop ( newScrollTop ) ;
149+ }
150+
123151 /**
124152 * This method listens to a stream of panel closing actions and resets the
125153 * stream every time the option list changes.
0 commit comments