2023-01-30 12:16:45 -05:00
|
|
|
import React, {
|
|
|
|
Children,
|
|
|
|
cloneElement,
|
|
|
|
type FC,
|
|
|
|
isValidElement,
|
|
|
|
useCallback,
|
|
|
|
} from 'react'
|
2023-01-05 05:17:57 -05:00
|
|
|
import { Dropdown, DropdownProps } from 'react-bootstrap'
|
|
|
|
import useDropdown from '../hooks/use-dropdown'
|
|
|
|
|
2023-01-30 12:16:45 -05:00
|
|
|
type ControlledDropdownProps = DropdownProps & {
|
|
|
|
defaultOpen?: boolean
|
|
|
|
onMainButtonClick?: (dropdownOpen: boolean) => void
|
|
|
|
}
|
|
|
|
|
|
|
|
const ControlledDropdown: FC<ControlledDropdownProps> = ({
|
|
|
|
defaultOpen,
|
|
|
|
onMainButtonClick,
|
|
|
|
...props
|
|
|
|
}) => {
|
|
|
|
const { onClick, ...dropdownProps } = useDropdown(Boolean(defaultOpen))
|
|
|
|
|
|
|
|
const handleClick = useCallback(
|
|
|
|
(e: React.MouseEvent<Dropdown, MouseEvent>) => {
|
|
|
|
onClick(e)
|
|
|
|
|
|
|
|
if (onMainButtonClick) {
|
|
|
|
onMainButtonClick(dropdownProps.open)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[onClick, onMainButtonClick, dropdownProps.open]
|
|
|
|
)
|
2023-01-05 05:17:57 -05:00
|
|
|
|
|
|
|
return (
|
2023-01-30 12:16:45 -05:00
|
|
|
<Dropdown {...props} {...dropdownProps} onClick={handleClick}>
|
2023-01-05 05:17:57 -05:00
|
|
|
{Children.map(props.children, child => {
|
|
|
|
if (!isValidElement(child)) {
|
|
|
|
return child
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dropdown.Menu
|
|
|
|
if ('open' in child.props) {
|
2023-06-08 04:38:16 -04:00
|
|
|
return cloneElement<any>(child, { open: dropdownProps.open })
|
2023-01-05 05:17:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Overlay
|
|
|
|
if ('show' in child.props) {
|
2023-06-08 04:38:16 -04:00
|
|
|
return cloneElement<any>(child, { show: dropdownProps.open })
|
2023-01-05 05:17:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// anything else
|
|
|
|
return cloneElement(child)
|
|
|
|
})}
|
|
|
|
</Dropdown>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default ControlledDropdown
|