Skip to content

Commit c20bec8

Browse files
crisbetojelbourn
authored andcommitted
fix(menu): align appearance with spec (#5361)
Aligns the menu panel appearance with [the spec](https://material.io/guidelines/components/menus.html) by: * Reducing the elevation from 8 to 3. * Adding a slight border radius. * Tweaking the animation to match the examples. Relates to #3814.
1 parent 78f0cec commit c20bec8

File tree

9 files changed

+61
-22
lines changed

9 files changed

+61
-22
lines changed

src/lib/autocomplete/autocomplete.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ $mat-autocomplete-panel-below-offset: 6px !default;
1313
$mat-autocomplete-panel-above-offset: -24px !default;
1414

1515
.mat-autocomplete-panel {
16-
@include mat-menu-base();
16+
@include mat-menu-base(8);
1717
visibility: hidden;
18-
18+
1919
max-width: none;
2020
max-height: $mat-autocomplete-panel-max-height;
2121
position: relative;

src/lib/core/style/_menu-common.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ $mat-menu-side-padding: 16px !default;
1313
$mat-menu-icon-margin: 16px !default;
1414

1515

16-
@mixin mat-menu-base() {
17-
@include mat-elevation(8);
16+
@mixin mat-menu-base($elevation) {
17+
@include mat-elevation($elevation);
1818
min-width: $mat-menu-overlay-min-width;
1919
max-width: $mat-menu-overlay-max-width;
2020

src/lib/menu/_menu-theme.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
$background: map-get($theme, background);
88
$foreground: map-get($theme, foreground);
99

10-
.mat-menu-content {
10+
.mat-menu-panel {
1111
background: mat-color($background, 'card');
1212
}
1313

src/lib/menu/menu-animations.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,23 @@ import{
3232

3333
// TODO(kara): switch to :enter and :leave once Mobile Safari is sorted out.
3434
export const transformMenu: AnimationTriggerMetadata = trigger('transformMenu', [
35-
state('showing', style({
35+
state('void', style({
36+
opacity: 0,
37+
transform: 'scale(0, 0)'
38+
})),
39+
state('enter-start', style({
3640
opacity: 1,
37-
transform: `scale(1)`
41+
transform: `scale(1, 0.5)`
3842
})),
39-
transition('void => *', [
40-
style({
41-
opacity: 0,
42-
transform: `scale(0)`
43-
}),
44-
animate(`200ms cubic-bezier(0.25, 0.8, 0.25, 1)`)
45-
]),
46-
transition('* => void', [
47-
animate('50ms 100ms linear', style({opacity: 0}))
48-
])
43+
state('enter', style({
44+
transform: 'scale(1, 1)'
45+
})),
46+
transition('void => enter-start', animate('100ms linear')),
47+
transition('enter-start => enter', animate('300ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
48+
transition('* => void', animate('150ms 50ms linear', style({opacity: 0})))
4949
]);
5050

51+
5152
/**
5253
* This animation fades in the background color and content of the menu panel
5354
* after its containing element is scaled in.
@@ -56,6 +57,6 @@ export const fadeInItems: AnimationTriggerMetadata = trigger('fadeInItems', [
5657
state('showing', style({opacity: 1})),
5758
transition('void => *', [
5859
style({opacity: 0}),
59-
animate(`200ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)`)
60+
animate(`400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)`)
6061
])
6162
]);

src/lib/menu/menu-directive.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
ElementRef,
2222
ChangeDetectionStrategy,
2323
} from '@angular/core';
24+
import {AnimationEvent} from '@angular/animations';
2425
import {MenuPositionX, MenuPositionY} from './menu-positions';
2526
import {throwMdMenuInvalidPositionX, throwMdMenuInvalidPositionY} from './menu-errors';
2627
import {MdMenuItem} from './menu-item';
@@ -55,6 +56,9 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
5556
/** Config object to be passed into the menu's ngClass */
5657
_classList: any = {};
5758

59+
/** Current state of the panel animation. */
60+
_panelAnimationState: 'void' | 'enter-start' | 'enter' = 'void';
61+
5862
/** Position of the menu in the X axis. */
5963
@Input()
6064
get xPosition() { return this._xPosition; }
@@ -161,4 +165,21 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
161165
this._classList['mat-menu-below'] = posY === 'below';
162166
}
163167

168+
/** Starts the enter animation. */
169+
_startAnimation() {
170+
this._panelAnimationState = 'enter-start';
171+
}
172+
173+
/** Resets the panel animation to its initial state. */
174+
_resetAnimation() {
175+
this._panelAnimationState = 'void';
176+
}
177+
178+
/** Callback that is invoked when the panel animation completes. */
179+
_onAnimationDone(event: AnimationEvent) {
180+
// After the initial expansion is done, trigger the second phase of the enter animation.
181+
if (event.toState === 'enter-start') {
182+
this._panelAnimationState = 'enter';
183+
}
184+
}
164185
}

src/lib/menu/menu-trigger.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
} from '../core';
3434
import {Subscription} from 'rxjs/Subscription';
3535
import {MenuPositionX, MenuPositionY} from './menu-positions';
36+
import {MdMenu} from './menu-directive';
3637

3738
// TODO(andrewseguin): Remove the kebab versions in favor of camelCased attribute selectors
3839

@@ -110,6 +111,10 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
110111
this._createOverlay().attach(this._portal);
111112
this._subscribeToBackdrop();
112113
this._initMenu();
114+
115+
if (this.menu instanceof MdMenu) {
116+
this.menu._startAnimation();
117+
}
113118
}
114119
}
115120

@@ -119,6 +124,10 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
119124
this._overlayRef.detach();
120125
this._backdropSubscription.unsubscribe();
121126
this._resetMenu();
127+
128+
if (this.menu instanceof MdMenu) {
129+
this.menu._resetAnimation();
130+
}
122131
}
123132
}
124133

src/lib/menu/menu.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
<ng-template>
2-
<div class="mat-menu-panel" [ngClass]="_classList" (keydown)="_handleKeydown($event)"
3-
(click)="_emitCloseEvent()" [@transformMenu]="'showing'" role="menu">
2+
<div
3+
class="mat-menu-panel"
4+
[ngClass]="_classList"
5+
(keydown)="_handleKeydown($event)"
6+
(click)="_emitCloseEvent()"
7+
[@transformMenu]="_panelAnimationState"
8+
(@transformMenu.done)="_onAnimationDone($event)"
9+
role="menu">
410
<div class="mat-menu-content" [@fadeInItems]="'showing'">
511
<ng-content></ng-content>
612
</div>

src/lib/menu/menu.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
@import '../core/a11y/a11y';
88

99
$mat-menu-vertical-padding: 8px !default;
10+
$mat-menu-border-radius: 2px !default;
1011

1112
.mat-menu-panel {
12-
@include mat-menu-base();
13+
@include mat-menu-base(2);
1314
@include mat-menu-positions();
1415
max-height: calc(100vh - #{$mat-menu-item-height});
16+
border-radius: $mat-menu-border-radius;
1517

1618
@include cdk-high-contrast {
1719
outline: solid 1px;

src/lib/select/select.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ $mat-select-trigger-underline-height: 1px !default;
123123
}
124124

125125
.mat-select-panel {
126-
@include mat-menu-base();
126+
@include mat-menu-base(8);
127127
padding-top: 0;
128128
padding-bottom: 0;
129129
max-height: $mat-select-panel-max-height;

0 commit comments

Comments
 (0)