import React, { FC, useRef, useState } from "react"; interface SubComponents { Button: FC; Panel: FC; } export interface DropdownProps { children: [ React.ReactComponentElement, React.ReactComponentElement ]; position?: "top-left" | "top-right" | "bottom-left" | "bottom-right"; open?: boolean; onChange?: (value: boolean) => void; } export interface DropdownPanelProps { children: React.ReactNode; } export interface DropdownButtonProps { children: React.ReactNode; } export const Dropdown: FC & SubComponents = ({ children, position = "bottom-right", open: openProp, onChange, }) => { const [internalOpen, setInternalOpen] = useState(false); const buttonRef = useRef(null); let open = internalOpen; let toggleOpen = () => setInternalOpen(prev => !prev); if (openProp !== undefined) { open = openProp; toggleOpen = () => onChange?.(!open); } let positionValues = {}; if (buttonRef.current) { const { height: buttonHeight } = buttonRef.current.getBoundingClientRect(); const [vertical, horizontal] = position.split("-"); positionValues = { [vertical === "bottom" ? "top" : "bottom"]: buttonHeight, [horizontal === "right" ? "left" : "right"]: 0, }; } return (
{children[0]}
{children[1]}
); }; Dropdown.Panel = ({ children }) => { return <>{children}; }; Dropdown.Button = ({ children }) => { return <>{children}; }; export default Dropdown;