import React, { cloneElement, isValidElement, useEffect, useImperativeHandle, useRef, useState } from "react"; import { createPopper } from "@popperjs/core"; import { usePopper } from 'react-popper'; import tw, { styled } 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, onValueChanged, button, buttonProps, popper, placement, hover, ...props }, 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; let click = item.props?.onClick; let close = item.props?.closeOnClick ?? true; return cloneElement(item, { key: children.indexOf ? children.indexOf(item) : 0, onClick: () => { close && closeDropdownPopover(); click && click() } }); }); return ( <> {dropdownPopoverShow &&
{ setOverDropDown(true); hover && await openDropdownPopover() }} onMouseLeave={() => { setOverDropDown(false); (!overButton && hover) && closeDropdownPopover() }} style={styles.popper} {...attributes.popper} css={[ dropdownPopoverShow ? tw`block` : tw`hidden`, tw`bg-trinary text-base z-50 float-left rounded-xl overflow-hidden text-left shadow-lg`, dropdownCss, props.css ]} > {childrenWithProps}
} ); }); export default Dropdown; export function DropdownMenu({ children, fallback, button, notSelectedOne = true, value, onChange, ...props }) { let ref = useRef() let btn = fallback ?? ""; if (children && children.length > 0) btn = children[value > children.length ? 0 : value] if (button != null) { btn = button(btn, value > children.length ? 0 : value); } return <> { children && children.map((i) => { if (children.indexOf(i) == value) return; return onChange(children.indexOf(i))}>{i} }) } { (children == null || children.length <= (notSelectedOne ? 1 : 0)) &&

Nothing to show

}
}