edvoyui-component-library-test-flight 0.0.241 → 0.0.243

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.
@@ -48,6 +48,7 @@
48
48
  :class="[getIconClass()]"
49
49
  @on-input="onInputChanged"
50
50
  @country-changed="onCountryChanged"
51
+ @focus="onFocus"
51
52
  @blur="onBlur"
52
53
  ></vue-tel-input>
53
54
  </button>
@@ -79,13 +80,13 @@ import {
79
80
  type PhoneMeta,
80
81
  type VueTelInputProps,
81
82
  } from "vue-tel-input";
82
- import { getExampleNumber } from "libphonenumber-js";
83
+ import { type CountryCode, getExampleNumber } from "libphonenumber-js";
83
84
  import mobileExamples from "libphonenumber-js/mobile/examples";
84
85
  import "vue-tel-input/vue-tel-input.css";
85
86
 
86
87
  type TelephoneInputMeta = PhoneMeta & { number: string };
87
88
 
88
- const emit = defineEmits(["update:modelValue", "blur", "update:isValid"]);
89
+ const emit = defineEmits(["update:modelValue", "blur", "focus", "update:isValid"]);
89
90
 
90
91
  const props = defineProps({
91
92
  modelValue: {
@@ -160,9 +161,9 @@ const id = generateUID();
160
161
 
161
162
  const hasError = computed({
162
163
  set: (value) => {
163
- emit("update:isValid", value);
164
+ emit("update:isValid", !value);
164
165
  },
165
- get: () => isValid.value,
166
+ get: () => !isValid.value,
166
167
  });
167
168
 
168
169
  const inputValue = computed(() => {
@@ -170,6 +171,7 @@ const inputValue = computed(() => {
170
171
  });
171
172
 
172
173
  const mobile = ref(String(props.modelValue ?? ""));
174
+ const isFocused = ref(false);
173
175
  const isTouched = ref(false);
174
176
  const telephoneIsValid = ref(props.isValid);
175
177
  const activeCountry = ref<CountryObject | null>(null);
@@ -191,8 +193,13 @@ const getCountryMaxLength = (
191
193
  ) => {
192
194
  if (!country) return props.length;
193
195
 
194
- const countryCode = typeof country === "string" ? country : country.iso2;
195
- const example = getExampleNumber(countryCode, mobileExamples);
196
+ const rawCode = typeof country === "string" ? country : country.iso2;
197
+ const countryCode = (
198
+ rawCode ? String(rawCode).toUpperCase() : ""
199
+ ) as CountryCode;
200
+ const example = countryCode
201
+ ? getExampleNumber(countryCode, mobileExamples)
202
+ : undefined;
196
203
  if (!example) return props.length;
197
204
 
198
205
  const dialCodeLength = String(example.countryCallingCode ?? "").length;
@@ -247,34 +254,28 @@ const bindProps = computed<VueTelInputProps>(() => ({
247
254
  },
248
255
  }));
249
256
 
257
+ const onFocus = () => {
258
+ isFocused.value = true;
259
+ emit("focus");
260
+ };
261
+
250
262
  const onInputChanged = (
251
263
  _formattedNumber: string,
252
264
  phoneObject: TelephoneInputMeta,
253
265
  ) => {
254
- const countryCode = phoneObject.country ?? activeCountry.value?.iso2;
255
- const example = countryCode
256
- ? getExampleNumber(countryCode, mobileExamples)
257
- : undefined;
258
- const dialCode =
259
- example?.countryCallingCode ?? activeCountry.value?.dialCode ?? "";
260
- const phoneDigits = String(phoneObject.number ?? "").replace(/\D/g, "");
261
- const nationalDigits = phoneDigits.slice(String(dialCode).length);
262
-
263
- if (nationalDigits.length > 0) {
264
- isTouched.value = true;
265
- }
266
-
266
+ isFocused.value = true;
267
267
  telephoneIsValid.value = Boolean(phoneObject.valid);
268
- hasError.value = telephoneIsValid.value;
268
+ hasError.value = !telephoneIsValid.value;
269
269
 
270
270
  dynamicMaxLength.value = getCountryMaxLength(
271
- activeCountry.value ?? phoneObject.country ?? null,
271
+ phoneObject.country ?? activeCountry.value ?? null,
272
272
  );
273
273
 
274
274
  emit("update:modelValue", phoneObject.number);
275
275
  };
276
276
 
277
277
  const onBlur = () => {
278
+ isFocused.value = false;
278
279
  isTouched.value = true;
279
280
  emit("blur");
280
281
  };
@@ -313,17 +314,34 @@ const externalErrorMessage = computed(() => {
313
314
  });
314
315
 
315
316
  const internalErrorMessage = computed(() => {
316
- if (!isTouched.value || props.readonly || props.disabled) return "";
317
+ if (
318
+ !isTouched.value ||
319
+ telephoneIsValid.value ||
320
+ props.readonly ||
321
+ props.disabled
322
+ ) {
323
+ return "";
324
+ }
317
325
 
318
326
  const value = String(mobile.value ?? "").trim();
319
327
  if (!value) return props.required ? "Mobile number is required" : "";
320
328
 
321
- return telephoneIsValid.value ? "" : "Enter a valid phone number";
329
+ return "Enter a valid phone number";
322
330
  });
323
331
 
324
- const errorMessage = computed(
325
- () => externalErrorMessage.value || internalErrorMessage.value,
326
- );
332
+ const errorMessage = computed(() => {
333
+ if (props.readonly || props.disabled) return "";
334
+
335
+ if (isFocused.value && !telephoneIsValid.value) {
336
+ return "";
337
+ }
338
+
339
+ if (isTouched.value) {
340
+ return internalErrorMessage.value || externalErrorMessage.value || "";
341
+ }
342
+
343
+ return externalErrorMessage.value || "";
344
+ });
327
345
 
328
346
  const getIconClass = () => {
329
347
  switch (props.iconType) {