diff --git a/apps/demo/src/app/app.component.html b/apps/demo/src/app/app.component.html
index b55900f6..ff0bdb5e 100644
--- a/apps/demo/src/app/app.component.html
+++ b/apps/demo/src/app/app.component.html
@@ -41,6 +41,11 @@
Getting up and running...
Tab 3's content
+
+
+
+
+
Getting up and running...
text="Run"
[iconProps]="{ iconName: 'CaretRight' }"
[disabled]="runDisabled"
+ data-track-type="run"
>
Getting up and running...
[iconProps]="{ iconName: 'Add' }"
(click)="onNewClicked()"
>
-
+
+
+
+
implements OnInit, AfterContentInit, OnDestroy {
@@ -167,6 +168,7 @@ export abstract class FabBaseButtonComponent extends ReactWrapperComponent {
directive.click.emit({ ev: ev && ev.nativeEvent, item: item });
},
diff --git a/libs/fabric/src/lib/components/command-bar/directives/command-bar-item.directives.ts b/libs/fabric/src/lib/components/command-bar/directives/command-bar-item.directives.ts
index 6002ca8c..b80c6dd3 100644
--- a/libs/fabric/src/lib/components/command-bar/directives/command-bar-item.directives.ts
+++ b/libs/fabric/src/lib/components/command-bar/directives/command-bar-item.directives.ts
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-import { ContentChild, Directive, Input, TemplateRef } from '@angular/core';
+import { ContentChild, Directive, Input, TemplateRef, ElementRef } from '@angular/core';
import { ContextualMenuItemDirective } from '../../contextual-menu/directives/contextual-menu-item.directive';
import { ItemChangedPayload } from '../../core/declarative/item-changed.payload';
import {
@@ -37,4 +37,8 @@ export class CommandBarItemDirective extends ContextualMenuItemDirective impleme
@Input() cacheKey?: ICommandBarItemOptions['cacheKey'];
@Input() renderedInOverflow?: ICommandBarItemOptions['renderedInOverflow'];
@Input() commandBarButtonAs?: ICommandBarItemOptions['commandBarButtonAs'];
+
+ constructor(elementRef: ElementRef) {
+ super(elementRef);
+ }
}
diff --git a/libs/fabric/src/lib/components/command-bar/directives/command-bar-items.directives.ts b/libs/fabric/src/lib/components/command-bar/directives/command-bar-items.directives.ts
index 2b6ef772..4fe401e9 100644
--- a/libs/fabric/src/lib/components/command-bar/directives/command-bar-items.directives.ts
+++ b/libs/fabric/src/lib/components/command-bar/directives/command-bar-items.directives.ts
@@ -6,6 +6,7 @@ import { ContentChildren, Directive, QueryList } from '@angular/core';
import { ChangeableItemsDirective } from '../../core/shared/changeable-items.directive';
import { ICommandBarItemOptions } from '../command-bar.component';
import { CommandBarItemDirective } from './command-bar-item.directives';
+import { getDataAttributes } from '../../../utils/get-data-attributes';
export abstract class CommandBarItemsDirectiveBase extends ChangeableItemsDirective {
abstract readonly directiveItems: QueryList;
@@ -13,8 +14,9 @@ export abstract class CommandBarItemsDirectiveBase extends ChangeableItemsDirect
get items() {
return (
this.directiveItems &&
- this.directiveItems.map(directiveItem => ({
+ this.directiveItems.map((directiveItem: CommandBarItemDirective) => ({
...directiveItem,
+ ...getDataAttributes(directiveItem.elementRef.nativeElement, true),
onClick: (ev, item) => {
directiveItem.click.emit({
ev: ev && ev.nativeEvent,
diff --git a/libs/fabric/src/lib/components/contextual-menu/directives/contextual-menu-item.directive.ts b/libs/fabric/src/lib/components/contextual-menu/directives/contextual-menu-item.directive.ts
index da641e99..a40dc829 100644
--- a/libs/fabric/src/lib/components/contextual-menu/directives/contextual-menu-item.directive.ts
+++ b/libs/fabric/src/lib/components/contextual-menu/directives/contextual-menu-item.directive.ts
@@ -12,6 +12,7 @@ import {
QueryList,
ContentChild,
TemplateRef,
+ ElementRef,
} from '@angular/core';
import { IContextualMenuItem } from 'office-ui-fabric-react';
import { KnownKeys, InputRendererOptions } from '@angular-react/core';
@@ -20,6 +21,7 @@ import { OnChanges } from '../../../declarations/angular/typed-changes';
import { ItemChangedPayload } from '../../core/declarative/item-changed.payload';
import { ChangeableItemsHelper, IChangeableItemsContainer } from '../../core/shared/changeable-helper';
import { ChangeableItemDirective } from '../../core/shared/changeable-item.directive';
+import { getDataAttributes } from '../../../utils/get-data-attributes';
export type ContextualMenuItemChangedPayload = ItemChangedPayload<
IContextualMenuItemOptions['key'],
@@ -101,6 +103,10 @@ export class ContextualMenuItemDirective extends ChangeableItemDirective) {
+ super();
+ }
+
private _changeableItemsHelper: ChangeableItemsHelper;
ngAfterContentInit() {
@@ -129,6 +135,7 @@ export class ContextualMenuItemDirective extends ChangeableItemDirective {
directive.click.emit({ ev: ev && ev.nativeEvent, item: item });
},
@@ -143,6 +150,11 @@ export interface IContextualMenuItemOptions
readonly renderIcon?: InputRendererOptions;
readonly render?: InputRendererOptions;
readonly data?: TData;
+
+ /**
+ * For any attributes like data-* etc.
+ */
+ [propertyName: string]: any;
}
export interface IContextualMenuItemOptionsRenderContext {
diff --git a/libs/fabric/src/lib/utils/get-data-attributes.ts b/libs/fabric/src/lib/utils/get-data-attributes.ts
new file mode 100644
index 00000000..48678a39
--- /dev/null
+++ b/libs/fabric/src/lib/utils/get-data-attributes.ts
@@ -0,0 +1,32 @@
+import { kebabCase } from './kebab-case';
+
+/**
+ * Gets the data attributes on an `HTMLElement`.
+ *
+ * @example
+```keepDataPrefix === false```:
+```html
+ -> { 'service': 'Foo', 'service-type': 'Bar' }
+```
+
+```keepDataPrefix === true```:
+```html
+ -> { 'data-service': 'Foo', 'data-service-type': 'Bar' }
+```
+ */
+export function getDataAttributes(
+ element: T,
+ keepDataPrefix: boolean = false
+): Record {
+ return Object.entries(element.dataset).reduce(
+ (acc, [key, value]) => ({
+ ...acc,
+ [calculateKey(key, keepDataPrefix)]: value,
+ }),
+ {}
+ );
+}
+
+function calculateKey(key: string, keepDataPrefix: boolean): string {
+ return `${keepDataPrefix && 'data-'}${kebabCase(key)}`;
+}
diff --git a/libs/fabric/src/lib/utils/kebab-case.ts b/libs/fabric/src/lib/utils/kebab-case.ts
new file mode 100644
index 00000000..55294c74
--- /dev/null
+++ b/libs/fabric/src/lib/utils/kebab-case.ts
@@ -0,0 +1,7 @@
+/** Implementation borrowed from https://github.com/joakimbeng/kebab-case */
+
+const KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g;
+
+export function kebabCase(str: string) {
+ return str.replace(KEBAB_REGEX, match => '-' + match.toLowerCase());
+}