Skip to content

Commit 4e41985

Browse files
vivian-hu-zzjelbourn
authored andcommitted
feat(form-field): support native select element (#12707)
1 parent 53b4af6 commit 4e41985

File tree

19 files changed

+510
-29
lines changed

19 files changed

+510
-29
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ node_modules
2727
# IDEs
2828
/.idea
2929
/.vscode
30+
/*.iml
3031

3132
# misc
3233
.DS_Store
@@ -38,6 +39,7 @@ npm-debug.log
3839
testem.log
3940
/.chrome
4041
/.git
42+
/.firebase
4143

4244
# schematics
4345
/src/lib/schematics/**/*.js

src/demo-app/input/input-demo.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<form>
55
<mat-form-field class="demo-full-width">
66
<mat-label>Company (disabled)</mat-label>
7-
<input matInput disabled value="Google">
7+
<input matNativeControl disabled value="Google">
88
</mat-form-field>
99

1010
<table style="width: 100%" cellspacing="0"><tr>
@@ -28,7 +28,7 @@
2828
</mat-form-field>
2929
<mat-form-field class="demo-full-width">
3030
<mat-label>Address 2</mat-label>
31-
<textarea matInput></textarea>
31+
<textarea matNativeControl></textarea>
3232
</mat-form-field>
3333
</p>
3434
<table style="width: 100%" cellspacing="0"><tr>

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

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,163 @@
1+
2+
3+
<mat-card class="demo-card demo-basic">
4+
<mat-toolbar color="primary">Native Select</mat-toolbar>
5+
<mat-card-content>
6+
<form>
7+
<h4>Basic</h4>
8+
<mat-form-field class="demo-full-width">
9+
<mat-label>Select your car</mat-label>
10+
<select matNativeControl id="mySelectId">
11+
<option value="" disabled selected></option>
12+
<option value="volvo">Volvo</option>
13+
<option value="saab" disabled>Saab</option>
14+
<option value="mercedes">Mercedes</option>
15+
<option value="audi">Audi</option>
16+
</select>
17+
</mat-form-field>
18+
<h4>Disabled and required</h4>
19+
<mat-form-field class="demo-full-width">
20+
<mat-label>Select your car (disabled)</mat-label>
21+
<select matNativeControl disabled required>
22+
<option value="volvo">Volvo</option>
23+
<option value="saab">Saab</option>
24+
<option value="mercedes">Mercedes</option>
25+
<option value="audi">Audi</option>
26+
</select>
27+
</mat-form-field>
28+
<h4>Floating label</h4>
29+
<mat-form-field>
30+
<mat-label>Float with value</mat-label>
31+
<select matNativeControl>
32+
<option value="volvo">Volvo</option>
33+
<option value="saab">Saab</option>
34+
<option value="mercedes">Mercedes</option>
35+
<option value="audi">Audi</option>
36+
</select>
37+
</mat-form-field>
38+
<mat-form-field>
39+
<mat-label>Not float when empty</mat-label>
40+
<select matNativeControl>
41+
<option value="" selected></option>
42+
<option value="saab">Saab</option>
43+
<option value="mercedes">Mercedes</option>
44+
<option value="audi">Audi</option>
45+
</select>
46+
</mat-form-field>
47+
<mat-form-field>
48+
<mat-label>Float with no value, but with label</mat-label>
49+
<select matNativeControl>
50+
<option value="" selected label="--select one--"></option>
51+
<option value="saab">Saab</option>
52+
<option value="mercedes">Mercedes</option>
53+
<option value="audi">Audi</option>
54+
</select>
55+
</mat-form-field>
56+
<mat-form-field>
57+
<mat-label>Float with no value, but with html</mat-label>
58+
<select matNativeControl>
59+
<option value="" selected>--select one--</option>
60+
<option value="saab">Saab</option>
61+
<option value="mercedes">Mercedes</option>
62+
<option value="audi">Audi</option>
63+
</select>
64+
</mat-form-field>
65+
<h4>Looks</h4>
66+
<mat-form-field appearance="legacy">
67+
<mat-label>Legacy</mat-label>
68+
<select matNativeControl required>
69+
<option value="volvo">Volvo</option>
70+
<option value="saab">Saab</option>
71+
<option value="mercedes">Mercedes</option>
72+
<option value="audi">Audi</option>
73+
</select>
74+
</mat-form-field>
75+
<mat-form-field appearance="standard">
76+
<mat-label>Standard</mat-label>
77+
<select matNativeControl required>
78+
<option value="volvo">Volvo</option>
79+
<option value="saab">Saab</option>
80+
<option value="mercedes">Mercedes</option>
81+
<option value="audi">Audi</option>
82+
</select>
83+
</mat-form-field>
84+
<mat-form-field appearance="fill">
85+
<mat-label>Fill</mat-label>
86+
<select matNativeControl required>
87+
<option value="volvo">Volvo</option>
88+
<option value="saab">Saab</option>
89+
<option value="mercedes">Mercedes</option>
90+
<option value="audi">Audi</option>
91+
</select>
92+
</mat-form-field>
93+
<mat-form-field appearance="outline">
94+
<mat-label>Outline</mat-label>
95+
<select matNativeControl>
96+
<option value="volvo">volvo</option>
97+
<option value="saab">Saab</option>
98+
<option value="mercedes">Mercedes</option>
99+
<option value="audi">Audi</option>
100+
</select>
101+
</mat-form-field>
102+
<h4>Option group</h4>
103+
<mat-form-field>
104+
<select matNativeControl>
105+
<optgroup label="Swedish Cars">
106+
<option value="volvo">volvo</option>
107+
<option value="saab">Saab</option>
108+
</optgroup>
109+
<optgroup label="German Cars">
110+
<option value="mercedes">Mercedes</option>
111+
<option value="audi">Audi</option>
112+
</optgroup>
113+
</select>
114+
</mat-form-field>
115+
<h4>Place holder</h4>
116+
<mat-form-field class="demo-full-width">
117+
<select matNativeControl placeholder="place holder">
118+
<option value="" disabled selected></option>
119+
<option value="volvo">Volvo</option>
120+
<option value="saab" disabled>Saab</option>
121+
<option value="mercedes">Mercedes</option>
122+
<option value="audi">Audi</option>
123+
</select>
124+
</mat-form-field>
125+
<h4>Error message, hint, form sumbit</h4>
126+
<mat-form-field class="demo-full-width">
127+
<mat-label>Select your car (required)</mat-label>
128+
<select matNativeControl required [formControl]="selectFormControl">
129+
<option label="--select something --"></option>
130+
<option value="saab">Saab</option>
131+
<option value="mercedes">Mercedes</option>
132+
<option value="audi">Audi</option>
133+
</select>
134+
<mat-error *ngIf="selectFormControl.hasError('required')">
135+
This field is required
136+
</mat-error>
137+
<mat-hint>You can pick up your favorite car here</mat-hint>
138+
</mat-form-field>
139+
140+
<h4>Error message with errorStateMatcher</h4>
141+
<mat-form-field class="demo-full-width">
142+
<mat-label>Select your car</mat-label>
143+
<select matNativeControl required [formControl]="selectFormControl" [errorStateMatcher]="matcher">
144+
<option label="--select something --"></option>
145+
<option value="saab">Saab</option>
146+
<option value="mercedes">Mercedes</option>
147+
<option value="audi">Audi</option>
148+
</select>
149+
<mat-error *ngIf="selectFormControl.hasError('required')">
150+
This field is required
151+
</mat-error>
152+
<mat-hint>You can pick up your favorite car here</mat-hint>
153+
</mat-form-field>
154+
<button color="primary" mat-raised-button>Submit</button>
155+
</form>
156+
</mat-card-content>
157+
</mat-card>
158+
159+
160+
<mat-toolbar color="primary">mat-select</mat-toolbar>
1161
Space above cards: <input type="number" [formControl]="topHeightCtrl">
2162
<button mat-button (click)="showSelect=!showSelect">SHOW SELECT</button>
3163
<div [style.height.px]="topHeightCtrl.value"></div>
@@ -240,3 +400,4 @@
240400

241401
</div>
242402
<div style="height: 500px">This div is for testing scrolled selects.</div>
403+

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,18 @@
77
*/
88

99
import {Component} from '@angular/core';
10-
import {FormControl} from '@angular/forms';
11-
import {MatSelectChange} from '@angular/material';
10+
import {FormControl, Validators} from '@angular/forms';
11+
import {ErrorStateMatcher, MatSelectChange} from '@angular/material';
1212

13+
/** Error any time control is invalid */
14+
export class MyErrorStateMatcher implements ErrorStateMatcher {
15+
isErrorState(control: FormControl | null): boolean {
16+
if (control) {
17+
return control.invalid;
18+
}
19+
return false;
20+
}
21+
}
1322

1423
@Component({
1524
moduleId: module.id,
@@ -37,6 +46,7 @@ export class SelectDemo {
3746
drinksTheme = 'primary';
3847
pokemonTheme = 'primary';
3948
compareByValue = true;
49+
selectFormControl = new FormControl('', Validators.required);
4050

4151
foods = [
4252
{value: null, viewValue: 'None'},
@@ -137,6 +147,8 @@ export class SelectDemo {
137147
return o1 === o2;
138148
}
139149

150+
matcher = new MyErrorStateMatcher();
151+
140152
toggleSelected() {
141153
this.currentAppearanceValue = this.currentAppearanceValue ? null : this.digimon[0].value;
142154
}

src/lib/form-field/form-field.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ In this document, "form field" refers to the wrapper component `<mat-form-field>
77
(e.g. the input, textarea, select, etc.)
88

99
The following Angular Material components are designed to work inside a `<mat-form-field>`:
10-
* [`<input matInput>` &amp; `<textarea matInput>`](https://material.angular.io/components/input/overview)
10+
* [`<input matNativeControl>` &amp; `<textarea matNativeControl>`](https://material.angular.io/components/input/overview)
11+
* [`<select matNativeControl>`](https://material.angular.io/components/select/overview)
1112
* [`<mat-select>`](https://material.angular.io/components/select/overview)
1213
* [`<mat-chip-list>`](https://material.angular.io/components/chips/overview)
1314

@@ -41,7 +42,8 @@ want a floating label, add a `<mat-label>` to the `mat-form-field`.
4142
### Floating label
4243

4344
The floating label is a text label displayed on top of the form field control when
44-
the control does not contain any text. By default, when text is present the floating label
45+
the control does not contain any text or when `<select matNativeControl>` does not show any option text.
46+
By default, when text is present the floating label
4547
floats above the form field control. The label for a form field can be specified by adding a
4648
`mat-label` element.
4749

src/lib/input/input.scss

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,29 @@ textarea.mat-input-element {
121121
padding: 2px 0;
122122
margin: -2px 0;
123123
}
124+
125+
// Encoded material design select arrow svg
126+
/* stylelint-disable max-line-length */
127+
$mat-native-select-arrow-svg: 'data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%2210%22%20height%3D%225%22%20viewBox%3D%227%2010%2010%205%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%230%22%20fill-rule%3D%22evenodd%22%20opacity%3D%22.54%22%20d%3D%22M7%2010l5%205%205-5z%22%2F%3E%3C%2Fsvg%3E';
128+
/* stylelint-enable */
129+
130+
// Remove the native select down arrow and replace it with material design arrow
131+
select.mat-input-element {
132+
&::-ms-expand {
133+
display: none;
134+
}
135+
-moz-appearance: none;
136+
-webkit-appearance: none;
137+
position: relative;
138+
background-color: transparent;
139+
background-image: url($mat-native-select-arrow-svg);
140+
background-repeat: no-repeat;
141+
display: inline-flex;
142+
box-sizing: border-box;
143+
background-position: right center;
144+
145+
[dir='rtl'] & {
146+
background-position: left center;
147+
}
148+
}
149+

0 commit comments

Comments
 (0)