1- import { Menu , Item , Separator , Submenu , useContextMenu , PredicateParams , ItemProps , ItemParams } from "react-contexify" ;
1+ import { Menu , Item , Separator , Submenu , useContextMenu , PredicateParams , ItemParams } from "react-contexify" ;
22import * as React from 'react' ;
3- import { ContextMenu , SubMenuItem , TitledContextMenuItem , ClickEventType , BaseContextMenuItem , ContextMenuItem , SeparatorMenuItem } from "./context-menu" ;
3+ import { ContextMenu , SubMenuItem , TitledContextMenuItem , ClickEventType , BaseContextMenuItem , ContextMenuItem , SeparatorMenuItem , SetNewContextMenuGenerator } from "./context-menu" ;
44
55type ItemData = any ;
66
7- export class HTMLContextMenu implements ContextMenu {
7+ export class HTMLContextMenu < PropType > extends ContextMenu < PropType > {
88 constructor ( component_id ?: string ) {
9+ super ( ) ;
910 this . menu = null ;
10- this . items = null ;
11+ this . items = [ ] ;
1112 if ( ! component_id )
1213 component_id = "ContextMenu" + HTMLContextMenu . auto_id ++ ;
1314 this . component_id = component_id ;
@@ -16,62 +17,71 @@ export class HTMLContextMenu implements ContextMenu {
1617 component_id : string ;
1718 menu : JSX . Element | null ;
1819
19- ContextMenuItemClicked ( { id, event, props, data, triggerEvent } : ItemParams < ItemProps , ItemData > ) {
20+ ContextMenuItemClicked = ( { id, event, props, data, triggerEvent } : ItemParams < PropType , ItemData > ) => {
2021
2122 let item = this . GetContextMenuItemById ( this . items , id ) ;
2223 if ( item && item instanceof ContextMenuItem )
2324 item . onClick ( event , props ) ;
25+ else
26+ console . log ( "Unable to find sub item on context menu something likely wrong" ) ;
2427 }
2528
2629
27- protected GetContextMenuItemById ( items : BaseContextMenuItem [ ] | null | undefined , id : string | undefined ) : BaseContextMenuItem | null {
30+ protected GetContextMenuItemById ( items : BaseContextMenuItem < PropType > [ ] | null | undefined , id : string | undefined ) : BaseContextMenuItem < PropType > | null {
2831 if ( ! items )
2932 return null ;
3033 let item = items ?. find ( i => i . component_id === id ) ;
31- if ( item == null ) {
32- items ?. forEach ( sub_item => {
34+ if ( item == null && items ) {
35+ for ( let sub_item of items ) {
3336 if ( sub_item instanceof SubMenuItem )
3437 return this . GetContextMenuItemById ( sub_item . sub_items , id ) ;
35- } ) ;
38+ }
3639 }
3740 if ( ! item )
3841 return null ;
3942 return item ;
4043 }
4144
42- items : BaseContextMenuItem [ ] | null ;
43- CreateContextMenu ( items : BaseContextMenuItem [ ] ) {
45+ items : BaseContextMenuItem < PropType > [ ] ;
46+ SetContextMenuItems ( items : BaseContextMenuItem < PropType > [ ] ) {
4447 this . items = items ;
45- this . menu = this . CreateMenuComponent ( items ) ;
48+ this . menu = null ;
49+ }
50+ AppendContextMenuItem ( item : BaseContextMenuItem < PropType > ) {
51+ this . items . push ( item ) ;
52+ }
53+ GetMenuComponent ( ) {
54+ if ( this . menu == null )
55+ this . menu = this . CreateMenuComponent ( this . items ) ;
4656 return this . menu ;
4757 }
48- GetContextMenuHandler ( props : any ) {
58+ GetContextMenuHandler ( props : PropType ) {
4959 return ( e : ClickEventType ) => this . displayMenu ( e , props ) ;
5060 }
5161 // AttachMenuToItem(domElem: any, props: any) {
5262 // domElem.setState( {onContextMenu: );
5363 // //would need to ues clonelem
5464 // return domElem;
5565 // }
56- displayMenu ( e : ClickEventType , props : object ) {
57- useContextMenu ( {
58- id : this . component_id
59- } ) . show ( { event : e , props : props } ) ;
66+ displayMenu ( e : ClickEventType , props : PropType ) {
67+ let selection = window . getSelection ( ) ;
68+ if ( selection == null || selection . toString ( ) . length < 2 ) //if text is selected use native menu, note if text is selected but its not what we right click on this will still work as that text is deselected prior to this call
69+ useContextMenu ( { id : this . component_id } ) . show ( { event : e , props : props } ) ;
6070 }
6171
62- IsDisabled = ( { id, triggerEvent, props, data } : PredicateParams < ItemProps , ItemData > ) => {
72+ IsDisabled = ( { id, triggerEvent, props, data } : PredicateParams < PropType , ItemData > ) => {
6373 let item = this . GetContextMenuItemById ( this . items , id ) ;
6474 if ( item && item instanceof TitledContextMenuItem )
65- return item . disabled ( ) ;
75+ return item . disabled ( props ) ;
6676 return false ;
6777 }
68- IsHidden = ( { id, triggerEvent, props, data } : PredicateParams < ItemProps , ItemData > ) => {
78+ IsHidden = ( { id, triggerEvent, props, data } : PredicateParams < PropType , ItemData > ) => {
6979 let item = this . GetContextMenuItemById ( this . items , id ) ;
7080 if ( item && item instanceof TitledContextMenuItem )
71- return item . hidden ( ) ;
81+ return item . hidden ( props ) ;
7282 return false ;
7383 }
74- GetItem ( item : BaseContextMenuItem ) {
84+ GetItem ( item : BaseContextMenuItem < PropType > ) {
7585 if ( item instanceof SubMenuItem ) {
7686 return < Submenu id = { item . component_id } label = { item . title } >
7787 { item . sub_items ?. map ( ( item ) => this . GetItem ( item ) ) }
@@ -82,7 +92,7 @@ export class HTMLContextMenu implements ContextMenu {
8292 else if ( item instanceof SeparatorMenuItem )
8393 return < Separator key = { item . component_id } />
8494 }
85- CreateMenuComponent ( items : BaseContextMenuItem [ ] ) {
95+ CreateMenuComponent ( items : BaseContextMenuItem < PropType > [ ] ) {
8696
8797 return ( < >
8898 < Menu id = { this . component_id } >
@@ -92,4 +102,6 @@ export class HTMLContextMenu implements ContextMenu {
92102
93103 }
94104
95- }
105+ }
106+ SetNewContextMenuGenerator ( < PropType , > ( component_id ?: string ) => new HTMLContextMenu < PropType > ( component_id ) ) ;
107+ export function noop ( ) { }
0 commit comments