= (props) => {
+
+ const {children, offset = 8, placement = "bottom start", ...args} = props
+
+ //get trigger and content from popover
+ const popoverTrigger = getChild(children, PopoverTrigger, true)
+ const popoverContent = getChild(children, PopoverContent, true)
+
+ //initial state for popover
+ const state = useOverlayTriggerState({
+ isOpen: props.isOpen,
+ defaultOpen: props.defaultOpen,
+ onOpenChange: props.onOpenChange
+ })
+
+ const triggerRef = React.useRef(null)
+ const popoverRef = React.useRef(null)
+
+ const {triggerProps} = useOverlayTrigger(
+ {type: 'dialog'},
+ state,
+ triggerRef
+ )
+ const {popoverProps} = usePopover({
+ placement,
+ offset,
+ triggerRef,
+ popoverRef
+ }, state);
+
+
+ const {buttonProps} = useButton(triggerProps as AriaButtonOptions<'div'>, triggerRef);
+
+
+ return (
+ <>
+
+ {popoverTrigger?.props.children}
+
+
+ {state.isOpen &&
+ (
+
+
+ {popoverContent}
+
+
+ )}
+ >
+ );
+
+}
+
+const PopoverTrigger: React.FC = (props) => {
+
+ const {children, ...args} = props
+
+ return
+ {children}
+
+}
+
+const PopoverContent: React.FC = (props) => {
+
+ const {children, ...args} = props
+
+ return <>
+ {children}
+ >
+}
+
+
+export default Object.assign(Popover, {
+ Trigger: PopoverTrigger,
+ Content: PopoverContent
+})
\ No newline at end of file
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 37f5ac30..42933557 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -1,10 +1,20 @@
-import React, {ReactNode, RefObject, useCallback, useEffect, useState} from "react";
-
-export const getChild = (children: ReactNode | ReactNode[], child: React.FC): ReactNode | null => {
- return React.Children.toArray(children).find((childT) => {
- if (!React.isValidElement(childT)) return false;
- return childT.type == child;
- })
+import React, {ReactNode, useEffect, useMemo, useState} from "react";
+
+export const getChild = (children: ReactNode | ReactNode[], child: React.FC, required?: boolean): React.ReactElement | undefined => {
+
+ const [childComponent, setChildComponent] = useState()
+ useMemo(() => {
+ let found = false
+ React.Children.forEach(children, (childT, index) => {
+ if (React.isValidElement(childT) && childT.type == child) {
+ setChildComponent(childT)
+ found = true
+ }
+ else if (React.Children.count(children) - 1 == index && !found && !childComponent && required) throw new Error(`${child.name} is required`)
+ })
+ }, [])
+
+ return childComponent
}
export const getContent = (children: ReactNode | ReactNode[], ...child: React.FC[]): ReactNode[] | null => {