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

Commit

Permalink
feat(notched-outline): Change notched outline to use 3 divs (#1581)
Browse files Browse the repository at this point in the history
  • Loading branch information
trimox authored Dec 5, 2018
1 parent f4a7539 commit 0614eba
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 68 deletions.
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

0 comments on commit 0614eba

Please sign in to comment.