Skip to content

Commit

Permalink
fix(select): Fixes width-issue of select option panel in IE (#11801)
Browse files Browse the repository at this point in the history
* fix(select): Fixes width-issue of select option panel in IE11

Fixes the select options panel width not matching the select width in IE11

Fixes #11609

* code cleanup

* fix leave-animation of select panel not working due to angular/angular#23302
  • Loading branch information
macjohnny authored and josephperrott committed Mar 5, 2019
1 parent 3c5e671 commit 81a73c6
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 12 deletions.
10 changes: 9 additions & 1 deletion src/dev-app/select/select-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ <h4>Error message with errorStateMatcher</h4>
<mat-card>
<mat-card-subtitle>ngModel</mat-card-subtitle>

<mat-form-field [floatLabel]="floatLabel" [color]="drinksTheme">
<mat-form-field [floatLabel]="floatLabel" [color]="drinksTheme"
[class.demo-drinks-width-large]="drinksWidth === '400px'">
<mat-label>Drink</mat-label>
<mat-select [(ngModel)]="currentDrink" [required]="drinksRequired"
[disabled]="drinksDisabled" #drinkControl="ngModel">
Expand All @@ -193,6 +194,13 @@ <h4>Error message with errorStateMatcher</h4>
<option value="never">Never</option>
</select>
</p>
<p>
<label for="drinks-width">Width:</label>
<select [(ngModel)]="drinksWidth" id="drinks-width">
<option value="default">Default</option>
<option value="400px">400px</option>
</select>
</p>
<p>
<label for="drinks-theme">Theme:</label>
<select [(ngModel)]="drinksTheme" id="drinks-theme">
Expand Down
4 changes: 4 additions & 0 deletions src/dev-app/select/select-demo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
vertical-align: bottom;
padding-right: 0.25em;
}

.demo-drinks-width-large {
width: 400px;
}
}

.demo-card {
Expand Down
1 change: 1 addition & 0 deletions src/dev-app/select/select-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export class SelectDemo {
currentAppearanceValue: string | null;
latestChangeEvent: MatSelectChange;
floatLabel = 'auto';
drinksWidth = 'default';
foodControl = new FormControl('pizza-1');
topHeightCtrl = new FormControl(0);
drinksTheme = 'primary';
Expand Down
13 changes: 13 additions & 0 deletions src/lib/select/select-animations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

import {
animate,
animateChild,
AnimationTriggerMetadata,
query,
state,
style,
transition,
Expand All @@ -23,9 +25,20 @@ import {
* @docs-private
*/
export const matSelectAnimations: {
readonly transformPanelWrap: AnimationTriggerMetadata;
readonly transformPanel: AnimationTriggerMetadata;
readonly fadeInContent: AnimationTriggerMetadata;
} = {
/**
* This animation ensures the select's overlay panel animation (transformPanel) is called when
* closing the select.
* This is needed due to https://github.com/angular/angular/issues/23302
*/
transformPanelWrap: trigger('transformPanelWrap', [
transition('* => void', query('@transformPanel', [animateChild()],
{optional: true}))
]),

/**
* This animation transforms the select's overlay panel on and off the page.
*
Expand Down
23 changes: 12 additions & 11 deletions src/lib/select/select.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@
(backdropClick)="close()"
(attach)="_onAttached()"
(detach)="close()">

<div
#panel
class="mat-select-panel {{ _getPanelTheme() }}"
[ngClass]="panelClass"
[@transformPanel]="multiple ? 'showing-multiple' : 'showing'"
(@transformPanel.done)="_panelDoneAnimatingStream.next($event.toState)"
[style.transformOrigin]="_transformOrigin"
[style.font-size.px]="_triggerFontSize"
(keydown)="_handleKeydown($event)">
<ng-content></ng-content>
<div class="mat-select-panel-wrap" [@transformPanelWrap]>
<div
#panel
class="mat-select-panel {{ _getPanelTheme() }}"
[ngClass]="panelClass"
[@transformPanel]="multiple ? 'showing-multiple' : 'showing'"
(@transformPanel.done)="_panelDoneAnimatingStream.next($event.toState)"
[style.transformOrigin]="_transformOrigin"
[style.font-size.px]="_triggerFontSize"
(keydown)="_handleKeydown($event)">
<ng-content></ng-content>
</div>
</div>
</ng-template>
6 changes: 6 additions & 0 deletions src/lib/select/select.scss
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ $mat-select-placeholder-arrow-space: 2 * ($mat-select-arrow-size + $mat-select-a
margin: 0 $mat-select-arrow-margin;
}

.mat-select-panel-wrap {
// Prevents width-issues of mat-select-panel with width: calc(100% + 32px)
// in IE11 due to the parents display: flex;
flex-basis: 100%;
}

.mat-select-panel {
@include mat-menu-base();
padding-top: 0;
Expand Down
24 changes: 24 additions & 0 deletions src/lib/select/select.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,29 @@ describe('MatSelect', () => {

const pane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
expect(pane.style.minWidth).toBe('200px');

const scrollContainer = document.querySelector('.cdk-overlay-pane .mat-select-panel');
const scrollContainerWidth = scrollContainer!.getBoundingClientRect().width;
expect(scrollContainerWidth).toBeCloseTo(200 + 32, 0,
'Expected select panel width to be 100% + 32px of the select field trigger');
}));

it('should set the width of the overlay based on a larger trigger width',
fakeAsync(() => {
// the trigger width exceeds the minimum width of the mat-select-panel
trigger.style.width = '400px';

trigger.click();
fixture.detectChanges();
flush();

const pane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
expect(pane.style.minWidth).toBe('400px');

const scrollContainer = document.querySelector('.cdk-overlay-pane .mat-select-panel');
const scrollContainerWidth = scrollContainer!.getBoundingClientRect().width;
expect(scrollContainerWidth).toBeCloseTo(400 + 32, 0,
'Expected select panel width to be 100% + 32px of the select field trigger');
}));

it('should not attempt to open a select that does not have any options', fakeAsync(() => {
Expand Down Expand Up @@ -3110,6 +3133,7 @@ describe('MatSelect', () => {

checkTriggerAlignedWithOption(7, groupFixture.componentInstance.select);
}));

});

describe('limited space to open vertically', () => {
Expand Down
1 change: 1 addition & 0 deletions src/lib/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ export class MatSelectTrigger {}
'(blur)': '_onBlur()',
},
animations: [
matSelectAnimations.transformPanelWrap,
matSelectAnimations.transformPanel
],
providers: [
Expand Down

0 comments on commit 81a73c6

Please sign in to comment.