diff --git a/src/dev-app/select/select-demo.html b/src/dev-app/select/select-demo.html index 9b7061c9d63d..abc808b618cd 100644 --- a/src/dev-app/select/select-demo.html +++ b/src/dev-app/select/select-demo.html @@ -168,7 +168,8 @@
+ Width: + + Default + 400px + +
Theme: diff --git a/src/dev-app/select/select-demo.scss b/src/dev-app/select/select-demo.scss index 996f1e1411ff..bdd018625297 100644 --- a/src/dev-app/select/select-demo.scss +++ b/src/dev-app/select/select-demo.scss @@ -11,6 +11,10 @@ vertical-align: bottom; padding-right: 0.25em; } + + .demo-drinks-width-large { + width: 400px; + } } .demo-card { diff --git a/src/dev-app/select/select-demo.ts b/src/dev-app/select/select-demo.ts index dabde38fca54..de7d21a1eff3 100644 --- a/src/dev-app/select/select-demo.ts +++ b/src/dev-app/select/select-demo.ts @@ -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'; diff --git a/src/lib/select/select-animations.ts b/src/lib/select/select-animations.ts index 4327e62e05a3..a7c3337a2ebe 100644 --- a/src/lib/select/select-animations.ts +++ b/src/lib/select/select-animations.ts @@ -8,7 +8,9 @@ import { animate, + animateChild, AnimationTriggerMetadata, + query, state, style, transition, @@ -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. * diff --git a/src/lib/select/select.html b/src/lib/select/select.html index b0d9f65e3613..bd0a4522c612 100644 --- a/src/lib/select/select.html +++ b/src/lib/select/select.html @@ -29,16 +29,17 @@ (backdropClick)="close()" (attach)="_onAttached()" (detach)="close()"> - - - + + + + diff --git a/src/lib/select/select.scss b/src/lib/select/select.scss index fcf98c9261db..ef021f3cac73 100644 --- a/src/lib/select/select.scss +++ b/src/lib/select/select.scss @@ -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; diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts index 3d01e8ae59ea..301d8026288a 100644 --- a/src/lib/select/select.spec.ts +++ b/src/lib/select/select.spec.ts @@ -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(() => { @@ -3110,6 +3133,7 @@ describe('MatSelect', () => { checkTriggerAlignedWithOption(7, groupFixture.componentInstance.select); })); + }); describe('limited space to open vertically', () => { diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index fca5c8a4a2bc..0126e617417f 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -216,6 +216,7 @@ export class MatSelectTrigger {} '(blur)': '_onBlur()', }, animations: [ + matSelectAnimations.transformPanelWrap, matSelectAnimations.transformPanel ], providers: [