Skip to content

Commit 58f3c54

Browse files
seritoolsjelbourn
authored andcommitted
fix(select): arrow position/animation for appearance="standard" (#12045)
This commit aims to fix the arrow positioning of mat-selects with appearance="standard". Since the label moves down whenever the selected value is empty, the arrow looks out of place. I added an animation that matches the speed of the label animation: Going from filled to empty transitions the arrow down so that it sits level with the label. Going from empty to filled snaps the arrow back up, matching the label's behavior.
1 parent 592af48 commit 58f3c54

File tree

4 files changed

+79
-3
lines changed

4 files changed

+79
-3
lines changed

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,61 @@
144144
</mat-card-content>
145145
</mat-card>
146146

147+
<mat-card>
148+
<mat-card-subtitle>Appearance comparison</mat-card-subtitle>
149+
<mat-card-content>
150+
<p>
151+
<mat-form-field>
152+
<mat-label>Legacy</mat-label>
153+
<mat-select [(value)]="currentAppearanceValue">
154+
<mat-option>None</mat-option>
155+
<mat-option *ngFor="let creature of digimon" [value]="creature.value">
156+
{{ creature.viewValue }}
157+
</mat-option>
158+
</mat-select>
159+
</mat-form-field>
160+
</p>
161+
162+
<p>
163+
<mat-form-field appearance="standard">
164+
<mat-label>Standard</mat-label>
165+
<mat-select [(value)]="currentAppearanceValue">
166+
<mat-option>None</mat-option>
167+
<mat-option *ngFor="let creature of digimon" [value]="creature.value">
168+
{{ creature.viewValue }}
169+
</mat-option>
170+
</mat-select>
171+
</mat-form-field>
172+
</p>
173+
174+
<p>
175+
<mat-form-field appearance="fill">
176+
<mat-label>Fill</mat-label>
177+
<mat-select [(value)]="currentAppearanceValue">
178+
<mat-option>None</mat-option>
179+
<mat-option *ngFor="let creature of digimon" [value]="creature.value">
180+
{{ creature.viewValue }}
181+
</mat-option>
182+
</mat-select>
183+
</mat-form-field>
184+
</p>
185+
186+
<p>
187+
<mat-form-field appearance="outline">
188+
<mat-label>Outline</mat-label>
189+
<mat-select [(value)]="currentAppearanceValue">
190+
<mat-option>None</mat-option>
191+
<mat-option *ngFor="let creature of digimon" [value]="creature.value">
192+
{{ creature.viewValue }}
193+
</mat-option>
194+
</mat-select>
195+
</mat-form-field>
196+
</p>
197+
198+
<button mat-button (click)="toggleSelected()">TOGGLE SELECTED</button>
199+
</mat-card-content>
200+
</mat-card>
201+
147202
<div *ngIf="showSelect">
148203
<mat-card>
149204
<mat-card-subtitle>formControl</mat-card-subtitle>

src/demo-app/select/select-demo.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export class SelectDemo {
2929
currentPokemon: string[];
3030
currentPokemonFromGroup: string;
3131
currentDigimon: string;
32+
currentAppearanceValue: string | null;
3233
latestChangeEvent: MatSelectChange;
3334
floatLabel = 'auto';
3435
foodControl = new FormControl('pizza-1');
@@ -135,4 +136,8 @@ export class SelectDemo {
135136
compareByReference(o1: any, o2: any) {
136137
return o1 === o2;
137138
}
139+
140+
toggleSelected() {
141+
this.currentAppearanceValue = this.currentAppearanceValue ? null : this.digimon[0].value;
142+
}
138143
}

src/lib/select/select.scss

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,31 @@ $mat-select-placeholder-arrow-space: 2 * ($mat-select-arrow-size + $mat-select-a
4646
display: table-cell;
4747
vertical-align: middle;
4848

49-
// When used in a box or standard appearance form-field the arrow should be shifted up 50%.
50-
.mat-form-field-appearance-fill &,
51-
.mat-form-field-appearance-standard & {
49+
// When used in a box appearance form-field the arrow should be shifted up 50%.
50+
.mat-form-field-appearance-fill & {
5251
transform: translateY(-50%);
5352
}
5453

5554
// When used in a outline form-field the arrow should be shifted up 25%.
5655
.mat-form-field-appearance-outline & {
5756
transform: translateY(-25%);
5857
}
58+
59+
// When used in a standard appearance form-field the arrow should be shifted up 50%,
60+
// but only if it's not empty
61+
.mat-form-field-appearance-standard .mat-select:not(.mat-select-empty) & {
62+
transform: translateY(-50%);
63+
}
64+
65+
// Animate the arrow position, but only when the transitioning to empty (animate the arrow down)
66+
// This is in line with the mat-form-field label animation
67+
.mat-form-field-appearance-standard .mat-select.mat-select-empty & {
68+
transition: transform $swift-ease-out-duration $swift-ease-out-timing-function;
69+
}
70+
71+
._mat-animation-noopable.mat-form-field-appearance-standard .mat-select.mat-select-empty & {
72+
transition: none;
73+
}
5974
}
6075

6176
.mat-select-arrow {

src/lib/select/select.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ export class MatSelectTrigger {}
202202
'[class.mat-select-disabled]': 'disabled',
203203
'[class.mat-select-invalid]': 'errorState',
204204
'[class.mat-select-required]': 'required',
205+
'[class.mat-select-empty]': 'empty',
205206
'class': 'mat-select',
206207
'(keydown)': '_handleKeydown($event)',
207208
'(focus)': '_onFocus()',

0 commit comments

Comments
 (0)