@@ -3,16 +3,25 @@ import { Context } from './context-menu-provider';
33import { appendContextMenuContent } from './context-menu-content' ;
44import type { MenuItem } from './types' ;
55
6- /**
7- * @returns an object with methods to {@link register} content for the menu and {@link close} the menu
8- */
6+ export type ContextMenuMethods < T extends MenuItem > = {
7+ /**
8+ * Close the context menu.
9+ */
10+ close : ( ) => void ;
11+ /**
12+ * Register the menu items for the context menu.
13+ * @returns a callback ref to be passed onto the element responsible for triggering the menu.
14+ */
15+ registerItems : ( items : T [ ] ) => ( trigger : HTMLElement | null ) => void ;
16+ } ;
17+
918export function useContextMenu < T extends MenuItem > ( {
1019 Menu,
1120} : {
1221 Menu : React . ComponentType < {
1322 items : T [ ] ;
1423 } > ;
15- } ) {
24+ } ) : ContextMenuMethods < T > {
1625 // Get the close function from the ContextProvider
1726 const context = useContext ( Context ) ;
1827 const previous = useRef < null | [ HTMLElement , ( event : MouseEvent ) => void ] > (
@@ -24,31 +33,29 @@ export function useContextMenu<T extends MenuItem>({
2433 throw new Error ( 'useContextMenu called outside of the provider' ) ;
2534 }
2635
36+ const register = ( content : React . ComponentType ) => {
37+ function listener ( event : MouseEvent ) {
38+ appendContextMenuContent ( event , content ) ;
39+ }
40+ return ( trigger : HTMLElement | null ) => {
41+ if ( previous . current ) {
42+ const [ previousTrigger , previousListener ] = previous . current ;
43+ previousTrigger . removeEventListener ( 'contextmenu' , previousListener ) ;
44+ }
45+ if ( trigger ) {
46+ trigger . addEventListener ( 'contextmenu' , listener ) ;
47+ previous . current = [ trigger , listener ] ;
48+ }
49+ } ;
50+ } ;
51+
2752 return {
2853 close : context . close . bind ( context ) ,
2954 /**
3055 * @returns a callback ref, passed onto the element responsible for triggering the menu.
3156 */
32- register ( content : React . ComponentType ) {
33- function listener ( event : MouseEvent ) {
34- appendContextMenuContent ( event , content ) ;
35- }
36- return ( trigger : HTMLElement | null ) => {
37- if ( previous . current ) {
38- const [ previousTrigger , previousListener ] = previous . current ;
39- previousTrigger . removeEventListener (
40- 'contextmenu' ,
41- previousListener
42- ) ;
43- }
44- if ( trigger ) {
45- trigger . addEventListener ( 'contextmenu' , listener ) ;
46- previous . current = [ trigger , listener ] ;
47- }
48- } ;
49- } ,
5057 registerItems ( items : T [ ] ) {
51- return this . register ( ( ) => < Menu items = { items } /> ) ;
58+ return register ( ( ) => < Menu items = { items } /> ) ;
5259 } ,
5360 } ;
5461 } , [ context , Menu ] ) ;
0 commit comments