@@ -14,6 +14,8 @@ import {RegistryContext} from './Contexts';
14
14
15
15
import styles from './ContextMenu.css' ;
16
16
17
+ import type { RegistryContextType } from './Contexts' ;
18
+
17
19
function respositionToFit ( element : HTMLElement , pageX : number , pageY : number ) {
18
20
const ownerWindow = element . ownerDocument . defaultView ;
19
21
if ( element !== null ) {
@@ -52,7 +54,7 @@ type Props = {|
52
54
| } ;
53
55
54
56
export default function ContextMenu ( { children, id} : Props ) {
55
- const { registerMenu} = useContext ( RegistryContext ) ;
57
+ const { registerMenu} = useContext < RegistryContextType > ( RegistryContext ) ;
56
58
57
59
const [ state , setState ] = useState ( HIDDEN_STATE ) ;
58
60
@@ -61,12 +63,15 @@ export default function ContextMenu({children, id}: Props) {
61
63
const menuRef = useRef ( null ) ;
62
64
63
65
useEffect ( ( ) => {
64
- const ownerDocument = bodyAccessorRef . current . ownerDocument ;
65
- containerRef . current = ownerDocument . createElement ( 'div' ) ;
66
- ownerDocument . body . appendChild ( containerRef . current ) ;
67
- return ( ) => {
68
- ownerDocument . body . removeChild ( containerRef . current ) ;
69
- } ;
66
+ const element = bodyAccessorRef . current ;
67
+ if ( element !== null ) {
68
+ const ownerDocument = element . ownerDocument ;
69
+ containerRef . current = ownerDocument . createElement ( 'div' ) ;
70
+ ownerDocument . body . appendChild ( containerRef . current ) ;
71
+ return ( ) => {
72
+ ownerDocument . body . removeChild ( containerRef . current ) ;
73
+ } ;
74
+ }
70
75
} , [ ] ) ;
71
76
72
77
useEffect ( ( ) => {
@@ -82,45 +87,52 @@ export default function ContextMenu({children, id}: Props) {
82
87
return ;
83
88
}
84
89
85
- const menu = menuRef . current ;
90
+ const menu = ( ( menuRef . current : any ) : HTMLElement ) ;
91
+ const container = containerRef . current ;
92
+ if ( container !== null ) {
93
+ const hideUnlessContains = event => {
94
+ if ( ! menu . contains ( event . target ) ) {
95
+ setState ( HIDDEN_STATE ) ;
96
+ }
97
+ } ;
86
98
87
- const hideUnlessContains = event => {
88
- if ( ! menu . contains ( event . target ) ) {
99
+ const hide = event => {
89
100
setState ( HIDDEN_STATE ) ;
90
- }
91
- } ;
101
+ } ;
92
102
93
- const hide = event => {
94
- setState ( HIDDEN_STATE ) ;
95
- } ;
103
+ const ownerDocument = container . ownerDocument ;
104
+ ownerDocument . addEventListener ( 'mousedown' , hideUnlessContains ) ;
105
+ ownerDocument . addEventListener ( 'touchstart' , hideUnlessContains ) ;
106
+ ownerDocument . addEventListener ( 'keydown' , hideUnlessContains ) ;
96
107
97
- const ownerDocument = containerRef . current . ownerDocument ;
98
- ownerDocument . addEventListener ( 'mousedown' , hideUnlessContains ) ;
99
- ownerDocument . addEventListener ( 'touchstart' , hideUnlessContains ) ;
100
- ownerDocument . addEventListener ( 'keydown' , hideUnlessContains ) ;
108
+ const ownerWindow = ownerDocument . defaultView ;
109
+ ownerWindow . addEventListener ( 'resize' , hide ) ;
101
110
102
- const ownerWindow = ownerDocument . defaultView ;
103
- ownerWindow . addEventListener ( 'resize' , hide ) ;
111
+ respositionToFit ( menu , state . pageX , state . pageY ) ;
104
112
105
- respositionToFit ( menu , state . pageX , state . pageY ) ;
113
+ return ( ) => {
114
+ ownerDocument . removeEventListener ( 'mousedown' , hideUnlessContains ) ;
115
+ ownerDocument . removeEventListener ( 'touchstart' , hideUnlessContains ) ;
116
+ ownerDocument . removeEventListener ( 'keydown' , hideUnlessContains ) ;
106
117
107
- return ( ) => {
108
- ownerDocument . removeEventListener ( 'mousedown' , hideUnlessContains ) ;
109
- ownerDocument . removeEventListener ( 'touchstart' , hideUnlessContains ) ;
110
- ownerDocument . removeEventListener ( 'keydown' , hideUnlessContains ) ;
111
-
112
- ownerWindow . removeEventListener ( 'resize' , hide ) ;
113
- } ;
118
+ ownerWindow . removeEventListener ( 'resize' , hide ) ;
119
+ } ;
120
+ }
114
121
} , [ state ] ) ;
115
122
116
123
if ( ! state . isVisible ) {
117
124
return < div ref = { bodyAccessorRef } /> ;
118
125
} else {
119
- return createPortal (
120
- < div ref = { menuRef } className = { styles . ContextMenu } >
121
- { children ( state . data ) }
122
- </ div > ,
123
- containerRef . current ,
124
- ) ;
126
+ const container = containerRef . current ;
127
+ if ( container !== null ) {
128
+ return createPortal (
129
+ < div ref = { menuRef } className = { styles . ContextMenu } >
130
+ { children ( state . data ) }
131
+ </ div > ,
132
+ container ,
133
+ ) ;
134
+ } else {
135
+ return null ;
136
+ }
125
137
}
126
138
}
0 commit comments