Skip to content

Commit 37a7080

Browse files
crisbetojelbourn
authored andcommittedDec 19, 2018
fix(menu): scroll position jumping to top after animation is done on scrollable menu (#14190)
Originally in #11859 we introduced some logic that makes sure that the menu panel is always scrolled to the top when it's open. This works, but is janky, because the user can see the menu being scrolled down while it's animating. These changes move the logic, that reset the scroll position, from the `done` callback to `start`. Fixes #11790.
1 parent 7ce7797 commit 37a7080

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed
 

‎src/lib/menu/menu-directive.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,17 @@ export class MatMenu implements AfterContentInit, MatMenuPanel<MatMenuItem>, OnI
384384
_onAnimationDone(event: AnimationEvent) {
385385
this._animationDone.next(event);
386386
this._isAnimating = false;
387+
}
388+
389+
_onAnimationStart(event: AnimationEvent) {
390+
this._isAnimating = true;
387391

388-
// Scroll the content element to the top once the animation is done. This is necessary, because
389-
// we move focus to the first item while it's still being animated, which can throw the browser
390-
// off when it determines the scroll position. Alternatively we can move focus when the
391-
// animation is done, however moving focus asynchronously will interrupt screen readers
392-
// which are in the process of reading out the menu already. We take the `element` from
393-
// the `event` since we can't use a `ViewChild` to access the pane.
392+
// Scroll the content element to the top as soon as the animation starts. This is necessary,
393+
// because we move focus to the first item while it's still being animated, which can throw
394+
// the browser off when it determines the scroll position. Alternatively we can move focus
395+
// when the animation is done, however moving focus asynchronously will interrupt screen
396+
// readers which are in the process of reading out the menu already. We take the `element`
397+
// from the `event` since we can't use a `ViewChild` to access the pane.
394398
if (event.toState === 'enter' && this._keyManager.activeItemIndex === 0) {
395399
event.element.scrollTop = 0;
396400
}

‎src/lib/menu/menu.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
(keydown)="_handleKeydown($event)"
66
(click)="closed.emit('click')"
77
[@transformMenu]="_panelAnimationState"
8-
(@transformMenu.start)="_isAnimating = true"
8+
(@transformMenu.start)="_onAnimationStart($event)"
99
(@transformMenu.done)="_onAnimationDone($event)"
1010
tabindex="-1"
1111
role="menu">

0 commit comments

Comments
 (0)
Please sign in to comment.