The Node.js® Website
at main 61 lines 1.8 kB view raw
1import { LanguageIcon } from '@heroicons/react/24/outline'; 2import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; 3import classNames from 'classnames'; 4import { useTranslations } from 'next-intl'; 5import type { FC } from 'react'; 6 7import type { LocaleConfig } from '@/types'; 8 9import styles from './index.module.css'; 10 11type SimpleLocaleConfig = Pick<LocaleConfig, 'name' | 'code'>; 12 13type LanguageDropDownProps = { 14 onChange?: (newLocale: SimpleLocaleConfig) => void; 15 currentLanguage: string; 16 availableLanguages: Array<SimpleLocaleConfig>; 17}; 18 19const LanguageDropdown: FC<LanguageDropDownProps> = ({ 20 onChange = () => {}, 21 currentLanguage, 22 availableLanguages, 23}) => { 24 const t = useTranslations(); 25 26 const ariaLabel = t('components.common.languageDropdown.label'); 27 28 return ( 29 <DropdownMenu.Root> 30 <DropdownMenu.Trigger asChild> 31 <button className={styles.languageDropdown} aria-label={ariaLabel}> 32 <LanguageIcon height="20" /> 33 </button> 34 </DropdownMenu.Trigger> 35 36 <DropdownMenu.Portal> 37 <DropdownMenu.Content 38 align="start" 39 className={styles.dropDownContent} 40 sideOffset={5} 41 > 42 <div> 43 {availableLanguages.map(({ name, code }) => ( 44 <DropdownMenu.Item 45 key={code} 46 onClick={() => onChange({ name, code })} 47 className={classNames(styles.dropDownItem, { 48 [styles.currentDropDown]: code === currentLanguage, 49 })} 50 > 51 {name} 52 </DropdownMenu.Item> 53 ))} 54 </div> 55 </DropdownMenu.Content> 56 </DropdownMenu.Portal> 57 </DropdownMenu.Root> 58 ); 59}; 60 61export default LanguageDropdown;