@@ -3,16 +3,25 @@ import { Context } from './context-menu-provider';
3
3
import { appendContextMenuContent } from './context-menu-content' ;
4
4
import type { MenuItem } from './types' ;
5
5
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
+
9
18
export function useContextMenu < T extends MenuItem > ( {
10
19
Menu,
11
20
} : {
12
21
Menu : React . ComponentType < {
13
22
items : T [ ] ;
14
23
} > ;
15
- } ) {
24
+ } ) : ContextMenuMethods < T > {
16
25
// Get the close function from the ContextProvider
17
26
const context = useContext ( Context ) ;
18
27
const previous = useRef < null | [ HTMLElement , ( event : MouseEvent ) => void ] > (
@@ -24,31 +33,29 @@ export function useContextMenu<T extends MenuItem>({
24
33
throw new Error ( 'useContextMenu called outside of the provider' ) ;
25
34
}
26
35
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
+
27
52
return {
28
53
close : context . close . bind ( context ) ,
29
54
/**
30
55
* @returns a callback ref, passed onto the element responsible for triggering the menu.
31
56
*/
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
- } ,
50
57
registerItems ( items : T [ ] ) {
51
- return this . register ( ( ) => < Menu items = { items } /> ) ;
58
+ return register ( ( ) => < Menu items = { items } /> ) ;
52
59
} ,
53
60
} ;
54
61
} , [ context , Menu ] ) ;
0 commit comments