Skip to content

Commit 38b5d23

Browse files
fix(material/select): close panel on detach output event
1 parent 443df26 commit 38b5d23

File tree

2 files changed

+56
-14
lines changed

2 files changed

+56
-14
lines changed

src/material/select/select.html

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
<div cdk-overlay-origin
2-
class="mat-mdc-select-trigger"
3-
(click)="open()"
4-
#fallbackOverlayOrigin="cdkOverlayOrigin"
5-
#trigger>
6-
1+
<div
2+
cdk-overlay-origin
3+
class="mat-mdc-select-trigger"
4+
(click)="open()"
5+
#fallbackOverlayOrigin="cdkOverlayOrigin"
6+
#trigger
7+
>
78
<div class="mat-mdc-select-value" [attr.id]="_valueId">
89
@if (empty) {
910
<span class="mat-mdc-select-placeholder mat-mdc-select-min-line">{{placeholder}}</span>
@@ -22,7 +23,7 @@
2223
<div class="mat-mdc-select-arrow">
2324
<!-- Use an inline SVG, because it works better than a CSS triangle in high contrast mode. -->
2425
<svg viewBox="0 0 24 24" width="24px" height="24px" focusable="false" aria-hidden="true">
25-
<path d="M7 10l5 5 5-5z"/>
26+
<path d="M7 10l5 5 5-5z" />
2627
</svg>
2728
</div>
2829
</div>
@@ -40,8 +41,10 @@
4041
[cdkConnectedOverlayPositions]="_positions"
4142
[cdkConnectedOverlayWidth]="_overlayWidth"
4243
[cdkConnectedOverlayFlexibleDimensions]="true"
44+
(detach)="close()"
4345
(backdropClick)="close()"
44-
(overlayKeydown)="_handleOverlayKeydown($event)">
46+
(overlayKeydown)="_handleOverlayKeydown($event)"
47+
>
4548
<div
4649
#panel
4750
role="listbox"
@@ -53,7 +56,8 @@
5356
[attr.aria-label]="ariaLabel || null"
5457
[attr.aria-labelledby]="_getPanelAriaLabelledby()"
5558
[ngClass]="panelClass"
56-
(keydown)="_handleKeydown($event)">
59+
(keydown)="_handleKeydown($event)"
60+
>
5761
<ng-content></ng-content>
5862
</div>
5963
</ng-template>

src/material/select/select.spec.ts

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
TAB,
1616
UP_ARROW,
1717
} from '@angular/cdk/keycodes';
18-
import {OverlayContainer, OverlayModule} from '@angular/cdk/overlay';
18+
import {CloseScrollStrategy, Overlay, OverlayContainer, OverlayModule} from '@angular/cdk/overlay';
1919
import {ScrollDispatcher} from '@angular/cdk/scrolling';
2020
import {
2121
createKeyboardEvent,
@@ -56,15 +56,15 @@ import {
5656
ReactiveFormsModule,
5757
Validators,
5858
} from '@angular/forms';
59-
import {ErrorStateMatcher, MatOption, MatOptionSelectionChange} from '../core';
60-
import {FloatLabelType, MAT_FORM_FIELD_DEFAULT_OPTIONS, MatFormFieldModule} from '../form-field';
61-
import {MAT_SELECT_CONFIG, MatSelectConfig} from '../select';
6259
import {By} from '@angular/platform-browser';
6360
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
6461
import {EMPTY, Observable, Subject, Subscription} from 'rxjs';
6562
import {map} from 'rxjs/operators';
63+
import {ErrorStateMatcher, MatOption, MatOptionSelectionChange} from '../core';
64+
import {FloatLabelType, MAT_FORM_FIELD_DEFAULT_OPTIONS, MatFormFieldModule} from '../form-field';
65+
import {MAT_SELECT_CONFIG, MatSelectConfig} from '../select';
6666
import {MatSelectModule} from './index';
67-
import {MatSelect} from './select';
67+
import {MAT_SELECT_SCROLL_STRATEGY, MatSelect} from './select';
6868
import {
6969
getMatSelectDynamicMultipleError,
7070
getMatSelectNonArrayValueError,
@@ -1782,6 +1782,44 @@ describe('MatSelect', () => {
17821782
.withContext('Expected select element to remain focused.')
17831783
.toBe(true);
17841784
}));
1785+
1786+
it('should close the panel on scroll event when MAT_SELECT_SCROLL_STRATEGY token was defined with CloseScrollStrategy', fakeAsync(() => {
1787+
// Need to recreate the testing module, because the issue we're
1788+
// testing for only the MAT_SELECT_SCROLL_STRATEGY is defined with thw
1789+
// is defined with the CloseScrollStrategy
1790+
1791+
TestBed.resetTestingModule();
1792+
TestBed.configureTestingModule({
1793+
imports: [MatFormFieldModule, MatSelectModule],
1794+
declarations: [BasicSelect],
1795+
providers: [
1796+
{
1797+
provide: MAT_SELECT_SCROLL_STRATEGY,
1798+
useFactory: (overlay: Overlay) => (): CloseScrollStrategy =>
1799+
overlay.scrollStrategies.close(),
1800+
deps: [Overlay],
1801+
},
1802+
{
1803+
provide: ScrollDispatcher,
1804+
useFactory: () => ({
1805+
scrolled: () => scrolledSubject,
1806+
}),
1807+
},
1808+
],
1809+
});
1810+
1811+
fixture = TestBed.createComponent(BasicSelect);
1812+
fixture.detectChanges();
1813+
1814+
const select = fixture.componentInstance.select;
1815+
select.open();
1816+
1817+
scrolledSubject.next();
1818+
fixture.detectChanges();
1819+
flush();
1820+
1821+
expect(select.panelOpen).toBe(false);
1822+
}));
17851823
});
17861824

17871825
describe('selection logic', () => {

0 commit comments

Comments
 (0)