fix: country code selector
This commit is contained in:
2
.npmrc
2
.npmrc
@@ -1,2 +1,2 @@
|
||||
@rkheftan:registry=https://npm.pkg.github.com
|
||||
//npm.pkg.github.com/:_authToken=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
|
||||
//npm.pkg.github.com/:_authToken=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
|
||||
6364
package-lock 2.json
Normal file
6364
package-lock 2.json
Normal file
File diff suppressed because it is too large
Load Diff
1604
package-lock.json
generated
1604
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,6 @@
|
||||
"@mui/x-data-grid-premium": "^8.10.0",
|
||||
"@mui/x-date-pickers": "^8.10.0",
|
||||
"@rkheftan/harmony-ui": "^0.1.8",
|
||||
"@rollup/rollup-win32-x64-msvc": "^4.46.3",
|
||||
"axios": "^1.11.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"date-fns-jalali": "^4.0.0-0",
|
||||
@@ -35,6 +34,7 @@
|
||||
"react-dom": "^19.1.0",
|
||||
"react-i18next": "^15.6.0",
|
||||
"react-router-dom": "^7.8.0",
|
||||
"react-virtuoso": "^4.14.0",
|
||||
"stylis": "^4.3.6",
|
||||
"stylis-plugin-rtl": "^2.1.1"
|
||||
},
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
"bosnia_and_herzegovina": "Bosnia and herzegovina",
|
||||
"botswana": "Botswana",
|
||||
"brazil": "Brazil",
|
||||
"british_indian_ocean_territory": "British indian ocean territory",
|
||||
"british_virgin_islands": "British virgin islands",
|
||||
"brunei": "Brunei",
|
||||
"bulgaria": "Bulgaria",
|
||||
@@ -45,8 +44,6 @@
|
||||
"chad": "Chad",
|
||||
"chile": "Chile",
|
||||
"china": "China",
|
||||
"christmas_island": "Christmas island",
|
||||
"cocos_keeling_islands": "Cocos keeling islands",
|
||||
"colombia": "Colombia",
|
||||
"comoros": "Comoros",
|
||||
"congo_brazzaville": "Congo brazzaville",
|
||||
|
||||
@@ -73,12 +73,14 @@
|
||||
"germany": "آلمان",
|
||||
"ghana": "غنا",
|
||||
"greece": "یونان",
|
||||
"greenland": "گرینلند",
|
||||
"guatemala": "گواتمالا",
|
||||
"guinea": "گینه",
|
||||
"guinea_bissau": "گینه بیسائو",
|
||||
"guyana": "گویان",
|
||||
"haiti": "هائیتی",
|
||||
"honduras": "هندوراس",
|
||||
"hong_kong": "هنگ کنگ",
|
||||
"hungary": "مجارستان",
|
||||
"iceland": "ایسلند",
|
||||
"india": "هندوستان",
|
||||
@@ -101,7 +103,10 @@
|
||||
"lesotho": "لسوتو",
|
||||
"liberia": "لیبریا",
|
||||
"libya": "لیبی",
|
||||
"lithuania": "لیتوانی",
|
||||
"luxembourg": "لوکزامبورگ",
|
||||
"macau": "ماکائو",
|
||||
"madagascar": "ماداگاسکار",
|
||||
"malaysia": "مالزی",
|
||||
"maldives": "مالدیو",
|
||||
"mali": "مالی",
|
||||
@@ -128,6 +133,7 @@
|
||||
"oman": "عمان",
|
||||
"pakistan": "پاکستان",
|
||||
"palau": "پالائو",
|
||||
"palestine": "فلسطین",
|
||||
"panama": "پاناما",
|
||||
"papua_new_guinea": "پاپوآ گینه نو",
|
||||
"paraguay": "پاراگوئه",
|
||||
@@ -135,6 +141,7 @@
|
||||
"philippines": "فیلیپین",
|
||||
"poland": "لهستان",
|
||||
"portugal": "پرتغال",
|
||||
"puerto_rico": "پورتوریکو",
|
||||
"qatar": "قطر",
|
||||
"romania": "رومانی",
|
||||
"russia": "روسیه",
|
||||
@@ -145,6 +152,9 @@
|
||||
"seychelles": "سیشل",
|
||||
"sierra_leone": "سیرالئون",
|
||||
"singapore": "سنگاپور",
|
||||
"slovakia": "اسلواکی",
|
||||
"slovenia": "اسلوونی",
|
||||
"somalia": "سومالی",
|
||||
"south_africa": "آفریقای جنوبی",
|
||||
"south_korea": "کره جنوبی",
|
||||
"south_sudan": "سودان جنوبی",
|
||||
@@ -175,6 +185,7 @@
|
||||
"uruguay": "اروگوئه",
|
||||
"uzbekistan": "ازبکستان",
|
||||
"vanuatu": "وانواتو",
|
||||
"vatican_city": "واتیکان",
|
||||
"venezuela": "ونزوئلا",
|
||||
"vietnam": "ویتنام",
|
||||
"yemen": "یمن",
|
||||
|
||||
@@ -37,11 +37,6 @@ export const countries: readonly Country[] = [
|
||||
{ code: 'BA', label: 'country.bosnia_and_herzegovina', phone: '+387' },
|
||||
{ code: 'BW', label: 'country.botswana', phone: '+267' },
|
||||
{ code: 'BR', label: 'country.brazil', phone: '+55' },
|
||||
{
|
||||
code: 'IO',
|
||||
label: 'country.british_indian_ocean_territory',
|
||||
phone: '+246',
|
||||
},
|
||||
{ code: 'VG', label: 'country.british_virgin_islands', phone: '+1284' },
|
||||
{ code: 'BN', label: 'country.brunei', phone: '+673' },
|
||||
{ code: 'BG', label: 'country.bulgaria', phone: '+359' },
|
||||
@@ -56,18 +51,12 @@ export const countries: readonly Country[] = [
|
||||
{ code: 'TD', label: 'country.chad', phone: '+235' },
|
||||
{ code: 'CL', label: 'country.chile', phone: '+56' },
|
||||
{ code: 'CN', label: 'country.china', phone: '+86' },
|
||||
{ code: 'CX', label: 'country.christmas_island', phone: '+61' },
|
||||
{ code: 'CC', label: 'country.cocos_keeling_islands', phone: '+61' },
|
||||
{ code: 'CO', label: 'country.colombia', phone: '+57' },
|
||||
{ code: 'KM', label: 'country.comoros', phone: '+269' },
|
||||
{ code: 'CG', label: 'country.congo_brazzaville', phone: '+242' },
|
||||
{ code: 'CD', label: 'country.congo_kinshasa', phone: '+243' },
|
||||
{ code: 'CK', label: 'country.cook_islands', phone: '+682' },
|
||||
{ code: 'CR', label: 'country.costa_rica', phone: '+506' },
|
||||
{ code: 'CI', label: 'country.cote_divoire', phone: '+225' },
|
||||
{ code: 'HR', label: 'country.croatia', phone: '+385' },
|
||||
{ code: 'CU', label: 'country.cuba', phone: '+53' },
|
||||
{ code: 'CW', label: 'country.curacao', phone: '+599' },
|
||||
{ code: 'CY', label: 'country.cyprus', phone: '+357' },
|
||||
{ code: 'CZ', label: 'country.czech_republic', phone: '+420' },
|
||||
{ code: 'DK', label: 'country.denmark', phone: '+45' },
|
||||
@@ -82,26 +71,17 @@ export const countries: readonly Country[] = [
|
||||
{ code: 'EE', label: 'country.estonia', phone: '+372' },
|
||||
{ code: 'SZ', label: 'country.eswatini', phone: '+268' },
|
||||
{ code: 'ET', label: 'country.ethiopia', phone: '+251' },
|
||||
{ code: 'FK', label: 'country.falkland_islands', phone: '+500' },
|
||||
{ code: 'FO', label: 'country.faroe_islands', phone: '+298' },
|
||||
{ code: 'FJ', label: 'country.fiji', phone: '+679' },
|
||||
{ code: 'FI', label: 'country.finland', phone: '+358' },
|
||||
{ code: 'FR', label: 'country.france', phone: '+33' },
|
||||
{ code: 'GF', label: 'country.french_guiana', phone: '+594' },
|
||||
{ code: 'PF', label: 'country.french_polynesia', phone: '+689' },
|
||||
{ code: 'GA', label: 'country.gabon', phone: '+241' },
|
||||
{ code: 'GM', label: 'country.gambia', phone: '+220' },
|
||||
{ code: 'GE', label: 'country.georgia', phone: '+995' },
|
||||
{ code: 'DE', label: 'country.germany', phone: '+49' },
|
||||
{ code: 'GH', label: 'country.ghana', phone: '+233' },
|
||||
{ code: 'GI', label: 'country.gibraltar', phone: '+350' },
|
||||
{ code: 'GR', label: 'country.greece', phone: '+30' },
|
||||
{ code: 'GL', label: 'country.greenland', phone: '+299' },
|
||||
{ code: 'GD', label: 'country.grenada', phone: '+1473' },
|
||||
{ code: 'GP', label: 'country.guadeloupe', phone: '+590' },
|
||||
{ code: 'GU', label: 'country.guam', phone: '+1671' },
|
||||
{ code: 'GT', label: 'country.guatemala', phone: '+502' },
|
||||
{ code: 'GG', label: 'country.guernsey', phone: '+44' },
|
||||
{ code: 'GN', label: 'country.guinea', phone: '+224' },
|
||||
{ code: 'GW', label: 'country.guinea_bissau', phone: '+245' },
|
||||
{ code: 'GY', label: 'country.guyana', phone: '+592' },
|
||||
@@ -115,17 +95,13 @@ export const countries: readonly Country[] = [
|
||||
{ code: 'IR', label: 'country.iran', phone: '+98' },
|
||||
{ code: 'IQ', label: 'country.iraq', phone: '+964' },
|
||||
{ code: 'IE', label: 'country.ireland', phone: '+353' },
|
||||
{ code: 'IM', label: 'country.isle_of_man', phone: '+44' },
|
||||
{ code: 'IL', label: 'country.israel', phone: '+972' },
|
||||
{ code: 'IT', label: 'country.italy', phone: '+39' },
|
||||
{ code: 'JM', label: 'country.jamaica', phone: '+1876' },
|
||||
{ code: 'JP', label: 'country.japan', phone: '+81' },
|
||||
{ code: 'JE', label: 'country.jersey', phone: '+44' },
|
||||
{ code: 'JO', label: 'country.jordan', phone: '+962' },
|
||||
{ code: 'KZ', label: 'country.kazakhstan', phone: '+7' },
|
||||
{ code: 'KE', label: 'country.kenya', phone: '+254' },
|
||||
{ code: 'KI', label: 'country.kiribati', phone: '+686' },
|
||||
{ code: 'XK', label: 'country.kosovo', phone: '+383' },
|
||||
{ code: 'KW', label: 'country.kuwait', phone: '+965' },
|
||||
{ code: 'KG', label: 'country.kyrgyzstan', phone: '+996' },
|
||||
{ code: 'LA', label: 'country.laos', phone: '+856' },
|
||||
@@ -134,45 +110,32 @@ export const countries: readonly Country[] = [
|
||||
{ code: 'LS', label: 'country.lesotho', phone: '+266' },
|
||||
{ code: 'LR', label: 'country.liberia', phone: '+231' },
|
||||
{ code: 'LY', label: 'country.libya', phone: '+218' },
|
||||
{ code: 'LI', label: 'country.liechtenstein', phone: '+423' },
|
||||
{ code: 'LT', label: 'country.lithuania', phone: '+370' },
|
||||
{ code: 'LU', label: 'country.luxembourg', phone: '+352' },
|
||||
{ code: 'MO', label: 'country.macau', phone: '+853' },
|
||||
{ code: 'MG', label: 'country.madagascar', phone: '+261' },
|
||||
{ code: 'MW', label: 'country.malawi', phone: '+265' },
|
||||
{ code: 'MY', label: 'country.malaysia', phone: '+60' },
|
||||
{ code: 'MV', label: 'country.maldives', phone: '+960' },
|
||||
{ code: 'ML', label: 'country.mali', phone: '+223' },
|
||||
{ code: 'MT', label: 'country.malta', phone: '+356' },
|
||||
{ code: 'MH', label: 'country.marshall_islands', phone: '+692' },
|
||||
{ code: 'MQ', label: 'country.martinique', phone: '+596' },
|
||||
{ code: 'MR', label: 'country.mauritania', phone: '+222' },
|
||||
{ code: 'MU', label: 'country.mauritius', phone: '+230' },
|
||||
{ code: 'YT', label: 'country.mayotte', phone: '+262' },
|
||||
{ code: 'MX', label: 'country.mexico', phone: '+52' },
|
||||
{ code: 'FM', label: 'country.micronesia', phone: '+691' },
|
||||
{ code: 'MD', label: 'country.moldova', phone: '+373' },
|
||||
{ code: 'MC', label: 'country.monaco', phone: '+377' },
|
||||
{ code: 'MN', label: 'country.mongolia', phone: '+976' },
|
||||
{ code: 'ME', label: 'country.montenegro', phone: '+382' },
|
||||
{ code: 'MS', label: 'country.montserrat', phone: '+1664' },
|
||||
{ code: 'MA', label: 'country.morocco', phone: '+212' },
|
||||
{ code: 'MZ', label: 'country.mozambique', phone: '+258' },
|
||||
{ code: 'MM', label: 'country.myanmar', phone: '+95' },
|
||||
{ code: 'NA', label: 'country.namibia', phone: '+264' },
|
||||
{ code: 'NR', label: 'country.nauru', phone: '+674' },
|
||||
{ code: 'NP', label: 'country.nepal', phone: '+977' },
|
||||
{ code: 'NL', label: 'country.netherlands', phone: '+31' },
|
||||
{ code: 'NC', label: 'country.new_caledonia', phone: '+687' },
|
||||
{ code: 'NZ', label: 'country.new_zealand', phone: '+64' },
|
||||
{ code: 'NI', label: 'country.nicaragua', phone: '+505' },
|
||||
{ code: 'NE', label: 'country.niger', phone: '+227' },
|
||||
{ code: 'NG', label: 'country.nigeria', phone: '+234' },
|
||||
{ code: 'NU', label: 'country.niue', phone: '+683' },
|
||||
{ code: 'NF', label: 'country.norfolk_island', phone: '+672' },
|
||||
{ code: 'KP', label: 'country.north_korea', phone: '+850' },
|
||||
{ code: 'MK', label: 'country.north_macedonia', phone: '+389' },
|
||||
{ code: 'MP', label: 'country.northern_mariana_islands', phone: '+1670' },
|
||||
{ code: 'NO', label: 'country.norway', phone: '+47' },
|
||||
{ code: 'OM', label: 'country.oman', phone: '+968' },
|
||||
{ code: 'PK', label: 'country.pakistan', phone: '+92' },
|
||||
@@ -183,53 +146,29 @@ export const countries: readonly Country[] = [
|
||||
{ code: 'PY', label: 'country.paraguay', phone: '+595' },
|
||||
{ code: 'PE', label: 'country.peru', phone: '+51' },
|
||||
{ code: 'PH', label: 'country.philippines', phone: '+63' },
|
||||
{ code: 'PN', label: 'country.pitcairn_islands', phone: '+64' },
|
||||
{ code: 'PL', label: 'country.poland', phone: '+48' },
|
||||
{ code: 'PT', label: 'country.portugal', phone: '+351' },
|
||||
{ code: 'PR', label: 'country.puerto_rico', phone: '+1' },
|
||||
{ code: 'QA', label: 'country.qatar', phone: '+974' },
|
||||
{ code: 'RE', label: 'country.reunion', phone: '+262' },
|
||||
{ code: 'RO', label: 'country.romania', phone: '+40' },
|
||||
{ code: 'RU', label: 'country.russia', phone: '+7' },
|
||||
{ code: 'RW', label: 'country.rwanda', phone: '+250' },
|
||||
{ code: 'BL', label: 'country.saint_barthelemy', phone: '+590' },
|
||||
{ code: 'SH', label: 'country.saint_helena', phone: '+290' },
|
||||
{ code: 'KN', label: 'country.saint_kitts_and_nevis', phone: '+1869' },
|
||||
{ code: 'LC', label: 'country.saint_lucia', phone: '+1758' },
|
||||
{ code: 'MF', label: 'country.saint_martin', phone: '+590' },
|
||||
{ code: 'PM', label: 'country.saint_pierre_and_miquelon', phone: '+508' },
|
||||
{
|
||||
code: 'VC',
|
||||
label: 'country.saint_vincent_and_the_grenadines',
|
||||
phone: '+1784',
|
||||
},
|
||||
{ code: 'WS', label: 'country.samoa', phone: '+685' },
|
||||
{ code: 'SM', label: 'country.san_marino', phone: '+378' },
|
||||
{ code: 'ST', label: 'country.sao_tome_and_principe', phone: '+239' },
|
||||
{ code: 'SA', label: 'country.saudi_arabia', phone: '+966' },
|
||||
{ code: 'SN', label: 'country.senegal', phone: '+221' },
|
||||
{ code: 'RS', label: 'country.serbia', phone: '+381' },
|
||||
{ code: 'SC', label: 'country.seychelles', phone: '+248' },
|
||||
{ code: 'SL', label: 'country.sierra_leone', phone: '+232' },
|
||||
{ code: 'SG', label: 'country.singapore', phone: '+65' },
|
||||
{ code: 'SX', label: 'country.sint_maarten', phone: '+1721' },
|
||||
{ code: 'SK', label: 'country.slovakia', phone: '+421' },
|
||||
{ code: 'SI', label: 'country.slovenia', phone: '+386' },
|
||||
{ code: 'SB', label: 'country.solomon_islands', phone: '+677' },
|
||||
{ code: 'SO', label: 'country.somalia', phone: '+252' },
|
||||
{ code: 'ZA', label: 'country.south_africa', phone: '+27' },
|
||||
{
|
||||
code: 'GS',
|
||||
label: 'country.south_georgia_and_south_sandwich_islands',
|
||||
phone: '+500',
|
||||
},
|
||||
{ code: 'KR', label: 'country.south_korea', phone: '+82' },
|
||||
{ code: 'SS', label: 'country.south_sudan', phone: '+211' },
|
||||
{ code: 'ES', label: 'country.spain', phone: '+34' },
|
||||
{ code: 'LK', label: 'country.sri_lanka', phone: '+94' },
|
||||
{ code: 'SD', label: 'country.sudan', phone: '+249' },
|
||||
{ code: 'SR', label: 'country.suriname', phone: '+597' },
|
||||
{ code: 'SJ', label: 'country.svalbard_and_jan_mayen', phone: '+47' },
|
||||
{ code: 'SE', label: 'country.sweden', phone: '+46' },
|
||||
{ code: 'CH', label: 'country.switzerland', phone: '+41' },
|
||||
{ code: 'SY', label: 'country.syria', phone: '+963' },
|
||||
@@ -239,15 +178,12 @@ export const countries: readonly Country[] = [
|
||||
{ code: 'TH', label: 'country.thailand', phone: '+66' },
|
||||
{ code: 'TL', label: 'country.timor_leste', phone: '+670' },
|
||||
{ code: 'TG', label: 'country.togo', phone: '+228' },
|
||||
{ code: 'TK', label: 'country.tokelau', phone: '+690' },
|
||||
{ code: 'TO', label: 'country.tonga', phone: '+676' },
|
||||
{ code: 'TT', label: 'country.trinidad_and_tobago', phone: '+1868' },
|
||||
{ code: 'TN', label: 'country.tunisia', phone: '+216' },
|
||||
{ code: 'TR', label: 'country.turkey', phone: '+90' },
|
||||
{ code: 'TM', label: 'country.turkmenistan', phone: '+993' },
|
||||
{ code: 'TC', label: 'country.turks_and_caicos_islands', phone: '+1649' },
|
||||
{ code: 'TV', label: 'country.tuvalu', phone: '+688' },
|
||||
{ code: 'VI', label: 'country.us_virgin_islands', phone: '+1340' },
|
||||
{ code: 'UG', label: 'country.uganda', phone: '+256' },
|
||||
{ code: 'UA', label: 'country.ukraine', phone: '+380' },
|
||||
{ code: 'AE', label: 'country.united_arab_emirates', phone: '+971' },
|
||||
@@ -259,8 +195,6 @@ export const countries: readonly Country[] = [
|
||||
{ code: 'VA', label: 'country.vatican_city', phone: '+39' },
|
||||
{ code: 'VE', label: 'country.venezuela', phone: '+58' },
|
||||
{ code: 'VN', label: 'country.vietnam', phone: '+84' },
|
||||
{ code: 'WF', label: 'country.wallis_and_futuna', phone: '+681' },
|
||||
{ code: 'EH', label: 'country.western_sahara', phone: '+212' },
|
||||
{ code: 'YE', label: 'country.yemen', phone: '+967' },
|
||||
{ code: 'ZM', label: 'country.zambia', phone: '+260' },
|
||||
{ code: 'ZW', label: 'country.zimbabwe', phone: '+263' },
|
||||
|
||||
@@ -14,6 +14,7 @@ import { useToast } from '@rkheftan/harmony-ui';
|
||||
import { useApi } from '@/hooks/useApi';
|
||||
import type { GenerateTokenResponse } from '../../api/identityAPI';
|
||||
import { GoogleAuthenticationV2 } from './GoogleAuthenticationV2';
|
||||
import { replacePersianWithRealNumbers } from '@/utils/replacePersianWithRealNumbers';
|
||||
|
||||
export interface LoginRegisterFormProps {
|
||||
loginRegisterValue: string;
|
||||
|
||||
@@ -17,6 +17,8 @@ import { countries, type Country } from '../../../data/countries';
|
||||
import type { CountryCode } from '@/types/commonTypes';
|
||||
import { Icon } from '@rkheftan/harmony-ui';
|
||||
import { LTRBox } from '@/components/common/LTRBox';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
|
||||
interface CountryCodeSelectorProps {
|
||||
show: boolean;
|
||||
value: CountryCode;
|
||||
@@ -25,10 +27,6 @@ interface CountryCodeSelectorProps {
|
||||
onCloseFocusRef: RefObject<HTMLInputElement | null>;
|
||||
}
|
||||
|
||||
/**
|
||||
* An animated country code adornment that fades and slides into view.
|
||||
* Its visibility is controlled by the `show` prop.
|
||||
*/
|
||||
export function CountryCodeSelector({
|
||||
show,
|
||||
value,
|
||||
@@ -46,18 +44,14 @@ export function CountryCodeSelector({
|
||||
const selectedCountry =
|
||||
countries.find((c) => c.phone === value) || countries[0];
|
||||
|
||||
const handleClick = () => {
|
||||
setAnchorEl(menuAnchor);
|
||||
};
|
||||
const handleClick = () => setAnchorEl(menuAnchor);
|
||||
|
||||
const handleClose = () => {
|
||||
setTimeout(() => {
|
||||
setAnchorEl(null);
|
||||
}, 0);
|
||||
setTimeout(() => setAnchorEl(null), 0);
|
||||
setTimeout(() => {
|
||||
onCloseFocusRef.current?.focus();
|
||||
}, 100);
|
||||
setSearchTerm(''); // Reset search on close
|
||||
setSearchTerm('');
|
||||
};
|
||||
|
||||
const handleSelect = (country: Country) => {
|
||||
@@ -66,7 +60,6 @@ export function CountryCodeSelector({
|
||||
};
|
||||
|
||||
const handleMenuEntered = () => {
|
||||
// Focus the input field after the menu has finished opening
|
||||
searchInputRef.current?.focus();
|
||||
};
|
||||
|
||||
@@ -74,55 +67,51 @@ export function CountryCodeSelector({
|
||||
() =>
|
||||
countries.filter(
|
||||
(country) =>
|
||||
t(country.label).toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
t(country.label, { ns: 'country' })
|
||||
.toLowerCase()
|
||||
.includes(searchTerm.toLowerCase()) ||
|
||||
country.label.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
country.phone.includes(searchTerm),
|
||||
),
|
||||
[searchTerm],
|
||||
[searchTerm, t],
|
||||
);
|
||||
|
||||
const initialIndex = Math.max(
|
||||
0,
|
||||
filteredCountries.findIndex((c) => c.phone === value),
|
||||
);
|
||||
|
||||
return (
|
||||
<InputAdornment
|
||||
position={i18n.dir() === 'rtl' ? 'start' : 'end'}
|
||||
sx={{
|
||||
mx: 0,
|
||||
}}
|
||||
sx={{ mx: 0 }}
|
||||
>
|
||||
<Box
|
||||
onClick={handleClick}
|
||||
sx={{
|
||||
// Animate width and opacity based on the 'show' prop
|
||||
width: show ? 'auto' : 0,
|
||||
opacity: show ? 1 : 0,
|
||||
transition: (theme) =>
|
||||
theme.transitions.create(['width', 'opacity'], {
|
||||
duration: theme.transitions.duration.standard,
|
||||
}),
|
||||
|
||||
// Prevent content from wrapping or spilling out during animation
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
|
||||
// layout styles
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 0.25,
|
||||
pl: show ? 0.25 : 0,
|
||||
|
||||
'&:hover': {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'&:hover': { cursor: 'pointer' },
|
||||
}}
|
||||
>
|
||||
{/* This inner Box prevents the content from being squeezed during the transition */}
|
||||
<Icon Component={ArrowDown2} size="medium" variant="Bold" />
|
||||
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="text.primary"
|
||||
component="div"
|
||||
sx={{ direction: 'rtl' }} // TODO: need to fixed for both en and fa
|
||||
sx={{ direction: 'rtl' }}
|
||||
>
|
||||
{value}
|
||||
</Typography>
|
||||
@@ -133,7 +122,6 @@ export function CountryCodeSelector({
|
||||
style={{
|
||||
height: '1.5rem',
|
||||
width: '1.5rem',
|
||||
// TODO: Check alignment for better styling definition
|
||||
marginTop: '-2px',
|
||||
marginRight: '4px',
|
||||
}}
|
||||
@@ -146,23 +134,15 @@ export function CountryCodeSelector({
|
||||
slotProps={{
|
||||
list: {
|
||||
sx: {
|
||||
// Set the width to match the anchor element's width
|
||||
width: menuWidth,
|
||||
height: '18.75rem',
|
||||
p: 0,
|
||||
},
|
||||
},
|
||||
transition: {
|
||||
onEntered: handleMenuEntered,
|
||||
},
|
||||
}}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'left',
|
||||
transition: { onEntered: handleMenuEntered },
|
||||
}}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
|
||||
transformOrigin={{ vertical: 'top', horizontal: 'left' }}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
@@ -183,8 +163,8 @@ export function CountryCodeSelector({
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* Can improve preformance with using virtual scrolling */}
|
||||
<Box sx={{ width: '100%', maxHeight: '14.75rem', overflow: 'auto' }}>
|
||||
{/* Virtualized country list */}
|
||||
<Box sx={{ width: '100%', height: '14.75rem' }}>
|
||||
{filteredCountries.length === 0 ? (
|
||||
<MenuItem disabled>
|
||||
<ListItem>
|
||||
@@ -194,65 +174,35 @@ export function CountryCodeSelector({
|
||||
</ListItem>
|
||||
</MenuItem>
|
||||
) : (
|
||||
filteredCountries.map((country) => (
|
||||
<MenuItem
|
||||
key={country.code}
|
||||
selected={country.phone === value}
|
||||
onClick={() => handleSelect(country)}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<ReactCountryFlag
|
||||
countryCode={country.code}
|
||||
svg
|
||||
style={{
|
||||
height: '1.125rem',
|
||||
width: '1.125rem',
|
||||
}}
|
||||
<Virtuoso
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
data={filteredCountries}
|
||||
initialTopMostItemIndex={initialIndex}
|
||||
itemContent={(_, country) => (
|
||||
<MenuItem
|
||||
key={country.code}
|
||||
selected={country.phone === value}
|
||||
onClick={() => handleSelect(country)}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<ReactCountryFlag
|
||||
countryCode={country.code}
|
||||
svg
|
||||
style={{ height: '1.125rem', width: '1.125rem' }}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={t(country.label, { ns: 'country' })}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={t(country.label, { ns: 'country' })} />
|
||||
<Typography color="text.secondary">
|
||||
<Typography>
|
||||
<Typography color="text.secondary">
|
||||
<LTRBox>{country.phone}</LTRBox>
|
||||
</Typography>
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
))
|
||||
</MenuItem>
|
||||
)}
|
||||
computeItemKey={(_, c) => c.code}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* virtual scrolling */}
|
||||
{/* <Virtuoso
|
||||
style={{ height: '14.75rem' }} // Adjust height to account for the search bar
|
||||
data={filteredCountries}
|
||||
components={{
|
||||
EmptyPlaceholder: () => (
|
||||
<MenuItem disabled>
|
||||
<ListItemText>{t('messages.noResultFound')}</ListItemText>
|
||||
</MenuItem>
|
||||
),
|
||||
}}
|
||||
initialTopMostItemIndex={countries.indexOf(selectedCountry)}
|
||||
itemContent={(_, country) => (
|
||||
<MenuItem
|
||||
key={country.code}
|
||||
selected={country.phone === value}
|
||||
onClick={() => handleSelect(country)}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<ReactCountryFlag
|
||||
countryCode={country.code}
|
||||
svg
|
||||
style={{ fontSize: '1.25em', lineHeight: '1.25em' }}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={country.label} />
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{country.phone}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
)}
|
||||
/> */}
|
||||
</Menu>
|
||||
</Box>
|
||||
</InputAdornment>
|
||||
|
||||
@@ -13,20 +13,20 @@ import { useMemo, useRef, useState, type RefObject } from 'react';
|
||||
import { ArrowDown2 } from 'iconsax-react';
|
||||
import ReactCountryFlag from 'react-country-flag';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { countries, type Country } from '@/data/countries';
|
||||
import { countries, type Country } from '../../../data/countries';
|
||||
import type { CountryCode } from '@/types/commonTypes';
|
||||
import { Icon } from '@rkheftan/harmony-ui';
|
||||
import { LTRBox } from '@/components/common/LTRBox';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
|
||||
interface CountryCodeSelectorProps {
|
||||
show: boolean;
|
||||
value: string;
|
||||
onChange: (newValue: string) => void;
|
||||
value: CountryCode;
|
||||
onChange: (newValue: CountryCode) => void;
|
||||
menuAnchor: HTMLElement | null;
|
||||
onCloseFocusRef: RefObject<HTMLInputElement | null>;
|
||||
}
|
||||
|
||||
/**
|
||||
* An animated country code adornment that fades and slides into view.
|
||||
* Its visibility is controlled by the `show` prop.
|
||||
*/
|
||||
export function CountryCodeSelector({
|
||||
show,
|
||||
value,
|
||||
@@ -39,23 +39,19 @@ export function CountryCodeSelector({
|
||||
const open = Boolean(anchorEl);
|
||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||
const menuWidth = menuAnchor ? menuAnchor.clientWidth : 'auto';
|
||||
const { t, i18n } = useTranslation();
|
||||
const { t, i18n } = useTranslation(['country', 'common']);
|
||||
|
||||
const selectedCountry =
|
||||
countries.find((c) => c.phone === value) || countries[0];
|
||||
|
||||
const handleClick = () => {
|
||||
setAnchorEl(menuAnchor);
|
||||
};
|
||||
const handleClick = () => setAnchorEl(menuAnchor);
|
||||
|
||||
const handleClose = () => {
|
||||
setTimeout(() => {
|
||||
setAnchorEl(null);
|
||||
}, 0);
|
||||
setTimeout(() => setAnchorEl(null), 0);
|
||||
setTimeout(() => {
|
||||
onCloseFocusRef.current?.focus();
|
||||
}, 100);
|
||||
setSearchTerm(''); // Reset search on close
|
||||
setSearchTerm('');
|
||||
};
|
||||
|
||||
const handleSelect = (country: Country) => {
|
||||
@@ -64,7 +60,6 @@ export function CountryCodeSelector({
|
||||
};
|
||||
|
||||
const handleMenuEntered = () => {
|
||||
// Focus the input field after the menu has finished opening
|
||||
searchInputRef.current?.focus();
|
||||
};
|
||||
|
||||
@@ -72,55 +67,51 @@ export function CountryCodeSelector({
|
||||
() =>
|
||||
countries.filter(
|
||||
(country) =>
|
||||
t(country.label).toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
t(country.label, { ns: 'country' })
|
||||
.toLowerCase()
|
||||
.includes(searchTerm.toLowerCase()) ||
|
||||
country.label.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
country.phone.includes(searchTerm),
|
||||
),
|
||||
[searchTerm, t],
|
||||
);
|
||||
|
||||
const initialIndex = Math.max(
|
||||
0,
|
||||
filteredCountries.findIndex((c) => c.phone === value),
|
||||
);
|
||||
|
||||
return (
|
||||
<InputAdornment
|
||||
position={i18n.dir() === 'rtl' ? 'start' : 'end'}
|
||||
sx={{
|
||||
mx: 0,
|
||||
}}
|
||||
sx={{ mx: 0 }}
|
||||
>
|
||||
<Box
|
||||
onClick={handleClick}
|
||||
sx={{
|
||||
// Animate width and opacity based on the 'show' prop
|
||||
width: show ? 'auto' : 0,
|
||||
opacity: show ? 1 : 0,
|
||||
transition: (theme) =>
|
||||
theme.transitions.create(['width', 'opacity'], {
|
||||
duration: theme.transitions.duration.standard,
|
||||
}),
|
||||
|
||||
// Prevent content from wrapping or spilling out during animation
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
|
||||
// layout styles
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 0.25,
|
||||
pl: show ? 0.25 : 0,
|
||||
|
||||
'&:hover': {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'&:hover': { cursor: 'pointer' },
|
||||
}}
|
||||
>
|
||||
{/* This inner Box prevents the content from being squeezed during the transition */}
|
||||
<ArrowDown2 size="24" variant="Bold" />
|
||||
<Icon Component={ArrowDown2} size="medium" variant="Bold" />
|
||||
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="text.primary"
|
||||
component="div"
|
||||
sx={{ direction: 'rtl' }} // TODO: need to fixed for both en and fa
|
||||
sx={{ direction: 'rtl' }}
|
||||
>
|
||||
{value}
|
||||
</Typography>
|
||||
@@ -131,7 +122,6 @@ export function CountryCodeSelector({
|
||||
style={{
|
||||
height: '1.5rem',
|
||||
width: '1.5rem',
|
||||
// TODO: Check alignment for better styling definition
|
||||
marginTop: '-2px',
|
||||
marginRight: '4px',
|
||||
}}
|
||||
@@ -144,23 +134,15 @@ export function CountryCodeSelector({
|
||||
slotProps={{
|
||||
list: {
|
||||
sx: {
|
||||
// Set the width to match the anchor element's width
|
||||
width: menuWidth,
|
||||
height: '18.75rem',
|
||||
p: 0,
|
||||
},
|
||||
},
|
||||
transition: {
|
||||
onEntered: handleMenuEntered,
|
||||
},
|
||||
}}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'left',
|
||||
transition: { onEntered: handleMenuEntered },
|
||||
}}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
|
||||
transformOrigin={{ vertical: 'top', horizontal: 'left' }}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
@@ -175,78 +157,52 @@ export function CountryCodeSelector({
|
||||
inputRef={searchInputRef}
|
||||
size="small"
|
||||
fullWidth
|
||||
label={t('labels.search')}
|
||||
label={t('labels.search', { ns: 'common' })}
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* Can improve preformance with using virtual scrolling */}
|
||||
<Box sx={{ width: '100%', maxHeight: '14.75rem', overflow: 'auto' }}>
|
||||
{/* Virtualized country list */}
|
||||
<Box sx={{ width: '100%', height: '14.75rem' }}>
|
||||
{filteredCountries.length === 0 ? (
|
||||
<MenuItem disabled>
|
||||
<ListItem>
|
||||
<ListItemText>{t('messages.noResualtFound')}</ListItemText>
|
||||
<ListItemText>
|
||||
{t('messages.noResualtFound', { ns: 'common' })}
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
</MenuItem>
|
||||
) : (
|
||||
filteredCountries.map((country) => (
|
||||
<MenuItem
|
||||
key={country.code}
|
||||
selected={country.phone === value}
|
||||
onClick={() => handleSelect(country)}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<ReactCountryFlag
|
||||
countryCode={country.code}
|
||||
svg
|
||||
style={{
|
||||
height: '1.125rem',
|
||||
width: '1.125rem',
|
||||
}}
|
||||
<Virtuoso
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
data={filteredCountries}
|
||||
initialTopMostItemIndex={initialIndex}
|
||||
itemContent={(_, country) => (
|
||||
<MenuItem
|
||||
key={country.code}
|
||||
selected={country.phone === value}
|
||||
onClick={() => handleSelect(country)}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<ReactCountryFlag
|
||||
countryCode={country.code}
|
||||
svg
|
||||
style={{ height: '1.125rem', width: '1.125rem' }}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={t(country.label, { ns: 'country' })}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={t(country.label)} />
|
||||
<Typography color="text.secondary">
|
||||
{country.phone}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
))
|
||||
<Typography color="text.secondary">
|
||||
<LTRBox>{country.phone}</LTRBox>
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
)}
|
||||
computeItemKey={(_, c) => c.code}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* virtual scrolling */}
|
||||
{/* <Virtuoso
|
||||
style={{ height: '14.75rem' }} // Adjust height to account for the search bar
|
||||
data={filteredCountries}
|
||||
components={{
|
||||
EmptyPlaceholder: () => (
|
||||
<MenuItem disabled>
|
||||
<ListItemText>{t('messages.noResultFound')}</ListItemText>
|
||||
</MenuItem>
|
||||
),
|
||||
}}
|
||||
initialTopMostItemIndex={countries.indexOf(selectedCountry)}
|
||||
itemContent={(_, country) => (
|
||||
<MenuItem
|
||||
key={country.code}
|
||||
selected={country.phone === value}
|
||||
onClick={() => handleSelect(country)}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<ReactCountryFlag
|
||||
countryCode={country.code}
|
||||
svg
|
||||
style={{ fontSize: '1.25em', lineHeight: '1.25em' }}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={country.label} />
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{country.phone}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
)}
|
||||
/> */}
|
||||
</Menu>
|
||||
</Box>
|
||||
</InputAdornment>
|
||||
|
||||
Reference in New Issue
Block a user