Skip to content

Commit 5cf0348

Browse files
committed
finish up MdFormFieldControl implementation
1 parent c1fac74 commit 5cf0348

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

src/lib/select/_select-theme.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,14 @@
5252
&.mat-accent {
5353
@include _mat-select-inner-content-theme($accent);
5454
}
55+
56+
&.mat-warn,
57+
&.mat-select-invalid {
58+
@include _mat-select-inner-content-theme($warn);
59+
}
5560
}
5661

57-
.mat-select:focus:not(.mat-select-disabled).mat-warn, .mat-select-invalid {
62+
.mat-select.mat-select-invalid:not(.mat-select-disabled) {
5863
@include _mat-select-inner-content-theme($warn);
5964
}
6065
}

src/lib/select/select.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,13 @@ export class MdSelectTrigger {}
180180
'[attr.aria-invalid]': 'errorState',
181181
'[attr.aria-owns]': '_optionIds',
182182
'[attr.aria-multiselectable]': 'multiple',
183+
'[attr.aria-describedby]': '_ariaDescribedby || null',
183184
'[class.mat-select-disabled]': 'disabled',
184185
'[class.mat-select-invalid]': 'errorState',
185186
'[class.mat-select-required]': 'required',
186187
'class': 'mat-select',
187188
'(keydown)': '_handleClosedKeydown($event)',
189+
'(focus)': '_onFocus()',
188190
'(blur)': '_onBlur()',
189191
},
190192
animations: [
@@ -229,6 +231,9 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
229231
/** The cached height of the trigger element. */
230232
private _triggerHeight: number;
231233

234+
/** The aria-describedby attribute on the select for improved a11y. */
235+
_ariaDescribedby: string;
236+
232237
/** The cached font-size of the trigger element. */
233238
_triggerFontSize = 0;
234239

@@ -297,12 +302,8 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
297302
*/
298303
stateChanges = new Subject<void>();
299304

300-
/** Whether the select is focused. TODO(mmalerba): Implement for real. */
301305
focused = false;
302306

303-
/** TODO(mmalerba): Implement for real. */
304-
setDescribedByIds(x: string[]) {return x}
305-
306307
/** Trigger that opens the select. */
307308
@ViewChild('trigger') trigger: ElementRef;
308309

@@ -329,6 +330,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
329330
get placeholder() { return this._placeholder; }
330331
set placeholder(value: string) {
331332
this._placeholder = value;
333+
this.stateChanges.next();
332334

333335
// Must wait to record the trigger width to ensure placeholder width is included.
334336
Promise.resolve(null).then(() => this._setTriggerWidth());
@@ -337,7 +339,10 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
337339
/** Whether the component is required. */
338340
@Input()
339341
get required() { return this._required; }
340-
set required(value: any) { this._required = coerceBooleanProperty(value); }
342+
set required(value: any) {
343+
this._required = coerceBooleanProperty(value);
344+
this.stateChanges.next();
345+
}
341346

342347
/** Whether the user should be allowed to select multiple options. */
343348
@Input()
@@ -374,6 +379,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
374379
set value(newValue: any) {
375380
this.writeValue(newValue);
376381
this._value = newValue;
382+
this.stateChanges.next();
377383
}
378384
private _value: any;
379385

@@ -395,7 +401,10 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
395401
/** Unique id of the element. */
396402
@Input()
397403
get id() { return this._id; }
398-
set id(value: string) { this._id = value || this._uid; }
404+
set id(value: string) {
405+
this._id = value || this._uid;
406+
this.stateChanges.next();
407+
}
399408
private _id: string;
400409

401410
/** Combined stream of all of the child options' change events. */
@@ -535,6 +544,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
535544
setDisabledState(isDisabled: boolean): void {
536545
this.disabled = isDisabled;
537546
this._changeDetectorRef.markForCheck();
547+
this.stateChanges.next();
538548
}
539549

540550
/** Whether or not the overlay panel is open. */
@@ -631,14 +641,23 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
631641
this._changeDetectorRef.markForCheck();
632642
}
633643

644+
_onFocus() {
645+
if (!this.disabled) {
646+
this.focused = true;
647+
this.stateChanges.next();
648+
}
649+
}
650+
634651
/**
635652
* Calls the touched callback only if the panel is closed. Otherwise, the trigger will
636653
* "blur" to the panel when it opens, causing a false positive.
637654
*/
638655
_onBlur() {
639656
if (!this.disabled && !this.panelOpen) {
657+
this.focused = false;
640658
this._onTouched();
641659
this._changeDetectorRef.markForCheck();
660+
this.stateChanges.next();
642661
}
643662
}
644663

@@ -1141,6 +1160,9 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
11411160
private _getItemCount(): number {
11421161
return this.options.length + this.optionGroups.length;
11431162
}
1163+
1164+
/** Sets the list of element IDs that currently describe this select. */
1165+
setDescribedByIds(ids: string[]) { this._ariaDescribedby = ids.join(' '); }
11441166
}
11451167

11461168
/** Clamps a value n between min and max values. */

0 commit comments

Comments
 (0)