diff --git a/.vscode/settings.json b/.vscode/settings.json
index 41752295..d3ecd8cc 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -16,6 +16,7 @@
"messagebar",
"nrwl",
"renderprop",
+ "resizable",
"scrollable",
"stylenames",
"submenu",
diff --git a/apps/demo/src/app/app.component.html b/apps/demo/src/app/app.component.html
index a00b374c..ac8ff54d 100644
--- a/apps/demo/src/app/app.component.html
+++ b/apps/demo/src/app/app.component.html
@@ -12,6 +12,10 @@
Getting up and running...
+
+
+{{ textFieldValue }}
+
Tab 1's content
diff --git a/apps/demo/src/app/app.component.ts b/apps/demo/src/app/app.component.ts
index be78a6f4..b18e9637 100644
--- a/apps/demo/src/app/app.component.ts
+++ b/apps/demo/src/app/app.component.ts
@@ -21,6 +21,8 @@ export class AppComponent {
console.log('onMouseOver', { ev });
}
+ textFieldValue = 'Hello';
+
marqueeEnabled: boolean;
runDisabled: boolean;
selection: ISelection;
diff --git a/apps/demo/src/app/app.module.ts b/apps/demo/src/app/app.module.ts
index 0f363758..0dcc981b 100644
--- a/apps/demo/src/app/app.module.ts
+++ b/apps/demo/src/app/app.module.ts
@@ -31,6 +31,7 @@ import {
FabSpinnerModule,
FabToggleModule,
FabTooltipModule,
+ FabTextFieldModule,
} from '@angular-react/fabric';
import { NgModule } from '@angular/core';
import { NxModule } from '@nrwl/nx';
@@ -73,6 +74,7 @@ import { CounterComponent } from './counter/counter.component';
FabDetailsListModule,
FabGroupModule,
FabMarqueeSelectionModule,
+ FabTextFieldModule,
],
declarations: [AppComponent, CounterComponent],
bootstrap: [AppComponent],
diff --git a/libs/fabric/src/lib/components/text-field/base-text-field.component.ts b/libs/fabric/src/lib/components/text-field/base-text-field.component.ts
new file mode 100644
index 00000000..72859e82
--- /dev/null
+++ b/libs/fabric/src/lib/components/text-field/base-text-field.component.ts
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { ReactWrapperComponent, InputRendererOptions, JsxRenderFunc } from '@angular-react/core';
+import {
+ ChangeDetectorRef,
+ EventEmitter,
+ ElementRef,
+ Input,
+ Renderer2,
+ ViewChild,
+ OnInit,
+ Output,
+} from '@angular/core';
+import { ITextFieldProps } from 'office-ui-fabric-react/lib/TextField';
+
+export class FabBaseTextFieldComponent extends ReactWrapperComponent implements OnInit {
+ @ViewChild('reactNode') protected reactNodeRef: ElementRef;
+
+ @Input() componentRef?: ITextFieldProps['componentRef'];
+ @Input() multiline?: ITextFieldProps['multiline'];
+ @Input() resizable?: ITextFieldProps['resizable'];
+ @Input() autoAdjustHeight?: ITextFieldProps['autoAdjustHeight'];
+ @Input() underlined?: ITextFieldProps['underlined'];
+ @Input() borderless?: ITextFieldProps['borderless'];
+ @Input() label?: ITextFieldProps['label'];
+ @Input() description?: ITextFieldProps['description'];
+ @Input() prefix?: ITextFieldProps['prefix'];
+ @Input() suffix?: ITextFieldProps['suffix'];
+ @Input() iconProps?: ITextFieldProps['iconProps'];
+ @Input() defaultValue?: ITextFieldProps['defaultValue'];
+ @Input() value?: ITextFieldProps['value'];
+ @Input() disabled?: ITextFieldProps['disabled'];
+ @Input() readOnly?: ITextFieldProps['readOnly'];
+ @Input() errorMessage?: ITextFieldProps['errorMessage'];
+ @Input() deferredValidationTime?: ITextFieldProps['deferredValidationTime'];
+ @Input() className?: ITextFieldProps['className'];
+ @Input() inputClassName?: ITextFieldProps['inputClassName'];
+ @Input() ariaLabel?: ITextFieldProps['ariaLabel'];
+ @Input() validateOnFocusIn?: ITextFieldProps['validateOnFocusIn'];
+ @Input() validateOnFocusOut?: ITextFieldProps['validateOnFocusOut'];
+ @Input() validateOnLoad?: ITextFieldProps['validateOnLoad'];
+ @Input() theme?: ITextFieldProps['theme'];
+ @Input() styles?: ITextFieldProps['styles'];
+ @Input() autoComplete?: ITextFieldProps['autoComplete'];
+ @Input() mask?: ITextFieldProps['mask'];
+ @Input() maskChar?: ITextFieldProps['maskChar'];
+ @Input() maskFormat?: ITextFieldProps['maskFormat'];
+ @Input() getErrorMessage?: ITextFieldProps['onGetErrorMessage'];
+
+ @Input() renderLabel?: InputRendererOptions;
+ @Input() renderDescription?: InputRendererOptions;
+ @Input() renderPrefix?: InputRendererOptions;
+ @Input() renderSuffix?: InputRendererOptions;
+
+ @Output() readonly onChange = new EventEmitter<{ event: Event; newValue?: string }>();
+ @Output() readonly onBeforeChange = new EventEmitter<{ newValue: any }>();
+ @Output() readonly onNotifyValidationResult = new EventEmitter<{ errorMessage: string; value: string | undefined }>();
+
+ /* Non-React props, more native support for Angular */
+ // support for two-way data binding for `@Input() checked`.
+ @Output() readonly valueChange = new EventEmitter();
+
+ onRenderLabel: (props?: ITextFieldProps, defaultRender?: JsxRenderFunc) => JSX.Element;
+ onRenderDescription: (props?: ITextFieldProps, defaultRender?: JsxRenderFunc) => JSX.Element;
+ onRenderPrefix: (props?: ITextFieldProps, defaultRender?: JsxRenderFunc) => JSX.Element;
+ onRenderSuffix: (props?: ITextFieldProps, defaultRender?: JsxRenderFunc) => JSX.Element;
+
+ constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, renderer: Renderer2) {
+ super(elementRef, changeDetectorRef, renderer);
+
+ this.onChangeHandler = this.onChangeHandler.bind(this);
+ this.onBeforeChangeHandler = this.onBeforeChangeHandler.bind(this);
+ this.onNotifyValidationResultHandler = this.onNotifyValidationResultHandler.bind(this);
+ }
+
+ ngOnInit() {
+ this.onRenderLabel = this.createRenderPropHandler(this.renderLabel);
+ this.onRenderDescription = this.createRenderPropHandler(this.renderDescription);
+ this.onRenderPrefix = this.createRenderPropHandler(this.renderPrefix);
+ this.onRenderSuffix = this.createRenderPropHandler(this.renderSuffix);
+ }
+
+ onChangeHandler(event: React.FormEvent, newValue?: string) {
+ this.onChange.emit({ event: event.nativeEvent, newValue });
+
+ this.valueChange.emit(newValue);
+ }
+
+ onBeforeChangeHandler(newValue: any) {
+ this.onBeforeChange.emit({ newValue });
+ }
+
+ onNotifyValidationResultHandler(errorMessage: string, value: string | undefined) {
+ this.onNotifyValidationResult.emit({ errorMessage, value });
+ }
+}
diff --git a/libs/fabric/src/lib/components/text-field/masked-text-field.component.ts b/libs/fabric/src/lib/components/text-field/masked-text-field.component.ts
new file mode 100644
index 00000000..511370c4
--- /dev/null
+++ b/libs/fabric/src/lib/components/text-field/masked-text-field.component.ts
@@ -0,0 +1,62 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Renderer2, ViewChild } from '@angular/core';
+import { FabBaseTextFieldComponent } from './base-text-field.component';
+
+@Component({
+ selector: 'fab-masked-text-field',
+ exportAs: 'fabMaskedTextField',
+ template: `
+
+
+ `,
+ styles: ['react-renderer'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class FabMaskedTextFieldComponent extends FabBaseTextFieldComponent {
+ @ViewChild('reactNode') protected reactNodeRef: ElementRef;
+
+ constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, renderer: Renderer2) {
+ super(elementRef, changeDetectorRef, renderer);
+ }
+}
diff --git a/libs/fabric/src/lib/components/text-field/public-api.ts b/libs/fabric/src/lib/components/text-field/public-api.ts
new file mode 100644
index 00000000..6c31f2b6
--- /dev/null
+++ b/libs/fabric/src/lib/components/text-field/public-api.ts
@@ -0,0 +1,3 @@
+export * from './text-field.module';
+export * from './masked-text-field.component';
+export * from './text-field.component';
diff --git a/libs/fabric/src/lib/components/text-field/text-field.component.ts b/libs/fabric/src/lib/components/text-field/text-field.component.ts
new file mode 100644
index 00000000..350e9ea0
--- /dev/null
+++ b/libs/fabric/src/lib/components/text-field/text-field.component.ts
@@ -0,0 +1,62 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Renderer2, ViewChild } from '@angular/core';
+import { FabBaseTextFieldComponent } from './base-text-field.component';
+
+@Component({
+ selector: 'fab-text-field',
+ exportAs: 'fabTextField',
+ template: `
+
+
+ `,
+ styles: ['react-renderer'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class FabTextFieldComponent extends FabBaseTextFieldComponent {
+ @ViewChild('reactNode') protected reactNodeRef: ElementRef;
+
+ constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, renderer: Renderer2) {
+ super(elementRef, changeDetectorRef, renderer);
+ }
+}
diff --git a/libs/fabric/src/lib/components/text-field/text-field.module.ts b/libs/fabric/src/lib/components/text-field/text-field.module.ts
new file mode 100644
index 00000000..49b8a82e
--- /dev/null
+++ b/libs/fabric/src/lib/components/text-field/text-field.module.ts
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { registerElement } from '@angular-react/core';
+import { CommonModule } from '@angular/common';
+import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
+import { TextField, MaskedTextField } from 'office-ui-fabric-react/lib/TextField';
+import { FabTextFieldComponent } from './text-field.component';
+import { FabMaskedTextFieldComponent } from './masked-text-field.component';
+
+const components = [FabTextFieldComponent, FabMaskedTextFieldComponent];
+
+@NgModule({
+ imports: [CommonModule],
+ declarations: components,
+ exports: components,
+ schemas: [NO_ERRORS_SCHEMA],
+})
+export class FabTextFieldModule {
+ constructor() {
+ // Add any React elements to the registry (used by the renderer).
+ registerElement('TextField', () => TextField);
+ registerElement('MaskedTextField', () => MaskedTextField);
+ }
+}
diff --git a/libs/fabric/src/public-api.ts b/libs/fabric/src/public-api.ts
index e0784193..5ad2d68b 100644
--- a/libs/fabric/src/public-api.ts
+++ b/libs/fabric/src/public-api.ts
@@ -31,6 +31,7 @@ export * from './lib/components/search-box/public-api';
export * from './lib/components/shimmer/public-api';
export * from './lib/components/slider/public-api';
export * from './lib/components/spinner/public-api';
+export * from './lib/components/text-field/public-api';
export * from './lib/components/toggle/public-api';
export * from './lib/components/tooltip/public-api';