/* eslint-disable @typescript-eslint/no-explicit-any */ import { useState, ReactNode } from "react"; import Select, { StylesConfig } from "react-select"; import CreatableSelect from "react-select/creatable"; // Option type export interface CustomOption { id: string | number; name: string; code: string; } interface CustomSelectOptionsProps { options: CustomOption[]; // <-- required className?: string; name: string; id?: string; onChange: (value: CustomOption | CustomOption[] | null, name: string, index?: string | number) => void; value?: CustomOption | CustomOption[] | null; required?: boolean; isMulti?: boolean; label?: string; isCreatable?: boolean; isLoading?: boolean; icon?: ReactNode | string; errors?: string; width?: string | number; index?: string | number; isClearable?: boolean; isDisabled?: boolean; placeholder?: string; style?: StylesConfig; divClassName?: string; onCreateOption?: (inputValue: string) => void; } const customStyles: StylesConfig = { option: (provided, state) => ({ ...provided, borderBottom: "1px dotted gray", color: state.isSelected ? "white" : "black", }), control: (base, state) => ({ ...base, border: state.isFocused ? "2px solid #1976d2" : "2px solid #222", borderRadius: "8px", minHeight: "48px", boxShadow: state.isFocused ? "0 0 0 1px #1976d2" : base.boxShadow, }), }; function CustomSelectOptions({ options, className = "", name, id, onChange, value, required = false, isMulti = false, label = "", isCreatable = false, isLoading = false, icon, errors, width, index = "", isClearable = true, isDisabled = false, placeholder = "", style, divClassName = "", onCreateOption, }: CustomSelectOptionsProps) { const [selectedValues, setSelectedValues] = useState(value || (isMulti ? [] : null)); const Multiselect = isCreatable ? CreatableSelect : Select; // Add new option handler const handleCreate = (inputValue: string) => { const newOption: CustomOption = { id: inputValue, name: inputValue, code: inputValue }; setSelectedValues(newOption); onChange(newOption, name, index); onCreateOption?.(inputValue); }; // Custom create label const formatCreateLabel = (inputValue: string) => { if (inputValue.trim() === "") { return "Add"; } else { return (
Add ‘{inputValue}’ to {label ? label : name} options
); } }; // Option label: code - name const getOptionLabel = (option: CustomOption) => `${option.code}${(option.name) ? ` - ${option.name}` : ``}`; // Selected value label: code only const getSingleValueLabel = (option: CustomOption) => option.code; return (
{icon && ( {typeof icon === "string" ? : icon} )} { setSelectedValues(selected as any); onChange(selected as any, name, index); }} options={options} required={required} className={className + " multiple-select01" + (errors ? " has-error" : "")} onCreateOption={isCreatable ? handleCreate : undefined} getOptionValue={(option) => option.id.toString()} getOptionLabel={getOptionLabel} styles={style || customStyles} formatCreateLabel={formatCreateLabel} isClearable={isClearable} isDisabled={isDisabled} placeholder={placeholder} isLoading={isLoading} isSearchable components={{ SingleValue: (props) => (
{getSingleValueLabel(props.data as CustomOption)}
), }} /> {errors && (
{errors}
)}
); } export default CustomSelectOptions;