Skip to content

fix(select): Fixes width-issue of select option panel in IE #11801

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -82,6 +82,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 @@ -982,6 +982,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 @@ -3070,6 +3093,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