Skip to content

Commit 35f54fd

Browse files
author
Ben Grynhaus
committed
CommandBar - declarative syntax. WIP 3
1 parent 91d6f52 commit 35f54fd

15 files changed

+227
-166
lines changed

.vscode/launch.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "chrome",
9+
"request": "launch",
10+
"name": "Launch Chrome against localhost",
11+
"url": "http://localhost:4001",
12+
"webRoot": "${workspaceFolder}"
13+
}
14+
]
15+
}

apps/demo/src/app/app.component.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,28 @@ <h2>Getting up and running...</h2>
2121
<fab-command-bar-item key="run" text="Run" [iconProps]="{ iconName: 'CaretRight' }" [disabled]="runDisabled"></fab-command-bar-item>
2222
<fab-command-bar-item key="new" text="New" [iconProps]="{ iconName: 'Add' }" (click)="onNewClicked()"></fab-command-bar-item>
2323
<fab-command-bar-item key="save" text="Save" [iconProps]="{ iconName: 'Save' }" [subMenuProps]="saveSubMenuProps">
24+
<contextual-menu-item *ngIf="runDisabled" key="sometimesVisible" text="woosh"></contextual-menu-item>
2425
<contextual-menu-item key="save" text="Save"></contextual-menu-item>
2526
<contextual-menu-item key="save-as" text="Save As" (click)="onSaveAsClicked()">
2627
<contextual-menu-item key="save-as-1" text="Save As 1" (click)="onSaveAsFirstClicked()"></contextual-menu-item>
2728
<contextual-menu-item key="save-as-2" text="Save As 2" (click)="onSaveAsSecondClicked()"></contextual-menu-item>
2829
</contextual-menu-item>
2930
</fab-command-bar-item>
3031
<fab-command-bar-item key="copy" text="Copy" [iconProps]="{ iconName: 'Copy' }" (click)="onCopyClicked()"></fab-command-bar-item>
32+
<fab-command-bar-item key="custom" text="custom text" (click)="onCopyClicked()">
33+
<!-- <render>
34+
<ng-template let-item="item">
35+
<div>Custom render</div>
36+
</ng-template>
37+
</render> -->
38+
39+
<render-icon>
40+
<ng-template let-contextualMenuItemProps="contextualMenuItemProps">
41+
<div>custom icon</div>
42+
</ng-template>
43+
</render-icon>
44+
</fab-command-bar-item>
45+
<fab-command-bar-item *ngIf="runDisabled" key="sometimesVisible" text="woosh"></fab-command-bar-item>
3146
</items>
3247

3348
<far-items>

apps/demo/src/app/app.component.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ export class AppComponent {
6363
console.log('Save as 2 clicked');
6464
}
6565

66+
onCustomItemClick(item: any) {
67+
this.customItemCount++;
68+
console.log('custom item clicked', item);
69+
this.cd.detectChanges();
70+
}
71+
72+
constructor(private readonly cd: ChangeDetectorRef) {}
73+
74+
customItemCount = 1;
75+
6676
// FIXME: Allow declarative syntax too
6777
saveSubMenuProps: Partial<IContextualMenuProps> = {
6878
gapSpace: 10,

libs/fabric/src/components/command-bar/command-bar.component.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,22 @@ import {
1212
ContentChild,
1313
AfterContentInit,
1414
OnDestroy,
15+
QueryList,
1516
} from '@angular/core';
17+
import { Subscription } from 'rxjs';
1618
import { ICommandBarItemProps, ICommandBarProps } from 'office-ui-fabric-react/lib/CommandBar';
1719
import { IContextualMenuItemProps } from 'office-ui-fabric-react/lib/ContextualMenu';
20+
1821
import omit from '../../utils/omit';
19-
import { CommandBarItemsDirective } from './directives/command-bar-items.directive';
20-
import { CommandBarFarItemsDirective } from './directives/command-bar-far-items.directive';
21-
import { CommandBarOverflowItemsDirective } from './directives/command-bar-overflow-items.directive';
22-
import { CommandBarItemsDirectiveBase } from './directives/command-bar-items-base.directive';
2322
import { TypedChanges, OnChanges } from '../../types/angular/typed-changes';
2423
import {
25-
CommandBarItemDirective,
26-
CommandBarItemChangedPayload,
27-
} from '@angular-react/fabric/src/components/command-bar/directives/command-bar-item.directive';
28-
import { Subscription } from 'rxjs';
24+
CommandBarItemsDirective,
25+
CommandBarFarItemsDirective,
26+
CommandBarOverflowItemsDirective,
27+
CommandBarItemsDirectiveBase,
28+
} from './directives/command-bar-items.directives';
29+
import { CommandBarItemChangedPayload, CommandBarItemDirective } from './directives/command-bar-item.directives';
30+
import { ItemChanges, mergeItemChanges } from '../core/declarative/item-changed';
2931

