@@ -10,14 +10,38 @@ import {
1010 OnDestroy ,
1111 Output ,
1212 QueryList ,
13+ ContentChild ,
14+ TemplateRef ,
1315} from '@angular/core' ;
1416import { IContextualMenuItem } from 'office-ui-fabric-react' ;
17+ import { KnownKeys , InputRendererOptions } from '@angular-react/core' ;
1518
1619import { OnChanges } from '../../../declarations/angular/typed-changes' ;
1720import { ItemChangedPayload } from '../../core/declarative/item-changed.payload' ;
1821import { ChangeableItemsHelper , IChangeableItemsContainer } from '../../core/shared/changeable-helper' ;
1922import { ChangeableItemDirective } from '../../core/shared/changeable-item.directive' ;
2023
24+ export type ContextualMenuItemChangedPayload = ItemChangedPayload <
25+ IContextualMenuItemOptions [ 'key' ] ,
26+ IContextualMenuItemOptions
27+ > ;
28+
29+ /**
30+ * Wrapper directive to allow rendering a custom item to a ContextualMenuItem.
31+ */
32+ @Directive ( { selector : 'fab-command-bar-item > render' } )
33+ export class ContextualMenuItemRenderDirective {
34+ @ContentChild ( TemplateRef ) readonly templateRef : TemplateRef < IContextualMenuItemOptionsRenderContext > ;
35+ }
36+
37+ /**
38+ * Wrapper directive to allow rendering a custom icon to a ContextualMenuItem.
39+ */
40+ @Directive ( { selector : 'fab-command-bar-item > render-icon' } )
41+ export class ContextualMenuItemRenderIconDirective {
42+ @ContentChild ( TemplateRef ) readonly templateRef : TemplateRef < IContextualMenuItemOptionsRenderIconContext > ;
43+ }
44+
2145@Directive ( { selector : 'contextual-menu-item' } )
2246export class ContextualMenuItemDirective extends ChangeableItemDirective < IContextualMenuItem >
2347 implements
@@ -27,13 +51,15 @@ export class ContextualMenuItemDirective extends ChangeableItemDirective<IContex
2751 OnChanges < ContextualMenuItemDirective > ,
2852 OnDestroy {
2953 @ContentChildren ( ContextualMenuItemDirective ) readonly menuItemsDirectives : QueryList < ContextualMenuItemDirective > ;
54+ @ContentChild ( ContextualMenuItemRenderDirective ) readonly renderDirective : ContextualMenuItemRenderDirective ;
55+ @ContentChild ( ContextualMenuItemRenderIconDirective )
56+ readonly renderIconDirective : ContextualMenuItemRenderIconDirective ;
3057
3158 @Input ( ) componentRef ?: IContextualMenuItem [ 'componentRef' ] ;
3259 @Input ( ) text ?: IContextualMenuItem [ 'text' ] ;
3360 @Input ( ) secondaryText ?: IContextualMenuItem [ 'secondaryText' ] ;
3461 @Input ( ) itemType ?: IContextualMenuItem [ 'itemType' ] ;
3562 @Input ( ) iconProps ?: IContextualMenuItem [ 'iconProps' ] ;
36- @Input ( ) onRenderIcon ?: IContextualMenuItem [ 'onRenderIcon' ] ;
3763 @Input ( ) submenuIconProps ?: IContextualMenuItem [ 'submenuIconProps' ] ;
3864 @Input ( ) disabled ?: IContextualMenuItem [ 'disabled' ] ;
3965 @Input ( ) primaryDisabled ?: IContextualMenuItem [ 'primaryDisabled' ] ;
@@ -54,29 +80,39 @@ export class ContextualMenuItemDirective extends ChangeableItemDirective<IContex
5480 @Input ( ) style ?: IContextualMenuItem [ 'style' ] ;
5581 @Input ( ) ariaLabel ?: IContextualMenuItem [ 'ariaLabel' ] ;
5682 @Input ( ) title ?: IContextualMenuItem [ 'title' ] ;
57- @Input ( ) onRender ?: IContextualMenuItem [ 'onRender' ] ;
5883 @Input ( ) onMouseDown ?: IContextualMenuItem [ 'onMouseDown' ] ;
5984 @Input ( ) role ?: IContextualMenuItem [ 'role' ] ;
6085 @Input ( ) customOnRenderListLength ?: IContextualMenuItem [ 'customOnRenderListLength' ] ;
6186 @Input ( ) keytipProps ?: IContextualMenuItem [ 'keytipProps' ] ;
6287 @Input ( ) inactive ?: IContextualMenuItem [ 'inactive' ] ;
6388 @Input ( ) name ?: IContextualMenuItem [ 'name' ] ;
89+ @Input ( ) render : IContextualMenuItemOptions [ 'render' ] ;
90+ @Input ( ) renderIcon : IContextualMenuItemOptions [ 'renderIcon' ] ;
6491
6592 @Output ( ) readonly click = new EventEmitter < { ev ?: MouseEvent | KeyboardEvent ; item ?: IContextualMenuItem } > ( ) ;
6693
6794 @Output ( )
6895 get onChildItemChanged ( ) : EventEmitter < ItemChangedPayload < string , IContextualMenuItem > > {
69- return this . changeableItemsHelper && this . changeableItemsHelper . onChildItemChanged ;
96+ return this . _changeableItemsHelper && this . _changeableItemsHelper . onChildItemChanged ;
7097 }
71- @Input ( )
98+
99+ @Output ( )
72100 get onItemsChanged ( ) : EventEmitter < QueryList < ChangeableItemDirective < IContextualMenuItem > > > {
73- return this . changeableItemsHelper && this . changeableItemsHelper . onItemsChanged ;
101+ return this . _changeableItemsHelper && this . _changeableItemsHelper . onItemsChanged ;
74102 }
75103
76- private changeableItemsHelper : ChangeableItemsHelper < IContextualMenuItem > ;
104+ private _changeableItemsHelper : ChangeableItemsHelper < IContextualMenuItem > ;
77105
78106 ngAfterContentInit ( ) {
79- this . changeableItemsHelper = new ChangeableItemsHelper ( this . menuItemsDirectives , this , nonSelfDirective => {
107+ if ( this . renderDirective && this . renderDirective . templateRef ) {
108+ this . render = this . renderDirective . templateRef ;
109+ }
110+
111+ if ( this . renderIconDirective && this . renderIconDirective . templateRef ) {
112+ this . renderIcon = this . renderIconDirective . templateRef ;
113+ }
114+
115+ this . _changeableItemsHelper = new ChangeableItemsHelper ( this . menuItemsDirectives , this , nonSelfDirective => {
80116 const items = nonSelfDirective . map ( directive => this . _directiveToContextualMenuItem ( directive as any ) ) ;
81117 if ( ! this . subMenuProps ) {
82118 this . subMenuProps = { items : items } ;
@@ -87,7 +123,7 @@ export class ContextualMenuItemDirective extends ChangeableItemDirective<IContex
87123 }
88124
89125 ngOnDestroy ( ) {
90- this . changeableItemsHelper . destroy ( ) ;
126+ this . _changeableItemsHelper . destroy ( ) ;
91127 }
92128
93129 private _directiveToContextualMenuItem ( directive : ContextualMenuItemDirective ) : IContextualMenuItem {
@@ -99,3 +135,21 @@ export class ContextualMenuItemDirective extends ChangeableItemDirective<IContex
99135 } ;
100136 }
101137}
138+
139+ // Not using `Omit` here since it confused the TypeScript compiler and it just showed the properties listed here (`renderIcon`, `render` and `data`).
140+ // The type here is just `Omit` without the generics though.
141+ export interface IContextualMenuItemOptions < TData = any >
142+ extends Pick < IContextualMenuItem , Exclude < KnownKeys < IContextualMenuItem > , 'onRender' | 'onRenderIcon' > > {
143+ readonly renderIcon ?: InputRendererOptions < IContextualMenuItemOptionsRenderIconContext > ;
144+ readonly render ?: InputRendererOptions < IContextualMenuItemOptionsRenderContext > ;
145+ readonly data ?: TData ;
146+ }
147+
148+ export interface IContextualMenuItemOptionsRenderContext {
149+ item : any ;
150+ dismissMenu : ( ev ?: any , dismissAll ?: boolean ) => void ;
151+ }
152+
153+ export interface IContextualMenuItemOptionsRenderIconContext {
154+ contextualMenuItem : IContextualMenuItem ;
155+ }
0 commit comments