feat(i18n): Hebrew locale + full RTL support

This commit is contained in:
Shuki Vaknin
2026-07-08 00:07:34 +02:00
committed by Linus Rath
parent 8904d724bb
commit 22418c17cf
113 changed files with 3958 additions and 494 deletions
+10 -9
View File
@@ -1,13 +1,13 @@
"use client";
import { useState, useRef, useEffect } from "react";
import { useLocale } from 'next-intl';
import { useLocaleStore } from '@/stores/locale-store';
import { ChevronDown } from 'lucide-react';
import { cn } from '@/lib/utils';
import { flagComponents } from './flag-icons';
const languages = [
{ value: 'auto', label: 'Auto' },
{ value: 'cs', label: 'Česky' },
{ value: 'sk', label: 'Slovenčina' },
{ value: 'da', label: 'Dansk' },
@@ -16,6 +16,7 @@ const languages = [
{ value: 'fa', label: 'فارسی' },
{ value: 'es', label: 'Español' },
{ value: 'fr', label: 'Français' },
{ value: 'he', label: 'עברית' },
{ value: 'it', label: 'Italiano' },
{ value: 'hu', label: 'Magyar' },
{ value: 'lv', label: 'Latviešu' },
@@ -38,13 +39,13 @@ function FlagIcon({ locale }: { locale: string }) {
}
export function LanguageSwitcher({ className }: { className?: string }) {
const currentLocale = useLocale();
const setLocale = useLocaleStore((state) => state.setLocale);
const choice = useLocaleStore((state) => state.locale) || 'auto';
const [open, setOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const listRef = useRef<HTMLUListElement>(null);
const current = languages.find((l) => l.value === currentLocale) ?? languages[0];
const current = languages.find((l) => l.value === choice) ?? languages[0];
// Close on outside click
useEffect(() => {
@@ -78,7 +79,7 @@ export function LanguageSwitcher({ className }: { className?: string }) {
aria-expanded={open}
>
<FlagIcon locale={current.value} />
<span className="flex-1 text-left">{current.label}</span>
<span className="flex-1 text-start">{current.label}</span>
<ChevronDown className={cn("h-3.5 w-3.5 text-muted-foreground transition-transform duration-150", open && "rotate-180")} />
</button>
@@ -86,22 +87,22 @@ export function LanguageSwitcher({ className }: { className?: string }) {
<ul
ref={listRef}
role="listbox"
aria-activedescendant={`lang-${currentLocale}`}
className="absolute z-50 mt-1 w-full max-h-60 overflow-auto rounded-md border border-border bg-background shadow-lg py-1"
aria-activedescendant={`lang-${choice}`}
className="absolute start-0 z-50 mt-1 min-w-full w-max max-w-[min(16rem,80vw)] max-h-60 overflow-auto rounded-md border border-border bg-background shadow-lg py-1"
>
{languages.map((lang) => (
<li
key={lang.value}
id={`lang-${lang.value}`}
role="option"
aria-selected={lang.value === currentLocale}
aria-selected={lang.value === choice}
onClick={() => {
setLocale(lang.value);
setOpen(false);
}}
className={cn(
"flex items-center gap-2 px-3 py-1.5 text-sm cursor-pointer transition-colors duration-100",
lang.value === currentLocale
"flex items-center gap-2 px-3 py-1.5 text-sm cursor-pointer whitespace-nowrap transition-colors duration-100",
lang.value === choice
? "bg-accent text-accent-foreground font-medium"
: "text-foreground hover:bg-accent/50"
)}