@@ -8,6 +8,7 @@ import useIdentifier from './useIdentifier';
88import usePopper from './usePopper' ;
99import concatRefs from '../utils/concatRefs' ;
1010import optional from '../utils/optional' ;
11+ import useControlledState from './useControlledState' ;
1112
1213export const OverlayPropTypes = {
1314 delay : PropTypes . oneOfType ( [
@@ -20,6 +21,9 @@ export const OverlayPropTypes = {
2021 trigger : PropTypes . oneOf ( TRIGGERS ) ,
2122 placement : PropTypes . oneOf ( PLACEMENTS ) ,
2223 fallbackPlacement : PropTypes . oneOf ( [ 'flip' , 'clockwise' , 'counterwise' ] ) ,
24+ defaultVisible : PropTypes . bool ,
25+ visible : PropTypes . bool ,
26+ onToggle : PropTypes . func ,
2327} ;
2428
2529function useOverlay ( target , template , config ) {
@@ -28,6 +32,9 @@ function useOverlay(target, template, config) {
2832 trigger : rawTrigger ,
2933 placement : defaultPlacement ,
3034 fallbackPlacement = 'flip' ,
35+ defaultVisible = false ,
36+ visible : controlledVisible ,
37+ onToggle,
3138 } = config ;
3239
3340 const delay =
@@ -37,7 +44,11 @@ function useOverlay(target, template, config) {
3744 const trigger = rawTrigger . split ( ' ' ) ;
3845
3946 const identifier = useIdentifier ( 'template' ) ;
40- const [ visible , setVisible ] = useState ( false ) ;
47+ const [ visible , setVisible ] = useControlledState (
48+ defaultVisible ,
49+ controlledVisible ,
50+ onToggle ,
51+ ) ;
4152 const [ focused , setFocused ] = useState ( false ) ;
4253 const [ hovered , setHovered ] = useState ( false ) ;
4354
@@ -64,7 +75,7 @@ function useOverlay(target, template, config) {
6475 } , target . ref ) ,
6576 ...optional ( visible , { 'aria-describedby' : identifier } ) ,
6677 onPress : ( event ) => {
67- if ( trigger . indexOf ( 'click' ) !== - 1 ) {
78+ if ( trigger . includes ( 'click' ) ) {
6879 setVisible ( ( value ) => ! value ) ;
6980 }
7081
@@ -73,10 +84,10 @@ function useOverlay(target, template, config) {
7384 }
7485 } ,
7586 onFocus : ( event ) => {
76- if ( trigger . indexOf ( 'focus' ) !== - 1 ) {
87+ if ( trigger . includes ( 'focus' ) ) {
7788 setFocused ( true ) ;
7889
79- if ( trigger . indexOf ( 'focus' ) !== - 1 && ! visible ) {
90+ if ( ! visible ) {
8091 setVisible ( true ) ;
8192 }
8293 }
@@ -86,10 +97,10 @@ function useOverlay(target, template, config) {
8697 }
8798 } ,
8899 onBlur : ( event ) => {
89- if ( trigger . indexOf ( 'focus' ) !== - 1 ) {
100+ if ( trigger . includes ( 'focus' ) ) {
90101 setFocused ( false ) ;
91102
92- const activeHoverTrigger = trigger . indexOf ( 'hover' ) !== - 1 && hovered ;
103+ const activeHoverTrigger = trigger . includes ( 'hover' ) && hovered ;
93104 if ( visible && ! activeHoverTrigger ) {
94105 setVisible ( false ) ;
95106 }
@@ -100,7 +111,7 @@ function useOverlay(target, template, config) {
100111 }
101112 } ,
102113 onMouseOver : ( event ) => {
103- if ( trigger . indexOf ( 'hover' ) !== - 1 ) {
114+ if ( trigger . includes ( 'hover' ) ) {
104115 setHovered ( true ) ;
105116
106117 if ( ! visible && ! focused ) {
@@ -113,10 +124,10 @@ function useOverlay(target, template, config) {
113124 }
114125 } ,
115126 onMouseLeave : ( event ) => {
116- if ( trigger . indexOf ( 'hover' ) !== - 1 ) {
127+ if ( trigger . includes ( 'hover' ) ) {
117128 setHovered ( false ) ;
118129
119- const activeFocusTrigger = trigger . indexOf ( 'focus' ) !== - 1 && focused ;
130+ const activeFocusTrigger = trigger . includes ( 'focus' ) && focused ;
120131 if ( visible && ! activeFocusTrigger ) {
121132 setVisible ( false ) ;
122133 }
0 commit comments