/** * LanguageSelector - Dropdown component for selecting UI language. * * Supports English, Hindi, and Gujarati. * Persists selection to localStorage and updates i18n context. */ import { useState, useRef, useEffect, useCallback } from "react"; import { useTranslation } from "react-i18next"; import PropTypes from "prop-types"; import { ChevronDownIcon, LanguageIcon, CheckIcon } from "@heroicons/react/24/outline"; import { LANGUAGES, LANGUAGE_NAMES } from "@utils/constants"; const LANGUAGE_OPTIONS = [ { code: LANGUAGES.EN, name: LANGUAGE_NAMES[LANGUAGES.EN], nativeName: "English" }, { code: LANGUAGES.HI, name: LANGUAGE_NAMES[LANGUAGES.HI], nativeName: "Hindi" }, { code: LANGUAGES.GU, name: LANGUAGE_NAMES[LANGUAGES.GU], nativeName: "Gujarati" }, ]; function LanguageSelector({ currentLanguage, onLanguageChange, compact = false }) { const { t } = useTranslation(); const [isOpen, setIsOpen] = useState(false); const dropdownRef = useRef(null); const currentOption = LANGUAGE_OPTIONS.find((opt) => opt.code === currentLanguage) || LANGUAGE_OPTIONS[0]; const handleSelect = useCallback( (langCode) => { onLanguageChange(langCode); setIsOpen(false); }, [onLanguageChange] ); const toggleDropdown = useCallback(() => { setIsOpen((prev) => !prev); }, []); useEffect(() => { function handleClickOutside(event) { if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { setIsOpen(false); } } function handleEscape(event) { if (event.key === "Escape") { setIsOpen(false); } } if (isOpen) { document.addEventListener("mousedown", handleClickOutside); document.addEventListener("keydown", handleEscape); } return () => { document.removeEventListener("mousedown", handleClickOutside); document.removeEventListener("keydown", handleEscape); }; }, [isOpen]); return (
{isOpen && (
{LANGUAGE_OPTIONS.map((option) => { const isSelected = option.code === currentLanguage; return ( ); })}
)}
); } LanguageSelector.propTypes = { currentLanguage: PropTypes.oneOf([LANGUAGES.EN, LANGUAGES.HI, LANGUAGES.GU]).isRequired, onLanguageChange: PropTypes.func.isRequired, compact: PropTypes.bool, }; export default LanguageSelector;