منتقي الإعدادات المحلية
منتقي المناطق مع قيم افتراضية مشتقة من الإعدادات المحلية — العملة وتنسيقات التاريخ والأرقام وأول يوم في الأسبوع. قابل للبحث ومتاح عبر لوحة المفاتيح ويراعي RTL.
- Currency
- INR₹12,34,567.89
- Date format
- 15 Jan 2026
- Number format
- 12,34,567.89
- Week starts on
- Sunday
التثبيت
npx shadcn@latest add @babelize/locale-pickerالاستخدام
import { LocalePicker } from "@/components/ui/locale-picker";<LocalePicker
regions={["IN", "US", "GB", "DE", "JP"]} // your ISO 3166-1 alpha-2 regions
defaultValue="en-IN"
onValueChange={(locale) => console.log("Selected locale:", locale)}
label="english" // native, english
variant="outline" // outline, ghost, secondary
size="default" // sm, default, lg
/>الخصائص
| الخاصية | النوع | مطلوب | الافتراضي | الوصف |
|---|---|---|---|---|
regions | string[] | نعم | — | المناطق المتاحة للاختيار، برموز ISO 3166-1 alpha-2 |
value | string | لا | — | الإعدادات المحلية المحددة (BCP 47) — مرّرها للتحكم في المكوّن |
defaultValue | string | لا | en-<first region> | الإعدادات المحلية المحددة الأولية عند عدم التحكم |
onValueChange | (locale: string) => void | لا | — | دالة استدعاء عند تغيّر المنطقة — تستقبل وسم BCP 47 الجديد |
label | "native" | "english" | لا | "english" | أسماء المناطق بالإنجليزية، أو مترجمة إلى الإعدادات المحلية المحددة |
showFlags | boolean | لا | true | إظهار علم emoji للمنطقة بجانب اسمها |
maxHeight | number | string | لا | "15rem" | أقصى ارتفاع لقائمة الخيارات القابلة للتمرير قبل أن تبدأ بالتمرير |
variant | "outline" | "ghost" | "secondary" | لا | "outline" | نمط الزر المُشغّل |
size | "sm" | "default" | "lg" | لا | "default" | حجم الزر المُشغّل |
align | "start" | "end" | لا | "start" | الحافة التي تصطف النافذة المنبثقة معها في الزر المُشغّل |
side | "top" | "bottom" | لا | "bottom" | الجانب المفضل للنافذة المنبثقة — يتبدّل عند عدم وجود مساحة في منفذ العرض |
searchable | boolean | لا | true | إظهار حقل البحث |
searchPlaceholder | string | لا | "Search regions..." | النص النائب لحقل البحث |
emptyMessage | React.ReactNode | لا | "No results" | المحتوى المعروض عندما لا يطابق البحث أي نتيجة |
disabled | boolean | لا | false | تعطيل الزر المُشغّل |
showSummary | boolean | لا | true | إظهار بطاقة ملخص القيم الافتراضية المشتقة للإعدادات المحلية |
labels | Partial<LocalePickerLabels> | لا | — | تجاوز نصوص الواجهة الإنجليزية المدمجة (انظر أدناه) |
classNames | LocalePickerClassNames | لا | — | أصناف لكل جزء: trigger، content، search، list، item، empty، summary |
className | string | لا | — | أصناف CSS إضافية |
القيمة المحددة وسم BCP 47 كامل: جزء المنطقة فيه هو المنطقة المختارة، ويبقى جزء اللغة سليمًا عند تغيير المنطقة. اختيار ألمانيا من en-IN ينتج en-DE؛ واختيارها من fr-JP ينتج fr-DE.
القيم الافتراضية المشتقة
تشتق بطاقة الملخص كل شيء من الإعدادات المحلية المحددة عبر Intl — دون بيانات مضمّنة تتجاوز جدول ISO 4217 الاحتياطي لرمز العملة:
| الصف | المصدر |
|---|---|
| العملة | المنطقة ← رمز ISO 4217، مع معاينة بـ Intl.NumberFormat (style: "currency") |
| تنسيق التاريخ | Intl.DateTimeFormat (dateStyle: "medium") بتاريخ عيّنة ثابت |
| تنسيق الأرقام | Intl.NumberFormat بمبلغ عيّنة ثابت |
| يبدأ الأسبوع يوم | Intl.Locale#getWeekInfo() حيثما توفر، مع احتياط إقليمي |
تعرض المناطق التي لا تملك ربطًا بعملة شرطةً طويلة بدلًا من التخمين.
دعم لوحة المفاتيح
تتبع النافذة المنبثقة نمط combobox في WAI-ARIA: يبقى التركيز في حقل البحث، الذي يُعرض كـ role="combobox"، ويُعلَن عن الخيار المميّز عبر aria-activedescendant.
| المفتاح | الإجراء |
|---|---|
Enter، Space، أو النقر | افتح النافذة المنبثقة من الزر المُشغّل |
ArrowDown / ArrowUp (مغلقة) | افتح مع تمييز أول منطقة / آخرها |
ArrowDown / ArrowUp | انقل التمييز، مع الالتفاف عند الطرفين |
Home / End | مميّز أول منطقة / آخرها |
Enter | اختر المنطقة المميّزة وأعد التركيز إلى الزر المُشغّل |
Escape | أغلق النافذة المنبثقة وأعد التركيز إلى الزر المُشغّل |
| الكتابة | صفِّ حسب الاسم أو الرمز؛ يبدأ التمييز من الأعلى مجددًا |
الميزات
- القيم الافتراضية المشتقة — العملة وتنسيق التاريخ وتنسيق الأرقام وأول يوم في الأسبوع، تُحسب مباشرة عبر
Intl - قائمة منسدلة مع بحث — صفِّ المناطق حسب الاسم الإنجليزي أو الاسم المترجم أو رمز المنطقة، مع زر مسح
- الحركة — تتلاشى النافذة المنبثقة وتنزلق عبر
motion/react، مع احترامprefers-reduced-motion، وتغادر شجرة إمكانية الوصول عند إغلاقها - يراعي RTL — يعكس الاتجاه للإعدادات المحلية من نوع RTL (ar وhe وfa وur) عبر
dirعلى الجذر - متاح عبر لوحة المفاتيح — التنقل بمفاتيح الأسهم وHome / End وEnter وEscape
- تسميات ARIA — حقل البحث
role="combobox"معaria-activedescendant، إضافةً إلىaria-expandedوaria-haspopupوaria-selected - منسّق برموز shadcn —
bg-popoverوborder-inputوbg-accentوغيرها، فيرث سمتك؛ ويأتي الوضع الداكن من الرموز - قابل للتخصيص — أزرار
variant/sizeإضافةً إلىclassNamesلكل جزء (LocalePickerClassNamesمُصدَّر من ملف التصدير الرئيسي)، مع أيقوناتlucide-reactفي كل مكان - متحكَّم به أو غير متحكَّم به —
value/defaultValue/onValueChange
أمثلة
متحكَّم به
<LocalePicker regions={["IN", "US", "GB", "DE", "JP"]} value={locale} onValueChange={setLocale} />أسماء المناطق الأصلية
<LocalePicker regions={["IN", "US", "GB", "DE", "JP"]} defaultValue="de-DE" label="native" />عند تحديد de-DE، يقرأ الزر المُشغّل "Deutschland" وتقرأ الخيارات "Vereinigte Staaten" و"Vereinigtes Königreich"، وهكذا.
نصوص الواجهة المترجمة
تكون النصوص النائبة للبحث وحالة الفراغ وتسميات إمكانية الوصول وتسميات صفوف الملخص بالإنجليزية افتراضيًا. مرّر labels لترجمتها — وأي مفتاح تتركه يحتفظ بقيمته الإنجليزية الافتراضية. وتظل الخاصيتان searchPlaceholder وemptyMessage تعملان، وتتغلبان على labels عند ضبطهما معًا.
"use client";
import { LocalePicker } from "@/components/ui/locale-picker";
export default function App() {
return (
<LocalePicker
regions={["IN", "US", "GB", "DE", "JP"]}
defaultValue="en-IN"
labels={{
searchPlaceholder: "Rechercher une région…",
searchLabel: "Rechercher une région",
clearSearch: "Effacer la recherche",
emptyMessage: "Aucune région trouvée.",
listbox: "Choisir la région",
current: (name) => `Région actuelle : ${name}`,
currency: "Devise",
dateFormat: "Format de date",
numberFormat: "Format de nombre",
weekStart: "La semaine commence le",
}}
/>
);
}الاعتماديات
يستخدم هذا المكوّن:
clsxوtailwind-merge(مُضمّنة كاعتماديات)lucide-react(الأيقونات)motion(حركة النافذة المنبثقة)
الاعتماديات النظيرة:
react>= 18react-dom>= 18tailwindcss>= 3
الإسناد
من إنشاء ujwalbajaj.