diff --git a/.vscode/settings.json b/.vscode/settings.json
index d3ecd8c..4dcdac2 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,10 +1,12 @@
{
"cSpell.words": [
"Callout",
+ "Droppable",
"Focusable",
"Injectable",
"Packagr",
"Renderable",
+ "Reselect",
"Selectable",
"VDOM",
"borderless",
diff --git a/apps/demo/src/app/app.component.html b/apps/demo/src/app/app.component.html
index cd0e184..b55900f 100644
--- a/apps/demo/src/app/app.component.html
+++ b/apps/demo/src/app/app.component.html
@@ -9,6 +9,16 @@
+
+
diff --git a/apps/demo/src/app/app.component.ts b/apps/demo/src/app/app.component.ts
index f25a917..2893476 100644
--- a/apps/demo/src/app/app.component.ts
+++ b/apps/demo/src/app/app.component.ts
@@ -1,5 +1,13 @@
import { ChangeDetectorRef, Component, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
-import { ICalendarStrings, IContextualMenuProps, ISelection, Selection } from 'office-ui-fabric-react';
+import {
+ ICalendarStrings,
+ IContextualMenuProps,
+ ISelection,
+ Selection,
+ DropdownMenuItemType,
+ IDropdownOption,
+} from 'office-ui-fabric-react';
+import { FabDropdownComponent } from '@angular-react/fabric';
const suffix = ' cm';
@@ -23,6 +31,22 @@ export class AppComponent {
console.log('onMouseOver', { ev });
}
+ logEvent(...args: any[]) {
+ console.log(args);
+ }
+
+ selectedItem?: IDropdownOption;
+ options: FabDropdownComponent['options'] = [
+ { key: 'A', text: 'Option a' },
+ { key: 'B', text: 'Option b' },
+ { key: 'C', text: 'Option c' },
+ { key: 'D', text: 'Option d' },
+ { key: 'divider_1', text: '-', itemType: DropdownMenuItemType.Divider },
+ { key: 'E', text: 'Option e' },
+ { key: 'F', text: 'Option f' },
+ { key: 'G', text: 'Option g' },
+ ];
+
textFieldValue = 'Hello';
marqueeEnabled: boolean;
diff --git a/apps/demo/src/app/app.module.ts b/apps/demo/src/app/app.module.ts
index 245b583..3bae67a 100644
--- a/apps/demo/src/app/app.module.ts
+++ b/apps/demo/src/app/app.module.ts
@@ -13,6 +13,7 @@ import {
FabDialogModule,
FabDividerModule,
FabFabricModule,
+ FabDropdownModule,
FabGroupModule,
FabGroupedListModule,
FabHoverCardModule,
@@ -49,6 +50,7 @@ import { CounterComponent } from './counter/counter.component';
FabButtonModule,
FabDialogModule,
FabImageModule,
+ FabDropdownModule,
FabPanelModule,
FabCommandBarModule,
FabBreadcrumbModule,
diff --git a/libs/fabric/src/lib/components/dropdown/dropdown.component.ts b/libs/fabric/src/lib/components/dropdown/dropdown.component.ts
new file mode 100644
index 0000000..3b717d8
--- /dev/null
+++ b/libs/fabric/src/lib/components/dropdown/dropdown.component.ts
@@ -0,0 +1,149 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { InputRendererOptions, JsxRenderFunc, ReactWrapperComponent } from '@angular-react/core';
+import {
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ ElementRef,
+ Input,
+ OnInit,
+ Renderer2,
+ ViewChild,
+ Output,
+ EventEmitter,
+} from '@angular/core';
+import { IDropdownProps, IDropdownOption, IDropdown } from 'office-ui-fabric-react/lib/Dropdown';
+import { ISelectableDroppableTextProps, ISelectableOption } from 'office-ui-fabric-react';
+
+@Component({
+ selector: 'fab-dropdown',
+ exportAs: 'fabDropdown',
+ template: `
+
+ `,
+ styles: ['react-renderer'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class FabDropdownComponent extends ReactWrapperComponent implements OnInit {
+ @ViewChild('reactNode') protected reactNodeRef: ElementRef;
+
+ @Input() componentRef?: IDropdownProps['componentRef'];
+ @Input() label?: IDropdownProps['label'];
+ @Input() ariaLabel?: IDropdownProps['ariaLabel'];
+ @Input() id?: IDropdownProps['id'];
+ @Input() className?: IDropdownProps['className'];
+ @Input() defaultSelectedKey?: IDropdownProps['defaultSelectedKey'];
+ @Input() selectedKey?: IDropdownProps['selectedKey'];
+ @Input() disabled?: IDropdownProps['disabled'];
+ @Input() required?: IDropdownProps['required'];
+ @Input() calloutProps?: IDropdownProps['calloutProps'];
+ @Input() panelProps?: IDropdownProps['panelProps'];
+ @Input() errorMessage?: IDropdownProps['errorMessage'];
+
+ @Input() placeholder: IDropdownProps['placeholder'];
+ @Input() options: IDropdownProps['options'];
+ @Input() dropdownWidth?: IDropdownProps['dropdownWidth'];
+ @Input() responsiveMode?: IDropdownProps['responsiveMode'];
+ @Input() multiSelect?: IDropdownProps['multiSelect'];
+ @Input() defaultSelectedKeys?: IDropdownProps['defaultSelectedKeys'];
+ @Input() selectedKeys?: IDropdownProps['selectedKeys'];
+ @Input() multiSelectDelimiter?: IDropdownProps['multiSelectDelimiter'];
+ @Input() notifyOnReselect?: IDropdownProps['notifyOnReselect'];
+ @Input() keytipProps?: IDropdownProps['keytipProps'];
+ @Input() theme?: IDropdownProps['theme'];
+ @Input() styles?: IDropdownProps['styles'];
+
+ @Input() renderContainer?: InputRendererOptions>;
+ @Input() renderList?: InputRendererOptions>;
+ @Input() renderItem?: InputRendererOptions;
+ @Input() renderOption?: InputRendererOptions;
+ @Input() renderPlaceHolder?: InputRendererOptions;
+ @Input() renderTitle?: InputRendererOptions;
+ @Input() renderCaretDown?: InputRendererOptions;
+
+ @Output() readonly onChange = new EventEmitter<{ event: Event; option?: IDropdownOption; index?: number }>();
+ @Output() readonly onDismiss = new EventEmitter();
+
+ onRenderContainer: (
+ props?: ISelectableDroppableTextProps,
+ defaultRender?: JsxRenderFunc>
+ ) => JSX.Element;
+ onRenderList: (
+ props?: ISelectableDroppableTextProps,
+ defaultRender?: JsxRenderFunc>
+ ) => JSX.Element;
+ onRenderItem: (props?: ISelectableOption, defaultRender?: JsxRenderFunc) => JSX.Element;
+ onRenderOption: (props?: ISelectableOption, defaultRender?: JsxRenderFunc) => JSX.Element;
+ onRenderPlaceHolder: (props?: IDropdownProps, defaultRender?: JsxRenderFunc) => JSX.Element;
+ onRenderTitle: (
+ props?: IDropdownOption | IDropdownOption[],
+ defaultRender?: JsxRenderFunc
+ ) => JSX.Element;
+ onRenderCaretDown: (props?: IDropdownProps, defaultRender?: JsxRenderFunc) => JSX.Element;
+
+ constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, renderer: Renderer2) {
+ super(elementRef, changeDetectorRef, renderer, { setHostDisplay: true });
+
+ this.onChangeHandler = this.onChangeHandler.bind(this);
+ this.onDismissHandler = this.onDismissHandler.bind(this);
+ }
+
+ ngOnInit() {
+ this.onRenderContainer = this.createRenderPropHandler(this.renderContainer);
+ this.onRenderList = this.createRenderPropHandler(this.renderList);
+ this.onRenderItem = this.createRenderPropHandler(this.renderItem);
+ this.onRenderOption = this.createRenderPropHandler(this.renderOption);
+ this.onRenderPlaceHolder = this.createRenderPropHandler(this.renderPlaceHolder);
+ this.onRenderTitle = this.createRenderPropHandler(this.renderTitle);
+ this.onRenderCaretDown = this.createRenderPropHandler(this.renderCaretDown);
+ }
+
+ onChangeHandler(event: React.FormEvent, option?: IDropdownOption, index?: number) {
+ this.onChange.emit({
+ event: event && event.nativeEvent,
+ option,
+ index,
+ });
+ }
+
+ onDismissHandler() {
+ this.onDismiss.emit();
+ }
+}
diff --git a/libs/fabric/src/lib/components/dropdown/dropdown.module.ts b/libs/fabric/src/lib/components/dropdown/dropdown.module.ts
new file mode 100644
index 0000000..6a95191
--- /dev/null
+++ b/libs/fabric/src/lib/components/dropdown/dropdown.module.ts
@@ -0,0 +1,23 @@
+// 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 { Dropdown } from 'office-ui-fabric-react/lib/Dropdown';
+import { FabDropdownComponent } from './dropdown.component';
+
+const components = [FabDropdownComponent];
+
+@NgModule({
+ imports: [CommonModule],
+ declarations: components,
+ exports: components,
+ schemas: [NO_ERRORS_SCHEMA],
+})
+export class FabDropdownModule {
+ constructor() {
+ // Add any React elements to the registry (used by the renderer).
+ registerElement('Dropdown', () => Dropdown);
+ }
+}
diff --git a/libs/fabric/src/lib/components/dropdown/public-api.ts b/libs/fabric/src/lib/components/dropdown/public-api.ts
new file mode 100644
index 0000000..c45bf36
--- /dev/null
+++ b/libs/fabric/src/lib/components/dropdown/public-api.ts
@@ -0,0 +1,5 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+export * from './dropdown.component';
+export * from './dropdown.module';
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
index 72859e8..1e0e041 100644
--- 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
@@ -67,7 +67,7 @@ export class FabBaseTextFieldComponent extends ReactWrapperComponent) => JSX.Element;
constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, renderer: Renderer2) {
- super(elementRef, changeDetectorRef, renderer);
+ super(elementRef, changeDetectorRef, renderer, { setHostDisplay: true });
this.onChangeHandler = this.onChangeHandler.bind(this);
this.onBeforeChangeHandler = this.onBeforeChangeHandler.bind(this);
diff --git a/libs/fabric/src/public-api.ts b/libs/fabric/src/public-api.ts
index dd69a26..f2ba220 100644
--- a/libs/fabric/src/public-api.ts
+++ b/libs/fabric/src/public-api.ts
@@ -14,6 +14,7 @@ export * from './lib/components/date-picker/public-api';
export * from './lib/components/details-list/public-api';
export * from './lib/components/dialog/public-api';
export * from './lib/components/divider/public-api';
+export * from './lib/components/dropdown/public-api';
export * from './lib/components/fabric/public-api';
export * from './lib/components/group/public-api';
export * from './lib/components/grouped-list/public-api';