@desource/phone-mask-vue 1.0.0 → 1.1.1

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/index.cjs CHANGED
@@ -10,17 +10,17 @@ const t$1 = /^[a-z]{2}$/i, countryCodeEmoji = (o2) => {
10
10
  const e2 = [...o2.toUpperCase()].map((t2) => (t2.codePointAt(0) ?? 0) + 127397);
11
11
  return String.fromCodePoint(...e2);
12
12
  };
13
- const o$1 = "en", n = /* @__PURE__ */ new Map(), getDisplayNames = (e2) => {
14
- const t2 = e2.toLowerCase(), s2 = n.get(t2);
13
+ const o$1 = "en", n$1 = /* @__PURE__ */ new Map(), getDisplayNames = (e2) => {
14
+ const t2 = e2.toLowerCase(), s2 = n$1.get(t2);
15
15
  if (s2) return s2;
16
16
  const r = new Intl.DisplayNames([e2], { type: "region" });
17
- if (n.size >= 10) {
18
- for (const e3 of n.keys()) if (e3 !== o$1) {
19
- n.delete(e3);
17
+ if (n$1.size >= 10) {
18
+ for (const e3 of n$1.keys()) if (e3 !== o$1) {
19
+ n$1.delete(e3);
20
20
  break;
21
21
  }
22
22
  }
23
- return n.set(t2, r), r;
23
+ return n$1.set(t2, r), r;
24
24
  }, s$1 = Object.entries(M), divideMask = (e2) => e2.split(/ (.*)/s);
25
25
  function getCodeAndMask(e2) {
26
26
  let t2 = "", o2 = "";
@@ -70,32 +70,32 @@ const MasksFullMap = (e2) => {
70
70
  MasksFull(o$1);
71
71
  const k = countryCodeEmoji;
72
72
  function getNavigatorLang() {
73
- return "undefined" != typeof navigator && navigator.language || "en";
73
+ return globalThis.navigator?.language || "en";
74
74
  }
75
75
  function detectCountryFromLocale() {
76
76
  try {
77
77
  const t2 = getNavigatorLang();
78
78
  try {
79
- const e3 = new Intl.Locale(t2);
80
- if (e3.region) return e3.region.toUpperCase();
79
+ const r2 = new Intl.Locale(t2);
80
+ if (r2.region) return r2.region.toUpperCase();
81
81
  } catch {
82
82
  }
83
- const e2 = t2.split(/[-_]/);
84
- if (e2.length > 1) return e2[1]?.toUpperCase() || null;
83
+ const r = t2.split(/[-_]/);
84
+ if (r.length > 1) return r[1]?.toUpperCase() || null;
85
85
  } catch {
86
86
  }
87
87
  return null;
88
88
  }
89
89
  function hasCountry(t2) {
90
- const r = f;
91
- return t2.toUpperCase() in r;
90
+ const e2 = f;
91
+ return t2.toUpperCase() in e2;
92
92
  }
93
- function getCountry(e2, r) {
94
- const n2 = MasksFullMap(r), o2 = e2.toUpperCase();
93
+ function getCountry(r, e2) {
94
+ const n2 = MasksFullMap(e2), o2 = r.toUpperCase();
95
95
  return o2 in n2 ? { id: o2, ...n2[o2] } : { id: "US", ...n2.US };
96
96
  }
97
- function parseCountryCode(t2, e2) {
98
- return t2 && hasCountry(t2) ? t2.toUpperCase() : e2 || "";
97
+ function parseCountryCode(t2, r) {
98
+ return t2 && hasCountry(t2) ? t2.toUpperCase() : r || "";
99
99
  }
100
100
  function toArray(t2) {
101
101
  return Array.isArray(t2) ? t2 : [t2];
@@ -106,147 +106,137 @@ function countPlaceholders(t2) {
106
106
  function removeCountryCodePrefix(t2) {
107
107
  return t2.replace(/^\+\d+\s?/, "");
108
108
  }
109
- function pickMaskVariant(t2, e2) {
109
+ function pickMaskVariant(t2, r) {
110
+ if (!t2.length) return "";
110
111
  if (1 === t2.length) return t2[0];
111
- const r = t2.map((t3) => ({ mask: t3, count: countPlaceholders(t3) })), n2 = r.filter((t3) => t3.count >= e2).sort((t3, e3) => t3.count - e3.count);
112
+ const e2 = t2.map((t3) => ({ mask: t3, count: countPlaceholders(t3) })), n2 = e2.filter((t3) => t3.count >= r).sort((t3, r2) => t3.count - r2.count);
112
113
  if (n2.length > 0) return n2[0].mask;
113
- const o2 = r.sort((t3, e3) => e3.count - t3.count)[0];
114
+ const o2 = e2.sort((t3, r2) => r2.count - t3.count)[0];
114
115
  return o2 ? o2.mask : t2[0];
115
116
  }
116
- function formatDigitsWithMap(t2, e2) {
117
- let r = "";
117
+ function formatDigitsWithMap(t2, r) {
118
+ let e2 = "";
118
119
  const n2 = [];
119
120
  let o2 = 0;
120
- const a = e2.length, s2 = t2.length;
121
+ const a = r.length, s2 = t2.length;
121
122
  for (let c = 0; c < s2; c++) {
122
123
  const s3 = t2[c];
123
124
  if ("#" === s3) {
124
125
  if (!(o2 < a)) break;
125
- r += e2[o2], n2.push(o2), o2++;
126
+ e2 += r[o2], n2.push(o2), o2++;
126
127
  } else {
127
- const e3 = -1 !== t2.indexOf("#", c + 1) && o2 < a;
128
- (r.length > 0 || e3) && (r += s3, n2.push(-1));
128
+ const r2 = -1 !== t2.indexOf("#", c + 1) && o2 < a;
129
+ (e2.length > 0 || r2) && (e2 += s3, n2.push(-1));
129
130
  }
130
131
  }
131
- return { display: r, map: n2 };
132
+ return { display: e2, map: n2 };
132
133
  }
133
- function filterCountries(t2, e2) {
134
- const r = e2.trim().toUpperCase();
135
- if (!r) return t2;
136
- const n2 = r.replace(/\D/g, ""), o2 = n2.length > 0;
134
+ function filterCountries(t2, r) {
135
+ const e2 = r.trim().toUpperCase();
136
+ if (!e2) return t2;
137
+ const n2 = e2.replace(/\D/g, ""), o2 = n2.length > 0;
137
138
  return t2.map((t3) => {
138
- const e3 = t3.name.toUpperCase(), a = t3.id.toUpperCase(), s2 = t3.code.toUpperCase(), c = t3.code.replace(/\D/g, "");
139
- let i2 = 0;
140
- return e3.startsWith(r) ? i2 = 1e3 : e3.includes(r) && (i2 = 500), s2.startsWith(r) ? i2 += 100 : s2.includes(r) && (i2 += 50), a === r ? i2 += 200 : a.startsWith(r) && (i2 += 150), o2 && c.startsWith(n2) ? i2 += 80 : o2 && c.includes(n2) && (i2 += 40), { country: t3, score: i2 };
141
- }).filter((t3) => t3.score > 0).sort((t3, e3) => e3.score !== t3.score ? e3.score - t3.score : t3.country.name.localeCompare(e3.country.name)).map((t3) => t3.country);
139
+ const r2 = t3.name.toUpperCase(), a = t3.id.toUpperCase(), s2 = t3.code.toUpperCase(), c = t3.code.replace(/\D/g, "");
140
+ let i = 0;
141
+ return r2.startsWith(e2) ? i = 1e3 : r2.includes(e2) && (i = 500), s2.startsWith(e2) ? i += 100 : s2.includes(e2) && (i += 50), a === e2 ? i += 200 : a.startsWith(e2) && (i += 150), o2 && c.startsWith(n2) ? i += 80 : o2 && c.includes(n2) && (i += 40), { country: t3, score: i };
142
+ }).filter((t3) => t3.score > 0).sort((t3, r2) => r2.score === t3.score ? t3.country.name.localeCompare(r2.country.name) : r2.score - t3.score).map((t3) => t3.country);
142
143
  }
143
- const t = [" ", "-", "(", ")"], e$1 = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End", "Tab"], i = /[^\d\s\-()]/;
144
- function extractDigits(t2, e2) {
145
- const i2 = t2.replace(/\D/g, "");
146
- return e2 ? i2.slice(0, e2) : i2;
144
+ const e$1 = [" ", "-", "(", ")"], t = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End", "Tab"], n = /[^\d\s\-()]/;
145
+ function removeDigitsRange(e2, t2, n2) {
146
+ return { newDigits: e2.slice(0, t2) + e2.slice(n2), caretDigitIndex: t2 };
147
147
  }
148
- function getSelection(t2) {
149
- return t2 ? [t2.selectionStart ?? 0, t2.selectionEnd ?? 0] : [0, 0];
148
+ function removeSelectedDigits(e2, t2, n2, i) {
149
+ if (n2 === i) return;
150
+ const r = t2.getDigitRange(e2, n2, i);
151
+ if (!r) return;
152
+ const [s2, g] = r;
153
+ return removeDigitsRange(e2, s2, g);
150
154
  }
151
- function setCaret(t2, e2) {
152
- if (t2) try {
153
- t2.setSelectionRange(e2, e2);
155
+ function extractDigits(e2, t2) {
156
+ const n2 = e2.replace(/\D/g, "");
157
+ return t2 ? n2.slice(0, t2) : n2;
158
+ }
159
+ function getSelection(e2) {
160
+ return e2 ? [e2.selectionStart ?? 0, e2.selectionEnd ?? 0] : [0, 0];
161
+ }
162
+ function setCaret(e2, t2) {
163
+ if (e2) try {
164
+ e2.setSelectionRange(t2, t2);
154
165
  } catch {
155
166
  }
156
167
  }
157
- function processBeforeInput(t2) {
158
- if (!t2.target) return;
159
- const e2 = t2.target, n2 = t2.data;
160
- "insertText" === t2.inputType && n2 && (i.test(n2) || " " === n2 && e2.value.endsWith(" ")) && t2.preventDefault();
168
+ function processBeforeInput(e2) {
169
+ if (!e2.target) return;
170
+ const t2 = e2.target, i = e2.data;
171
+ "insertText" === e2.inputType && i && (n.test(i) || " " === i && t2.value.endsWith(" ")) && e2.preventDefault();
161
172
  }
162
- function processInput(t2, e2) {
163
- if (!t2.target) return;
164
- const i2 = t2.target, { formatter: n2 } = e2, r = n2.getMaxDigits(), s2 = extractDigits(i2.value, r);
173
+ function processInput(e2, t2) {
174
+ if (!e2.target) return;
175
+ const n2 = e2.target, { formatter: i } = t2, r = i.getMaxDigits(), s2 = extractDigits(n2.value, r);
165
176
  return { newDigits: s2, caretDigitIndex: s2.length };
166
177
  }
167
- function processKeydown(i2, n2) {
168
- if (!i2.target) return;
169
- const r = i2.target, { digits: s2, formatter: c } = n2;
170
- if (i2.ctrlKey || i2.metaKey || i2.altKey || e$1.includes(i2.key)) return;
171
- const [g, a] = getSelection(r);
172
- if ("Backspace" !== i2.key) if ("Delete" !== i2.key) /^[0-9]$/.test(i2.key) ? s2.length >= c.getMaxDigits() && i2.preventDefault() : 1 === i2.key.length && i2.preventDefault();
173
- else {
174
- if (i2.preventDefault(), g !== a) {
175
- const t2 = c.getDigitRange(s2, g, a);
176
- if (t2) {
177
- const [e2, i3] = t2;
178
- return { newDigits: s2.slice(0, e2) + s2.slice(i3), caretDigitIndex: e2 };
179
- }
180
- }
181
- if (g < r.value.length) {
182
- const t2 = c.getDigitRange(s2, g, r.value.length);
183
- if (t2) {
184
- const [e2] = t2;
185
- return { newDigits: s2.slice(0, e2) + s2.slice(e2 + 1), caretDigitIndex: e2 };
186
- }
187
- }
188
- }
189
- else {
190
- if (i2.preventDefault(), g !== a) {
191
- const t2 = c.getDigitRange(s2, g, a);
192
- if (t2) {
193
- const [e2, i3] = t2;
194
- return { newDigits: s2.slice(0, e2) + s2.slice(i3), caretDigitIndex: e2 };
195
- }
196
- }
197
- if (g > 0) {
198
- const e2 = r.value;
199
- let i3 = g - 1;
200
- for (; i3 >= 0 && t.includes(e2[i3]); ) i3--;
201
- if (i3 >= 0) {
202
- const t2 = c.getDigitRange(s2, i3, i3 + 1);
203
- if (t2) {
204
- const [e3] = t2;
205
- return { newDigits: s2.slice(0, e3) + s2.slice(e3 + 1), caretDigitIndex: e3 };
206
- }
207
- }
208
- }
209
- }
178
+ function processKeydown(n2, i) {
179
+ if (!n2.target) return;
180
+ const r = n2.target, { digits: s2, formatter: g } = i;
181
+ if ((function shouldIgnoreKeydown(e2) {
182
+ return e2.ctrlKey || e2.metaKey || e2.altKey || t.includes(e2.key);
183
+ })(n2)) return;
184
+ const [o2, c] = getSelection(r), a = r.value;
185
+ return "Backspace" === n2.key ? (n2.preventDefault(), removeSelectedDigits(s2, g, o2, c) ?? (function removePreviousDigit(t2, n3, i2, r2) {
186
+ if (r2 <= 0) return;
187
+ let s3 = r2 - 1;
188
+ for (; s3 >= 0 && e$1.includes(i2[s3]); ) s3--;
189
+ if (s3 < 0) return;
190
+ const g2 = n3.getDigitRange(t2, s3, s3 + 1);
191
+ if (!g2) return;
192
+ const [o3] = g2;
193
+ return removeDigitsRange(t2, o3, o3 + 1);
194
+ })(s2, g, a, o2)) : "Delete" === n2.key ? (n2.preventDefault(), removeSelectedDigits(s2, g, o2, c) ?? (function removeNextDigit(e2, t2, n3, i2) {
195
+ if (i2 >= n3.length) return;
196
+ const r2 = t2.getDigitRange(e2, i2, n3.length);
197
+ if (!r2) return;
198
+ const [s3] = r2;
199
+ return removeDigitsRange(e2, s3, s3 + 1);
200
+ })(s2, g, a, o2)) : void (/^\d$/.test(n2.key) ? s2.length >= g.getMaxDigits() && n2.preventDefault() : 1 === n2.key.length && n2.preventDefault());
210
201
  }
211
- function processPaste(t2, e2) {
212
- if (!t2.target) return;
213
- t2.preventDefault();
214
- const i2 = t2.target, { digits: n2, formatter: r } = e2, s2 = t2.clipboardData?.getData("text") || "", c = r.getMaxDigits(), g = extractDigits(s2, c);
215
- if (0 === g.length) return;
216
- const [a, o2] = getSelection(i2);
217
- if (a !== o2) {
218
- const t3 = r.getDigitRange(n2, a, o2);
219
- if (t3) {
220
- const [e3, i3] = t3;
221
- return { newDigits: extractDigits(n2.slice(0, e3) + g + n2.slice(i3), c), caretDigitIndex: e3 + g.length };
202
+ function processPaste(e2, t2) {
203
+ if (!e2.target) return;
204
+ e2.preventDefault();
205
+ const n2 = e2.target, { digits: i, formatter: r } = t2, s2 = e2.clipboardData?.getData("text") || "", g = r.getMaxDigits(), o2 = extractDigits(s2, g);
206
+ if (0 === o2.length) return;
207
+ const [c, a] = getSelection(n2);
208
+ if (c !== a) {
209
+ const e3 = r.getDigitRange(i, c, a);
210
+ if (e3) {
211
+ const [t3, n3] = e3;
212
+ return { newDigits: extractDigits(i.slice(0, t3) + o2 + i.slice(n3), g), caretDigitIndex: t3 + o2.length };
222
213
  }
223
214
  }
224
- const l = r.getDigitRange(n2, 0, a), f2 = l ? l[1] : 0;
225
- return { newDigits: extractDigits(n2.slice(0, f2) + g + n2.slice(f2), c), caretDigitIndex: f2 + g.length };
215
+ const u = r.getDigitRange(i, 0, c), l = u ? u[1] : 0;
216
+ return { newDigits: extractDigits(i.slice(0, l) + o2 + i.slice(l), g), caretDigitIndex: l + o2.length };
226
217
  }
227
218
  function createPhoneFormatter(o2) {
228
- const a = toArray(o2.mask), i2 = a.map((n2) => countPlaceholders(removeCountryCodePrefix(n2))), g = Math.max(...i2), getMask = (t2) => {
229
- const n2 = pickMaskVariant(a, t2);
219
+ const i = toArray(o2.mask), l = i.map((n2) => countPlaceholders(removeCountryCodePrefix(n2))), s2 = Math.max(...l), getMask = (t2) => {
220
+ const n2 = pickMaskVariant(i, t2);
230
221
  return removeCountryCodePrefix(n2);
231
222
  };
232
223
  return { formatDisplay: (t2) => {
233
224
  const e2 = getMask(t2.length);
234
225
  return formatDigitsWithMap(e2, t2).display;
235
- }, getMaxDigits: () => g, getPlaceholder: () => getMask(0), getCaretPosition: (t2) => {
236
- const e2 = getMask(t2), { display: r, map: l } = formatDigitsWithMap(e2, "0".repeat(t2));
237
- for (let e3 = 0; e3 < l.length; e3++) if (l[e3] === t2) return e3;
238
- if (t2 >= l.length) return r.length;
239
- for (let e3 = 0; e3 < l.length; e3++) if (l[e3] > t2) return e3;
240
- return r.length;
226
+ }, getMaxDigits: () => s2, getPlaceholder: () => getMask(0), getCaretPosition: (t2) => {
227
+ const e2 = Math.max(0, t2);
228
+ if (0 === e2) return 0;
229
+ const r = getMask(e2), { display: a } = formatDigitsWithMap(r, "0".repeat(e2));
230
+ return a.length;
241
231
  }, getDigitRange: (t2, e2, r) => {
242
- const l = getMask(t2.length), { map: o3 } = formatDigitsWithMap(l, t2);
243
- let a2 = 1 / 0, i3 = -1 / 0;
232
+ const a = getMask(t2.length), { map: o3 } = formatDigitsWithMap(a, t2);
233
+ let i2 = 1 / 0, l2 = -1 / 0;
244
234
  for (let t3 = e2; t3 < r && t3 < o3.length; t3++) {
245
235
  const e3 = o3[t3];
246
- void 0 !== e3 && e3 >= 0 && (a2 = Math.min(a2, e3), i3 = Math.max(i3, e3));
236
+ void 0 !== e3 && e3 >= 0 && (i2 = Math.min(i2, e3), l2 = Math.max(l2, e3));
247
237
  }
248
- return a2 === 1 / 0 ? null : [a2, i3 + 1];
249
- }, isComplete: (t2) => i2.includes(t2.length) };
238
+ return i2 === 1 / 0 ? null : [i2, l2 + 1];
239
+ }, isComplete: (t2) => l.includes(t2.length) };
250
240
  }
251
241
  const o = "https://ipapi.co/json/", e = 1500, p = "@desource/phone-mask:geo", s = 864e5;
252
242
  async function detectCountryFromGeoIP(t2 = o, r = e) {
@@ -290,7 +280,7 @@ function useCountry({
290
280
  const locale = vue.computed(() => vue.toValue(localeOption) || getNavigatorLang());
291
281
  const countryCode = vue.ref(parseCountryCode(vue.toValue(countryOption), "US"));
292
282
  const country = vue.computed(() => getCountry(countryCode.value, locale.value));
293
- const setCountry = (code) => {
283
+ const setCountry2 = (code) => {
294
284
  const parsed = parseCountryCode(code);
295
285
  if (parsed) {
296
286
  countryCode.value = parsed;
@@ -300,14 +290,14 @@ function useCountry({
300
290
  };
301
291
  const detectCountry = async () => {
302
292
  const geoCountry = await detectByGeoIp();
303
- if (setCountry(geoCountry)) return;
293
+ if (setCountry2(geoCountry)) return;
304
294
  const localeCountry = detectCountryFromLocale();
305
- setCountry(localeCountry);
295
+ setCountry2(localeCountry);
306
296
  };
307
297
  vue.watchEffect(() => {
308
298
  const newCountry = vue.toValue(countryOption);
309
299
  if (newCountry && newCountry !== countryCode.value) {
310
- setCountry(newCountry);
300
+ setCountry2(newCountry);
311
301
  }
312
302
  });
313
303
  vue.watchEffect(() => {
@@ -318,7 +308,7 @@ function useCountry({
318
308
  vue.watchEffect(() => {
319
309
  onCountryChange?.(country.value);
320
310
  });
321
- return { country, setCountry, locale };
311
+ return { country, setCountry: setCountry2, locale };
322
312
  }
323
313
  function useFormatter({
324
314
  country,
@@ -505,8 +495,8 @@ function useCountrySelector({
505
495
  if (!rootRef.value) return;
506
496
  const rect = rootRef.value.getBoundingClientRect();
507
497
  dropdownStyle.value = {
508
- top: `${rect.bottom + window.scrollY + 8}px`,
509
- left: `${rect.left + window.scrollX}px`,
498
+ top: `${rect.bottom + globalThis.scrollY + 8}px`,
499
+ left: `${rect.left + globalThis.scrollX}px`,
510
500
  width: `${rect.width}px`
511
501
  };
512
502
  };
@@ -545,9 +535,9 @@ function useCountrySelector({
545
535
  }
546
536
  };
547
537
  const removeListeners = () => {
548
- window.removeEventListener("resize", positionDropdown);
549
- window.removeEventListener("scroll", positionDropdown, true);
550
- window.removeEventListener("click", onDocClick, true);
538
+ globalThis.removeEventListener("resize", positionDropdown);
539
+ globalThis.removeEventListener("scroll", positionDropdown, true);
540
+ globalThis.removeEventListener("click", onDocClick, true);
551
541
  };
552
542
  vue.watch(hasDropdown, (dropdownExists) => {
553
543
  if (!dropdownExists && dropdownOpen.value) {
@@ -560,9 +550,9 @@ function useCountrySelector({
560
550
  return;
561
551
  }
562
552
  positionDropdown();
563
- window.addEventListener("resize", positionDropdown);
564
- window.addEventListener("scroll", positionDropdown, true);
565
- window.addEventListener("click", onDocClick, true);
553
+ globalThis.addEventListener("resize", positionDropdown);
554
+ globalThis.addEventListener("scroll", positionDropdown, true);
555
+ globalThis.addEventListener("click", onDocClick, true);
566
556
  });
567
557
  vue.onBeforeUnmount(removeListeners);
568
558
  return {
@@ -640,15 +630,18 @@ function useCopyAction({ liveRef, fullFormatted, onCopy }) {
640
630
  function useTheme({ theme }) {
641
631
  const systemDark = vue.ref(false);
642
632
  const themeClass = vue.computed(() => {
643
- return vue.toValue(theme) !== "auto" ? `theme-${vue.toValue(theme)}` : systemDark.value ? "theme-dark" : "theme-light";
633
+ const resolvedTheme = vue.toValue(theme);
634
+ if (resolvedTheme === "auto") {
635
+ return systemDark.value ? "theme-dark" : "theme-light";
636
+ }
637
+ return `theme-${resolvedTheme}`;
644
638
  });
645
639
  let mq = null;
646
640
  const handler = (e2) => {
647
641
  systemDark.value = e2.matches;
648
642
  };
649
643
  vue.onBeforeMount(() => {
650
- if (typeof window === "undefined") return;
651
- mq = window.matchMedia?.("(prefers-color-scheme: dark)") ?? null;
644
+ mq = globalThis.matchMedia?.("(prefers-color-scheme: dark)") ?? null;
652
645
  if (!mq) return;
653
646
  systemDark.value = mq.matches;
654
647
  mq.addEventListener("change", handler);
@@ -697,13 +690,12 @@ const _hoisted_11 = {
697
690
  "aria-hidden": "true"
698
691
  };
699
692
  const _hoisted_12 = { class: "pi-search-wrap" };
700
- const _hoisted_13 = ["value", "placeholder"];
701
- const _hoisted_14 = ["aria-activedescendant"];
702
- const _hoisted_15 = ["id", "aria-selected", "title", "onClick", "onMouseenter"];
703
- const _hoisted_16 = ["aria-label"];
704
- const _hoisted_17 = { class: "pi-opt-name" };
705
- const _hoisted_18 = { class: "pi-opt-code" };
706
- const _hoisted_19 = {
693
+ const _hoisted_13 = ["value", "aria-activedescendant", "placeholder"];
694
+ const _hoisted_14 = ["id", "aria-selected", "title", "onClick", "onMouseenter"];
695
+ const _hoisted_15 = ["aria-label"];
696
+ const _hoisted_16 = { class: "pi-opt-name" };
697
+ const _hoisted_17 = { class: "pi-opt-code" };
698
+ const _hoisted_18 = {
707
699
  key: 0,
708
700
  class: "pi-empty"
709
701
  };
@@ -738,7 +730,7 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
738
730
  const onChange = (v) => {
739
731
  model.value = v;
740
732
  };
741
- const { country, setCountry, locale } = useCountry({
733
+ const { country, setCountry: setCountry2, locale } = useCountry({
742
734
  country: () => props.country,
743
735
  locale: () => props.locale,
744
736
  detect: () => props.detect,
@@ -768,6 +760,9 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
768
760
  const dropdownRef = vue.useTemplateRef("dropdownRef");
769
761
  const searchRef = vue.useTemplateRef("searchRef");
770
762
  const selectorRef = vue.useTemplateRef("selectorRef");
763
+ const dropdownId = vue.getCurrentInstance()?.uid ?? 0;
764
+ const listboxId = `pi-options-${dropdownId}`;
765
+ const getOptionId = (idx) => `pi-option-${dropdownId}-${idx}`;
771
766
  const inactive = vue.computed(() => props.disabled || props.readonly);
772
767
  const incomplete = vue.computed(() => showValidationHint.value && shouldShowWarn.value);
773
768
  const showCopyButton = vue.computed(() => props.showCopy && !isEmpty.value && !props.disabled);
@@ -799,9 +794,12 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
799
794
  locale,
800
795
  countryOption: () => props.country,
801
796
  inactive,
802
- onSelectCountry: setCountry,
797
+ onSelectCountry: setCountry2,
803
798
  onAfterSelect: focusInput
804
799
  });
800
+ const activeOptionId = vue.computed(
801
+ () => dropdownOpen.value && filteredCountries.value[focusedIndex.value] ? getOptionId(focusedIndex.value) : void 0
802
+ );
805
803
  const { handleBeforeInput, handleInput, handleKeydown, handlePaste } = useInputHandlers({
806
804
  formatter,
807
805
  digits,
@@ -1013,6 +1011,8 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
1013
1011
  type: "search",
1014
1012
  class: "pi-search",
1015
1013
  "aria-label": "Search countries",
1014
+ "aria-controls": listboxId,
1015
+ "aria-activedescendant": activeOptionId.value,
1016
1016
  placeholder: __props.searchPlaceholder,
1017
1017
  onKeydown: _cache[6] || (_cache[6] = //@ts-ignore
1018
1018
  (...args) => vue.unref(handleSearchKeydown) && vue.unref(handleSearchKeydown)(...args)),
@@ -1021,14 +1021,14 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
1021
1021
  }, null, 40, _hoisted_13)
1022
1022
  ]),
1023
1023
  vue.createElementVNode("ul", {
1024
+ id: listboxId,
1024
1025
  class: "pi-options",
1025
1026
  role: "listbox",
1026
- "aria-activedescendant": `option-${vue.unref(focusedIndex)}`,
1027
1027
  tabindex: "-1"
1028
1028
  }, [
1029
1029
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(filteredCountries), (c, idx) => {
1030
1030
  return vue.openBlock(), vue.createElementBlock("li", {
1031
- id: `option-${idx}`,
1031
+ id: getOptionId(idx),
1032
1032
  key: c.id,
1033
1033
  role: "option",
1034
1034
  class: vue.normalizeClass([
@@ -1051,13 +1051,13 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
1051
1051
  vue.renderSlot(_ctx.$slots, "flag", { country: c }, () => [
1052
1052
  vue.createTextVNode(vue.toDisplayString(c.flag), 1)
1053
1053
  ], true)
1054
- ], 8, _hoisted_16),
1055
- vue.createElementVNode("span", _hoisted_17, vue.toDisplayString(c.name), 1),
1056
- vue.createElementVNode("span", _hoisted_18, vue.toDisplayString(c.code), 1)
1057
- ], 42, _hoisted_15);
1054
+ ], 8, _hoisted_15),
1055
+ vue.createElementVNode("span", _hoisted_16, vue.toDisplayString(c.name), 1),
1056
+ vue.createElementVNode("span", _hoisted_17, vue.toDisplayString(c.code), 1)
1057
+ ], 42, _hoisted_14);
1058
1058
  }), 128)),
1059
- vue.unref(filteredCountries).length === 0 ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_19, vue.toDisplayString(__props.noResultsText), 1)) : vue.createCommentVNode("", true)
1060
- ], 8, _hoisted_14)
1059
+ vue.unref(filteredCountries).length === 0 ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_18, vue.toDisplayString(__props.noResultsText), 1)) : vue.createCommentVNode("", true)
1060
+ ])
1061
1061
  ], 6)) : vue.createCommentVNode("", true)
1062
1062
  ]),
1063
1063
  _: 3
@@ -1082,47 +1082,18 @@ const _export_sfc = (sfc, props) => {
1082
1082
  }
1083
1083
  return target;
1084
1084
  };
1085
- const PhoneInput = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-33134720"]]);
1086
- async function initState(binding) {
1087
- const value = binding.value;
1088
- let options = {};
1089
- if (typeof value === "string") {
1090
- options = { country: value };
1091
- } else if (typeof value === "object" && value !== null) {
1092
- options = value;
1093
- }
1094
- const locale = options.locale || getNavigatorLang();
1095
- let country;
1096
- if (options.country) {
1097
- country = getCountry(options.country, locale);
1098
- } else if (options.detect) {
1099
- const geoCountry = await detectCountryFromGeoIP();
1100
- if (geoCountry) {
1101
- country = getCountry(geoCountry, locale);
1102
- } else {
1103
- const localeCountry = detectCountryFromLocale();
1104
- if (localeCountry) {
1105
- country = getCountry(localeCountry, locale);
1106
- } else {
1107
- country = getCountry("US", locale);
1108
- }
1109
- }
1110
- } else {
1111
- country = getCountry("US", locale);
1112
- }
1113
- return {
1114
- country,
1115
- formatter: createPhoneFormatter(country),
1116
- digits: "",
1117
- locale,
1118
- options
1119
- };
1085
+ const PhoneInput = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d730aa54"]]);
1086
+ function parseParams(params) {
1087
+ if (typeof params === "string") return { country: params };
1088
+ if (params && typeof params === "object") return params;
1089
+ return {};
1120
1090
  }
1121
- function updateDisplay(el, state) {
1091
+ function updateDigits(el, state, digits) {
1092
+ state.digits = digits;
1122
1093
  el.value = state.formatter.formatDisplay(state.digits);
1123
1094
  if (state.options.onChange) {
1124
- const fullNumberFormatted = `${state.country.code} ${el.value}`;
1125
- const fullNumber = `${state.country.code}${state.digits}`;
1095
+ const fullNumberFormatted = el.value ? `${state.country.code} ${el.value}` : "";
1096
+ const fullNumber = state.digits ? `${state.country.code}${state.digits}` : "";
1126
1097
  state.options.onChange({
1127
1098
  full: fullNumber,
1128
1099
  fullFormatted: fullNumberFormatted,
@@ -1130,113 +1101,92 @@ function updateDisplay(el, state) {
1130
1101
  });
1131
1102
  }
1132
1103
  }
1133
- function createInputHandler(el, state) {
1134
- return (e2) => {
1135
- const result = processInput(e2, { formatter: state.formatter });
1136
- if (!result) return;
1137
- state.digits = result.newDigits;
1138
- updateDisplay(el, state);
1139
- vue.nextTick(() => {
1140
- const pos = state.formatter.getCaretPosition(result.caretDigitIndex);
1141
- setCaret(el, pos);
1142
- });
1143
- };
1104
+ function checkDigitsUpdate(el, state) {
1105
+ const maxDigits = state.formatter.getMaxDigits();
1106
+ const digits = extractDigits(el.value, maxDigits);
1107
+ const displayValue = state.formatter.formatDisplay(digits);
1108
+ if (digits !== state.digits || el.value !== displayValue) {
1109
+ updateDigits(el, state, digits);
1110
+ }
1144
1111
  }
1145
- function createKeydownHandler(el, state) {
1146
- return (e2) => {
1147
- const result = processKeydown(e2, {
1148
- digits: state.digits,
1149
- formatter: state.formatter
1150
- });
1151
- if (!result) return;
1152
- state.digits = result.newDigits;
1153
- updateDisplay(el, state);
1154
- vue.nextTick(() => {
1155
- const pos = state.formatter.getCaretPosition(result.caretDigitIndex);
1156
- setCaret(el, pos);
1157
- });
1158
- };
1112
+ function checkCountryUpdate(el, state) {
1113
+ const oldCountry = state.country.id;
1114
+ const newCountry = parseCountryCode(state.options.country);
1115
+ if (newCountry && newCountry !== oldCountry) {
1116
+ setCountry(el, state, newCountry);
1117
+ }
1159
1118
  }
1160
- function createPasteHandler(el, state) {
1119
+ function createHandler(el, state, handler) {
1161
1120
  return (e2) => {
1162
- const result = processPaste(e2, {
1163
- digits: state.digits,
1164
- formatter: state.formatter
1165
- });
1121
+ const result = handler(e2, state);
1166
1122
  if (!result) return;
1167
- state.digits = result.newDigits;
1168
- updateDisplay(el, state);
1123
+ updateDigits(el, state, result.newDigits);
1169
1124
  vue.nextTick(() => {
1170
1125
  const pos = state.formatter.getCaretPosition(result.caretDigitIndex);
1171
1126
  setCaret(el, pos);
1172
1127
  });
1173
1128
  };
1174
1129
  }
1175
- async function updateCountry(el, state, newCountryCode) {
1176
- const newCountry = getCountry(newCountryCode, state.locale);
1130
+ async function detectInitialCountry(options) {
1131
+ const countryOption = parseCountryCode(options.country);
1132
+ if (countryOption) return countryOption;
1133
+ if (options.detect) {
1134
+ const geoCountry = parseCountryCode(await detectByGeoIp());
1135
+ if (geoCountry) return geoCountry;
1136
+ const localeCountry = parseCountryCode(detectCountryFromLocale());
1137
+ if (localeCountry) return localeCountry;
1138
+ }
1139
+ return "US";
1140
+ }
1141
+ function setCountry(el, state, newCountryCode) {
1142
+ const parsed = parseCountryCode(newCountryCode);
1143
+ if (!parsed) return;
1144
+ const newCountry = getCountry(parsed, state.locale);
1177
1145
  state.country = newCountry;
1146
+ state.options.onCountryChange?.(newCountry);
1178
1147
  state.formatter = createPhoneFormatter(newCountry);
1179
1148
  el.placeholder = state.formatter.getPlaceholder();
1180
- const maxDigits = state.formatter.getMaxDigits();
1181
- if (state.digits.length > maxDigits) {
1182
- state.digits = state.digits.slice(0, maxDigits);
1183
- }
1184
- updateDisplay(el, state);
1185
- if (state.options.onCountryChange) {
1186
- state.options.onCountryChange(newCountry);
1187
- }
1149
+ checkDigitsUpdate(el, state);
1188
1150
  }
1189
1151
  const vPhoneMask = {
1190
- async mounted(el, binding) {
1152
+ mounted(el, binding) {
1191
1153
  if (el.tagName !== "INPUT") {
1192
1154
  console.warn("[v-phone-mask] Directive can only be used on input elements");
1193
1155
  return;
1194
1156
  }
1195
1157
  el.setAttribute("type", "tel");
1196
1158
  el.setAttribute("inputmode", "tel");
1197
- const state = await initState(binding);
1159
+ el.setAttribute("placeholder", "");
1160
+ const options = parseParams(binding.value);
1161
+ const locale = options.locale || getNavigatorLang();
1162
+ const country = getCountry(parseCountryCode(options.country, "US"), locale);
1163
+ const state = {
1164
+ country,
1165
+ formatter: createPhoneFormatter(country),
1166
+ digits: "",
1167
+ locale,
1168
+ options
1169
+ };
1198
1170
  el.__phoneMaskState = state;
1199
- state.inputHandler = createInputHandler(el, state);
1200
- state.keydownHandler = createKeydownHandler(el, state);
1201
- state.pasteHandler = createPasteHandler(el, state);
1171
+ state.inputHandler = createHandler(el, state, processInput);
1172
+ state.keydownHandler = createHandler(el, state, processKeydown);
1173
+ state.pasteHandler = createHandler(el, state, processPaste);
1202
1174
  state.beforeInputHandler = processBeforeInput;
1203
1175
  el.addEventListener("beforeinput", state.beforeInputHandler);
1204
1176
  el.addEventListener("input", state.inputHandler);
1205
1177
  el.addEventListener("keydown", state.keydownHandler);
1206
1178
  el.addEventListener("paste", state.pasteHandler);
1207
- el.setAttribute("placeholder", state.formatter.getPlaceholder());
1208
- if (state.options.onCountryChange) {
1209
- state.options.onCountryChange(state.country);
1210
- }
1211
- if (el.value) {
1212
- const maxDigits = state.formatter.getMaxDigits();
1213
- state.digits = extractDigits(el.value, maxDigits);
1214
- updateDisplay(el, state);
1215
- }
1179
+ detectInitialCountry(options).then((countryCode) => {
1180
+ if (el.__phoneMaskState !== state) return;
1181
+ setCountry(el, state, countryCode);
1182
+ });
1216
1183
  },
1217
- async updated(el, binding) {
1184
+ updated(el, binding) {
1218
1185
  const state = el.__phoneMaskState;
1219
1186
  if (!state) return;
1220
- const value = binding.value;
1221
- let newOptions = {};
1222
- if (typeof value === "string") {
1223
- newOptions = { country: value };
1224
- } else if (typeof value === "object" && value !== null) {
1225
- newOptions = value;
1226
- }
1227
- const oldCountry = state.options.country;
1228
- state.options = newOptions;
1229
- const newCountry = newOptions.country;
1230
- if (newCountry && newCountry !== oldCountry) {
1231
- await updateCountry(el, state, newCountry);
1232
- }
1233
- const maxDigits = state.formatter.getMaxDigits();
1234
- const newDigits = extractDigits(el.value, maxDigits);
1235
- const normalizedDisplay = state.formatter.formatDisplay(newDigits);
1236
- if (newDigits !== state.digits || el.value !== normalizedDisplay) {
1237
- state.digits = newDigits;
1238
- updateDisplay(el, state);
1239
- }
1187
+ state.options = parseParams(binding.value);
1188
+ checkCountryUpdate(el, state);
1189
+ checkDigitsUpdate(el, state);
1240
1190
  },
1241
1191
  unmounted(el) {
1242
1192
  const state = el.__phoneMaskState;
@@ -1250,7 +1200,7 @@ const vPhoneMask = {
1250
1200
  };
1251
1201
  function usePhoneMask(options) {
1252
1202
  const inputRef = vue.shallowRef(null);
1253
- const { country, setCountry } = useCountry({
1203
+ const { country, setCountry: setCountry2 } = useCountry({
1254
1204
  country: options.country,
1255
1205
  locale: options.locale,
1256
1206
  detect: options.detect,
@@ -1314,13 +1264,14 @@ function usePhoneMask(options) {
1314
1264
  return {
1315
1265
  inputRef,
1316
1266
  digits,
1267
+ formatter,
1317
1268
  full,
1318
1269
  fullFormatted,
1319
1270
  isComplete,
1320
1271
  isEmpty,
1321
1272
  shouldShowWarn,
1322
1273
  country,
1323
- setCountry,
1274
+ setCountry: setCountry2,
1324
1275
  clear
1325
1276
  };
1326
1277
  }
@@ -1345,4 +1296,4 @@ exports.default = index;
1345
1296
  exports.install = install;
1346
1297
  exports.usePhoneMask = usePhoneMask;
1347
1298
  exports.vPhoneMask = vPhoneMask;
1348
- exports.vPhoneMaskSetCountry = updateCountry;
1299
+ exports.vPhoneMaskSetCountry = setCountry;