diff --git a/apps/demo/src/app/app.component.html b/apps/demo/src/app/app.component.html
index ff0bdb5e..77fbc103 100644
--- a/apps/demo/src/app/app.component.html
+++ b/apps/demo/src/app/app.component.html
@@ -142,6 +142,30 @@
Getting up and running...
+
+
+
+
Microsoft Fabric [React] Components
Button
-
+
Dialog
>
{{ sampleContent2 }} {{ sampleContent3 }}
-
+
+
+
+
+Combo box
+
+
+
+
+
+
+{{ selectedComboBoxKey }}: {{ selectedComboBoxValue }}
+
+
+
+Directive Calendar
+
+
+
+{{ selectedDate }}
diff --git a/apps/docs/src/app/containers/component-docs/fabric/fabric.component.ts b/apps/docs/src/app/containers/component-docs/fabric/fabric.component.ts
index bf39cc9f..6109e152 100644
--- a/apps/docs/src/app/containers/component-docs/fabric/fabric.component.ts
+++ b/apps/docs/src/app/containers/component-docs/fabric/fabric.component.ts
@@ -1,4 +1,5 @@
import { Component } from '@angular/core';
+import { IComboBoxOption, ICalendarStrings } from 'office-ui-fabric-react';
@Component({
selector: 'app-fabric',
@@ -12,6 +13,23 @@ export class FabricComponent {
secondsCounter = 0;
sampleContent2 = '0 Seconds Passed';
sampleContent3 = '';
+ selectedComboBoxKey: string = "None";
+ selectedComboBoxValue: string = "None";
+ selectedDate: Date;
+
+ comboBoxOptions: IComboBoxOption[] = [
+ { key: 'A', text: 'See option A' },
+ { key: 'B', text: 'See option B' },
+ ];
+
+ onSelectDate(event) {
+ this.selectedDate = event.date;
+ }
+
+ comboChange(event) {
+ this.selectedComboBoxKey = event.option.key;
+ this.selectedComboBoxValue = event.option.text;
+ }
get sampleContent() {
return `Button clicked ${this.sampleContentCounter} times.`;
diff --git a/apps/docs/src/app/fabric.module.ts b/apps/docs/src/app/fabric.module.ts
index 42c601bb..dafe848d 100644
--- a/apps/docs/src/app/fabric.module.ts
+++ b/apps/docs/src/app/fabric.module.ts
@@ -1,7 +1,17 @@
import { NgModule } from '@angular/core';
-import { FabButtonModule, FabDialogModule } from '@angular-react/fabric';
+import {
+ FabButtonModule,
+ FabDialogModule,
+ FabComboBoxModule,
+ FabCalendarModule
+} from '@angular-react/fabric';
-const componentModules = [FabButtonModule, FabDialogModule];
+const componentModules = [
+ FabButtonModule,
+ FabDialogModule,
+ FabComboBoxModule,
+ FabCalendarModule
+];
@NgModule({
imports: componentModules,
exports: componentModules,
diff --git a/libs/core/src/lib/components/wrapper-component.ts b/libs/core/src/lib/components/wrapper-component.ts
index 77accbf0..0dc6e3e1 100644
--- a/libs/core/src/lib/components/wrapper-component.ts
+++ b/libs/core/src/lib/components/wrapper-component.ts
@@ -97,7 +97,7 @@ export abstract class ReactWrapperComponent implements AfterV
this._contentClass = value;
if (isReactNode(this.reactNodeRef.nativeElement)) {
this.reactNodeRef.nativeElement.setProperty('className', classnames(value));
- this.changeDetectorRef.detectChanges();
+ this.markForCheck();
}
}
@@ -118,7 +118,7 @@ export abstract class ReactWrapperComponent implements AfterV
if (isReactNode(this.reactNodeRef.nativeElement)) {
const stringValue = typeof value === 'string' ? value : stylenames(value);
this.reactNodeRef.nativeElement.setProperty('style', toStyle(stringValue));
- this.changeDetectorRef.detectChanges();
+ this.markForCheck();
}
}
@@ -142,9 +142,11 @@ export abstract class ReactWrapperComponent implements AfterV
this._shouldSetHostDisplay = setHostDisplay;
}
- ngAfterViewInit() {
+ ngAfterContentInit() {
this._passAttributesAsProps();
+ }
+ ngAfterViewInit() {
if (this._shouldSetHostDisplay) {
this._setHostDisplay();
}
diff --git a/libs/fabric/src/lib/components/button/base-button.component.ts b/libs/fabric/src/lib/components/button/base-button.component.ts
index a6977cbc..e43cd76d 100644
--- a/libs/fabric/src/lib/components/button/base-button.component.ts
+++ b/libs/fabric/src/lib/components/button/base-button.component.ts
@@ -129,6 +129,7 @@ export abstract class FabBaseButtonComponent extends ReactWrapperComponent {
+export class FabCalendarComponent extends ReactWrapperComponent implements AfterContentInit {
@ViewChild('reactNode') protected reactNodeRef: ElementRef;
@Input() componentRef?: ICalendarProps['componentRef'];
@@ -91,14 +94,22 @@ export class FabCalendarComponent extends ReactWrapperComponent
@Output() readonly onSelectDate = new EventEmitter<{ date: Date; selectedDateRangeArray?: Date[] }>();
@Output() readonly onDismiss = new EventEmitter();
+ @ContentChild(CalendarStringsDirective) readonly calendarStringsDirective?: CalendarStringsDirective;
+
constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, renderer: Renderer2) {
super(elementRef, changeDetectorRef, renderer);
-
// coming from React context - we need to bind to this so we can access the Angular Component properties
this.onSelectDateHandler = this.onSelectDateHandler.bind(this);
this.onDismissHandler = this.onDismissHandler.bind(this);
}
+ ngAfterContentInit() {
+ if (this.calendarStringsDirective) {
+ this._initDirective(this.calendarStringsDirective);
+ super.ngAfterContentInit();
+ }
+ }
+
onSelectDateHandler(date: Date, selectedDateRangeArray?: Date[]) {
this.onSelectDate.emit({
date,
@@ -109,4 +120,8 @@ export class FabCalendarComponent extends ReactWrapperComponent
onDismissHandler() {
this.onDismiss.emit();
}
+
+ private _initDirective(calendarStringsDirective: CalendarStringsDirective) {
+ this.strings = calendarStringsDirective.strings;
+ }
}
diff --git a/libs/fabric/src/lib/components/calendar/calendar.module.ts b/libs/fabric/src/lib/components/calendar/calendar.module.ts
index 32b55ab7..1aaacfbd 100644
--- a/libs/fabric/src/lib/components/calendar/calendar.module.ts
+++ b/libs/fabric/src/lib/components/calendar/calendar.module.ts
@@ -8,16 +8,17 @@ import * as CalendarCss from 'office-ui-fabric-react/lib-amd/components/Calendar
import { Calendar } from 'office-ui-fabric-react';
import { noop } from '../../utils/noop';
import { FabCalendarComponent } from './calendar.component';
+import { CalendarStringsDirective } from './directives/calendar-strings-directive.component';
// Dummy action to force CalendarCss to load and not be tree-shaken away.
noop(CalendarCss);
-const components = [FabCalendarComponent];
+const declarations = [FabCalendarComponent, CalendarStringsDirective];
@NgModule({
imports: [CommonModule],
- declarations: components,
- exports: components,
+ declarations: declarations,
+ exports: declarations,
schemas: [NO_ERRORS_SCHEMA],
})
export class FabCalendarModule {
diff --git a/libs/fabric/src/lib/components/calendar/directives/calendar-strings-directive.component.ts b/libs/fabric/src/lib/components/calendar/directives/calendar-strings-directive.component.ts
new file mode 100644
index 00000000..70ac7c7f
--- /dev/null
+++ b/libs/fabric/src/lib/components/calendar/directives/calendar-strings-directive.component.ts
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { Directive, Input } from '@angular/core';
+import { ICalendarStrings } from 'office-ui-fabric-react';
+
+/**
+ * Wrapper directive for calendar strings
+ */
+@Directive({ selector: 'fab-calendar > fab-calendar-strings' })
+export class CalendarStringsDirective {
+
+ @Input() months: ICalendarStrings['months'];
+ @Input() shortMonths: ICalendarStrings['shortMonths'];
+ @Input() days: ICalendarStrings['days'];
+ @Input() shortDays: ICalendarStrings['shortDays'];
+ @Input() goToToday: ICalendarStrings['goToToday'];
+ @Input() weekNumberFormatString: ICalendarStrings['weekNumberFormatString'];
+
+
+ get strings(): ICalendarStrings {
+ return {
+ months: this.months,
+ shortMonths: this.shortMonths,
+ days: this.days,
+ shortDays: this.shortDays,
+ goToToday: this.goToToday,
+ weekNumberFormatString: this.weekNumberFormatString
+ }
+ }
+}
diff --git a/libs/fabric/src/lib/components/combo-box/base-combo-box.component.ts b/libs/fabric/src/lib/components/combo-box/base-combo-box.component.ts
index 435bae06..18ef0823 100644
--- a/libs/fabric/src/lib/components/combo-box/base-combo-box.component.ts
+++ b/libs/fabric/src/lib/components/combo-box/base-combo-box.component.ts
@@ -2,10 +2,26 @@
// Licensed under the MIT License.
import { InputRendererOptions, JsxRenderFunc, ReactWrapperComponent } from '@angular-react/core';
-import { ChangeDetectorRef, ElementRef, EventEmitter, Input, NgZone, OnInit, Output, Renderer2 } from '@angular/core';
+import {
+ ChangeDetectorRef,
+ ElementRef,
+ EventEmitter,
+ Input,
+ NgZone,
+ OnInit,
+ Output,
+ Renderer2,
+ ContentChild,
+ AfterContentInit,
+} from '@angular/core';
import { IComboBox, IComboBoxOption, IComboBoxProps } from 'office-ui-fabric-react/lib/ComboBox';
+import { ComboBoxOptionDirective } from './directives/combo-box-option.directive';
+import { ComboBoxOptionsDirective } from './directives/combo-box-options.directive';
+
+export abstract class FabBaseComboBoxComponent extends ReactWrapperComponent
+ implements OnInit, AfterContentInit {
+ @ContentChild(ComboBoxOptionDirective) readonly optionsDirective?: ComboBoxOptionDirective;
-export abstract class FabBaseComboBoxComponent extends ReactWrapperComponent implements OnInit {
@Input() componentRef?: IComboBoxProps['componentRef'];
@Input() options: IComboBoxProps['options'];
@Input() allowFreeform?: IComboBoxProps['allowFreeform'];
@@ -49,6 +65,8 @@ export abstract class FabBaseComboBoxComponent extends ReactWrapperComponent();
@Output() readonly onScrollToItem = new EventEmitter<{ itemIndex: number }>();
+ @ContentChild(ComboBoxOptionsDirective) readonly comboBoxOptionsDirective?: ComboBoxOptionsDirective;
+
onRenderLowerContent: (props?: IComboBoxProps, defaultRender?: JsxRenderFunc) => JSX.Element;
constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, renderer: Renderer2, ngZone: NgZone) {
@@ -65,6 +83,13 @@ export abstract class FabBaseComboBoxComponent extends ReactWrapperComponent, option?: IComboBoxOption, index?: number) {
this.onItemClick.emit({
event: event.nativeEvent,
@@ -95,4 +120,9 @@ export abstract class FabBaseComboBoxComponent extends ReactWrapperComponent options' })
+export class ComboBoxOptionsDirective {
+ @ContentChildren(ComboBoxOptionDirective) readonly directiveItems: QueryList;
+
+ get items() {
+ return this.directiveItems.map(directiveItem => {
+ return {
+ key: directiveItem.optionKey,
+ text: directiveItem.text,
+ title: directiveItem.title,
+ itemType: directiveItem.itemType,
+ index: directiveItem.index,
+ ariaLabel: directiveItem.ariaLabel,
+ selected: directiveItem.selected,
+ disabled: directiveItem.disabled,
+ data: directiveItem.data,
+ styles: directiveItem.styles,
+ useAriaLabelAsText: directiveItem.useAriaLabelAsText
+ }
+ });
+ }
+}
diff --git a/libs/fabric/src/lib/components/command-bar/command-bar.component.ts b/libs/fabric/src/lib/components/command-bar/command-bar.component.ts
index 48f4dbea..3c5358a6 100644
--- a/libs/fabric/src/lib/components/command-bar/command-bar.component.ts
+++ b/libs/fabric/src/lib/components/command-bar/command-bar.component.ts
@@ -127,6 +127,7 @@ export class FabCommandBarComponent extends ReactWrapperComponent