import clsx from "clsx" import IconCheckMini from "../../Icons/CheckMini" import IconEllipseMiniSolid from "../../Icons/EllipseMiniSolid" import { OptionType } from "../../../hooks/use-select" import { forwardRef, useCallback, useEffect, useRef } from "react" type SelectDropdownProps = { options: OptionType[] open: boolean setOpen: React.Dispatch> addAll?: boolean multiple?: boolean isAllSelected: boolean isValueSelected: (val: string) => boolean handleSelectAll: () => void handleChange?: (selectedValue: string, wasSelected: boolean) => void parentRef?: React.RefObject className?: string } const SelectDropdown = forwardRef( function SelectDropdown( { open, setOpen, options, addAll, multiple = false, isAllSelected, isValueSelected, handleSelectAll, handleChange: handleSelectChange, parentRef, className, }, passedRef ) { const ref = useRef(null) const setRefs = useCallback( (node: HTMLDivElement) => { // Ref's from useRef needs to have the node assigned to `current` ref.current = node if (typeof passedRef === "function") { passedRef(node) } else if (passedRef && "current" in passedRef) { passedRef.current = node } }, [passedRef] ) const handleChange = (clickedValue: string, wasSelected: boolean) => { handleSelectChange?.(clickedValue, wasSelected) if (!multiple) { setOpen(false) } } const handleOutsideClick = useCallback( (e: MouseEvent) => { if ( open && !ref.current?.contains(e.target as Element) && !parentRef?.current?.contains(e.target as Element) ) { setOpen(false) } }, [open, parentRef, setOpen] ) useEffect(() => { document.body.addEventListener("click", handleOutsideClick) return () => { document.body.removeEventListener("click", handleOutsideClick) } }, [handleOutsideClick]) const getSelectOption = (option: OptionType, index: number) => { const isSelected = option.isAllOption ? isAllSelected : isValueSelected(option.value) return (
  • svg]:left-0.75 cursor-pointer [&>svg]:absolute [&>svg]:top-0.5", !isSelected && "text-compact-small", isSelected && "text-compact-small-plus" )} onClick={() => { if (option.isAllOption) { handleSelectAll() } else { handleChange(option.value, isSelected) } }} > {isSelected && ( <> {multiple && ( )} {!multiple && ( )} )} {option.label}
  • ) } return (
      {addAll && getSelectOption( { value: "all", label: "All Areas", isAllOption: true, }, -1 )} {options.map(getSelectOption)}
    ) } ) export default SelectDropdown