import { useCallback, useMemo } from "react" export type OptionType = { value: string label: string index?: string isAllOption?: boolean } export type SelectOptions = { value: string | string[] multiple?: boolean options: OptionType[] setSelected?: (value: string | string[]) => void addSelected?: (value: string) => void removeSelected?: (value: string) => void handleAddAll?: (isAllSelected: boolean) => void } const useSelect = ({ value, options, multiple = false, setSelected, addSelected, removeSelected, handleAddAll, }: SelectOptions) => { const isValueSelected = useCallback( (val: string) => { return ( (typeof value === "string" && val === value) || (Array.isArray(value) && value.includes(val)) ) }, [value] ) // checks if there are multiple selected values const hasSelectedValues = useMemo(() => { return multiple && Array.isArray(value) && value.length > 0 }, [value, multiple]) // checks if there are any selected values, // whether multiple or one const hasSelectedValue = useMemo(() => { return hasSelectedValues || (typeof value === "string" && value.length) }, [hasSelectedValues, value]) const selectedValues: OptionType[] = useMemo(() => { if (typeof value === "string") { const selectedValue = options.find((option) => option.value === value) return selectedValue ? [selectedValue] : [] } else if (Array.isArray(value)) { return options.filter((option) => value.includes(option.value)) } return [] }, [options, value]) const isAllSelected = useMemo(() => { return Array.isArray(value) && value.length === options.length }, [options, value]) const handleChange = (selectedValue: string, wasSelected: boolean) => { if (multiple) { wasSelected ? removeSelected?.(selectedValue) : addSelected?.(selectedValue) } else { setSelected?.(selectedValue) } } const handleSelectAll = () => { if (handleAddAll) { handleAddAll(isAllSelected) } else { setSelected?.(options.map((option) => option.value)) } } return { isValueSelected, hasSelectedValue, hasSelectedValues, selectedValues, isAllSelected, handleChange, handleSelectAll, } } export default useSelect