@@ -7,10 +7,11 @@ import BaseOverlay, {
7
7
} from 'react-overlays/Overlay' ;
8
8
import safeFindDOMNode from 'react-overlays/safeFindDOMNode' ;
9
9
import { componentOrElement , elementType } from 'prop-types-extra' ;
10
+ import useMergedRefs from '@restart/hooks/useMergedRefs' ;
10
11
import useOverlayOffset from './useOverlayOffset' ;
11
12
import Fade from './Fade' ;
12
13
import { TransitionType } from './helpers' ;
13
- import { ArrowProps , Placement } from './types' ;
14
+ import { ArrowProps , Placement , RootCloseEvent } from './types' ;
14
15
15
16
export interface OverlayInjectedProps {
16
17
ref : React . RefCallback < HTMLElement > ;
@@ -35,10 +36,11 @@ export type OverlayChildren =
35
36
| ( ( injected : OverlayInjectedProps ) => React . ReactNode ) ;
36
37
37
38
export interface OverlayProps
38
- extends Omit < BaseOverlayProps , 'children' | 'transition' > {
39
+ extends Omit < BaseOverlayProps , 'children' | 'transition' | 'rootCloseEvent' > {
39
40
children : OverlayChildren ;
40
41
transition ?: TransitionType ;
41
42
placement ?: Placement ;
43
+ rootCloseEvent ?: RootCloseEvent ;
42
44
}
43
45
44
46
const propTypes = {
@@ -72,7 +74,7 @@ const propTypes = {
72
74
/**
73
75
* Specify event for triggering a "root close" toggle.
74
76
*/
75
- rootCloseEvent : PropTypes . oneOf ( [ 'click' , 'mousedown' ] ) ,
77
+ rootCloseEvent : PropTypes . oneOf < RootCloseEvent > ( [ 'click' , 'mousedown' ] ) ,
76
78
77
79
/**
78
80
* A callback invoked by the overlay when it wishes to be hidden. Required if
@@ -119,7 +121,7 @@ const propTypes = {
119
121
/**
120
122
* The placement of the Overlay in relation to it's `target`.
121
123
*/
122
- placement : PropTypes . oneOf ( [
124
+ placement : PropTypes . oneOf < Placement > ( [
123
125
'auto-start' ,
124
126
'auto' ,
125
127
'auto-end' ,
@@ -138,7 +140,7 @@ const propTypes = {
138
140
] ) ,
139
141
} ;
140
142
141
- const defaultProps = {
143
+ const defaultProps : Partial < OverlayProps > = {
142
144
transition : Fade ,
143
145
rootClose : false ,
144
146
show : false ,
@@ -154,77 +156,80 @@ function wrapRefs(props, arrowProps) {
154
156
aRef . __wrapped || ( aRef . __wrapped = ( r ) => aRef ( safeFindDOMNode ( r ) ) ) ;
155
157
}
156
158
157
- function Overlay ( {
158
- children : overlay ,
159
- transition,
160
- popperConfig = { } ,
161
- ...outerProps
162
- } : OverlayProps ) {
163
- const popperRef = useRef ( { } ) ;
164
- const [ ref , modifiers ] = useOverlayOffset ( ) ;
165
-
166
- const actualTransition = transition === true ? Fade : transition || null ;
167
-
168
- return (
169
- < BaseOverlay
170
- { ...outerProps }
171
- ref = { ref }
172
- popperConfig = { {
173
- ...popperConfig ,
174
- modifiers : modifiers . concat ( popperConfig . modifiers || [ ] ) ,
175
- } }
176
- transition = { actualTransition as any }
177
- >
178
- { ( {
179
- props : overlayProps ,
180
- arrowProps,
181
- show,
182
- update,
183
- forceUpdate : _ ,
184
- placement,
185
- state,
186
- ...props
187
- } ) => {
188
- wrapRefs ( overlayProps , arrowProps ) ;
189
- const popper = Object . assign ( popperRef . current , {
190
- state,
191
- scheduleUpdate : update ,
159
+ const Overlay = React . forwardRef < HTMLElement , OverlayProps > (
160
+ (
161
+ { children : overlay , transition, popperConfig = { } , ...outerProps } ,
162
+ outerRef ,
163
+ ) => {
164
+ const popperRef = useRef ( { } ) ;
165
+ const [ ref , modifiers ] = useOverlayOffset ( ) ;
166
+ const mergedRef = useMergedRefs ( outerRef , ref ) ;
167
+
168
+ const actualTransition =
169
+ transition === true ? Fade : transition || undefined ;
170
+
171
+ return (
172
+ < BaseOverlay
173
+ { ...outerProps }
174
+ ref = { mergedRef }
175
+ popperConfig = { {
176
+ ...popperConfig ,
177
+ modifiers : modifiers . concat ( popperConfig . modifiers || [ ] ) ,
178
+ } }
179
+ transition = { actualTransition }
180
+ >
181
+ { ( {
182
+ props : overlayProps ,
183
+ arrowProps,
184
+ show,
185
+ update,
186
+ forceUpdate : _ ,
192
187
placement,
193
- outOfBoundaries :
194
- state ?. modifiersData . hide ?. isReferenceHidden || false ,
195
- } ) ;
188
+ state,
189
+ ...props
190
+ } ) => {
191
+ wrapRefs ( overlayProps , arrowProps ) ;
192
+ const popper = Object . assign ( popperRef . current , {
193
+ state,
194
+ scheduleUpdate : update ,
195
+ placement,
196
+ outOfBoundaries :
197
+ state ?. modifiersData . hide ?. isReferenceHidden || false ,
198
+ } ) ;
196
199
197
- if ( typeof overlay === 'function' )
198
- return overlay ( {
200
+ if ( typeof overlay === 'function' )
201
+ return overlay ( {
202
+ ...props ,
203
+ ...overlayProps ,
204
+ placement,
205
+ show,
206
+ ...( ! transition && show && { className : 'show' } ) ,
207
+ popper,
208
+ arrowProps,
209
+ } ) ;
210
+
211
+ return React . cloneElement ( overlay as React . ReactElement , {
199
212
...props ,
200
213
...overlayProps ,
201
214
placement,
202
- show,
203
- ...( ! transition && show && { className : 'show' } ) ,
204
- popper,
205
215
arrowProps,
216
+ popper,
217
+ className : classNames (
218
+ ( overlay as React . ReactElement ) . props . className ,
219
+ ! transition && show && 'show' ,
220
+ ) ,
221
+ style : {
222
+ ...( overlay as React . ReactElement ) . props . style ,
223
+ ...overlayProps . style ,
224
+ } ,
206
225
} ) ;
226
+ } }
227
+ </ BaseOverlay >
228
+ ) ;
229
+ } ,
230
+ ) ;
207
231
208
- return React . cloneElement ( overlay , {
209
- ...props ,
210
- ...overlayProps ,
211
- placement,
212
- arrowProps,
213
- popper,
214
- className : classNames (
215
- overlay . props . className ,
216
- ! transition && show && 'show' ,
217
- ) ,
218
- style : {
219
- ...overlay . props . style ,
220
- ...overlayProps . style ,
221
- } ,
222
- } ) ;
223
- } }
224
- </ BaseOverlay >
225
- ) ;
226
- }
227
-
232
+ Overlay . displayName = 'Overlay' ;
228
233
Overlay . propTypes = propTypes ;
229
234
Overlay . defaultProps = defaultProps ;
230
235
0 commit comments