3032
@Component({
3133
selector: 'fab-command-bar',
@@ -151,20 +153,16 @@ export class FabCommandBarComponent extends ReactWrapperComponent<ICommandBarPro
151153
transformItemsFunc(this[itemsPropertyKey]);
152154
};
153155

154-
const mergeItemChanges = (item: ICommandBarItemOptions, changes: TypedChanges<ICommandBarItemOptions>) => {
155-
const itemChangesOverrides = Object.entries(changes).reduce<Partial<ICommandBarItemOptions>>(
156-
(acc, [propertyKey, change]) => ({
157-
[propertyKey]: change.currentValue,
158-
}),
159-
{}
160-
);
161-
162-
return Object.assign({}, item, itemChangesOverrides);
163-
};
164-
165156
// Initial items
166157
setItems(() => directive.items);
167158

159+
// Subscribe to adding/removing items
160+
this._subscriptions.push(
161+
directive.onItemsChanged.subscribe((newItems: QueryList<CommandBarItemDirective>) => {
162+
setItems(() => newItems.map<ICommandBarItemOptions>(directive => directive));
163+
})
164+
);
165+
168166
// Subscribe for existing items changes
169167
this._subscriptions.push(
170168
directive.onItemChanged.subscribe(({ key, changes }: CommandBarItemChangedPayload) => {

libs/fabric/src/components/command-bar/command-bar.module.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,16 @@ import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
44
import { CommandBar } from 'office-ui-fabric-react/lib/CommandBar';
55

66
import { FabCommandBarComponent } from './command-bar.component';
7-
import { CommandBarItemDirective } from './directives/command-bar-item.directive';
8-
import { CommandBarItemsDirective } from './directives/command-bar-items.directive';
9-
import { CommandBarFarItemsDirective } from './directives/command-bar-far-items.directive';
10-
import { CommandBarOverflowItemsDirective } from './directives/command-bar-overflow-items.directive';
7+
import {
8+
CommandBarItemDirective,
9+
CommandBarItemRenderIconDirective,
10+
CommandBarItemRenderDirective,
11+
} from './directives/command-bar-item.directives';
12+
import {
13+
CommandBarFarItemsDirective,
14+
CommandBarItemsDirective,
15+
CommandBarOverflowItemsDirective,
16+
} from './directives/command-bar-items.directives';
1117
import { FabContextualMenuModule } from '../contextual-menu/contextual-menu.module';
1218

1319
const components = [
@@ -16,6 +22,8 @@ const components = [
1622
CommandBarFarItemsDirective,
1723
CommandBarOverflowItemsDirective,
1824
CommandBarItemDirective,
25+
CommandBarItemRenderDirective,
26+
CommandBarItemRenderIconDirective,
1927
];
2028

2129
@NgModule({

libs/fabric/src/components/command-bar/directives/command-bar-far-items.directive.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

libs/fabric/src/components/command-bar/directives/command-bar-item.directive.ts

Lines changed: 0 additions & 95 deletions
This file was deleted.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import {
2+
Directive,
3+
Input,
4+
TemplateRef,
5+
Output,
6+
EventEmitter,
7+
ContentChildren,
8+
ContentChild,
9+
QueryList,
10+
AfterContentInit,
11+
ViewChild,
12+
OnDestroy,
13+
} from '@angular/core';
14+
import { OnChanges, TypedChanges } from '../../../types/angular/typed-changes';
15+
import {
16+
ICommandBarItemOptions,
17+
ICommandBarItemOptionsRenderContext,
18+
ICommandBarItemOptionsRenderIconContext,
19+
} from '../command-bar.component';
20+
import { IContextualMenuItem, ICommandBarItemProps } from 'office-ui-fabric-react';
21+
import { ContextualMenuItemDirective } from '../../contextual-menu';
22+
import { ItemChangedPayload } from '../../core/declarative/item-changed.payload';
23+
import { Subscription } from 'rxjs';
24+
25+
export type CommandBarItemChangedPayload = ItemChangedPayload<ICommandBarItemOptions['key'], ICommandBarItemOptions>;
26+
27+
/**
28+
* Wrapper directive to allow rendering a custom item to a CommandBarItem.
29+
*/
30+
@Directive({ selector: 'fab-command-bar-item > render' })
31+
export class CommandBarItemRenderDirective {
32+
@ContentChild(TemplateRef) readonly templateRef: TemplateRef<ICommandBarItemOptionsRenderContext>;
33+
}
34+
35+
/**
36+
* Wrapper directive to allow rendering a custom icon to a CommandBarItem.
37+
*/
38+
@Directive({ selector: 'fab-command-bar-item > render-icon' })
39+
export class CommandBarItemRenderIconDirective {
40+
@ContentChild(TemplateRef) readonly templateRef: TemplateRef<ICommandBarItemOptionsRenderIconContext>;
41+
}
42+
43+
@Directive({ selector: 'fab-command-bar-item' })
44+
export class CommandBarItemDirective extends ContextualMenuItemDirective
45+
implements ICommandBarItemOptions, AfterContentInit {
46+
@ContentChild(CommandBarItemRenderDirective) readonly renderDirective: CommandBarItemRenderDirective;
47+
@ContentChild(CommandBarItemRenderIconDirective) readonly renderIconDirective: CommandBarItemRenderIconDirective;
48+
49+
// ICommandBarItemOptions implementation
50+
@Input() iconOnly?: ICommandBarItemOptions['iconOnly'];
51+
@Input() buttonStyles?: ICommandBarItemOptions['buttonStyles'];
52+
@Input() cacheKey?: ICommandBarItemOptions['cacheKey'];
53+
@Input() renderedInOverflow?: ICommandBarItemOptions['renderedInOverflow'];
54+
@Input() render: ICommandBarItemOptions['render'];
55+
@Input() renderIcon: ICommandBarItemOptions['renderIcon'];
56+
57+
ngAfterContentInit() {
58+
super.ngAfterContentInit();
59+
60+
if (this.renderDirective && this.renderDirective.templateRef) {
61+
this.render = this.renderDirective.templateRef;
62+
}
63+
64+
if (this.renderIconDirective && this.renderIconDirective.templateRef) {
65+
this.renderIcon = this.renderIconDirective.templateRef;
66+
}
67+
}
68+
}

libs/fabric/src/components/command-bar/directives/command-bar-items.directive.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

libs/fabric/src/components/command-bar/directives/command-bar-items-base.directive.ts renamed to libs/fabric/src/components/command-bar/directives/command-bar-items.directives.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@ import {
77
Output,
88
EventEmitter,
99
} from '@angular/core';
10-
import { CommandBarItemDirective, CommandBarItemChangedPayload } from './command-bar-item.directive';
1110
import { ICommandBarItemOptions } from '../command-bar.component';
1211
import { Subscription } from 'rxjs';
12+
import { CommandBarItemDirective, CommandBarItemChangedPayload } from './command-bar-item.directives';
1313

1414
export abstract class CommandBarItemsDirectiveBase implements AfterContentInit, OnDestroy {
1515
private readonly _subscriptions: Subscription[] = [];
1616

1717
abstract readonly directiveItems: QueryList<CommandBarItemDirective>;
1818

1919
@Output() readonly onItemChanged = new EventEmitter<CommandBarItemChangedPayload>();
20+
@Output() readonly onItemsChanged = new EventEmitter<QueryList<CommandBarItemDirective>>();
2021

2122
get items() {
2223
return (
@@ -40,6 +41,12 @@ export abstract class CommandBarItemsDirectiveBase implements AfterContentInit,
4041
directiveItem.onItemChanged.subscribe(changes => this.onItemChangedHandler(changes))
4142
)
4243
);
44+
45+
this._subscriptions.push(
46+
this.directiveItems.changes.subscribe((newValue: this['directiveItems']) => {
47+
this.onItemsChanged.emit(newValue);
48+
})
49+
);
4350
}
4451

4552
ngOnDestroy() {
@@ -50,3 +57,18 @@ export abstract class CommandBarItemsDirectiveBase implements AfterContentInit,
5057
this.onItemChanged.emit(payload);
5158
}
5259
}
60+
61+
@Directive({ selector: 'fab-command-bar > items' })
62+
export class CommandBarItemsDirective extends CommandBarItemsDirectiveBase {
63+
@ContentChildren(CommandBarItemDirective) readonly directiveItems: QueryList<CommandBarItemDirective>;
64+
}
65+
66+
@Directive({ selector: 'fab-command-bar > far-items' })
67+
export class CommandBarFarItemsDirective extends CommandBarItemsDirectiveBase {
68+
@ContentChildren(CommandBarItemDirective) readonly directiveItems: QueryList<CommandBarItemDirective>;
69+
}
70+
71+
@Directive({ selector: 'fab-command-bar > overflow-items' })
72+
export class CommandBarOverflowItemsDirective extends CommandBarItemsDirectiveBase {
73+
@ContentChildren(CommandBarItemDirective) readonly directiveItems: QueryList<CommandBarItemDirective>;
74+
}

0 commit comments

Comments
 (0)