Merge pull request #20 from damjan1996/auto-claude/011-languageswitcher-arrow-key-navigation

auto-claude: 011-languageswitcher-arrow-key-navigation
This commit is contained in:
Damjan Savic
2026-01-25 19:44:48 +01:00
committed by GitHub
+32 -5
View File
@@ -11,6 +11,7 @@ const LanguageSwitcher = () => {
const pathname = usePathname(); const pathname = usePathname();
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [isMobile, setIsMobile] = useState(false); const [isMobile, setIsMobile] = useState(false);
const [focusedIndex, setFocusedIndex] = useState<number>(-1);
const dropdownRef = useRef<HTMLDivElement>(null); const dropdownRef = useRef<HTMLDivElement>(null);
const languages = [ const languages = [
@@ -30,8 +31,28 @@ const LanguageSwitcher = () => {
}; };
const handleKeyDown = (e: React.KeyboardEvent) => { const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Escape') { if (!isOpen) return;
setIsOpen(false);
switch (e.key) {
case 'Escape':
setIsOpen(false);
setFocusedIndex(-1);
break;
case 'ArrowDown':
e.preventDefault();
setFocusedIndex(prev => (prev + 1) % languages.length);
break;
case 'ArrowUp':
e.preventDefault();
setFocusedIndex(prev => (prev - 1 + languages.length) % languages.length);
break;
case 'Enter':
e.preventDefault();
if (focusedIndex >= 0) {
handleLanguageChange(languages[focusedIndex].code);
setFocusedIndex(-1);
}
break;
} }
}; };
@@ -63,7 +84,10 @@ const LanguageSwitcher = () => {
px-4 py-2 rounded-full transition-all duration-200 px-4 py-2 rounded-full transition-all duration-200
hover:bg-zinc-800/50 border border-transparent hover:border-zinc-800 hover:bg-zinc-800/50 border border-transparent hover:border-zinc-800
hover:scale-105 active:scale-95" hover:scale-105 active:scale-95"
onClick={() => setIsOpen(!isOpen)} onClick={() => {
setIsOpen(!isOpen);
setFocusedIndex(-1);
}}
aria-expanded={isOpen} aria-expanded={isOpen}
aria-haspopup="listbox" aria-haspopup="listbox"
aria-label="Select language" aria-label="Select language"
@@ -79,18 +103,21 @@ const LanguageSwitcher = () => {
${isOpen ? 'opacity-100 scale-100' : 'opacity-0 scale-95 pointer-events-none'}`} ${isOpen ? 'opacity-100 scale-100' : 'opacity-0 scale-95 pointer-events-none'}`}
role="listbox" role="listbox"
aria-label="Languages" aria-label="Languages"
aria-activedescendant={focusedIndex >= 0 ? `lang-option-${languages[focusedIndex].code}` : undefined}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
> >
<div className="py-1"> <div className="py-1">
{languages.map((lang) => ( {languages.map((lang, index) => (
<button <button
key={lang.code} key={lang.code}
id={`lang-option-${lang.code}`}
className={`w-full text-left px-4 py-2 text-sm transition-colors duration-200 className={`w-full text-left px-4 py-2 text-sm transition-colors duration-200
hover:bg-zinc-800/50 hover:bg-zinc-800/50
${locale === lang.code ${locale === lang.code
? 'bg-zinc-800 text-white' ? 'bg-zinc-800 text-white'
: 'text-zinc-400 hover:text-white' : 'text-zinc-400 hover:text-white'
}`} }
${focusedIndex === index ? 'ring-2 ring-orange-500 ring-inset' : ''}`}
onClick={() => handleLanguageChange(lang.code)} onClick={() => handleLanguageChange(lang.code)}
role="option" role="option"
aria-selected={locale === lang.code} aria-selected={locale === lang.code}