Skip to content

Commit e8ca023

Browse files
committed
strip down select DOM and implement MdFormFieldControl
1 parent d2ceb2c commit e8ca023

File tree

10 files changed

+96
-225
lines changed

10 files changed

+96
-225
lines changed

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

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
<md-card>
77
<md-card-subtitle>ngModel</md-card-subtitle>
88

9-
<md-select placeholder="Drink" [color]="drinksTheme" [(ngModel)]="currentDrink" [required]="drinksRequired"
10-
[disabled]="drinksDisabled" [floatPlaceholder]="floatPlaceholder" #drinkControl="ngModel">
11-
<md-option>None</md-option>
12-
<md-option *ngFor="let drink of drinks" [value]="drink.value" [disabled]="drink.disabled">
13-
{{ drink.viewValue }}
14-
</md-option>
15-
</md-select>
9+
<md-form-field>
10+
<md-select placeholder="Drink" [color]="drinksTheme" [(ngModel)]="currentDrink" [required]="drinksRequired"
11+
[disabled]="drinksDisabled" #drinkControl="ngModel">
12+
<md-option>None</md-option>
13+
<md-option *ngFor="let drink of drinks" [value]="drink.value" [disabled]="drink.disabled">
14+
{{ drink.viewValue }}
15+
</md-option>
16+
</md-select>
17+
</md-form-field>
1618
<p> Value: {{ currentDrink }} </p>
1719
<p> Touched: {{ drinkControl.touched }} </p>
1820
<p> Dirty: {{ drinkControl.dirty }} </p>
@@ -42,12 +44,14 @@
4244
<md-card-subtitle>Multiple selection</md-card-subtitle>
4345

4446
<md-card-content>
45-
<md-select multiple [color]="pokemonTheme" placeholder="Pokemon" [(ngModel)]="currentPokemon"
46-
[required]="pokemonRequired" [disabled]="pokemonDisabled" #pokemonControl="ngModel">
47-
<md-option *ngFor="let creature of pokemon" [value]="creature.value">
48-
{{ creature.viewValue }}
49-
</md-option>
50-
</md-select>
47+
<md-form-field>
48+
<md-select multiple [color]="pokemonTheme" placeholder="Pokemon" [(ngModel)]="currentPokemon"
49+
[required]="pokemonRequired" [disabled]="pokemonDisabled" #pokemonControl="ngModel">
50+
<md-option *ngFor="let creature of pokemon" [value]="creature.value">
51+
{{ creature.viewValue }}
52+
</md-option>
53+
</md-select>
54+
</md-form-field>
5155
<p> Value: {{ currentPokemon }} </p>
5256
<p> Touched: {{ pokemonControl.touched }} </p>
5357
<p> Dirty: {{ pokemonControl.dirty }} </p>
@@ -68,12 +72,14 @@
6872
<md-card>
6973
<md-card-subtitle>Without Angular forms</md-card-subtitle>
7074

71-
<md-select placeholder="Digimon" [(value)]="currentDigimon">
72-
<md-option>None</md-option>
73-
<md-option *ngFor="let creature of digimon" [value]="creature.value">
74-
{{ creature.viewValue }}
75-
</md-option>
76-
</md-select>
75+
<md-form-field>
76+
<md-select placeholder="Digimon" [(value)]="currentDigimon">
77+
<md-option>None</md-option>
78+
<md-option *ngFor="let creature of digimon" [value]="creature.value">
79+
{{ creature.viewValue }}
80+
</md-option>
81+
</md-select>
82+
</md-form-field>
7783

7884
<p>Value: {{ currentDigimon }}</p>
7985

@@ -85,14 +91,16 @@
8591
<md-card-subtitle>Option groups</md-card-subtitle>
8692

8793
<md-card-content>
88-
<md-select placeholder="Pokemon" [(ngModel)]="currentPokemonFromGroup">
89-
<md-optgroup *ngFor="let group of pokemonGroups" [label]="group.name"
90-
[disabled]="group.disabled">
91-
<md-option *ngFor="let creature of group.pokemon" [value]="creature.value">
92-
{{ creature.viewValue }}
93-
</md-option>
94-
</md-optgroup>
95-
</md-select>
94+
<md-form-field>
95+
<md-select placeholder="Pokemon" [(ngModel)]="currentPokemonFromGroup">
96+
<md-optgroup *ngFor="let group of pokemonGroups" [label]="group.name"
97+
[disabled]="group.disabled">
98+
<md-option *ngFor="let creature of group.pokemon" [value]="creature.value">
99+
{{ creature.viewValue }}
100+
</md-option>
101+
</md-optgroup>
102+
</md-select>
103+
</md-form-field>
96104
</md-card-content>
97105
</md-card>
98106

