The Node.js® Website
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;