Skip to content

Commit 6f69911

Browse files
committed
feat(material/select): add option to enable inlined overlay
1 parent 3c91ce6 commit 6f69911

File tree

3 files changed

+25
-12
lines changed

3 files changed

+25
-12
lines changed

src/dev-app/select/select-demo.html

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
[class.demo-drinks-width-large]="drinksWidth === '400px'">
1212
<mat-label>Drink</mat-label>
1313
<mat-select [(ngModel)]="currentDrink" [required]="drinksRequired"
14-
[disabled]="drinksDisabled" #drinkControl="ngModel">
14+
[disabled]="drinksDisabled" overlayInlined #drinkControl="ngModel">
1515
<mat-option [disabled]="drinksOptionsDisabled === 'all'">None</mat-option>
1616
@for (drink of drinks; track drink; let index = $index) {
1717
<mat-option [value]="drink.value"
@@ -73,7 +73,7 @@
7373
<mat-card-content>
7474
<mat-form-field [color]="pokemonTheme">
7575
<mat-label>Pokemon</mat-label>
76-
<mat-select multiple [(ngModel)]="currentPokemon"
76+
<mat-select multiple overlayInlined [(ngModel)]="currentPokemon"
7777
[required]="pokemonRequired" [disabled]="pokemonDisabled" #pokemonControl="ngModel">
7878
@for (creature of pokemon; track creature) {
7979
<mat-option [value]="creature.value" [disabled]="pokemonOptionsDisabled">
@@ -108,7 +108,7 @@
108108
<mat-card-content>
109109
<mat-form-field>
110110
<mat-label>Digimon</mat-label>
111-
<mat-select [(value)]="currentDigimon">
111+
<mat-select overlayInlined [(value)]="currentDigimon">
112112
<mat-option>None</mat-option>
113113
@for (creature of digimon; track creature) {
114114
<mat-option [value]="creature.value">{{ creature.viewValue }}</mat-option>
@@ -129,7 +129,7 @@
129129
<mat-card-content>
130130
<mat-form-field>
131131
<mat-label>Pokemon</mat-label>
132-
<mat-select [(ngModel)]="currentPokemonFromGroup">
132+
<mat-select overlayInlined [(ngModel)]="currentPokemonFromGroup">
133133
@for (group of pokemonGroups; track group) {
134134
<mat-optgroup [label]="group.name" [disabled]="group.disabled">
135135
@for (creature of group.pokemon; track creature) {
@@ -151,6 +151,7 @@
151151
<mat-select [(ngModel)]="currentDrinkObject"
152152
[required]="drinkObjectRequired"
153153
[compareWith]="compareByValue ? compareDrinkObjectsByValue : compareByReference"
154+
overlayInlined
154155
#drinkObjectControl="ngModel">
155156
@for (drink of drinks; track drink) {
156157
<mat-option [value]="drink" [disabled]="drink.disabled">{{ drink.viewValue }}</mat-option>
@@ -179,7 +180,7 @@
179180
<p>
180181
<mat-form-field appearance="fill">
181182
<mat-label>Fill</mat-label>
182-
<mat-select [(value)]="currentAppearanceValue">
183+
<mat-select overlayInlined [(value)]="currentAppearanceValue">
183184
<mat-option>None</mat-option>
184185
@for (creature of digimon; track creature) {
185186
<mat-option [value]="creature.value">{{ creature.viewValue }}</mat-option>
@@ -191,7 +192,7 @@
191192
<p>
192193
<mat-form-field appearance="outline">
193194
<mat-label>Outline</mat-label>
194-
<mat-select [(value)]="currentAppearanceValue">
195+
<mat-select overlayInlined [(value)]="currentAppearanceValue">
195196
<mat-option>None</mat-option>
196197
@for (creature of digimon; track creature) {
197198
<mat-option [value]="creature.value">{{ creature.viewValue }}</mat-option>
@@ -212,7 +213,7 @@
212213
<mat-card-content>
213214
<mat-form-field>
214215
<mat-label>Food I would like to eat</mat-label>
215-
<mat-select [formControl]="foodControl">
216+
<mat-select overlayInlined [formControl]="foodControl">
216217
@for (food of foods; track food) {
217218
<mat-option [value]="food.value">{{ food.viewValue }}</mat-option>
218219
}
@@ -238,7 +239,7 @@
238239
<mat-card-content>
239240
<mat-form-field>
240241
<mat-label>Starter pokemon</mat-label>
241-
<mat-select (selectionChange)="latestChangeEvent = $event">
242+
<mat-select overlayInlined (selectionChange)="latestChangeEvent = $event">
242243
@for (creature of pokemon; track creature) {
243244
<mat-option [value]="creature.value">{{ creature.viewValue }}</mat-option>
244245
}
@@ -387,7 +388,7 @@ <h4>Error message with errorStateMatcher</h4>
387388
<p class="demo-narrow-sandwich">
388389
<mat-form-field>
389390
<mat-label>Bread</mat-label>
390-
<mat-select [(ngModel)]="sandwichBread"
391+
<mat-select overlayInlined [(ngModel)]="sandwichBread"
391392
[hideSingleSelectionIndicator]="sandwichHideSingleSelectionIndicator">
392393
@for (bread of breads; track bread) {
393394
<mat-option [value]="bread.value">{{ bread.viewValue }}</mat-option>
@@ -396,7 +397,7 @@ <h4>Error message with errorStateMatcher</h4>
396397
</mat-form-field>
397398
<mat-form-field>
398399
<mat-label>Meat</mat-label>
399-
<mat-select [(ngModel)]="sandwichMeat"
400+
<mat-select overlayInlined [(ngModel)]="sandwichMeat"
400401
[hideSingleSelectionIndicator]="sandwichHideSingleSelectionIndicator">
401402
@for (meat of meats; track meat) {
402403
<mat-option [value]="meat.value">{{ meat.viewValue }}</mat-option>
@@ -405,7 +406,7 @@ <h4>Error message with errorStateMatcher</h4>
405406
</mat-form-field>
406407
<mat-form-field>
407408
<mat-label>Cheese</mat-label>
408-
<mat-select [(ngModel)]="sandwichCheese"
409+
<mat-select overlayInlined [(ngModel)]="sandwichCheese"
409410
[hideSingleSelectionIndicator]="sandwichHideSingleSelectionIndicator">
410411
@for (cheese of cheeses; track cheese) {
411412
<mat-option [value]="cheese.value">{{ cheese.viewValue }}</mat-option>

src/material/select/select.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
[cdkConnectedOverlayPositions]="_positions"
4141
[cdkConnectedOverlayWidth]="_overlayWidth"
4242
[cdkConnectedOverlayFlexibleDimensions]="true"
43+
[cdkConnectedOverlayInsertAfter]="inlineOverlayAfter"
4344
(detach)="close()"
4445
(backdropClick)="close()"
4546
(overlayKeydown)="_handleOverlayKeydown($event)">

src/material/select/select.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ export class MatSelect
346346
_keyManager: ActiveDescendantKeyManager<MatOption>;
347347

348348
/** Ideal origin for the overlay panel. */
349-
_preferredOverlayOrigin: CdkOverlayOrigin | ElementRef | undefined;
349+
_preferredOverlayOrigin: ElementRef | undefined;
350350

351351
/** Width of the overlay panel. */
352352
_overlayWidth: string | number;
@@ -555,6 +555,12 @@ export class MatSelect
555555
@Input({transform: booleanAttribute})
556556
canSelectNullableOptions: boolean = this._defaultOptions?.canSelectNullableOptions ?? false;
557557

558+
/**
559+
* Whether to inline the overlay, instead of using the global overlay container.
560+
*/
561+
@Input({transform: booleanAttribute})
562+
overlayInlined: boolean;
563+
558564
/** Combined stream of all of the child options' change events. */
559565
readonly optionSelectionChanges: Observable<MatOptionSelectionChange> = defer(() => {
560566
const options = this.options;
@@ -948,6 +954,11 @@ export class MatSelect
948954
return this._selectionModel.selected[0].viewValue;
949955
}
950956

957+
/** Whether to inline the overlay and after which element. */
958+
get inlineOverlayAfter(): ElementRef | undefined {
959+
return this.overlayInlined ? this._parentFormField?.getConnectedOverlayOrigin() : undefined;
960+
}
961+
951962
/** Refreshes the error state of the select. */
952963
updateErrorState() {
953964
this._errorStateTracker.updateErrorState();

0 commit comments

Comments
 (0)