import React, { forwardRef } from 'react';
import { useControllableState } from '@gluestack-ui/hooks';
import { Overlay } from '@gluestack-ui/overlay';
import { PopoverProvider } from './PopoverContext';
export const Popover = (StyledPopover: any) =>
forwardRef(
(
{
onOpen,
trigger,
onClose,
isOpen: isOpenProp,
children,
defaultIsOpen = false,
initialFocusRef,
finalFocusRef,
useRNModal,
focusScope = true,
trapFocus = true,
placement = 'bottom',
shouldOverlapWithTrigger = false,
crossOffset,
offset,
isKeyboardDismissable = true,
shouldFlip,
// @ts-ignore
_experimentalOverlay = false,
...props
}: any,
ref?: any
) => {
const [isOpen, setIsOpen] = useControllableState({
value: isOpenProp,
defaultValue: defaultIsOpen,
onChange: (value) => {
value ? onOpen && onOpen() : onClose && onClose();
},
});
const [bodyMounted, setBodyMounted] = React.useState(false);
const [headerMounted, setHeaderMounted] = React.useState(false);
var idCounter = 0;
function uniqueId(prefix = '') {
var id = ++idCounter;
return prefix + id;
}
const id = uniqueId();
const popoverContentId = `${id}-content`;
const headerId = `${popoverContentId}-header`;
const bodyId = `${popoverContentId}-body`;
const handleOpen = React.useCallback(() => {
setIsOpen(true);
}, [setIsOpen]);
const handleClose = React.useCallback(() => {
setIsOpen(false);
}, [setIsOpen]);
const updatedTrigger = (reference: any) => {
return trigger(
{
'ref': reference,
'onPress': handleOpen,
'aria-expanded': isOpen ? true : false,
'aria-controls': isOpen ? popoverContentId : undefined,
'aria-haspopup': true,
},
{ open: isOpen }
);
};
// let floatingParams: any = {};
// if (Platform.OS === 'web') {
// floatingParams = { whileElementsMounted: autoUpdate };
// }
const targetRef = React.useRef(null);
const contextValue: any = React.useMemo(() => {
return {
targetRef,
strategy: 'absolute',
handleClose,
initialFocusRef,
finalFocusRef,
popoverContentId,
bodyId,
headerId,
headerMounted,
bodyMounted,
setBodyMounted,
setHeaderMounted,
isOpen,
placement,
shouldOverlapWithTrigger,
crossOffset,
offset,
focusScope,
trapFocus,
shouldFlip,
};
}, [
targetRef,
handleClose,
initialFocusRef,
finalFocusRef,
popoverContentId,
bodyId,
headerId,
headerMounted,
bodyMounted,
setBodyMounted,
setHeaderMounted,
isOpen,
placement,
shouldOverlapWithTrigger,
crossOffset,
offset,
focusScope,
trapFocus,
shouldFlip,
]);
if (_experimentalOverlay) {
return (
<>
{updatedTrigger(targetRef)}
{children}
>
);
}
return (
<>
{updatedTrigger(targetRef)}
{children}
>
);
}
);