Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions apps/demo/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,30 @@ <h2>Getting up and running...</h2>
<fab-pivot-item headerText="Tab 3"> <div>Tab 3's content</div> </fab-pivot-item>
</fab-pivot>

<fab-default-button text="button">
<contextual-menu-item key="item1" text="item1" data-track-type="button > item1"></contextual-menu-item>
<contextual-menu-item key="item2" text="item2" data-track-type="button > item2"></contextual-menu-item>
</fab-default-button>

<fab-command-bar>
<items>
<fab-command-bar-item
key="run"
text="Run"
[iconProps]="{ iconName: 'CaretRight' }"
[disabled]="runDisabled"
data-track-type="run"
></fab-command-bar-item>
<fab-command-bar-item
key="new"
text="New"
[iconProps]="{ iconName: 'Add' }"
(click)="onNewClicked()"
></fab-command-bar-item>
<fab-command-bar-item
key="copy1"
text="Copy1"
[iconProps]="{ iconName: 'Copy' }"
(click)="onCopyClicked()"
></fab-command-bar-item>
<fab-command-bar-item key="copy" text="Copy" [iconProps]="{ iconName: 'Copy' }" (click)="onCopyClicked()">
<contextual-menu-item key="item1" text="Item1" data-track-type="copy1 > item1"></contextual-menu-item>
<contextual-menu-item key="item2" text="Item2" data-track-type="copy1 > item2"></contextual-menu-item>
</fab-command-bar-item>
<fab-command-bar-item
key="copy2"
text="Copy2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { Subscription } from 'rxjs';
import { CommandBarItemChangedPayload } from '../command-bar/directives/command-bar-item.directives';
import { mergeItemChanges } from '../core/declarative/item-changed';
import { omit } from '../../utils/omit';
import { getDataAttributes } from '../../utils/get-data-attributes';

export abstract class FabBaseButtonComponent extends ReactWrapperComponent<IButtonProps>
implements OnInit, AfterContentInit, OnDestroy {
Expand Down Expand Up @@ -167,6 +168,7 @@ export abstract class FabBaseButtonComponent extends ReactWrapperComponent<IButt
'ngOnDestroy',
'ngAfterContentInit'
),
...getDataAttributes(directive.elementRef.nativeElement, true),
onClick: (ev, item) => {
directive.click.emit({ ev: ev && ev.nativeEvent, item: item });
},
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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<HTMLElement>) {
super(elementRef);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ 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<ICommandBarItemOptions> {
abstract readonly directiveItems: QueryList<CommandBarItemDirective>;

get items() {
return (
this.directiveItems &&
this.directiveItems.map<ICommandBarItemOptions>(directiveItem => ({
this.directiveItems.map<ICommandBarItemOptions>((directiveItem: CommandBarItemDirective) => ({
...directiveItem,
...getDataAttributes(directiveItem.elementRef.nativeElement, true),
onClick: (ev, item) => {
directiveItem.click.emit({
ev: ev && ev.nativeEvent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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'],
Expand Down Expand Up @@ -101,6 +103,10 @@ export class ContextualMenuItemDirective extends ChangeableItemDirective<IContex
return this._changeableItemsHelper && this._changeableItemsHelper.onItemsChanged;
}

constructor(readonly elementRef: ElementRef<HTMLElement>) {
super();
}

private _changeableItemsHelper: ChangeableItemsHelper<IContextualMenuItem>;

ngAfterContentInit() {
Expand Down Expand Up @@ -129,6 +135,7 @@ export class ContextualMenuItemDirective extends ChangeableItemDirective<IContex
private _directiveToContextualMenuItem(directive: ContextualMenuItemDirective): IContextualMenuItem {
return {
...directive,
...getDataAttributes(directive.elementRef.nativeElement, true),
onClick: (ev, item) => {
directive.click.emit({ ev: ev && ev.nativeEvent, item: item });
},
Expand All @@ -143,6 +150,11 @@ export interface IContextualMenuItemOptions<TData = any>
readonly renderIcon?: InputRendererOptions<IContextualMenuItemOptionsRenderIconContext>;
readonly render?: InputRendererOptions<IContextualMenuItemOptionsRenderContext>;
readonly data?: TData;

/**
* For any attributes like data-* etc.
*/
[propertyName: string]: any;
}

export interface IContextualMenuItemOptionsRenderContext {
Expand Down
32 changes: 32 additions & 0 deletions libs/fabric/src/lib/utils/get-data-attributes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { kebabCase } from './kebab-case';

/**
* Gets the data attributes on an `HTMLElement`.
*
* @example
```keepDataPrefix === false```:
```html
<div data-service="Foo" data-service-type="bar"></div> -> { 'service': 'Foo', 'service-type': 'Bar' }
```

```keepDataPrefix === true```:
```html
<div data-service="Foo" data-service-type="bar"></div> -> { 'data-service': 'Foo', 'data-service-type': 'Bar' }
```
*/
export function getDataAttributes<T extends HTMLElement>(
element: T,
keepDataPrefix: boolean = false
): Record<string, string> {
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)}`;
}
7 changes: 7 additions & 0 deletions libs/fabric/src/lib/utils/kebab-case.ts
Original file line number Diff line number Diff line change
@@ -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());
}