@@ -8,6 +8,7 @@ import useIdentifier from './useIdentifier';
8
8
import usePopper from './usePopper' ;
9
9
import concatRefs from '../utils/concatRefs' ;
10
10
import optional from '../utils/optional' ;
11
+ import useControlledState from './useControlledState' ;
11
12
12
13
export const OverlayPropTypes = {
13
14
delay : PropTypes . oneOfType ( [
@@ -20,6 +21,9 @@ export const OverlayPropTypes = {
20
21
trigger : PropTypes . oneOf ( TRIGGERS ) ,
21
22
placement : PropTypes . oneOf ( PLACEMENTS ) ,
22
23
fallbackPlacement : PropTypes . oneOf ( [ 'flip' , 'clockwise' , 'counterwise' ] ) ,
24
+ defaultVisible : PropTypes . bool ,
25
+ visible : PropTypes . bool ,
26
+ onToggle : PropTypes . func ,
23
27
} ;
24
28
25
29
function useOverlay ( target , template , config ) {
@@ -28,6 +32,9 @@ function useOverlay(target, template, config) {
28
32
trigger : rawTrigger ,
29
33
placement : defaultPlacement ,
30
34
fallbackPlacement = 'flip' ,
35
+ defaultVisible = false ,
36
+ visible : controlledVisible ,
37
+ onToggle,
31
38
} = config ;
32
39
33
40
const delay =
@@ -37,7 +44,11 @@ function useOverlay(target, template, config) {
37
44
const trigger = rawTrigger . split ( ' ' ) ;
38
45
39
46
const identifier = useIdentifier ( 'template' ) ;
40
- const [ visible , setVisible ] = useState ( false ) ;
47
+ const [ visible , setVisible ] = useControlledState (
48
+ defaultVisible ,
49
+ controlledVisible ,
50
+ onToggle ,
51
+ ) ;
41
52
const [ focused , setFocused ] = useState ( false ) ;
42
53
const [ hovered , setHovered ] = useState ( false ) ;
43
54
@@ -64,7 +75,7 @@ function useOverlay(target, template, config) {
64
75
} , target . ref ) ,
65
76
...optional ( visible , { 'aria-describedby' : identifier } ) ,
66
77
onPress : ( event ) => {
67
- if ( trigger . indexOf ( 'click' ) !== - 1 ) {
78
+ if ( trigger . includes ( 'click' ) ) {
68
79
setVisible ( ( value ) => ! value ) ;
69
80
}
70
81
@@ -73,10 +84,10 @@ function useOverlay(target, template, config) {
73
84
}
74
85
} ,
75
86
onFocus : ( event ) => {
76
- if ( trigger . indexOf ( 'focus' ) !== - 1 ) {
87
+ if ( trigger . includes ( 'focus' ) ) {
77
88
setFocused ( true ) ;
78
89
79
- if ( trigger . indexOf ( 'focus' ) !== - 1 && ! visible ) {
90
+ if ( ! visible ) {
80
91
setVisible ( true ) ;
81
92
}
82
93
}
@@ -86,10 +97,10 @@ function useOverlay(target, template, config) {
86
97
}
87
98
} ,
88
99
onBlur : ( event ) => {
89
- if ( trigger . indexOf ( 'focus' ) !== - 1 ) {
100
+ if ( trigger . includes ( 'focus' ) ) {
90
101
setFocused ( false ) ;
91
102
92
- const activeHoverTrigger = trigger . indexOf ( 'hover' ) !== - 1 && hovered ;
103
+ const activeHoverTrigger = trigger . includes ( 'hover' ) && hovered ;
93
104
if ( visible && ! activeHoverTrigger ) {
94
105
setVisible ( false ) ;
95
106
}
@@ -100,7 +111,7 @@ function useOverlay(target, template, config) {
100
111
}
101
112
} ,
102
113
onMouseOver : ( event ) => {
103
- if ( trigger . indexOf ( 'hover' ) !== - 1 ) {
114
+ if ( trigger . includes ( 'hover' ) ) {
104
115
setHovered ( true ) ;
105
116
106
117
if ( ! visible && ! focused ) {
@@ -113,10 +124,10 @@ function useOverlay(target, template, config) {
113
124
}
114
125
} ,
115
126
onMouseLeave : ( event ) => {
116
- if ( trigger . indexOf ( 'hover' ) !== - 1 ) {
127
+ if ( trigger . includes ( 'hover' ) ) {
117
128
setHovered ( false ) ;
118
129
119
- const activeFocusTrigger = trigger . indexOf ( 'focus' ) !== - 1 && focused ;
130
+ const activeFocusTrigger = trigger . includes ( 'focus' ) && focused ;
120
131
if ( visible && ! activeFocusTrigger ) {
121
132
setVisible ( false ) ;
122
133
}
0 commit comments