Skip to content

Commit 4757d2d

Browse files
committed
fix(menu): align appearance with spec
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 angular#3814.
1 parent b00f838 commit 4757d2d

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
@@ -20,6 +20,7 @@ import {
2020
ViewEncapsulation,
2121
ElementRef,
2222
} from '@angular/core';
23+
import {AnimationEvent} from '@angular/animations';
2324
import {MenuPositionX, MenuPositionY} from './menu-positions';
2425
import {throwMdMenuInvalidPositionX, throwMdMenuInvalidPositionY} from './menu-errors';
2526
import {MdMenuItem} from './menu-item';
@@ -53,6 +54,9 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
5354
/** Config object to be passed into the menu's ngClass */
5455
_classList: any = {};
5556

57+
/** Current state of the panel animation. */
58+
_panelAnimationState: 'void' | 'enter-start' | 'enter' = 'void';
59+
5660
/** Position of the menu in the X axis. */
5761
@Input()
5862
get xPosition() { return this._xPosition; }
@@ -156,4 +160,21 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
156160
this._classList['mat-menu-below'] = posY === 'below';
157161
}
158162

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

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
@@ -118,7 +118,7 @@ $mat-select-panel-max-height: 256px !default;
118118
}
119119

120120
.mat-select-panel {
121-
@include mat-menu-base();
121+
@include mat-menu-base(8);
122122
padding-top: 0;
123123
padding-bottom: 0;
124124
max-height: $mat-select-panel-max-height;

0 commit comments

Comments
 (0)