@@ -149,9 +157,11 @@
149157
<md-card-subtitle>Change event</md-card-subtitle>
150158

151159
<md-card-content>
152-
<md-select placeholder="Starter Pokemon" (change)="latestChangeEvent = $event">
153-
<md-option *ngFor="let creature of pokemon" [value]="creature.value">{{ creature.viewValue }}</md-option>
154-
</md-select>
160+
<md-form-field>
161+
<md-select placeholder="Starter Pokemon" (change)="latestChangeEvent = $event">
162+
<md-option *ngFor="let creature of pokemon" [value]="creature.value">{{ creature.viewValue }}</md-option>
163+
</md-select>
164+
</md-form-field>
155165

156166
<p> Change event value: {{ latestChangeEvent?.value }} </p>
157167
</md-card-content>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class SelectDemo {
2121
currentPokemonFromGroup: string;
2222
currentDigimon: string;
2323
latestChangeEvent: MdSelectChange;
24-
floatPlaceholder: string = 'auto';
24+
floatPlaceholder: string = 'auto'; // add to form-field
2525
foodControl = new FormControl('pizza-1');
2626
topHeightCtrl = new FormControl(0);
2727
drinksTheme = 'primary';

src/lib/input/input.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ let nextUniqueId = 0;
5555
'class': 'mat-input-element mat-form-field-autofill-control',
5656
// Native input properties that are overwritten by Angular inputs need to be synced with
5757
// the native input element. Otherwise property bindings for those don't work.
58-
'[id]': 'id',
58+
'[attr.id]': 'id',
5959
'[placeholder]': 'placeholder',
6060
'[disabled]': 'disabled',
6161
'[required]': 'required',

src/lib/select/_select-theme.scss

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@
99
.mat-select-trigger, .mat-select-arrow {
1010
color: $color;
1111
}
12-
13-
.mat-select-underline {
14-
background-color: $color;
15-
}
1612
}
1713

1814
@mixin mat-select-theme($theme) {
@@ -22,22 +18,12 @@
2218
$accent: map-get($theme, accent);
2319
$warn: map-get($theme, warn);
2420
$is-dark-theme: map-get($theme, is-dark);
25-
$underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42));
2621

2722
.mat-select-trigger,
2823
.mat-select-arrow {
2924
color: mat-color($foreground, secondary-text);
3025
}
3126

32-
.mat-select-underline {
33-
background-color: $underline-color;
34-
}
35-
36-
[aria-disabled='true'] .mat-select-underline {
37-
// Since this is a dotted line, we need to make it slightly darker to get it to stand out.
38-
@include mat-control-disabled-underline($underline-color);
39-
}
40-
4127
.mat-select-disabled .mat-select-value,
4228
.mat-select-arrow,
4329
.mat-select-trigger {
@@ -66,10 +52,6 @@
6652
&.mat-accent {
6753
@include _mat-select-inner-content-theme($accent);
6854
}
69-
70-
&.mat-select-required .mat-select-placeholder::after {
71-
color: mat-color($warn);
72-
}
7355
}
7456

