Skip to content

feat(form-field): support native select element #12707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ node_modules
# IDEs
/.idea
/.vscode
/*.iml

# misc
.DS_Store
Expand All @@ -38,6 +39,7 @@ npm-debug.log
testem.log
/.chrome
/.git
/.firebase

# schematics
/src/lib/schematics/**/*.js
Expand Down
4 changes: 2 additions & 2 deletions src/demo-app/input/input-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<form>
<mat-form-field class="demo-full-width">
<mat-label>Company (disabled)</mat-label>
<input matInput disabled value="Google">
<input matNativeControl disabled value="Google">
</mat-form-field>

<table style="width: 100%" cellspacing="0"><tr>
Expand All @@ -28,7 +28,7 @@
</mat-form-field>
<mat-form-field class="demo-full-width">
<mat-label>Address 2</mat-label>
<textarea matInput></textarea>
<textarea matNativeControl></textarea>
</mat-form-field>
</p>
<table style="width: 100%" cellspacing="0"><tr>
Expand Down
161 changes: 161 additions & 0 deletions src/demo-app/select/select-demo.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,163 @@


<mat-card class="demo-card demo-basic">
<mat-toolbar color="primary">Native Select</mat-toolbar>
<mat-card-content>
<form>
<h4>Basic</h4>
<mat-form-field class="demo-full-width">
<mat-label>Select your car</mat-label>
<select matNativeControl id="mySelectId">
<option value="" disabled selected></option>
<option value="volvo">Volvo</option>
<option value="saab" disabled>Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Disabled and required</h4>
<mat-form-field class="demo-full-width">
<mat-label>Select your car (disabled)</mat-label>
<select matNativeControl disabled required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Floating label</h4>
<mat-form-field>
<mat-label>Float with value</mat-label>
<select matNativeControl>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field>
<mat-label>Not float when empty</mat-label>
<select matNativeControl>
<option value="" selected></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field>
<mat-label>Float with no value, but with label</mat-label>
<select matNativeControl>
<option value="" selected label="--select one--"></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field>
<mat-label>Float with no value, but with html</mat-label>
<select matNativeControl>
<option value="" selected>--select one--</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Looks</h4>
<mat-form-field appearance="legacy">
<mat-label>Legacy</mat-label>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field appearance="standard">
<mat-label>Standard</mat-label>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Fill</mat-label>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Outline</mat-label>
<select matNativeControl>
<option value="volvo">volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Option group</h4>
<mat-form-field>
<select matNativeControl>
<optgroup label="Swedish Cars">
<option value="volvo">volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</optgroup>
</select>
</mat-form-field>
<h4>Place holder</h4>
<mat-form-field class="demo-full-width">
<select matNativeControl placeholder="place holder">
<option value="" disabled selected></option>
<option value="volvo">Volvo</option>
<option value="saab" disabled>Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Error message, hint, form sumbit</h4>
<mat-form-field class="demo-full-width">
<mat-label>Select your car (required)</mat-label>
<select matNativeControl required [formControl]="selectFormControl">
<option label="--select something --"></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<mat-error *ngIf="selectFormControl.hasError('required')">
This field is required
</mat-error>
<mat-hint>You can pick up your favorite car here</mat-hint>
</mat-form-field>

<h4>Error message with errorStateMatcher</h4>
<mat-form-field class="demo-full-width">
<mat-label>Select your car</mat-label>
<select matNativeControl required [formControl]="selectFormControl" [errorStateMatcher]="matcher">
<option label="--select something --"></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<mat-error *ngIf="selectFormControl.hasError('required')">
This field is required
</mat-error>
<mat-hint>You can pick up your favorite car here</mat-hint>
</mat-form-field>
<button color="primary" mat-raised-button>Submit</button>
</form>
</mat-card-content>
</mat-card>


<mat-toolbar color="primary">mat-select</mat-toolbar>
Space above cards: <input type="number" [formControl]="topHeightCtrl">
<button mat-button (click)="showSelect=!showSelect">SHOW SELECT</button>
<div [style.height.px]="topHeightCtrl.value"></div>
Expand Down Expand Up @@ -240,3 +400,4 @@

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

16 changes: 14 additions & 2 deletions src/demo-app/select/select-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@
*/

import {Component} from '@angular/core';
import {FormControl} from '@angular/forms';
import {MatSelectChange} from '@angular/material';
import {FormControl, Validators} from '@angular/forms';
import {ErrorStateMatcher, MatSelectChange} from '@angular/material';

/** Error any time control is invalid */
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null): boolean {
if (control) {
return control.invalid;
}
return false;
}
}

@Component({
moduleId: module.id,
Expand Down Expand Up @@ -37,6 +46,7 @@ export class SelectDemo {
drinksTheme = 'primary';
pokemonTheme = 'primary';
compareByValue = true;
selectFormControl = new FormControl('', Validators.required);

foods = [
{value: null, viewValue: 'None'},
Expand Down Expand Up @@ -137,6 +147,8 @@ export class SelectDemo {
return o1 === o2;
}

matcher = new MyErrorStateMatcher();

toggleSelected() {
this.currentAppearanceValue = this.currentAppearanceValue ? null : this.digimon[0].value;
}
Expand Down
6 changes: 4 additions & 2 deletions src/lib/form-field/form-field.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ In this document, "form field" refers to the wrapper component `<mat-form-field>
(e.g. the input, textarea, select, etc.)

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

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

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

Expand Down
26 changes: 26 additions & 0 deletions src/lib/input/input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,29 @@ textarea.mat-input-element {
padding: 2px 0;
margin: -2px 0;
}

// Encoded material design select arrow svg
/* stylelint-disable max-line-length */
$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';
/* stylelint-enable */

// Remove the native select down arrow and replace it with material design arrow
select.mat-input-element {
&::-ms-expand {
display: none;
}
-moz-appearance: none;
-webkit-appearance: none;
position: relative;
background-color: transparent;
background-image: url($mat-native-select-arrow-svg);
background-repeat: no-repeat;
display: inline-flex;
box-sizing: border-box;
background-position: right center;

[dir='rtl'] & {
background-position: left center;
}
}

Loading