Files
element-call/src/PopoverMenu.jsx

73 lines
1.9 KiB
React
Raw Normal View History

2021-12-06 17:34:10 -08:00
import React, { useRef } from "react";
2021-12-03 16:42:29 -08:00
import styles from "./PopoverMenu.module.css";
import { useMenuTriggerState } from "@react-stately/menu";
2021-12-06 17:34:10 -08:00
import { useMenuTrigger } from "@react-aria/menu";
2021-12-14 15:28:54 -08:00
import { OverlayContainer, useOverlayPosition } from "@react-aria/overlays";
2021-12-03 16:42:29 -08:00
import classNames from "classnames";
2021-12-06 17:34:10 -08:00
import { Popover } from "./Popover";
2021-12-03 16:42:29 -08:00
2021-12-06 17:34:10 -08:00
export function PopoverMenuTrigger({
children,
placement,
className,
2021-12-13 15:36:35 -08:00
disableOnState,
2021-12-06 17:34:10 -08:00
...rest
}) {
2021-12-03 16:42:29 -08:00
const popoverMenuState = useMenuTriggerState(rest);
const buttonRef = useRef();
const { menuTriggerProps, menuProps } = useMenuTrigger(
{},
popoverMenuState,
buttonRef
);
const popoverRef = useRef();
2021-12-06 17:34:10 -08:00
const { overlayProps } = useOverlayPosition({
2021-12-03 16:42:29 -08:00
targetRef: buttonRef,
overlayRef: popoverRef,
placement: placement || "top",
offset: 5,
isOpen: popoverMenuState.isOpen,
});
if (
!Array.isArray(children) ||
children.length > 2 ||
typeof children[1] !== "function"
) {
throw new Error(
"PopoverMenu must have two props. The first being a button and the second being a render prop."
);
}
2021-12-06 17:34:10 -08:00
const [popoverTrigger, popoverMenu] = children;
2021-12-03 16:42:29 -08:00
return (
2021-12-06 17:34:10 -08:00
<div className={classNames(styles.popoverMenuTrigger, className)}>
2021-12-03 16:42:29 -08:00
<popoverTrigger.type
{...popoverTrigger.props}
{...menuTriggerProps}
2021-12-13 15:36:35 -08:00
on={!disableOnState && popoverMenuState.isOpen}
2021-12-03 16:42:29 -08:00
ref={buttonRef}
/>
2021-12-06 17:34:10 -08:00
{popoverMenuState.isOpen && (
2021-12-14 15:28:54 -08:00
<OverlayContainer>
<Popover
{...overlayProps}
isOpen={popoverMenuState.isOpen}
onClose={popoverMenuState.close}
ref={popoverRef}
>
{popoverMenu({
...menuProps,
autoFocus: popoverMenuState.focusStrategy,
onClose: popoverMenuState.close,
})}
</Popover>
</OverlayContainer>
2021-12-06 17:34:10 -08:00
)}
</div>
2021-12-03 16:42:29 -08:00
);
}