7557
.mat-select:focus:not(.mat-select-disabled).mat-warn, .mat-select-invalid {

src/lib/select/public_api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88

99
export * from './select-module';
1010
export * from './select';
11-
export {fadeInContent, transformPanel, transformPlaceholder} from './select-animations';
11+
export * from './select-animations';
1212
export * from './mat-exports';

src/lib/select/select-animations.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,6 @@ import {
2222
* The values below match the implementation of the AngularJS Material md-select animation.
2323
*/
2424

25-
/**
26-
* This animation shrinks the placeholder text to 75% of its normal size and translates
27-
* it to either the top left corner (ltr) or top right corner (rtl) of the trigger,
28-
* depending on the text direction of the application.
29-
*/
30-
export const transformPlaceholder: AnimationTriggerMetadata = trigger('transformPlaceholder', [
31-
state('floating-ltr', style({
32-
top: '-22px',
33-
left: '-2px',
34-
transform: 'scale(0.75)'
35-
})),
36-
state('floating-rtl', style({
37-
top: '-22px',
38-
left: '2px',
39-
transform: 'scale(0.75)'
40-
})),
41-
transition('* => *', animate('400ms cubic-bezier(0.25, 0.8, 0.25, 1)'))
42-
]);
43-
4425
/**
4526
* This animation transforms the select's overlay panel on and off the page.
4627
*

src/lib/select/select.html

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
11
<div
2-
cdk-overlay-origin
3-
class="mat-select-trigger"
4-
aria-hidden="true"
5-
(click)="toggle()"
6-
#origin="cdkOverlayOrigin"
7-
#trigger>
8-
<span
9-
class="mat-select-placeholder"
10-
[class.mat-floating-placeholder]="_hasValue()"
11-
[@transformPlaceholder]="_getPlaceholderAnimationState()"
12-
[style.opacity]="_getPlaceholderOpacity()"
13-
[style.width.px]="_selectedValueWidth">{{ placeholder }}</span>
14-
15-
<span class="mat-select-value" *ngIf="_hasValue()">
16-
<span class="mat-select-value-text" [ngSwitch]="!!customTrigger">
2+
cdk-overlay-origin
3+
class="mat-select-trigger"
4+
aria-hidden="true"
5+
(click)="toggle()"
6+
#origin="cdkOverlayOrigin"
7+
#trigger>
8+
<span class="mat-select-value">
9+
<span class="mat-select-value-text" *ngIf="!empty" [ngSwitch]="!!customTrigger">
1710
<span *ngSwitchDefault>{{ triggerValue }}</span>
1811
<ng-content select="md-select-trigger, mat-select-trigger" *ngSwitchCase="true"></ng-content>
1912
</span>
2013
</span>
2114

2215
<span class="mat-select-arrow"></span>
23-
<span class="mat-select-underline"></span>
2416
</div>
2517

2618
<ng-template

src/lib/select/select.scss

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ $mat-select-trigger-min-width: 112px !default;
99
$mat-select-arrow-size: 5px !default;
1010
$mat-select-arrow-margin: 4px !default;
1111
$mat-select-panel-max-height: 256px !default;
12-
$mat-select-trigger-underline-height: 1px !default;
1312

1413
.mat-select {
1514
display: inline-block;
@@ -31,55 +30,6 @@ $mat-select-trigger-underline-height: 1px !default;
3130
}
3231
}
3332

34-
.mat-select-underline {
35-
position: absolute;
36-
bottom: 0;
37-
left: 0;
38-
right: 0;
39-
height: $mat-select-trigger-underline-height;
40-
41-
.mat-select:focus & {
42-
height: $mat-select-trigger-underline-height * 2;
43-
}
44-
45-
.mat-select-disabled & {
46-
background-color: transparent;
47-
background-position: 0 bottom;
48-
}
49-
}
50-
51-
.mat-select-placeholder {
52-
position: relative;
53-
padding: 0 2px;
54-
transform-origin: left top;
55-
flex-grow: 1;
56-
57-
// These values are duplicated from animation code in order to
58-
// allow placeholders to sometimes float without animating,
59-
// for example when the value is set programmatically.
60-
// TODO(kara): Change when animations API supports skipping animation.
61-
&.mat-floating-placeholder {
62-
top: -22px;
63-
left: -2px;
64-
text-align: left;
65-
transform: scale(0.75);
66-
}
67-
68-
[dir='rtl'] & {
69-
transform-origin: right top;
70-
71-
&.mat-floating-placeholder {
72-
left: 2px;
73-
text-align: right;
74-
}
75-
}
76-
77-
// TODO: Double-check accessibility of this style
78-
.mat-select-required &::after {
79-
content: ' *';
80-
}
81-
}
82-
8333
.mat-select-value {
8434
position: absolute;
8535
max-width: calc(100% - #{($mat-select-arrow-size + $mat-select-arrow-margin) * 2});

src/lib/select/select.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ describe('MdSelect', () => {
952952
spyOn(fixture.componentInstance.customAccessor, 'writeValue');
953953
fixture.detectChanges();
954954

955-
expect(fixture.componentInstance.customAccessor.select._control)
955+
expect(fixture.componentInstance.customAccessor.select.ngControl)
956956
.toBe(null, 'Expected md-select NOT to inherit control from parent value accessor.');
957957
expect(fixture.componentInstance.customAccessor.writeValue).toHaveBeenCalled();
958958
});

0 commit comments

Comments
 (0)