@marianmeres/stuic 3.106.0 โ 3.108.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attachments/auto-height.d.ts +7 -0
- package/dist/attachments/auto-height.js +17 -1
- package/dist/components/Checkout/CheckoutAddressForm.svelte +6 -6
- package/dist/components/Checkout/CheckoutAddressForm.svelte.d.ts +3 -3
- package/dist/components/Input/FieldCountry.svelte +63 -14
- package/dist/components/Input/FieldCountry.svelte.d.ts +24 -3
- package/dist/components/Input/FieldPhoneNumber.svelte +10 -8
- package/dist/components/Input/_internal/PhonePrefixPicker.svelte +2 -2
- package/dist/components/Input/_internal/PhonePrefixPicker.svelte.d.ts +1 -1
- package/dist/components/Input/index.d.ts +0 -1
- package/dist/components/Input/index.js +0 -1
- package/package.json +7 -6
- package/dist/components/Input/_internal/countries.d.ts +0 -20
- package/dist/components/Input/_internal/countries.js +0 -252
|
@@ -26,6 +26,13 @@ import type { Attachment } from "svelte/attachments";
|
|
|
26
26
|
* then a `ResizeObserver` keeps it in sync. With no transition configured, or under
|
|
27
27
|
* `prefers-reduced-motion`, the height simply snaps and nothing is ever clipped.
|
|
28
28
|
*
|
|
29
|
+
* Resize-driven measures are coalesced to the next animation frame, so the height
|
|
30
|
+
* write never happens *inside* the `ResizeObserver` delivery cycle. Mutating layout
|
|
31
|
+
* synchronously in that callback is what triggers the browser's benign-but-noisy
|
|
32
|
+
* "ResizeObserver loop completed with undelivered notifications" warning; the
|
|
33
|
+
* one-frame deferral (~16ms, imperceptible against the transition) avoids it. The
|
|
34
|
+
* initial on-mount measure stays synchronous to keep the height lock before paint.
|
|
35
|
+
*
|
|
29
36
|
* @example
|
|
30
37
|
* ```svelte
|
|
31
38
|
* <div class="viewport" {@attach autoHeight}>
|
|
@@ -25,6 +25,13 @@
|
|
|
25
25
|
* then a `ResizeObserver` keeps it in sync. With no transition configured, or under
|
|
26
26
|
* `prefers-reduced-motion`, the height simply snaps and nothing is ever clipped.
|
|
27
27
|
*
|
|
28
|
+
* Resize-driven measures are coalesced to the next animation frame, so the height
|
|
29
|
+
* write never happens *inside* the `ResizeObserver` delivery cycle. Mutating layout
|
|
30
|
+
* synchronously in that callback is what triggers the browser's benign-but-noisy
|
|
31
|
+
* "ResizeObserver loop completed with undelivered notifications" warning; the
|
|
32
|
+
* one-frame deferral (~16ms, imperceptible against the transition) avoids it. The
|
|
33
|
+
* initial on-mount measure stays synchronous to keep the height lock before paint.
|
|
34
|
+
*
|
|
28
35
|
* @example
|
|
29
36
|
* ```svelte
|
|
30
37
|
* <div class="viewport" {@attach autoHeight}>
|
|
@@ -73,13 +80,22 @@ export const autoHeight = (node) => {
|
|
|
73
80
|
if (e.target === node && e.propertyName === "height")
|
|
74
81
|
node.style.overflow = "";
|
|
75
82
|
};
|
|
83
|
+
// Defer the resize-driven measure to the next frame so the layout write
|
|
84
|
+
// never lands inside the ResizeObserver delivery cycle (see top doc comment).
|
|
85
|
+
let rafId = 0;
|
|
86
|
+
const scheduleMeasure = () => {
|
|
87
|
+
cancelAnimationFrame(rafId);
|
|
88
|
+
rafId = requestAnimationFrame(measure);
|
|
89
|
+
};
|
|
90
|
+
// Initial measure stays synchronous: lock height from `auto` to px before paint.
|
|
76
91
|
measure();
|
|
77
|
-
const ro = new ResizeObserver(
|
|
92
|
+
const ro = new ResizeObserver(scheduleMeasure);
|
|
78
93
|
if (node.firstElementChild)
|
|
79
94
|
ro.observe(node.firstElementChild);
|
|
80
95
|
node.addEventListener("transitionend", reveal);
|
|
81
96
|
node.addEventListener("transitioncancel", reveal);
|
|
82
97
|
return () => {
|
|
98
|
+
cancelAnimationFrame(rafId);
|
|
83
99
|
ro.disconnect();
|
|
84
100
|
node.removeEventListener("transitionend", reveal);
|
|
85
101
|
node.removeEventListener("transitioncancel", reveal);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
+
import type { Country } from "@marianmeres/countries";
|
|
2
3
|
import type { Snippet } from "svelte";
|
|
3
4
|
import type { HTMLAttributes } from "svelte/elements";
|
|
4
5
|
import type { TranslateFn } from "../../types.js";
|
|
6
|
+
import type { Props as FieldCountryProps } from "../Input/FieldCountry.svelte";
|
|
7
|
+
import type { Props as FieldPhoneNumberProps } from "../Input/FieldPhoneNumber.svelte";
|
|
5
8
|
import type {
|
|
6
9
|
CheckoutAddressData,
|
|
7
10
|
CheckoutValidationError,
|
|
8
11
|
} from "./_internal/checkout-types.js";
|
|
9
|
-
import type { Props as FieldPhoneNumberProps } from "../Input/FieldPhoneNumber.svelte";
|
|
10
|
-
import type { Props as FieldCountryProps } from "../Input/FieldCountry.svelte";
|
|
11
|
-
import type { Country } from "../Input/_internal/countries.js";
|
|
12
12
|
|
|
13
13
|
export interface Props extends Omit<HTMLAttributes<HTMLFieldSetElement>, "children"> {
|
|
14
14
|
/**
|
|
@@ -106,12 +106,12 @@
|
|
|
106
106
|
scrollToFirstInvalidField,
|
|
107
107
|
validateAllFields,
|
|
108
108
|
} from "../../utils/validate-fields.js";
|
|
109
|
-
import
|
|
110
|
-
import { createEmptyAddress } from "./_internal/checkout-utils.js";
|
|
109
|
+
import FieldCountry from "../Input/FieldCountry.svelte";
|
|
111
110
|
import FieldInput from "../Input/FieldInput.svelte";
|
|
112
111
|
import FieldPhoneNumber from "../Input/FieldPhoneNumber.svelte";
|
|
113
|
-
import FieldCountry from "../Input/FieldCountry.svelte";
|
|
114
112
|
import { validatePhoneNumber } from "../Input/phone-validation.js";
|
|
113
|
+
import { t_default } from "./_internal/checkout-i18n-defaults.js";
|
|
114
|
+
import { createEmptyAddress } from "./_internal/checkout-utils.js";
|
|
115
115
|
|
|
116
116
|
const DEFAULT_REQUIRED = ["name", "street", "city", "postal_code", "country"];
|
|
117
117
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import type { Country } from "@marianmeres/countries";
|
|
1
2
|
import type { Snippet } from "svelte";
|
|
2
3
|
import type { HTMLAttributes } from "svelte/elements";
|
|
3
4
|
import type { TranslateFn } from "../../types.js";
|
|
4
|
-
import type { CheckoutAddressData, CheckoutValidationError } from "./_internal/checkout-types.js";
|
|
5
|
-
import type { Props as FieldPhoneNumberProps } from "../Input/FieldPhoneNumber.svelte";
|
|
6
5
|
import type { Props as FieldCountryProps } from "../Input/FieldCountry.svelte";
|
|
7
|
-
import type {
|
|
6
|
+
import type { Props as FieldPhoneNumberProps } from "../Input/FieldPhoneNumber.svelte";
|
|
7
|
+
import type { CheckoutAddressData, CheckoutValidationError } from "./_internal/checkout-types.js";
|
|
8
8
|
export interface Props extends Omit<HTMLAttributes<HTMLFieldSetElement>, "children"> {
|
|
9
9
|
/**
|
|
10
10
|
* Bindable address data. Default: createEmptyAddress().
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
+
import type { Country } from "@marianmeres/countries";
|
|
2
3
|
import type { Snippet } from "svelte";
|
|
3
4
|
import type { ValidateOptions } from "../../actions/validate.svelte.js";
|
|
4
5
|
import type { TranslateFn } from "../../types.js";
|
|
5
6
|
import type { THC } from "../Thc/Thc.svelte";
|
|
6
|
-
import type { Country } from "./_internal/countries.js";
|
|
7
7
|
import type { InputWrapClassProps } from "./types.js";
|
|
8
8
|
|
|
9
9
|
type SnippetWithId = Snippet<[{ id: string }]>;
|
|
@@ -26,11 +26,33 @@
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Override displayed country names. Keys are ISO alpha-2 codes,
|
|
29
|
-
* values are the localized name.
|
|
30
|
-
* name
|
|
29
|
+
* values are the localized name. Takes precedence over `locale`; missing
|
|
30
|
+
* keys fall back to the locale-resolved name (then the English name).
|
|
31
31
|
*/
|
|
32
32
|
countryNames?: Record<string, string>;
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Display country names in this locale (ISO 639-1 code, e.g. "sk").
|
|
36
|
+
* Resolved via @marianmeres/countries' built-in locales.
|
|
37
|
+
*
|
|
38
|
+
* Locales load lazily (code-split), so by default names render in
|
|
39
|
+
* English for one frame until the chunk arrives. To avoid that flash,
|
|
40
|
+
* make the locale synchronously available before this field renders โ
|
|
41
|
+
* either register it once at app startup:
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { registerLocale } from "@marianmeres/countries";
|
|
45
|
+
* import sk from "@marianmeres/countries/locales/sk";
|
|
46
|
+
* registerLocale("sk", sk);
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* โฆor skip the `locale` prop entirely and pass the statically-imported
|
|
50
|
+
* map straight to `countryNames={sk}` (it's keyed by ISO code).
|
|
51
|
+
*
|
|
52
|
+
* Default: "en". Overridden per-country by `countryNames`.
|
|
53
|
+
*/
|
|
54
|
+
locale?: string;
|
|
55
|
+
|
|
34
56
|
/** Show country flag emoji in dropdown items. Default: true. */
|
|
35
57
|
flags?: boolean;
|
|
36
58
|
|
|
@@ -68,21 +90,28 @@
|
|
|
68
90
|
</script>
|
|
69
91
|
|
|
70
92
|
<script lang="ts">
|
|
93
|
+
import {
|
|
94
|
+
COUNTRIES,
|
|
95
|
+
DEFAULT_LOCALE,
|
|
96
|
+
ISO_MAP,
|
|
97
|
+
getName,
|
|
98
|
+
hasLocale,
|
|
99
|
+
loadLocale,
|
|
100
|
+
} from "@marianmeres/countries";
|
|
71
101
|
import { tick } from "svelte";
|
|
72
102
|
import {
|
|
73
103
|
validate as validateAction,
|
|
74
104
|
type ValidationResult,
|
|
75
105
|
} from "../../actions/validate.svelte.js";
|
|
106
|
+
import { iconChevronDown } from "../../icons/index.js";
|
|
76
107
|
import { getId } from "../../utils/get-id.js";
|
|
77
108
|
import { twMerge } from "../../utils/tw-merge.js";
|
|
78
|
-
import { iconChevronDown } from "../../icons/index.js";
|
|
79
109
|
import DropdownMenu, {
|
|
80
110
|
type DropdownMenuActionItem,
|
|
81
111
|
type DropdownMenuItem,
|
|
82
112
|
type DropdownMenuSearchConfig,
|
|
83
113
|
} from "../DropdownMenu/DropdownMenu.svelte";
|
|
84
114
|
import InputWrap from "./_internal/InputWrap.svelte";
|
|
85
|
-
import { COUNTRIES, ISO_MAP } from "./_internal/countries.js";
|
|
86
115
|
|
|
87
116
|
let {
|
|
88
117
|
value = $bindable(""),
|
|
@@ -90,6 +119,7 @@
|
|
|
90
119
|
countryList: countryListProp,
|
|
91
120
|
preferredCountries,
|
|
92
121
|
countryNames,
|
|
122
|
+
locale = DEFAULT_LOCALE,
|
|
93
123
|
flags = true,
|
|
94
124
|
//
|
|
95
125
|
name,
|
|
@@ -171,8 +201,32 @@
|
|
|
171
201
|
});
|
|
172
202
|
}
|
|
173
203
|
|
|
204
|
+
// Reactive marker: bumps once the requested locale is registered, so the
|
|
205
|
+
// derived names below recompute. The locale registry in @marianmeres/countries
|
|
206
|
+
// is plain module state, not a Svelte reactive source, hence this $state tick.
|
|
207
|
+
let localeLoaded = $state(DEFAULT_LOCALE);
|
|
208
|
+
$effect(() => {
|
|
209
|
+
const code = locale;
|
|
210
|
+
if (hasLocale(code)) {
|
|
211
|
+
localeLoaded = code;
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
let cancelled = false;
|
|
215
|
+
loadLocale(code)
|
|
216
|
+
.then(() => {
|
|
217
|
+
if (!cancelled) localeLoaded = code;
|
|
218
|
+
})
|
|
219
|
+
.catch(() => {
|
|
220
|
+
if (!cancelled) localeLoaded = DEFAULT_LOCALE;
|
|
221
|
+
});
|
|
222
|
+
return () => {
|
|
223
|
+
cancelled = true;
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
|
|
174
227
|
function localizedName(c: Country): string {
|
|
175
|
-
|
|
228
|
+
void localeLoaded; // establish reactive dependency on locale load
|
|
229
|
+
return countryNames?.[c.iso] ?? getName(c.iso, locale) ?? c.name;
|
|
176
230
|
}
|
|
177
231
|
|
|
178
232
|
// Resolve the working country list (accept ISO codes or Country objects).
|
|
@@ -180,9 +234,7 @@
|
|
|
180
234
|
if (!countryListProp) return COUNTRIES;
|
|
181
235
|
if (countryListProp.length === 0) return [];
|
|
182
236
|
if (typeof countryListProp[0] === "string") {
|
|
183
|
-
const set = new Set(
|
|
184
|
-
(countryListProp as string[]).map((c) => c.toUpperCase())
|
|
185
|
-
);
|
|
237
|
+
const set = new Set((countryListProp as string[]).map((c) => c.toUpperCase()));
|
|
186
238
|
return COUNTRIES.filter((c) => set.has(c.iso));
|
|
187
239
|
}
|
|
188
240
|
return countryListProp as Country[];
|
|
@@ -223,9 +275,7 @@
|
|
|
223
275
|
|
|
224
276
|
let items: DropdownMenuItem[] = $derived.by(() => {
|
|
225
277
|
const result: DropdownMenuItem[] = [];
|
|
226
|
-
const preferredSet = new Set(
|
|
227
|
-
preferredCountries?.map((c) => c.toUpperCase()) ?? []
|
|
228
|
-
);
|
|
278
|
+
const preferredSet = new Set(preferredCountries?.map((c) => c.toUpperCase()) ?? []);
|
|
229
279
|
|
|
230
280
|
if (preferredSet.size > 0) {
|
|
231
281
|
// Preserve the order given in `preferredCountries`.
|
|
@@ -260,8 +310,7 @@
|
|
|
260
310
|
return `${localized} ${c.name} ${c.iso}`;
|
|
261
311
|
},
|
|
262
312
|
autoFocus: true,
|
|
263
|
-
noResultsMessage:
|
|
264
|
-
t?.("checkout.address.country_no_results") || "No country found",
|
|
313
|
+
noResultsMessage: t?.("checkout.address.country_no_results") || "No country found",
|
|
265
314
|
});
|
|
266
315
|
|
|
267
316
|
let triggerText = $derived.by(() => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { Country } from "@marianmeres/countries";
|
|
1
2
|
import type { Snippet } from "svelte";
|
|
2
3
|
import type { ValidateOptions } from "../../actions/validate.svelte.js";
|
|
3
4
|
import type { TranslateFn } from "../../types.js";
|
|
4
5
|
import type { THC } from "../Thc/Thc.svelte";
|
|
5
|
-
import type { Country } from "./_internal/countries.js";
|
|
6
6
|
import type { InputWrapClassProps } from "./types.js";
|
|
7
7
|
type SnippetWithId = Snippet<[{
|
|
8
8
|
id: string;
|
|
@@ -21,10 +21,31 @@ export interface Props extends InputWrapClassProps, Record<string, any> {
|
|
|
21
21
|
preferredCountries?: string[];
|
|
22
22
|
/**
|
|
23
23
|
* Override displayed country names. Keys are ISO alpha-2 codes,
|
|
24
|
-
* values are the localized name.
|
|
25
|
-
* name
|
|
24
|
+
* values are the localized name. Takes precedence over `locale`; missing
|
|
25
|
+
* keys fall back to the locale-resolved name (then the English name).
|
|
26
26
|
*/
|
|
27
27
|
countryNames?: Record<string, string>;
|
|
28
|
+
/**
|
|
29
|
+
* Display country names in this locale (ISO 639-1 code, e.g. "sk").
|
|
30
|
+
* Resolved via @marianmeres/countries' built-in locales.
|
|
31
|
+
*
|
|
32
|
+
* Locales load lazily (code-split), so by default names render in
|
|
33
|
+
* English for one frame until the chunk arrives. To avoid that flash,
|
|
34
|
+
* make the locale synchronously available before this field renders โ
|
|
35
|
+
* either register it once at app startup:
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { registerLocale } from "@marianmeres/countries";
|
|
39
|
+
* import sk from "@marianmeres/countries/locales/sk";
|
|
40
|
+
* registerLocale("sk", sk);
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* โฆor skip the `locale` prop entirely and pass the statically-imported
|
|
44
|
+
* map straight to `countryNames={sk}` (it's keyed by ISO code).
|
|
45
|
+
*
|
|
46
|
+
* Default: "en". Overridden per-country by `countryNames`.
|
|
47
|
+
*/
|
|
48
|
+
locale?: string;
|
|
28
49
|
/** Show country flag emoji in dropdown items. Default: true. */
|
|
29
50
|
flags?: boolean;
|
|
30
51
|
/** Hidden input name (enables form submission + validation). */
|
|
@@ -59,6 +59,13 @@
|
|
|
59
59
|
</script>
|
|
60
60
|
|
|
61
61
|
<script lang="ts">
|
|
62
|
+
import {
|
|
63
|
+
COUNTRIES,
|
|
64
|
+
DIAL_CODES_DESC,
|
|
65
|
+
DIAL_CODE_MAP,
|
|
66
|
+
ISO_MAP,
|
|
67
|
+
type Country,
|
|
68
|
+
} from "@marianmeres/countries";
|
|
62
69
|
import { tick, untrack } from "svelte";
|
|
63
70
|
import {
|
|
64
71
|
validate as validateAction,
|
|
@@ -68,13 +75,6 @@
|
|
|
68
75
|
import { twMerge } from "../../utils/tw-merge.js";
|
|
69
76
|
import InputWrap from "./_internal/InputWrap.svelte";
|
|
70
77
|
import PhonePrefixPicker from "./_internal/PhonePrefixPicker.svelte";
|
|
71
|
-
import {
|
|
72
|
-
COUNTRIES,
|
|
73
|
-
ISO_MAP,
|
|
74
|
-
DIAL_CODES_DESC,
|
|
75
|
-
DIAL_CODE_MAP,
|
|
76
|
-
type Country,
|
|
77
|
-
} from "./_internal/countries.js";
|
|
78
78
|
import { validatePhoneNumber } from "./phone-validation.js";
|
|
79
79
|
|
|
80
80
|
let {
|
|
@@ -173,7 +173,9 @@
|
|
|
173
173
|
|
|
174
174
|
// Selected country object (initialize once from defaultCountry prop)
|
|
175
175
|
let selectedCountry: Country | undefined = $state(
|
|
176
|
-
untrack(() =>
|
|
176
|
+
untrack(() =>
|
|
177
|
+
defaultCountry ? ISO_MAP.get(defaultCountry.toUpperCase()) : undefined
|
|
178
|
+
)
|
|
177
179
|
);
|
|
178
180
|
|
|
179
181
|
// Internal local number (for controlled input)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { type Country, ISO_MAP } from "@marianmeres/countries";
|
|
3
3
|
import { iconChevronDown } from "../../../icons/index.js";
|
|
4
|
+
import { twMerge } from "../../../utils/tw-merge.js";
|
|
4
5
|
import DropdownMenu, {
|
|
5
6
|
type DropdownMenuActionItem,
|
|
6
7
|
type DropdownMenuItem,
|
|
7
8
|
type DropdownMenuSearchConfig,
|
|
8
9
|
} from "../../DropdownMenu/DropdownMenu.svelte";
|
|
9
|
-
import { type Country, ISO_MAP } from "./countries.js";
|
|
10
10
|
|
|
11
11
|
interface Props {
|
|
12
12
|
selectedCountry?: Country;
|
|
@@ -16,4 +16,3 @@ export { default as FieldObject, type Props as FieldObjectProps, } from "./Field
|
|
|
16
16
|
export { default as FieldPhoneNumber, type Props as FieldPhoneNumberProps, } from "./FieldPhoneNumber.svelte";
|
|
17
17
|
export { default as FieldCountry, type Props as FieldCountryProps, } from "./FieldCountry.svelte";
|
|
18
18
|
export { validatePhoneNumber } from "./phone-validation.js";
|
|
19
|
-
export { type Country, COUNTRIES, ISO_MAP } from "./_internal/countries.js";
|
|
@@ -16,4 +16,3 @@ export { default as FieldObject, } from "./FieldObject.svelte";
|
|
|
16
16
|
export { default as FieldPhoneNumber, } from "./FieldPhoneNumber.svelte";
|
|
17
17
|
export { default as FieldCountry, } from "./FieldCountry.svelte";
|
|
18
18
|
export { validatePhoneNumber } from "./phone-validation.js";
|
|
19
|
-
export { COUNTRIES, ISO_MAP } from "./_internal/countries.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marianmeres/stuic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.108.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev",
|
|
6
6
|
"build": "vite build && pnpm run prepack",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@eslint/js": "^9.39.4",
|
|
56
|
-
"@marianmeres/random-human-readable": "^1.
|
|
56
|
+
"@marianmeres/random-human-readable": "^1.10.2",
|
|
57
57
|
"@sveltejs/adapter-auto": "^4.0.0",
|
|
58
58
|
"@sveltejs/kit": "^2.61.1",
|
|
59
59
|
"@sveltejs/package": "^2.5.7",
|
|
@@ -70,16 +70,17 @@
|
|
|
70
70
|
"prettier-plugin-svelte": "^3.5.2",
|
|
71
71
|
"publint": "^0.3.21",
|
|
72
72
|
"svelte": "^5.56.0",
|
|
73
|
-
"svelte-check": "^4.
|
|
73
|
+
"svelte-check": "^4.5.0",
|
|
74
74
|
"tailwindcss": "^4.3.0",
|
|
75
|
-
"tsx": "^4.22.
|
|
75
|
+
"tsx": "^4.22.4",
|
|
76
76
|
"typescript": "^5.9.3",
|
|
77
77
|
"typescript-eslint": "^8.60.0",
|
|
78
|
-
"vite": "^7.3.
|
|
79
|
-
"vitest": "^3.2.
|
|
78
|
+
"vite": "^7.3.5",
|
|
79
|
+
"vitest": "^3.2.6"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@marianmeres/clog": "^3.21.0",
|
|
83
|
+
"@marianmeres/countries": "^1.0.1",
|
|
83
84
|
"@marianmeres/cron": "^2.0.1",
|
|
84
85
|
"@marianmeres/design-tokens": "^1.8.0",
|
|
85
86
|
"@marianmeres/icons-fns": "^5.0.0",
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export interface Country {
|
|
2
|
-
/** ISO 3166-1 alpha-2 code, e.g. "SK" */
|
|
3
|
-
iso: string;
|
|
4
|
-
/** Country name in English, e.g. "Slovakia" */
|
|
5
|
-
name: string;
|
|
6
|
-
/** Dial code without leading +, e.g. "421" */
|
|
7
|
-
dialCode: string;
|
|
8
|
-
/** Country flag emoji, e.g. "๐ธ๐ฐ" */
|
|
9
|
-
flag: string;
|
|
10
|
-
}
|
|
11
|
-
export declare const COUNTRIES: Country[];
|
|
12
|
-
/** Lookup map: ISO code -> Country */
|
|
13
|
-
export declare const ISO_MAP: Map<string, Country>;
|
|
14
|
-
/** Lookup map: dial code -> Country[]. Multiple countries can share a code (e.g. +1). */
|
|
15
|
-
export declare const DIAL_CODE_MAP: Map<string, Country[]>;
|
|
16
|
-
/**
|
|
17
|
-
* Sorted list of unique dial codes (longest first) for prefix detection during paste.
|
|
18
|
-
* Longest-first ensures we match "+1684" (American Samoa) before "+1" (US).
|
|
19
|
-
*/
|
|
20
|
-
export declare const DIAL_CODES_DESC: string[];
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
// prettier-ignore
|
|
2
|
-
export const COUNTRIES = [
|
|
3
|
-
{ iso: "AF", name: "Afghanistan", dialCode: "93", flag: "๐ฆ๐ซ" },
|
|
4
|
-
{ iso: "AL", name: "Albania", dialCode: "355", flag: "๐ฆ๐ฑ" },
|
|
5
|
-
{ iso: "DZ", name: "Algeria", dialCode: "213", flag: "๐ฉ๐ฟ" },
|
|
6
|
-
{ iso: "AS", name: "American Samoa", dialCode: "1684", flag: "๐ฆ๐ธ" },
|
|
7
|
-
{ iso: "AD", name: "Andorra", dialCode: "376", flag: "๐ฆ๐ฉ" },
|
|
8
|
-
{ iso: "AO", name: "Angola", dialCode: "244", flag: "๐ฆ๐ด" },
|
|
9
|
-
{ iso: "AI", name: "Anguilla", dialCode: "1264", flag: "๐ฆ๐ฎ" },
|
|
10
|
-
{ iso: "AG", name: "Antigua and Barbuda", dialCode: "1268", flag: "๐ฆ๐ฌ" },
|
|
11
|
-
{ iso: "AR", name: "Argentina", dialCode: "54", flag: "๐ฆ๐ท" },
|
|
12
|
-
{ iso: "AM", name: "Armenia", dialCode: "374", flag: "๐ฆ๐ฒ" },
|
|
13
|
-
{ iso: "AW", name: "Aruba", dialCode: "297", flag: "๐ฆ๐ผ" },
|
|
14
|
-
{ iso: "AU", name: "Australia", dialCode: "61", flag: "๐ฆ๐บ" },
|
|
15
|
-
{ iso: "AT", name: "Austria", dialCode: "43", flag: "๐ฆ๐น" },
|
|
16
|
-
{ iso: "AZ", name: "Azerbaijan", dialCode: "994", flag: "๐ฆ๐ฟ" },
|
|
17
|
-
{ iso: "BS", name: "Bahamas", dialCode: "1242", flag: "๐ง๐ธ" },
|
|
18
|
-
{ iso: "BH", name: "Bahrain", dialCode: "973", flag: "๐ง๐ญ" },
|
|
19
|
-
{ iso: "BD", name: "Bangladesh", dialCode: "880", flag: "๐ง๐ฉ" },
|
|
20
|
-
{ iso: "BB", name: "Barbados", dialCode: "1246", flag: "๐ง๐ง" },
|
|
21
|
-
{ iso: "BY", name: "Belarus", dialCode: "375", flag: "๐ง๐พ" },
|
|
22
|
-
{ iso: "BE", name: "Belgium", dialCode: "32", flag: "๐ง๐ช" },
|
|
23
|
-
{ iso: "BZ", name: "Belize", dialCode: "501", flag: "๐ง๐ฟ" },
|
|
24
|
-
{ iso: "BJ", name: "Benin", dialCode: "229", flag: "๐ง๐ฏ" },
|
|
25
|
-
{ iso: "BM", name: "Bermuda", dialCode: "1441", flag: "๐ง๐ฒ" },
|
|
26
|
-
{ iso: "BT", name: "Bhutan", dialCode: "975", flag: "๐ง๐น" },
|
|
27
|
-
{ iso: "BO", name: "Bolivia", dialCode: "591", flag: "๐ง๐ด" },
|
|
28
|
-
{ iso: "BA", name: "Bosnia and Herzegovina", dialCode: "387", flag: "๐ง๐ฆ" },
|
|
29
|
-
{ iso: "BW", name: "Botswana", dialCode: "267", flag: "๐ง๐ผ" },
|
|
30
|
-
{ iso: "BR", name: "Brazil", dialCode: "55", flag: "๐ง๐ท" },
|
|
31
|
-
{ iso: "IO", name: "British Indian Ocean Territory", dialCode: "246", flag: "๐ฎ๐ด" },
|
|
32
|
-
{ iso: "VG", name: "British Virgin Islands", dialCode: "1284", flag: "๐ป๐ฌ" },
|
|
33
|
-
{ iso: "BN", name: "Brunei", dialCode: "673", flag: "๐ง๐ณ" },
|
|
34
|
-
{ iso: "BG", name: "Bulgaria", dialCode: "359", flag: "๐ง๐ฌ" },
|
|
35
|
-
{ iso: "BF", name: "Burkina Faso", dialCode: "226", flag: "๐ง๐ซ" },
|
|
36
|
-
{ iso: "BI", name: "Burundi", dialCode: "257", flag: "๐ง๐ฎ" },
|
|
37
|
-
{ iso: "KH", name: "Cambodia", dialCode: "855", flag: "๐ฐ๐ญ" },
|
|
38
|
-
{ iso: "CM", name: "Cameroon", dialCode: "237", flag: "๐จ๐ฒ" },
|
|
39
|
-
{ iso: "CA", name: "Canada", dialCode: "1", flag: "๐จ๐ฆ" },
|
|
40
|
-
{ iso: "CV", name: "Cape Verde", dialCode: "238", flag: "๐จ๐ป" },
|
|
41
|
-
{ iso: "KY", name: "Cayman Islands", dialCode: "1345", flag: "๐ฐ๐พ" },
|
|
42
|
-
{ iso: "CF", name: "Central African Republic", dialCode: "236", flag: "๐จ๐ซ" },
|
|
43
|
-
{ iso: "TD", name: "Chad", dialCode: "235", flag: "๐น๐ฉ" },
|
|
44
|
-
{ iso: "CL", name: "Chile", dialCode: "56", flag: "๐จ๐ฑ" },
|
|
45
|
-
{ iso: "CN", name: "China", dialCode: "86", flag: "๐จ๐ณ" },
|
|
46
|
-
{ iso: "CO", name: "Colombia", dialCode: "57", flag: "๐จ๐ด" },
|
|
47
|
-
{ iso: "KM", name: "Comoros", dialCode: "269", flag: "๐ฐ๐ฒ" },
|
|
48
|
-
{ iso: "CK", name: "Cook Islands", dialCode: "682", flag: "๐จ๐ฐ" },
|
|
49
|
-
{ iso: "CR", name: "Costa Rica", dialCode: "506", flag: "๐จ๐ท" },
|
|
50
|
-
{ iso: "HR", name: "Croatia", dialCode: "385", flag: "๐ญ๐ท" },
|
|
51
|
-
{ iso: "CU", name: "Cuba", dialCode: "53", flag: "๐จ๐บ" },
|
|
52
|
-
{ iso: "CW", name: "Curaรงao", dialCode: "599", flag: "๐จ๐ผ" },
|
|
53
|
-
{ iso: "CY", name: "Cyprus", dialCode: "357", flag: "๐จ๐พ" },
|
|
54
|
-
{ iso: "CZ", name: "Czech Republic", dialCode: "420", flag: "๐จ๐ฟ" },
|
|
55
|
-
{ iso: "CD", name: "Democratic Republic of the Congo", dialCode: "243", flag: "๐จ๐ฉ" },
|
|
56
|
-
{ iso: "DK", name: "Denmark", dialCode: "45", flag: "๐ฉ๐ฐ" },
|
|
57
|
-
{ iso: "DJ", name: "Djibouti", dialCode: "253", flag: "๐ฉ๐ฏ" },
|
|
58
|
-
{ iso: "DM", name: "Dominica", dialCode: "1767", flag: "๐ฉ๐ฒ" },
|
|
59
|
-
{ iso: "DO", name: "Dominican Republic", dialCode: "1809", flag: "๐ฉ๐ด" },
|
|
60
|
-
{ iso: "EC", name: "Ecuador", dialCode: "593", flag: "๐ช๐จ" },
|
|
61
|
-
{ iso: "EG", name: "Egypt", dialCode: "20", flag: "๐ช๐ฌ" },
|
|
62
|
-
{ iso: "SV", name: "El Salvador", dialCode: "503", flag: "๐ธ๐ป" },
|
|
63
|
-
{ iso: "GQ", name: "Equatorial Guinea", dialCode: "240", flag: "๐ฌ๐ถ" },
|
|
64
|
-
{ iso: "ER", name: "Eritrea", dialCode: "291", flag: "๐ช๐ท" },
|
|
65
|
-
{ iso: "EE", name: "Estonia", dialCode: "372", flag: "๐ช๐ช" },
|
|
66
|
-
{ iso: "SZ", name: "Eswatini", dialCode: "268", flag: "๐ธ๐ฟ" },
|
|
67
|
-
{ iso: "ET", name: "Ethiopia", dialCode: "251", flag: "๐ช๐น" },
|
|
68
|
-
{ iso: "FK", name: "Falkland Islands", dialCode: "500", flag: "๐ซ๐ฐ" },
|
|
69
|
-
{ iso: "FO", name: "Faroe Islands", dialCode: "298", flag: "๐ซ๐ด" },
|
|
70
|
-
{ iso: "FJ", name: "Fiji", dialCode: "679", flag: "๐ซ๐ฏ" },
|
|
71
|
-
{ iso: "FI", name: "Finland", dialCode: "358", flag: "๐ซ๐ฎ" },
|
|
72
|
-
{ iso: "FR", name: "France", dialCode: "33", flag: "๐ซ๐ท" },
|
|
73
|
-
{ iso: "GF", name: "French Guiana", dialCode: "594", flag: "๐ฌ๐ซ" },
|
|
74
|
-
{ iso: "PF", name: "French Polynesia", dialCode: "689", flag: "๐ต๐ซ" },
|
|
75
|
-
{ iso: "GA", name: "Gabon", dialCode: "241", flag: "๐ฌ๐ฆ" },
|
|
76
|
-
{ iso: "GM", name: "Gambia", dialCode: "220", flag: "๐ฌ๐ฒ" },
|
|
77
|
-
{ iso: "GE", name: "Georgia", dialCode: "995", flag: "๐ฌ๐ช" },
|
|
78
|
-
{ iso: "DE", name: "Germany", dialCode: "49", flag: "๐ฉ๐ช" },
|
|
79
|
-
{ iso: "GH", name: "Ghana", dialCode: "233", flag: "๐ฌ๐ญ" },
|
|
80
|
-
{ iso: "GI", name: "Gibraltar", dialCode: "350", flag: "๐ฌ๐ฎ" },
|
|
81
|
-
{ iso: "GR", name: "Greece", dialCode: "30", flag: "๐ฌ๐ท" },
|
|
82
|
-
{ iso: "GL", name: "Greenland", dialCode: "299", flag: "๐ฌ๐ฑ" },
|
|
83
|
-
{ iso: "GD", name: "Grenada", dialCode: "1473", flag: "๐ฌ๐ฉ" },
|
|
84
|
-
{ iso: "GP", name: "Guadeloupe", dialCode: "590", flag: "๐ฌ๐ต" },
|
|
85
|
-
{ iso: "GU", name: "Guam", dialCode: "1671", flag: "๐ฌ๐บ" },
|
|
86
|
-
{ iso: "GT", name: "Guatemala", dialCode: "502", flag: "๐ฌ๐น" },
|
|
87
|
-
{ iso: "GG", name: "Guernsey", dialCode: "44", flag: "๐ฌ๐ฌ" },
|
|
88
|
-
{ iso: "GN", name: "Guinea", dialCode: "224", flag: "๐ฌ๐ณ" },
|
|
89
|
-
{ iso: "GW", name: "Guinea-Bissau", dialCode: "245", flag: "๐ฌ๐ผ" },
|
|
90
|
-
{ iso: "GY", name: "Guyana", dialCode: "592", flag: "๐ฌ๐พ" },
|
|
91
|
-
{ iso: "HT", name: "Haiti", dialCode: "509", flag: "๐ญ๐น" },
|
|
92
|
-
{ iso: "HN", name: "Honduras", dialCode: "504", flag: "๐ญ๐ณ" },
|
|
93
|
-
{ iso: "HK", name: "Hong Kong", dialCode: "852", flag: "๐ญ๐ฐ" },
|
|
94
|
-
{ iso: "HU", name: "Hungary", dialCode: "36", flag: "๐ญ๐บ" },
|
|
95
|
-
{ iso: "IS", name: "Iceland", dialCode: "354", flag: "๐ฎ๐ธ" },
|
|
96
|
-
{ iso: "IN", name: "India", dialCode: "91", flag: "๐ฎ๐ณ" },
|
|
97
|
-
{ iso: "ID", name: "Indonesia", dialCode: "62", flag: "๐ฎ๐ฉ" },
|
|
98
|
-
{ iso: "IR", name: "Iran", dialCode: "98", flag: "๐ฎ๐ท" },
|
|
99
|
-
{ iso: "IQ", name: "Iraq", dialCode: "964", flag: "๐ฎ๐ถ" },
|
|
100
|
-
{ iso: "IE", name: "Ireland", dialCode: "353", flag: "๐ฎ๐ช" },
|
|
101
|
-
{ iso: "IM", name: "Isle of Man", dialCode: "44", flag: "๐ฎ๐ฒ" },
|
|
102
|
-
{ iso: "IL", name: "Israel", dialCode: "972", flag: "๐ฎ๐ฑ" },
|
|
103
|
-
{ iso: "IT", name: "Italy", dialCode: "39", flag: "๐ฎ๐น" },
|
|
104
|
-
{ iso: "CI", name: "Ivory Coast", dialCode: "225", flag: "๐จ๐ฎ" },
|
|
105
|
-
{ iso: "JM", name: "Jamaica", dialCode: "1876", flag: "๐ฏ๐ฒ" },
|
|
106
|
-
{ iso: "JP", name: "Japan", dialCode: "81", flag: "๐ฏ๐ต" },
|
|
107
|
-
{ iso: "JE", name: "Jersey", dialCode: "44", flag: "๐ฏ๐ช" },
|
|
108
|
-
{ iso: "JO", name: "Jordan", dialCode: "962", flag: "๐ฏ๐ด" },
|
|
109
|
-
{ iso: "KZ", name: "Kazakhstan", dialCode: "7", flag: "๐ฐ๐ฟ" },
|
|
110
|
-
{ iso: "KE", name: "Kenya", dialCode: "254", flag: "๐ฐ๐ช" },
|
|
111
|
-
{ iso: "KI", name: "Kiribati", dialCode: "686", flag: "๐ฐ๐ฎ" },
|
|
112
|
-
{ iso: "XK", name: "Kosovo", dialCode: "383", flag: "๐ฝ๐ฐ" },
|
|
113
|
-
{ iso: "KW", name: "Kuwait", dialCode: "965", flag: "๐ฐ๐ผ" },
|
|
114
|
-
{ iso: "KG", name: "Kyrgyzstan", dialCode: "996", flag: "๐ฐ๐ฌ" },
|
|
115
|
-
{ iso: "LA", name: "Laos", dialCode: "856", flag: "๐ฑ๐ฆ" },
|
|
116
|
-
{ iso: "LV", name: "Latvia", dialCode: "371", flag: "๐ฑ๐ป" },
|
|
117
|
-
{ iso: "LB", name: "Lebanon", dialCode: "961", flag: "๐ฑ๐ง" },
|
|
118
|
-
{ iso: "LS", name: "Lesotho", dialCode: "266", flag: "๐ฑ๐ธ" },
|
|
119
|
-
{ iso: "LR", name: "Liberia", dialCode: "231", flag: "๐ฑ๐ท" },
|
|
120
|
-
{ iso: "LY", name: "Libya", dialCode: "218", flag: "๐ฑ๐พ" },
|
|
121
|
-
{ iso: "LI", name: "Liechtenstein", dialCode: "423", flag: "๐ฑ๐ฎ" },
|
|
122
|
-
{ iso: "LT", name: "Lithuania", dialCode: "370", flag: "๐ฑ๐น" },
|
|
123
|
-
{ iso: "LU", name: "Luxembourg", dialCode: "352", flag: "๐ฑ๐บ" },
|
|
124
|
-
{ iso: "MO", name: "Macau", dialCode: "853", flag: "๐ฒ๐ด" },
|
|
125
|
-
{ iso: "MG", name: "Madagascar", dialCode: "261", flag: "๐ฒ๐ฌ" },
|
|
126
|
-
{ iso: "MW", name: "Malawi", dialCode: "265", flag: "๐ฒ๐ผ" },
|
|
127
|
-
{ iso: "MY", name: "Malaysia", dialCode: "60", flag: "๐ฒ๐พ" },
|
|
128
|
-
{ iso: "MV", name: "Maldives", dialCode: "960", flag: "๐ฒ๐ป" },
|
|
129
|
-
{ iso: "ML", name: "Mali", dialCode: "223", flag: "๐ฒ๐ฑ" },
|
|
130
|
-
{ iso: "MT", name: "Malta", dialCode: "356", flag: "๐ฒ๐น" },
|
|
131
|
-
{ iso: "MH", name: "Marshall Islands", dialCode: "692", flag: "๐ฒ๐ญ" },
|
|
132
|
-
{ iso: "MQ", name: "Martinique", dialCode: "596", flag: "๐ฒ๐ถ" },
|
|
133
|
-
{ iso: "MR", name: "Mauritania", dialCode: "222", flag: "๐ฒ๐ท" },
|
|
134
|
-
{ iso: "MU", name: "Mauritius", dialCode: "230", flag: "๐ฒ๐บ" },
|
|
135
|
-
{ iso: "YT", name: "Mayotte", dialCode: "262", flag: "๐พ๐น" },
|
|
136
|
-
{ iso: "MX", name: "Mexico", dialCode: "52", flag: "๐ฒ๐ฝ" },
|
|
137
|
-
{ iso: "FM", name: "Micronesia", dialCode: "691", flag: "๐ซ๐ฒ" },
|
|
138
|
-
{ iso: "MD", name: "Moldova", dialCode: "373", flag: "๐ฒ๐ฉ" },
|
|
139
|
-
{ iso: "MC", name: "Monaco", dialCode: "377", flag: "๐ฒ๐จ" },
|
|
140
|
-
{ iso: "MN", name: "Mongolia", dialCode: "976", flag: "๐ฒ๐ณ" },
|
|
141
|
-
{ iso: "ME", name: "Montenegro", dialCode: "382", flag: "๐ฒ๐ช" },
|
|
142
|
-
{ iso: "MS", name: "Montserrat", dialCode: "1664", flag: "๐ฒ๐ธ" },
|
|
143
|
-
{ iso: "MA", name: "Morocco", dialCode: "212", flag: "๐ฒ๐ฆ" },
|
|
144
|
-
{ iso: "MZ", name: "Mozambique", dialCode: "258", flag: "๐ฒ๐ฟ" },
|
|
145
|
-
{ iso: "MM", name: "Myanmar", dialCode: "95", flag: "๐ฒ๐ฒ" },
|
|
146
|
-
{ iso: "NA", name: "Namibia", dialCode: "264", flag: "๐ณ๐ฆ" },
|
|
147
|
-
{ iso: "NR", name: "Nauru", dialCode: "674", flag: "๐ณ๐ท" },
|
|
148
|
-
{ iso: "NP", name: "Nepal", dialCode: "977", flag: "๐ณ๐ต" },
|
|
149
|
-
{ iso: "NL", name: "Netherlands", dialCode: "31", flag: "๐ณ๐ฑ" },
|
|
150
|
-
{ iso: "NC", name: "New Caledonia", dialCode: "687", flag: "๐ณ๐จ" },
|
|
151
|
-
{ iso: "NZ", name: "New Zealand", dialCode: "64", flag: "๐ณ๐ฟ" },
|
|
152
|
-
{ iso: "NI", name: "Nicaragua", dialCode: "505", flag: "๐ณ๐ฎ" },
|
|
153
|
-
{ iso: "NE", name: "Niger", dialCode: "227", flag: "๐ณ๐ช" },
|
|
154
|
-
{ iso: "NG", name: "Nigeria", dialCode: "234", flag: "๐ณ๐ฌ" },
|
|
155
|
-
{ iso: "NU", name: "Niue", dialCode: "683", flag: "๐ณ๐บ" },
|
|
156
|
-
{ iso: "NF", name: "Norfolk Island", dialCode: "672", flag: "๐ณ๐ซ" },
|
|
157
|
-
{ iso: "KP", name: "North Korea", dialCode: "850", flag: "๐ฐ๐ต" },
|
|
158
|
-
{ iso: "MK", name: "North Macedonia", dialCode: "389", flag: "๐ฒ๐ฐ" },
|
|
159
|
-
{ iso: "MP", name: "Northern Mariana Islands", dialCode: "1670", flag: "๐ฒ๐ต" },
|
|
160
|
-
{ iso: "NO", name: "Norway", dialCode: "47", flag: "๐ณ๐ด" },
|
|
161
|
-
{ iso: "OM", name: "Oman", dialCode: "968", flag: "๐ด๐ฒ" },
|
|
162
|
-
{ iso: "PK", name: "Pakistan", dialCode: "92", flag: "๐ต๐ฐ" },
|
|
163
|
-
{ iso: "PW", name: "Palau", dialCode: "680", flag: "๐ต๐ผ" },
|
|
164
|
-
{ iso: "PS", name: "Palestine", dialCode: "970", flag: "๐ต๐ธ" },
|
|
165
|
-
{ iso: "PA", name: "Panama", dialCode: "507", flag: "๐ต๐ฆ" },
|
|
166
|
-
{ iso: "PG", name: "Papua New Guinea", dialCode: "675", flag: "๐ต๐ฌ" },
|
|
167
|
-
{ iso: "PY", name: "Paraguay", dialCode: "595", flag: "๐ต๐พ" },
|
|
168
|
-
{ iso: "PE", name: "Peru", dialCode: "51", flag: "๐ต๐ช" },
|
|
169
|
-
{ iso: "PH", name: "Philippines", dialCode: "63", flag: "๐ต๐ญ" },
|
|
170
|
-
{ iso: "PL", name: "Poland", dialCode: "48", flag: "๐ต๐ฑ" },
|
|
171
|
-
{ iso: "PT", name: "Portugal", dialCode: "351", flag: "๐ต๐น" },
|
|
172
|
-
{ iso: "PR", name: "Puerto Rico", dialCode: "1787", flag: "๐ต๐ท" },
|
|
173
|
-
{ iso: "QA", name: "Qatar", dialCode: "974", flag: "๐ถ๐ฆ" },
|
|
174
|
-
{ iso: "CG", name: "Republic of the Congo", dialCode: "242", flag: "๐จ๐ฌ" },
|
|
175
|
-
{ iso: "RE", name: "Rรฉunion", dialCode: "262", flag: "๐ท๐ช" },
|
|
176
|
-
{ iso: "RO", name: "Romania", dialCode: "40", flag: "๐ท๐ด" },
|
|
177
|
-
{ iso: "RU", name: "Russia", dialCode: "7", flag: "๐ท๐บ" },
|
|
178
|
-
{ iso: "RW", name: "Rwanda", dialCode: "250", flag: "๐ท๐ผ" },
|
|
179
|
-
{ iso: "KN", name: "Saint Kitts and Nevis", dialCode: "1869", flag: "๐ฐ๐ณ" },
|
|
180
|
-
{ iso: "LC", name: "Saint Lucia", dialCode: "1758", flag: "๐ฑ๐จ" },
|
|
181
|
-
{ iso: "PM", name: "Saint Pierre and Miquelon", dialCode: "508", flag: "๐ต๐ฒ" },
|
|
182
|
-
{ iso: "VC", name: "Saint Vincent and the Grenadines", dialCode: "1784", flag: "๐ป๐จ" },
|
|
183
|
-
{ iso: "WS", name: "Samoa", dialCode: "685", flag: "๐ผ๐ธ" },
|
|
184
|
-
{ iso: "SM", name: "San Marino", dialCode: "378", flag: "๐ธ๐ฒ" },
|
|
185
|
-
{ iso: "ST", name: "Sรฃo Tomรฉ and Prรญncipe", dialCode: "239", flag: "๐ธ๐น" },
|
|
186
|
-
{ iso: "SA", name: "Saudi Arabia", dialCode: "966", flag: "๐ธ๐ฆ" },
|
|
187
|
-
{ iso: "SN", name: "Senegal", dialCode: "221", flag: "๐ธ๐ณ" },
|
|
188
|
-
{ iso: "RS", name: "Serbia", dialCode: "381", flag: "๐ท๐ธ" },
|
|
189
|
-
{ iso: "SC", name: "Seychelles", dialCode: "248", flag: "๐ธ๐จ" },
|
|
190
|
-
{ iso: "SL", name: "Sierra Leone", dialCode: "232", flag: "๐ธ๐ฑ" },
|
|
191
|
-
{ iso: "SG", name: "Singapore", dialCode: "65", flag: "๐ธ๐ฌ" },
|
|
192
|
-
{ iso: "SX", name: "Sint Maarten", dialCode: "1721", flag: "๐ธ๐ฝ" },
|
|
193
|
-
{ iso: "SK", name: "Slovakia", dialCode: "421", flag: "๐ธ๐ฐ" },
|
|
194
|
-
{ iso: "SI", name: "Slovenia", dialCode: "386", flag: "๐ธ๐ฎ" },
|
|
195
|
-
{ iso: "SB", name: "Solomon Islands", dialCode: "677", flag: "๐ธ๐ง" },
|
|
196
|
-
{ iso: "SO", name: "Somalia", dialCode: "252", flag: "๐ธ๐ด" },
|
|
197
|
-
{ iso: "ZA", name: "South Africa", dialCode: "27", flag: "๐ฟ๐ฆ" },
|
|
198
|
-
{ iso: "KR", name: "South Korea", dialCode: "82", flag: "๐ฐ๐ท" },
|
|
199
|
-
{ iso: "SS", name: "South Sudan", dialCode: "211", flag: "๐ธ๐ธ" },
|
|
200
|
-
{ iso: "ES", name: "Spain", dialCode: "34", flag: "๐ช๐ธ" },
|
|
201
|
-
{ iso: "LK", name: "Sri Lanka", dialCode: "94", flag: "๐ฑ๐ฐ" },
|
|
202
|
-
{ iso: "SD", name: "Sudan", dialCode: "249", flag: "๐ธ๐ฉ" },
|
|
203
|
-
{ iso: "SR", name: "Suriname", dialCode: "597", flag: "๐ธ๐ท" },
|
|
204
|
-
{ iso: "SE", name: "Sweden", dialCode: "46", flag: "๐ธ๐ช" },
|
|
205
|
-
{ iso: "CH", name: "Switzerland", dialCode: "41", flag: "๐จ๐ญ" },
|
|
206
|
-
{ iso: "SY", name: "Syria", dialCode: "963", flag: "๐ธ๐พ" },
|
|
207
|
-
{ iso: "TW", name: "Taiwan", dialCode: "886", flag: "๐น๐ผ" },
|
|
208
|
-
{ iso: "TJ", name: "Tajikistan", dialCode: "992", flag: "๐น๐ฏ" },
|
|
209
|
-
{ iso: "TZ", name: "Tanzania", dialCode: "255", flag: "๐น๐ฟ" },
|
|
210
|
-
{ iso: "TH", name: "Thailand", dialCode: "66", flag: "๐น๐ญ" },
|
|
211
|
-
{ iso: "TL", name: "Timor-Leste", dialCode: "670", flag: "๐น๐ฑ" },
|
|
212
|
-
{ iso: "TG", name: "Togo", dialCode: "228", flag: "๐น๐ฌ" },
|
|
213
|
-
{ iso: "TK", name: "Tokelau", dialCode: "690", flag: "๐น๐ฐ" },
|
|
214
|
-
{ iso: "TO", name: "Tonga", dialCode: "676", flag: "๐น๐ด" },
|
|
215
|
-
{ iso: "TT", name: "Trinidad and Tobago", dialCode: "1868", flag: "๐น๐น" },
|
|
216
|
-
{ iso: "TN", name: "Tunisia", dialCode: "216", flag: "๐น๐ณ" },
|
|
217
|
-
{ iso: "TR", name: "Turkey", dialCode: "90", flag: "๐น๐ท" },
|
|
218
|
-
{ iso: "TM", name: "Turkmenistan", dialCode: "993", flag: "๐น๐ฒ" },
|
|
219
|
-
{ iso: "TC", name: "Turks and Caicos Islands", dialCode: "1649", flag: "๐น๐จ" },
|
|
220
|
-
{ iso: "TV", name: "Tuvalu", dialCode: "688", flag: "๐น๐ป" },
|
|
221
|
-
{ iso: "VI", name: "U.S. Virgin Islands", dialCode: "1340", flag: "๐ป๐ฎ" },
|
|
222
|
-
{ iso: "UG", name: "Uganda", dialCode: "256", flag: "๐บ๐ฌ" },
|
|
223
|
-
{ iso: "UA", name: "Ukraine", dialCode: "380", flag: "๐บ๐ฆ" },
|
|
224
|
-
{ iso: "AE", name: "United Arab Emirates", dialCode: "971", flag: "๐ฆ๐ช" },
|
|
225
|
-
{ iso: "GB", name: "United Kingdom", dialCode: "44", flag: "๐ฌ๐ง" },
|
|
226
|
-
{ iso: "US", name: "United States", dialCode: "1", flag: "๐บ๐ธ" },
|
|
227
|
-
{ iso: "UY", name: "Uruguay", dialCode: "598", flag: "๐บ๐พ" },
|
|
228
|
-
{ iso: "UZ", name: "Uzbekistan", dialCode: "998", flag: "๐บ๐ฟ" },
|
|
229
|
-
{ iso: "VU", name: "Vanuatu", dialCode: "678", flag: "๐ป๐บ" },
|
|
230
|
-
{ iso: "VA", name: "Vatican City", dialCode: "379", flag: "๐ป๐ฆ" },
|
|
231
|
-
{ iso: "VE", name: "Venezuela", dialCode: "58", flag: "๐ป๐ช" },
|
|
232
|
-
{ iso: "VN", name: "Vietnam", dialCode: "84", flag: "๐ป๐ณ" },
|
|
233
|
-
{ iso: "WF", name: "Wallis and Futuna", dialCode: "681", flag: "๐ผ๐ซ" },
|
|
234
|
-
{ iso: "YE", name: "Yemen", dialCode: "967", flag: "๐พ๐ช" },
|
|
235
|
-
{ iso: "ZM", name: "Zambia", dialCode: "260", flag: "๐ฟ๐ฒ" },
|
|
236
|
-
{ iso: "ZW", name: "Zimbabwe", dialCode: "263", flag: "๐ฟ๐ผ" },
|
|
237
|
-
];
|
|
238
|
-
/** Lookup map: ISO code -> Country */
|
|
239
|
-
export const ISO_MAP = new Map();
|
|
240
|
-
COUNTRIES.forEach((c) => ISO_MAP.set(c.iso, c));
|
|
241
|
-
/** Lookup map: dial code -> Country[]. Multiple countries can share a code (e.g. +1). */
|
|
242
|
-
export const DIAL_CODE_MAP = new Map();
|
|
243
|
-
COUNTRIES.forEach((c) => {
|
|
244
|
-
const arr = DIAL_CODE_MAP.get(c.dialCode) || [];
|
|
245
|
-
arr.push(c);
|
|
246
|
-
DIAL_CODE_MAP.set(c.dialCode, arr);
|
|
247
|
-
});
|
|
248
|
-
/**
|
|
249
|
-
* Sorted list of unique dial codes (longest first) for prefix detection during paste.
|
|
250
|
-
* Longest-first ensures we match "+1684" (American Samoa) before "+1" (US).
|
|
251
|
-
*/
|
|
252
|
-
export const DIAL_CODES_DESC = [...new Set(COUNTRIES.map((c) => c.dialCode))].sort((a, b) => b.length - a.length);
|