diff --git a/lib/click-outside/click-outside.tsx b/lib/click-outside/click-outside.tsx index 3c6b0ef28..8e90a3af0 100644 --- a/lib/click-outside/click-outside.tsx +++ b/lib/click-outside/click-outside.tsx @@ -1,4 +1,5 @@ -import React, { useRef, useEffect, MouseEvent } from 'react' +import React, { useRef, useEffect, MouseEvent, ReactElement } from 'react' +import mergeRefs from 'react-merge-refs' import hasParent from './has-parent' interface ClickOutsideProps { @@ -13,13 +14,9 @@ const ClickOutside = ({ children, }: ClickOutsideProps) => { const innerRef = useRef() - - const handleClick = (event: any) => { - if (!hasParent(event.target, innerRef?.current)) { - if (typeof onClick === 'function') { - onClick(event) - } - } + const child = children ? React.Children.only(children) : undefined + if (!child) { + throw new Error('A valid non Fragment React Children should be provided') } useEffect(() => { @@ -36,7 +33,27 @@ const ClickOutside = ({ } }) - return React.cloneElement(children, { ref: innerRef }) + const handleClick = (event: any) => { + if (!hasParent(event.target, innerRef?.current)) { + if (typeof onClick === 'function') { + onClick(event) + } + } + } + + const composedRefCallback = (element: ReactElement) => { + if (child) { + if (typeof child.ref === 'function') { + child.ref(element) + } else if (child.ref) { + child.ref.current = element + } + } + } + + return React.cloneElement(child, { + ref: mergeRefs([composedRefCallback, innerRef]), + }) } export default ClickOutside