UNPKG

react-country-dropdown-cu

Version:

A simple country selector dropdown for React with flags and search

120 lines (110 loc) 3.41 kB
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import Flag from 'react-world-flags'; import { countries as countryList } from './countries'; const CountryDropdown = ({ selectedCountry, onCountrySelect }) => { const [selected, setSelected] = useState( selectedCountry || { code: 'IN', shortName: 'India' } ); const [open, setOpen] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const dropdownRef = useRef(null); const toggleDropdown = () => setOpen(!open); const filteredCountries = useMemo(() => { return countryList.filter(({ code, shortName }) => { const term = searchTerm.toLowerCase(); return ( shortName.toLowerCase().includes(term) || code.toLowerCase().includes(term) ); }); }, [searchTerm]); const handleCountrySelect = useCallback( (country) => { setSelected(country); onCountrySelect?.(country); setOpen(false); setSearchTerm(''); }, [onCountrySelect] ); const handleClickOutside = (e) => { if (dropdownRef.current && !dropdownRef.current.contains(e.target)) { setOpen(false); } }; useEffect(() => { document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); return ( <div style={{ position: 'relative', width: '100%' }} ref={dropdownRef}> <div onClick={toggleDropdown} role="button" aria-haspopup="listbox" aria-expanded={open} tabIndex={0} style={{ border: '1px solid #ccc', padding: '10px', borderRadius: '5px', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: '10px', }} > <Flag code={selected.code} style={{ width: '20px', height: '15px' }} /> <span>{selected.shortName}</span> </div> {open && ( <div style={{ position: 'absolute', zIndex: 10, background: '#fff', border: '1px solid #ccc', borderRadius: '5px', marginTop: '5px', width: '100%', maxHeight: '200px', overflowY: 'auto', }} role="listbox" > <input type="text" placeholder="Search country" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} style={{ width: '100%', padding: '8px', borderBottom: '1px solid #ccc', boxSizing: 'border-box', }} /> {filteredCountries.map((country) => ( <div key={country.code} role="option" aria-selected={country.code === selected.code} onClick={() => handleCountrySelect(country)} style={{ padding: '10px', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: '10px', }} > <Flag code={country.code} style={{ width: '20px', height: '15px' }} /> <span>{country.shortName}</span> </div> ))} </div> )} </div> ); }; export default CountryDropdown;