created new component SelectMultiple items

This commit is contained in:
Pramod Mahajan 2025-05-18 02:13:38 +05:30
parent b33fad1b17
commit c2ead3cd0f

View File

@ -0,0 +1,125 @@
import React, { useState, useEffect, useRef } from 'react';
import { useFormContext } from 'react-hook-form';
import './MultiSelectDropdown.css';
const SelectMultiple = ({
name,
options = [],
label = 'Select options',
labelKey = 'name',
valueKey = 'id',
placeholder = 'Please select...',
IsLoading = false
}) => {
const { setValue, watch } = useFormContext();
const selectedValues = watch(name) || [];
const [isOpen, setIsOpen] = useState(false);
const [searchText, setSearchText] = useState('');
const dropdownRef = useRef(null);
useEffect(() => {
const handleClickOutside = (e) => {
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
setIsOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
const handleCheckboxChange = (value) => {
const updated = selectedValues.includes(value)
? selectedValues.filter((v) => v !== value)
: [...selectedValues, value];
setValue(name, updated, { shouldValidate: true });
};
const filteredOptions = options.filter((item) =>
item[labelKey]?.toLowerCase().includes(searchText.toLowerCase())
);
return (
<div ref={dropdownRef} className="multi-select-dropdown-container">
<label className="form-label mb-1">{label}</label>
<div
className="multi-select-dropdown-header"
onClick={() => setIsOpen((prev) => !prev)}
>
<span
className={
selectedValues.length > 0
? 'placeholder-style-selected'
: 'placeholder-style'
}
>
<div className="selected-badges-container">
{selectedValues.length > 0 ? (
selectedValues.map((val) => {
const found = options.find((opt) => opt[valueKey] === val);
return (
<span key={val} className="badge badge-selected-item mx-1">
{found ? found[labelKey] : ''}
</span>
);
})
) : (
<span className="placeholder-text">{placeholder}</span>
)}
</div>
</span>
<i className="bx bx-chevron-down"></i>
</div>
{isOpen && (
<div className="multi-select-dropdown-options">
<div className="multi-select-dropdown-search">
<input
type="text"
placeholder="Search..."
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
className="multi-select-dropdown-search-input"
/>
</div>
{filteredOptions.map((item) => {
const labelVal = item[labelKey];
const valueVal = item[valueKey];
const isChecked = selectedValues.includes(valueVal);
return (
<div
key={valueVal}
className={`multi-select-dropdown-option ${isChecked ? 'selected' : ''}`}
>
<input
type="checkbox"
className="custom-checkbox form-check-input"
checked={isChecked}
onChange={() => handleCheckboxChange(valueVal)}
/>
<label className="text-secondary">{labelVal}</label>
</div>
);
} )}
{!IsLoading && filteredOptions.length === 0 && (
<div className='multi-select-dropdown-Not-found'>
<label className="text-muted">Not Found {`'${searchText}'`}</label>
</div>
)}
{IsLoading && filteredOptions.length === 0 && (
<div className='multi-select-dropdown-Not-found'>
<label className="text-muted">Loading...</label>
</div>
)}
</div>
)}
</div>
);
};
export default SelectMultiple;