import React, { cloneElement, isValidElement, useEffect, useImperativeHandle, useRef, useState } from "react"; import { createPopper, Placement } from "@popperjs/core"; import { usePopper } from 'react-popper'; import styled from "styled-components"; import tw from "twin.macro" import { colors, colorsDisabled, colorsHover, textColors, textColorsHover } from "./Colors"; const DropDownItem = styled.button(({ type }) => [ // The common button styles added with the tw import tw`text-sm text-left py-2 px-4 focus:outline-none block w-full whitespace-nowrap bg-transparent hover:bg-secondary disabled:bg-secondary text-primary hover:text-primary`, // Use props to conditionally style your components textColors[type], colorsHover[type] ]) export { DropDownItem } let Dropdown = React.forwardRef(({ children, dropdownCss = null, onValueChanged = null, button, buttonProps = null, popper = null, placement = null, hover = null, ...props }: { children: React.ReactNode, dropdownCss?: any, onValueChanged?: (value: boolean) => void, button?: React.ReactNode, buttonProps?: any, popper?: any, placement?: Placement, hover?: boolean, }, ref) => { // dropdown props const [overButton, setOverButton] = React.useState(false); const [overDropDown, setOverDropDown] = React.useState(false); const [dropdownPopoverShow, setDropdownPopoverShow] = React.useState(false); const [btnDropdownRef, setBtnDropdownRef] = React.useState(null); const [popoverDropdownRef, setPopoverDropdownRef] = React.useState(null); const { styles, attributes, update } = usePopper(btnDropdownRef, popoverDropdownRef, { placement: placement ?? "bottom", strategy: "fixed", ...popper }); const openDropdownPopover = async () => { setDropdownPopoverShow(true); if (update != null) { await update(); } try { if (onValueChanged) onValueChanged(true); } catch (e) { console.error(e); } }; const closeDropdownPopover = () => { setDropdownPopoverShow(false); try { if (onValueChanged) onValueChanged(false); } catch (e) { console.error(e); } }; function handleOutsideClick(event) { let node = popoverDropdownRef; if (node && !node?.contains(event.target) && !btnDropdownRef?.contains(event.target)) { closeDropdownPopover(); } } useEffect(() => { if ("ontouchend" in window) { document.addEventListener("touchend", handleOutsideClick) } else { document.addEventListener("click", handleOutsideClick) } // Specify how to clean up after this effect: return function cleanup() { document.removeEventListener("touchend", handleOutsideClick) document.removeEventListener("click", handleOutsideClick) }; }); /* useImperativeHandle(ref, () => ({ openDropdownPopover, closeDropdownPopover }))*/ let childrenWithProps = React.Children.map(children, (item) => { if (!item) return; //check that item is not only ReactNode if (!isValidElement(item)) return; let click = item.props?.onClick; let close = item.props?.closeOnClick ?? true; return cloneElement(item as any, { key: Array.isArray(children) ? children.indexOf(item) : 0, onClick: () => { close && closeDropdownPopover(); click && click() } }); }); return ( <> {dropdownPopoverShow &&
Nothing to show
}