Skip to content
This repository has been archived by the owner on Oct 7, 2020. It is now read-only.

feat(notched-outline): Change notched outline to use 3 divs #1581

Merged
merged 2 commits into from
Dec 5, 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
4 changes: 2 additions & 2 deletions packages/floating-label/floating-label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class MdcFloatingLabel implements AfterContentInit, OnDestroy {

@Input() for?: string;

createAdapter() {
private _createAdapter() {
return {
addClass: (className: string) => this._getHostElement().classList.add(className),
removeClass: (className: string) => this._getHostElement().classList.remove(className),
Expand All @@ -45,7 +45,7 @@ export class MdcFloatingLabel implements AfterContentInit, OnDestroy {
public elementRef: ElementRef<HTMLElement>) { }

ngAfterContentInit(): void {
this._foundation = new MDCFloatingLabelFoundation(this.createAdapter());
this._foundation = new MDCFloatingLabelFoundation(this._createAdapter());
this._loadListeners();
}

Expand Down
4 changes: 2 additions & 2 deletions packages/line-ripple/line-ripple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class MdcLineRipple implements OnInit, OnDestroy {
/** Emits whenever the component is destroyed. */
private _destroy = new Subject<void>();

createAdapter() {
private _createAdapter() {
return {
addClass: (className: string) => this._getHostElement().classList.add(className),
removeClass: (className: string) => this._getHostElement().classList.remove(className),
Expand All @@ -33,7 +33,7 @@ export class MdcLineRipple implements OnInit, OnDestroy {
deactivate(): void,
setRippleCenter(xCoordinate: number): void,
handleTransitionEnd(evt: TransitionEvent): void
} = new MDCLineRippleFoundation(this.createAdapter());
} = new MDCLineRippleFoundation(this._createAdapter());

constructor(
private _ngZone: NgZone,
Expand Down
2 changes: 2 additions & 0 deletions packages/notched-outline/notched-outline-module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { NgModule } from '@angular/core';

import { MdcFloatingLabelModule } from '@angular-mdc/web/floating-label';
import { MdcNotchedOutline } from './notched-outline';

@NgModule({
imports: [MdcFloatingLabelModule],
exports: [MdcNotchedOutline],
declarations: [MdcNotchedOutline]
})
Expand Down
56 changes: 29 additions & 27 deletions packages/notched-outline/notched-outline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,63 @@ import {
ChangeDetectionStrategy,
Component,
ElementRef,
Input,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import { Platform } from '@angular-mdc/web/common';

import { MdcFloatingLabel } from '@angular-mdc/web/floating-label';

import { MDCNotchedOutlineFoundation } from '@material/notched-outline/index';

@Component({
moduleId: module.id,
selector: '[mdcNotchedOutline], mdc-notched-outline',
exportAs: 'mdcNotchedOutline',
host: {
'class': 'mdc-notched-outline',
'[class.mdc-notched-outline--upgraded]': 'label',
'[class.mdc-notched-outline--no-label]': '!label'
},
template: `
<div #notchOutline class="mdc-notched-outline">
<svg
focusable="false">
<path #svgpath class="mdc-notched-outline__path"/>
</svg>
<div class="mdc-notched-outline__leading"></div>
<div #notch class="mdc-notched-outline__notch">
<label mdcFloatingLabel [for]="for">{{label}}</label>
</div>
<div #notchIdle class="mdc-notched-outline__idle"></div>
<div class="mdc-notched-outline__trailing"></div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
})
export class MdcNotchedOutline {
@ViewChild('notchOutline') _notchOutline!: ElementRef<HTMLElement>;
@ViewChild('svgpath') _svgpath!: ElementRef;
@ViewChild('notchIdle') _notchIdle!: ElementRef<HTMLElement>;
@Input() label?: string;
@Input() for?: string;
@ViewChild('notch') _notchElement!: ElementRef<HTMLElement>;
@ViewChild(MdcFloatingLabel) floatingLabel!: MdcFloatingLabel;

createAdapter() {
private _createAdapter() {
return {
getWidth: () => this._notchOutline.nativeElement.offsetWidth,
getHeight: () => this._notchOutline.nativeElement.offsetHeight,
addClass: (className: string) => this._notchOutline.nativeElement.classList.add(className),
removeClass: (className: string) => this._notchOutline.nativeElement.classList.remove(className),
setOutlinePathAttr: (value: string) => this._svgpath.nativeElement.setAttribute('d', value),
getIdleOutlineStyleValue: (propertyName: string) =>
this._platform.isBrowser ? window.getComputedStyle(this._notchIdle.nativeElement).getPropertyValue(propertyName) : ''
addClass: (className: string) => this.elementRef.nativeElement.classList.add(className),
removeClass: (className: string) =>
this.elementRef.nativeElement.classList.remove(className),
setNotchWidthProperty: (width: number) =>
this._notchElement.nativeElement.style.setProperty('width', width > 0 ? width + 'px' : '0')
};
}

private _foundation: {
notch(notchWidth: number, isRtl: boolean): void,
notch(notchWidth: number): void,
closeNotch(): void
} = new MDCNotchedOutlineFoundation(this.createAdapter());
} = new MDCNotchedOutlineFoundation(this._createAdapter());

constructor(
private _platform: Platform,
public elementRef: ElementRef<HTMLElement>) { }
constructor(public elementRef: ElementRef<HTMLElement>) { }

/** Updates outline selectors and SVG path to open notch. */
notch(notchWidth: number, isRtl: boolean): void {
this._foundation.notch(notchWidth, isRtl);
/** Updates notched outline to open notch in outline path. */
notch(notchWidth: number): void {
this._foundation.notch(notchWidth);
}

/** Updates the outline selectors to close notch and return it to idle state. */
/** Updates the notched outline to close notch in outline path. */
closeNotch(): void {
this._foundation.closeNotch();
}
Expand Down
81 changes: 45 additions & 36 deletions packages/textfield/text-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ let nextUniqueId = 0;
(change)="onChange($event)"
(blur)="onBlur()" />
<ng-content></ng-content>
<label mdcFloatingLabel [for]="id" *ngIf="!this.placeholder">{{label}}</label>
<label mdcFloatingLabel [for]="id" *ngIf="!this.placeholder && !outlined">{{label}}</label>
<mdc-line-ripple *ngIf="!this.outlined && !this.textarea"></mdc-line-ripple>
<mdc-notched-outline *ngIf="outlined"></mdc-notched-outline>
<mdc-notched-outline *ngIf="outlined" [label]="label" [for]="id"></mdc-notched-outline>
`,
providers: [
MdcRipple,
Expand Down Expand Up @@ -138,7 +138,6 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
const newValue = toBoolean(value);
if (newValue !== this._outlined) {
this._outlined = toBoolean(newValue);
this._reinitialize();
this.layout();
}
}
Expand Down Expand Up @@ -227,9 +226,9 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
@Output() readonly blur = new EventEmitter<any>();

@ViewChild('input') _input!: ElementRef<HTMLInputElement | HTMLTextAreaElement>;
@ViewChild(MdcFloatingLabel) _floatingLabel!: MdcFloatingLabel;
@ViewChild(MdcLineRipple) _lineRipple!: MdcLineRipple;
@ViewChild(MdcNotchedOutline) _notchedOutline!: MdcNotchedOutline;
@ViewChild(MdcFloatingLabel) _floatingLabel!: MdcFloatingLabel;
@ContentChildren(MdcTextFieldIcon, { descendants: true }) _icons!: QueryList<MdcTextFieldIcon>;

/** View -> model callback called when value changes */
Expand All @@ -248,9 +247,7 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
addClass: (className: string) => this._getHostElement().classList.add(className),
removeClass: (className: string) => this._getHostElement().classList.remove(className),
hasClass: (className: string) => this._getHostElement().classList.contains(className),
isFocused: () => this._platform.isBrowser ? document.activeElement! === this._getInputElement() : false,
isRtl: () =>
this._platform.isBrowser ? window.getComputedStyle(this._getHostElement()).getPropertyValue('direction') === 'rtl' : false
isFocused: () => this._platform.isBrowser ? document.activeElement! === this._getInputElement() : false
},
this._getInputAdapterMethods(),
this._getLabelAdapterMethods(),
Expand All @@ -267,7 +264,7 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
value: this._value,
disabled: this._disabled,
validity: {
valid: this._valid ? this._valid : this._platform.isBrowser ? this._input.nativeElement.validity.valid : true,
valid: this._hasErrorState(),
badInput: this._platform.isBrowser ? this._input.nativeElement.validity.badInput : false
}
};
Expand All @@ -277,10 +274,10 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni

private _getLabelAdapterMethods() {
return {
shakeLabel: (shouldShake: boolean) => this._floatingLabel.shake(shouldShake),
floatLabel: (shouldFloat: boolean) => this._floatingLabel.float(shouldFloat),
hasLabel: () => this._floatingLabel,
getLabelWidth: () => this._floatingLabel ? this._floatingLabel.getWidth() : 0
shakeLabel: (shouldShake: boolean) => this._getFloatingLabel().shake(shouldShake),
floatLabel: (shouldFloat: boolean) => this._getFloatingLabel().float(shouldFloat),
hasLabel: () => this._hasFloatingLabel(),
getLabelWidth: () => this._hasFloatingLabel() ? this._getFloatingLabel().getWidth() : 0
};
}

Expand All @@ -307,7 +304,7 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
private _getOutlineAdapterMethods() {
return {
hasOutline: () => this._notchedOutline,
notchOutline: (labelWidth: number, isRtl: boolean) => this._notchedOutline.notch(labelWidth, isRtl),
notchOutline: (labelWidth: number) => this._notchedOutline.notch(labelWidth),
closeOutline: () => this._notchedOutline.closeNotch()
};
}
Expand All @@ -328,18 +325,18 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
readonly shouldFloat: boolean,
notchOutline(openNotch: boolean): void,
setUseNativeValidation(useNativeValidation: boolean): void,
setTransformOrigin(evt: Event): void,
setTransformOrigin(evt: Event | TouchEvent): void,
handleTextFieldInteraction(): void,
activateFocus(): void,
deactivateFocus(): void,
handleValidationAttributeChange(attributesList?: string[]): void
} = new MDCTextFieldFoundation();

constructor(
public _defaultErrorStateMatcher: ErrorStateMatcher,
private _platform: Platform,
private _changeDetectorRef: ChangeDetectorRef,
public elementRef: ElementRef<HTMLElement>,
public _defaultErrorStateMatcher: ErrorStateMatcher,
@Optional() private _parentFormField: MdcFormField,
@Optional() private _ripple: MdcRipple,
@Self() @Optional() public ngControl: NgControl,
Expand Down Expand Up @@ -367,10 +364,10 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
}

ngOnDestroy(): void {
this._destroyTextField();
this._destroy();
}

ngDoCheck() {
ngDoCheck(): void {
if (this.ngControl) {
// We need to re-evaluate this on every change detection cycle, because there are some
// error triggers that we can't subscribe to (e.g. parent form submissions). This means
Expand Down Expand Up @@ -475,6 +472,22 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
}
}

/** Initializes Text Field's internal state based on the environment state */
private layout(): void {
this._destroy();
this.init();
this._changeDetectorRef.markForCheck();

setTimeout(() => {
if (this._outlined) {
this._foundation.notchOutline(this._foundation.shouldFloat);
}
if (this._hasFloatingLabel()) {
this._getFloatingLabel().float(this._foundation.shouldFloat);
}
});
}

/** Implemented as part of ControlValueAccessor. */
setDisabledState(isDisabled: boolean) {
const newValue = toBoolean(isDisabled);
Expand All @@ -486,19 +499,6 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
this._changeDetectorRef.markForCheck();
}

/** Recomputes the outline SVG path for the outline element. */
layout(): void {
setTimeout(() => {
if (this._outlined) {
this._foundation.notchOutline(this._foundation.shouldFloat);
}

if (this._floatingLabel) {
this._floatingLabel.float(this._foundation.shouldFloat);
}
});
}

private _checkCustomValidity(): void {
Promise.resolve().then(() => {
if (this._valid !== undefined) {
Expand Down Expand Up @@ -533,7 +533,7 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
}
}

private _destroyTextField(): void {
private _destroy(): void {
if (this._lineRipple) {
this._lineRipple.destroy();
}
Expand All @@ -543,12 +543,21 @@ export class MdcTextField extends _MdcTextFieldMixinBase implements AfterViewIni
this._foundation.destroy();
}

private _reinitialize(): void {
if (this._initialized) {
this._destroyTextField();
this.init();
this._changeDetectorRef.markForCheck();
private _hasErrorState(): boolean {
if (this.ngControl) {
return !this.errorState;
}

return this._valid ? this._valid : this._platform.isBrowser ?
this._input.nativeElement.validity.valid : true;
}

private _hasFloatingLabel(): boolean {
return this.label && (this._floatingLabel || this._notchedOutline) ? true : false;
}

private _getFloatingLabel(): MdcFloatingLabel {
return this._floatingLabel || this._notchedOutline.floatingLabel;
}

private _getInputElement(): HTMLInputElement | HTMLTextAreaElement {
Expand Down
3 changes: 2 additions & 1 deletion packages/textfield/textarea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { MdcTextField } from './text-field';
'class': 'mdc-text-field',
'[class.mdc-text-field--textarea]': 'true',
'[class.mdc-text-field--dense]': 'dense',
'[class.mdc-text-field--invalid]': 'errorState'
},
template: `
<textarea #input class="mdc-text-field__input"
Expand All @@ -33,7 +34,7 @@ import { MdcTextField } from './text-field';
(input)="onInput($event.target.value)"
(change)="onChange($event)"
(blur)="onBlur()"></textarea>
<label mdcFloatingLabel [for]="id">{{label}}</label>
<mdc-notched-outline [label]="label" [for]="id"></mdc-notched-outline>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
Expand Down