Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 41 additions & 18 deletions components/languageSelector/LanguageSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { twMerge } from 'tailwind-merge';

import i18nextConfig from '@/next-i18next.config.cjs';
Expand All @@ -13,29 +13,52 @@ import IconLanguage from '../icons/Language';
* @param {Array} [props.options=[]] - An array of options for the select dropdown.
* @param {string} props.selected - The currently selected option value.
*/
export default function LanguageSelect({ className = '', onChange = () => {}, options = [], selected }: SelectProps) {
export default function LanguageSelect({ options = [], selected, onChange = () => {}, className = '' }: SelectProps) {
const [open, setOpen] = useState(false);
const { langMap } = i18nextConfig;

const selectedOption = options.find((o) => o.value === selected);
const selectedDisplayText =
selectedOption && (langMap[selectedOption.text.toLowerCase() as keyof typeof langMap] || selectedOption.text)
? langMap[selectedOption.text.toLowerCase() as keyof typeof langMap] || selectedOption.text
: 'Select';

return (
<div className='relative inline-block'>
<div className='relative flex items-center gap-2'>
{/* Display Icon Next to the Select Box */}
<IconLanguage className='pointer-events-none absolute left-3 text-gray-600' />
<select
data-testid='Select-form'
onChange={(ev) => onChange(ev.target.value)}
className={twMerge(
`form-select h-full px-10 pr-7 inline-flex justify-center rounded-md border border-gray-300 shadow-sm py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:border-gray-500 focus:outline-none focus:ring-0 focus:ring-black ${className}`
)}
value={selected}
>
{options.map((option, index) => (
<option key={index} value={option.value} data-testid='Option-form'>
{/* Trigger button */}
<button
type='button'
onClick={() => setOpen((prev) => !prev)}
className={twMerge(
`flex items-center w-full justify-between rounded-md border border-gray-300
bg-white px-3 py-2 text-sm text-gray-700 shadow-sm hover:bg-gray-50
focus:outline-none ${className}`
)}
>
<span className='flex items-center gap-2'>
<IconLanguage className='text-gray-600' />
{selectedDisplayText}
</span>
<span className='ml-2 text-gray-500'>▾</span>
</button>

{/* Dropdown menu */}
{open && (
<ul className='absolute mt-1 w-full rounded-md border border-gray-300 bg-white shadow-lg z-10 overflow-hidden'>
{options.map((option) => (
<li
key={option.value}
onClick={() => {
onChange(option.value);
setOpen(false);
}}
className='cursor-pointer px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 transition-colors'
>
{langMap[option.text.toLowerCase() as keyof typeof langMap] || option.text}
</option>
</li>
))}
</select>
</div>
</ul>
)}
</div>
);
}