Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalerba committed Aug 8, 2017
1 parent b16ef28 commit 9baaaeb
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 128 deletions.
24 changes: 11 additions & 13 deletions src/lib/autocomplete/autocomplete-trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import {MdOptionSelectionChange, MdOption} from '../core/option/option';
import {ENTER, UP_ARROW, DOWN_ARROW, ESCAPE} from '../core/keyboard/keycodes';
import {Directionality} from '../core/bidi/index';
import {MdFormField} from '../form-field/index';
import {MdInput} from '../input/input';
import {Subscription} from 'rxjs/Subscription';
import {merge} from 'rxjs/observable/merge';
import {fromEvent} from 'rxjs/observable/fromEvent';
Expand Down Expand Up @@ -154,7 +153,7 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
private _changeDetectorRef: ChangeDetectorRef,
@Inject(MD_AUTOCOMPLETE_SCROLL_STRATEGY) private _scrollStrategy,
@Optional() private _dir: Directionality,
@Optional() @Host() private _inputContainer: MdFormField,
@Optional() @Host() private _formField: MdFormField,
@Optional() @Inject(DOCUMENT) private _document: any) {}

ngOnDestroy() {
Expand Down Expand Up @@ -247,8 +246,8 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
fromEvent(this._document, 'touchend')
)).call(filter, (event: MouseEvent | TouchEvent) => {
const clickTarget = event.target as HTMLElement;
const inputContainer = this._inputContainer ?
this._inputContainer._elementRef.nativeElement : null;
const inputContainer = this._formField ?
this._formField._elementRef.nativeElement : null;

return this._panelOpen &&
clickTarget !== this._element.nativeElement &&
Expand Down Expand Up @@ -330,16 +329,16 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
* This method manually floats the placeholder until the panel can be closed.
*/
private _floatPlaceholder(): void {
if (this._inputContainer && this._inputContainer.floatPlaceholder === 'auto') {
this._inputContainer.floatPlaceholder = 'always';
if (this._formField && this._formField.floatPlaceholder === 'auto') {
this._formField.floatPlaceholder = 'always';
this._manuallyFloatingPlaceholder = true;
}
}

/** If the placeholder has been manually elevated, return it to its normal state. */
private _resetPlaceholder(): void {
if (this._manuallyFloatingPlaceholder) {
this._inputContainer.floatPlaceholder = 'auto';
this._formField.floatPlaceholder = 'auto';
this._manuallyFloatingPlaceholder = false;
}
}
Expand Down Expand Up @@ -409,11 +408,10 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
// The display value can also be the number zero and shouldn't fall back to an empty string.
const inputValue = toDisplay != null ? toDisplay : '';

// If it's used in a Material container, we should set it through
// the property so it can go through the change detection.
if (this._inputContainer &&
this._inputContainer._control instanceof MdInput) {
this._inputContainer._control.value = inputValue;
// If it's used within a `MdFormField`, we should set it through the property so it can go
// through change detection.
if (this._formField) {
this._formField._control.value = inputValue;
} else {
this._element.nativeElement.value = inputValue;
}
Expand Down Expand Up @@ -471,7 +469,7 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
}

private _getConnectedElement(): ElementRef {
return this._inputContainer ? this._inputContainer._connectionContainerRef : this._element;
return this._formField ? this._formField._connectionContainerRef : this._element;
}

/** Returns the width of the input element, so the panel width can match it. */
Expand Down
26 changes: 26 additions & 0 deletions src/lib/form-field/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Directive, Input} from '@angular/core';


let nextUniqueId = 0;


/** Single error message to be shown underneath the form field. */
@Directive({
selector: 'md-error, mat-error',
host: {
'class': 'mat-error',
'role': 'alert',
'[attr.id]': 'id',
}
})
export class MdError {
@Input() id: string = `mat-error-${nextUniqueId++}`;
}
53 changes: 53 additions & 0 deletions src/lib/form-field/form-field-control.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Observable} from 'rxjs/Observable';
import {NgControl} from '@angular/forms';


/** An interface which allows a control to work inside of a `MdFormField`. */
export abstract class MdFormFieldControl {
/**
* Stream that emits whenever the state of the control changes such that the parent `MdFormField`
* needs to run change detection.
*/
stateChanges: Observable<void>;

/** The value of the control. */
value: any;

/** Gets the element ID for this control. */
abstract getId(): string;

/** Gets the placeholder for this control. */
abstract getPlaceholder(): string;

/** Gets the NgControl for this control. */
abstract getNgControl(): NgControl | null;

/** Whether the control is focused. */
abstract isFocused(): boolean;

/** Whether the control is empty. */
abstract isEmpty(): boolean;

/** Whether the control is required. */
abstract isRequired(): boolean;

/** Whether the control is disabled. */
abstract isDisabled(): boolean;

/** Whether the control is in an error state. */
abstract isErrorState(): boolean;

/** Sets the list of element IDs that currently describe this control. */
abstract setDescribedByIds(ids: string[]): void;

/** Focuses this control. */
abstract focus(): void;
}
109 changes: 8 additions & 101 deletions src/lib/form-field/form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
Component,
ContentChild,
ContentChildren,
Directive,
ElementRef,
Inject,
Input,
Expand All @@ -26,7 +25,6 @@ import {
} from '@angular/core';
import {animate, state, style, transition, trigger} from '@angular/animations';
import {coerceBooleanProperty} from '../core';
import {NgControl} from '@angular/forms';
import {
getMdFormFieldDuplicatedHintError,
getMdFormFieldMissingControlError,
Expand All @@ -38,110 +36,21 @@ import {
PlaceholderOptions
} from '../core/placeholder/placeholder-options';
import {startWith} from '@angular/cdk/rxjs';
import {Observable} from 'rxjs/Observable';

let nextUniqueId = 0;


/**
* The placeholder directive. The content can declare this to implement more
* complex placeholders.
*/
@Directive({
selector: 'md-placeholder, mat-placeholder'
})
export class MdPlaceholder {}


/** Hint text to be shown underneath the form field control. */
@Directive({
selector: 'md-hint, mat-hint',
host: {
'class': 'mat-hint',
'[class.mat-right]': 'align == "end"',
'[attr.id]': 'id',
}
})
export class MdHint {
/** Whether to align the hint label at the start or end of the line. */
@Input() align: 'start' | 'end' = 'start';

/** Unique ID for the hint. Used for the aria-describedby on the form field control. */
@Input() id: string = `md-hint-${nextUniqueId++}`;
}


/** Single error message to be shown underneath the form field. */
@Directive({
selector: 'md-error, mat-error',
host: {
'class': 'mat-error',
'role': 'alert',
'[attr.id]': 'id',
}
})
export class MdError {
@Input() id: string = `md-error-${nextUniqueId++}`;
}
import {MdError} from './error';
import {MdFormFieldControl} from './form-field-control';
import {MdHint} from './hint';
import {MdPlaceholder} from './placeholder';
import {MdPrefix} from './prefix';
import {MdSuffix} from './suffix';


/** Prefix to be placed the the front of the form field. */
@Directive({
selector: '[mdPrefix], [matPrefix]',
})
export class MdPrefix {}


/** Suffix to be placed at the end of the form field. */
@Directive({
selector: '[mdSuffix], [matSuffix]',
})
export class MdSuffix {}


/** An interface which allows a control to work inside of a `MdFormField`. */
export abstract class MdFormFieldControl {
/**
* Stream that emits whenever the state of the control changes such that the parent `MdFormField`
* needs to run change detection.
*/
stateChanges: Observable<void>;

/** Gets the element ID for this control. */
abstract getId(): string;

/** Gets the placeholder for this control. */
abstract getPlaceholder(): string;

/** Gets the NgControl for this control. */
abstract getNgControl(): NgControl | null;

/** Whether the control is focused. */
abstract isFocused(): boolean;

/** Whether the control is empty. */
abstract isEmpty(): boolean;

/** Whether the control is required. */
abstract isRequired(): boolean;

/** Whether the control is disabled. */
abstract isDisabled(): boolean;

/** Whether the control is in an error state. */
abstract isErrorState(): boolean;

/** Sets the list of element IDs that currently describe this control. */
abstract setDescribedByIds(ids: string[]): void;

/** Focuses this control. */
abstract focus(): void;
}
let nextUniqueId = 0;


/** Container for form controls that applies Material Design styling and behavior. */
@Component({
moduleId: module.id,
// TODO(mmalerba): the input-container selectors and classes are deprecated and will be removed.
selector: 'md-input-container, mat-input-container, md-form-field, mat-form-field',
templateUrl: 'form-field.html',
// MdInput is a directive and can't have styles, so we need to include its styles here.
Expand All @@ -158,8 +67,6 @@ export abstract class MdFormFieldControl {
]),
],
host: {
// Remove align attribute to prevent it from interfering with layout.
'[attr.align]': 'null',
'class': 'mat-input-container mat-form-field',
'[class.mat-input-invalid]': '_control.isErrorState()',
'[class.mat-form-field-invalid]': '_control.isErrorState()',
Expand Down
32 changes: 32 additions & 0 deletions src/lib/form-field/hint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Directive, Input} from '@angular/core';


let nextUniqueId = 0;


/** Hint text to be shown underneath the form field control. */
@Directive({
selector: 'md-hint, mat-hint',
host: {
'class': 'mat-hint',
'[class.mat-right]': 'align == "end"',
'[attr.id]': 'id',
// Remove align attribute to prevent it from interfering with layout.
'[attr.align]': 'null',
}
})
export class MdHint {
/** Whether to align the hint label at the start or end of the line. */
@Input() align: 'start' | 'end' = 'start';

/** Unique ID for the hint. Used for the aria-describedby on the form field control. */
@Input() id: string = `mat-hint-${nextUniqueId++}`;
}
20 changes: 12 additions & 8 deletions src/lib/form-field/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
*/

import {NgModule} from '@angular/core';
import {
MdError,
MdHint,
MdFormField,
MdPlaceholder,
MdPrefix,
MdSuffix
} from './form-field';
import {MdError} from './error';
import {MdFormField} from './form-field';
import {MdHint} from './hint';
import {MdPlaceholder} from './placeholder';
import {MdPrefix} from './prefix';
import {MdSuffix} from './suffix';
import {CommonModule} from '@angular/common';
import {PlatformModule} from '../core/platform/index';

Expand Down Expand Up @@ -44,6 +42,12 @@ import {PlatformModule} from '../core/platform/index';
export class MdFormFieldModule {}


export * from './error';
export * from './form-field';
export * from './form-field-control';
export * from './form-field-errors';
export * from './hint';
export * from './placeholder';
export * from './prefix';
export * from './suffix';

16 changes: 16 additions & 0 deletions src/lib/form-field/placeholder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Directive} from '@angular/core';


/** The floating placeholder for an `MdFormField`. */
@Directive({
selector: 'md-placeholder, mat-placeholder'
})
export class MdPlaceholder {}
16 changes: 16 additions & 0 deletions src/lib/form-field/prefix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Directive} from '@angular/core';


/** Prefix to be placed the the front of the form field. */
@Directive({
selector: '[mdPrefix], [matPrefix]',
})
export class MdPrefix {}
Loading

0 comments on commit 9baaaeb

Please sign in to comment.