Skip to content

Commit ef818fb

Browse files
Improve outside click handling
1 parent 199431c commit ef818fb

File tree

4 files changed

+29
-18
lines changed

4 files changed

+29
-18
lines changed

src/DatePicker.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useRef } from 'react'
1+
import React, { useState } from 'react'
22
import { func, instanceOf, object, objectOf, string } from 'prop-types'
33
import useDateInput from './useDateInput'
44
import useDetectTouch from './useDetectTouch'
@@ -21,10 +21,11 @@ export default function DatePicker({
2121
const [month, setMonth] = useState(date || new Date())
2222
const [focused, setFocused] = useState(false)
2323
const isTouch = useDetectTouch()
24-
const inputRef = useRef()
2524

26-
const containerRef = useOutsideClickHandler(() => {
27-
setFocused(false)
25+
const [inputRef, popoverRef] = useOutsideClickHandler(() => {
26+
if (focused) {
27+
setFocused(false)
28+
}
2829
})
2930

3031
const inputProps = useDateInput({
@@ -45,7 +46,7 @@ export default function DatePicker({
4546
}
4647

4748
return (
48-
<div className='nice-dates' ref={containerRef}>
49+
<div className='nice-dates'>
4950
{children({
5051
inputProps: {
5152
...inputProps,
@@ -63,7 +64,7 @@ export default function DatePicker({
6364
focused
6465
})}
6566

66-
<Popover open={focused}>
67+
<Popover open={focused} ref={popoverRef}>
6768
<DatePickerCalendar
6869
locale={locale}
6970
date={date}

src/DateRangePicker.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useState } from 'react'
1+
import React, { useState } from 'react'
22
import { func, instanceOf, object, objectOf, string } from 'prop-types'
33
import { addDays, subDays } from 'date-fns'
44
import { isSelectable } from './utils'
@@ -26,10 +26,8 @@ export default function DateRangePicker({
2626
const [focus, setFocus] = useState()
2727
const [month, setMonth] = useState(startDate || endDate || new Date())
2828
const isTouch = useDetectTouch()
29-
const startDateInputRef = useRef()
30-
const endDateInputRef = useRef()
3129

32-
const containerRef = useOutsideClickHandler(() => {
30+
const [startDateInputRef, endDateInputRef, popoverRef] = useOutsideClickHandler(() => {
3331
setFocus(null)
3432
})
3533

@@ -60,7 +58,7 @@ export default function DateRangePicker({
6058
})
6159

6260
return (
63-
<div className='nice-dates' ref={containerRef}>
61+
<div className='nice-dates'>
6462
{children({
6563
startDateInputProps: {
6664
...startDateInputProps,
@@ -91,7 +89,7 @@ export default function DateRangePicker({
9189
focus
9290
})}
9391

94-
<Popover open={!!focus}>
92+
<Popover open={!!focus} ref={popoverRef}>
9593
<DateRangePickerCalendar
9694
locale={locale}
9795
startDate={startDate}

src/Popover.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@ import React from 'react'
22
import { bool, node } from 'prop-types'
33
import classNames from 'classnames'
44

5-
export default function Popover({ open, children }) {
6-
return <div className={classNames('nice-dates-popover', { '-open': open })}>{children}</div>
7-
}
5+
const Popover = React.forwardRef(({ children, open }, ref) => (
6+
<div className={classNames('nice-dates-popover', { '-open': open })} ref={ref}>
7+
{children}
8+
</div>
9+
))
10+
11+
Popover.displayName = 'Popover'
812

913
Popover.propTypes = {
1014
children: node,
1115
open: bool
1216
}
17+
18+
export default Popover

src/useOutsideClickHandler.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import { useRef, useEffect } from 'react'
22

33
export default function useOutsideClickHandler(callback) {
4-
const ref = useRef()
4+
const refA = useRef()
5+
const refB = useRef()
6+
const refC = useRef()
57

68
useEffect(() => {
79
const handleOutsideClick = event => {
8-
if (!ref.current.contains(event.target)) {
10+
if (
11+
(!refA.current || !refA.current.contains(event.target)) &&
12+
(!refB.current || !refB.current.contains(event.target)) &&
13+
(!refC.current || !refC.current.contains(event.target))
14+
) {
915
callback()
1016
}
1117
}
@@ -17,5 +23,5 @@ export default function useOutsideClickHandler(callback) {
1723
}
1824
}, [callback])
1925

20-
return ref
26+
return [refA, refB, refC]
2127
}

0 commit comments

Comments
 (0)