@flyanra/vue-core 1.3.8 → 1.4.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.
Files changed (42) hide show
  1. package/dist/types/components/form/index.d.ts +1 -3
  2. package/dist/types/components/form/input-renderers/country-input/FlyCountryCitySelect.vue.d.ts +19 -0
  3. package/dist/types/components/form/input-renderers/country-input/FlyCountrySelect.types.d.ts +4 -0
  4. package/dist/types/components/form/input-renderers/country-input/FlyCountrySelect.vue.d.ts +30 -0
  5. package/dist/types/components/form/input-renderers/country-input/FlyCountryStatesSelect.vue.d.ts +18 -0
  6. package/dist/types/components/form/input-renderers/country-input/countries.d.ts +49 -0
  7. package/dist/types/components/form/input-renderers/country-input/index.d.ts +5 -0
  8. package/dist/types/components/form/input-renderers/index.d.ts +5 -0
  9. package/dist/types/components/form/input-renderers/phone-number/FlyPhoneNumberInput.types.d.ts +1 -0
  10. package/dist/types/components/form/input-renderers/phone-number/FlyPhoneNumberInput.vue.d.ts +17 -0
  11. package/dist/types/components/form/input-renderers/phone-number/index.d.ts +3 -0
  12. package/dist/types/components/form/input-validators.d.ts +5 -0
  13. package/dist/types/composables/useLocaleInjector/index.d.ts +2 -2
  14. package/dist/types/composables/useLocaleInjector/useLocaleInjector.d.ts +13 -0
  15. package/dist/types/utils/country-utils.d.ts +3 -0
  16. package/dist/types/utils/index.d.ts +1 -0
  17. package/package.json +8 -4
  18. package/src/components/basic/typography/FlyCollapseTitleRenderer.vue +2 -2
  19. package/src/components/form/form.utils.ts +3 -3
  20. package/src/components/form/index.ts +1 -4
  21. package/src/components/form/input-renderers/country-input/FlyCountryCitySelect.vue +73 -0
  22. package/src/components/form/input-renderers/country-input/FlyCountrySelect.types.ts +4 -0
  23. package/src/components/form/input-renderers/country-input/FlyCountrySelect.vue +76 -0
  24. package/src/components/form/input-renderers/country-input/FlyCountryStatesSelect.vue +80 -0
  25. package/src/components/form/input-renderers/country-input/countries.ts +5746 -0
  26. package/src/components/form/input-renderers/country-input/index.ts +6 -0
  27. package/src/components/form/input-renderers/form-item-renderer/FlyFormItemRenderer.vue +2 -2
  28. package/src/components/form/input-renderers/index.ts +7 -0
  29. package/src/components/form/input-renderers/phone-number/FlyPhoneNumberInput.scss +1 -0
  30. package/src/components/form/input-renderers/phone-number/FlyPhoneNumberInput.types.ts +0 -0
  31. package/src/components/form/input-renderers/phone-number/FlyPhoneNumberInput.vue +99 -0
  32. package/src/components/form/input-renderers/phone-number/index.ts +4 -0
  33. package/src/components/form/input-renderers/regional-tenant-form-renderer/FlyRegionalTenantFormRenderer.vue +2 -2
  34. package/src/components/form/input-validators.ts +109 -2
  35. package/src/composables/useLocaleInjector/index.ts +2 -2
  36. package/src/composables/useLocaleInjector/useLocaleInjector.ts +34 -0
  37. package/src/styles/element/overrides/form.scss +0 -2
  38. package/src/utils/country-utils.ts +27 -0
  39. package/src/utils/index.ts +2 -0
  40. package/src/utils/validators.ts +3 -3
  41. package/dist/types/composables/useLocaleInjector/UseLocaleInjector.d.ts +0 -14
  42. package/src/composables/useLocaleInjector/UseLocaleInjector.ts +0 -37
@@ -1,5 +1,3 @@
1
- export * from './input-renderers/form-item-renderer';
2
- export * from './input-renderers/input-renderer';
3
- export type { T_InputRendererBase } from './input-renderers/input-renderer.types';
1
+ export * from './input-renderers';
4
2
  export * from './input-validators';
5
3
  export * from './form.utils';
@@ -0,0 +1,19 @@
1
+ import '../select/FlySelect.scss';
2
+ type __VLS_Props = {
3
+ modelValue?: string;
4
+ country?: string;
5
+ state?: string;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
8
+ focus: () => any;
9
+ "update:modelValue": (value: string | undefined) => any;
10
+ change: (value: string | undefined) => any;
11
+ blur: () => any;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ onFocus?: (() => any) | undefined;
14
+ "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
15
+ onChange?: ((value: string | undefined) => any) | undefined;
16
+ onBlur?: (() => any) | undefined;
17
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
@@ -0,0 +1,4 @@
1
+ export type T_CountryValueLabel = {
2
+ label: string;
3
+ value: string;
4
+ };
@@ -0,0 +1,30 @@
1
+ import '../select/FlySelect.scss';
2
+ import type { T_CountryValueLabel } from './FlyCountrySelect.types';
3
+ type __VLS_Props = {
4
+ modelValue?: string | undefined;
5
+ };
6
+ declare var __VLS_13: {
7
+ scope: T_CountryValueLabel;
8
+ };
9
+ type __VLS_Slots = {} & {
10
+ label?: (props: typeof __VLS_13) => any;
11
+ };
12
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
13
+ focus: () => any;
14
+ "update:modelValue": (v?: string | undefined) => any;
15
+ change: (v: string | undefined) => any;
16
+ blur: () => any;
17
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
18
+ onFocus?: (() => any) | undefined;
19
+ "onUpdate:modelValue"?: ((v?: string | undefined) => any) | undefined;
20
+ onChange?: ((v: string | undefined) => any) | undefined;
21
+ onBlur?: (() => any) | undefined;
22
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
24
+ declare const _default: typeof __VLS_export;
25
+ export default _default;
26
+ type __VLS_WithSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -0,0 +1,18 @@
1
+ import '../select/FlySelect.scss';
2
+ type __VLS_Props = {
3
+ modelValue?: string;
4
+ country?: string;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
7
+ focus: () => any;
8
+ "update:modelValue": (value: string | undefined) => any;
9
+ change: (value: string | undefined) => any;
10
+ blur: () => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ onFocus?: (() => any) | undefined;
13
+ "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
14
+ onChange?: ((value: string | undefined) => any) | undefined;
15
+ onBlur?: (() => any) | undefined;
16
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
@@ -0,0 +1,49 @@
1
+ interface I_CountryFlags {
2
+ png: string;
3
+ svg: string;
4
+ alt: string;
5
+ }
6
+ interface I_CountryPostalCode {
7
+ format?: string;
8
+ regex?: string;
9
+ }
10
+ interface I_CountryNativeName {
11
+ official: string;
12
+ common: string;
13
+ }
14
+ interface I_CountryName {
15
+ common: string;
16
+ official: string;
17
+ nativeName: {
18
+ [key: string]: I_CountryNativeName;
19
+ };
20
+ }
21
+ interface I_CountryCurrency {
22
+ name: string;
23
+ symbol: string;
24
+ }
25
+ interface I_CountryCurrencies {
26
+ [key: string]: I_CountryCurrency;
27
+ }
28
+ interface I_CountryId {
29
+ root: string;
30
+ suffixes: string[];
31
+ }
32
+ export interface I_Country {
33
+ capital: string[];
34
+ cca2: string;
35
+ currencies: I_CountryCurrencies;
36
+ flags: I_CountryFlags;
37
+ idd: I_CountryId;
38
+ latlng: number[];
39
+ name: I_CountryName;
40
+ postalCode: I_CountryPostalCode;
41
+ }
42
+ export declare const countryList: I_Country[];
43
+ /**
44
+ * Map of country codes to country objects.
45
+ * Generated once to avoid performance issues.
46
+ */
47
+ export declare const countryListMap: Map<string, I_Country>;
48
+ export declare const getCountryName: (countryCode: string) => string;
49
+ export {};
@@ -0,0 +1,5 @@
1
+ import FlyCountryCitySelect from './FlyCountryCitySelect.vue';
2
+ import FlyCountrySelect from './FlyCountrySelect.vue';
3
+ import FlyCountryStatesSelect from './FlyCountryStatesSelect.vue';
4
+ export default FlyCountrySelect;
5
+ export { FlyCountrySelect, FlyCountryCitySelect, FlyCountryStatesSelect };
@@ -0,0 +1,5 @@
1
+ export * from './form-item-renderer';
2
+ export * from './input-renderer';
3
+ export * from './country-input';
4
+ export * from './phone-number';
5
+ export type { T_InputRendererBase } from './input-renderer.types';
@@ -0,0 +1,17 @@
1
+ import './FlyPhoneNumberInput.scss';
2
+ type __VLS_Props = {
3
+ modelValue?: string;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
6
+ focus: () => any;
7
+ "update:modelValue": (value: string | undefined) => any;
8
+ change: (value: string | undefined) => any;
9
+ blur: () => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ onFocus?: (() => any) | undefined;
12
+ "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
13
+ onChange?: ((value: string | undefined) => any) | undefined;
14
+ onBlur?: (() => any) | undefined;
15
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import FlyPhoneNumberInput from './FlyPhoneNumberInput.vue';
2
+ export default FlyPhoneNumberInput;
3
+ export { FlyPhoneNumberInput };
@@ -9,4 +9,9 @@ export declare const requiredFieldValueUnit: (label: string | undefined, trigger
9
9
  valueType?: "text" | "number";
10
10
  }) => FormItemRule;
11
11
  export declare const requiredFieldArray: (label?: string, trigger?: InputTriggers, useRequiredMessage?: boolean) => FormItemRule;
12
+ export declare const requiredFieldEmail: (label?: string, trigger?: InputTriggers, useRequiredMessage?: boolean) => FormItemRule;
13
+ export declare const fieldEmail: (languageKey?: string, trigger?: InputTriggers) => FormItemRule;
14
+ export declare const requiredFieldEmailArray: (label?: string, trigger?: InputTriggers, useRequiredMessage?: boolean, required?: boolean) => FormItemRule;
15
+ export declare const requiredFieldE164PhoneNumber: (label?: string, trigger?: InputTriggers, useRequiredMessage?: boolean) => FormItemRule;
16
+ export declare const fieldE164PhoneNumber: (trigger?: InputTriggers) => FormItemRule;
12
17
  export {};
@@ -1,2 +1,2 @@
1
- export { initLocaleInjector, UseLocaleInjector } from './UseLocaleInjector';
2
- export type { T_LocaleInjector } from './UseLocaleInjector';
1
+ export { initLocaleInjector, useLocaleInjector } from './useLocaleInjector';
2
+ export type { T_LocaleInjector, T_I18nAdapter as I18nAdapter } from './useLocaleInjector';
@@ -0,0 +1,13 @@
1
+ import type { ComputedRef, MaybeRef } from 'vue';
2
+ import type { Locale } from '@flyanra/js-utils/locales';
3
+ import type { ComposerTranslation } from 'vue-i18n';
4
+ export type T_LocaleInjector = {
5
+ t: ComposerTranslation;
6
+ locale: ComputedRef<Locale>;
7
+ };
8
+ export type T_I18nAdapter = {
9
+ t: ComposerTranslation;
10
+ locale: MaybeRef<Locale>;
11
+ };
12
+ export declare function initLocaleInjector(i18n: T_I18nAdapter): void;
13
+ export declare function useLocaleInjector(): T_LocaleInjector;
@@ -0,0 +1,3 @@
1
+ declare function getAdministrativeAreaLabel(countryCode?: string): string;
2
+ declare function getNationalIdLabel(countryCode?: string): string;
3
+ export { getAdministrativeAreaLabel, getNationalIdLabel };
@@ -1,2 +1,3 @@
1
1
  export { checkRange } from './pure-functions';
2
2
  export { checkInputRange, isRequiredError } from './validators';
3
+ export * from './country-utils';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flyanra/vue-core",
3
- "version": "1.3.8",
3
+ "version": "1.4.0",
4
4
  "private": false,
5
5
  "description": "Source-distributed Vue component library for Vite and Nuxt consumers.",
6
6
  "sideEffects": false,
@@ -96,10 +96,14 @@
96
96
  "eslint --fix"
97
97
  ]
98
98
  },
99
+ "dependencies": {
100
+ "country-state-city": "^3.2.1",
101
+ "libphonenumber-js": "^1.13.10"
102
+ },
99
103
  "devDependencies": {
100
104
  "@changesets/cli": "^2.30.0",
101
105
  "@eslint/js": "^10.0.1",
102
- "@flyanra/js-utils": "^1.6.0",
106
+ "@flyanra/js-utils": "^1.6.5",
103
107
  "@iconify-json/mdi": "^1.2.3",
104
108
  "@iconify-json/ri": "^1.2.10",
105
109
  "@jamescoyle/vue-icon": "^0.1.2",
@@ -142,7 +146,7 @@
142
146
  "vitest": "^4.1.4",
143
147
  "vue": "^3.5.32",
144
148
  "vue-eslint-parser": "^10.4.0",
145
- "vue-i18n": "^11.4.0",
149
+ "vue-i18n": "^11.3.2",
146
150
  "vue-tsc": "^3.2.6"
147
151
  },
148
152
  "peerDependencies": {
@@ -151,7 +155,7 @@
151
155
  "element-plus": "^2.13.7",
152
156
  "maska": "^3.2.0",
153
157
  "vue": "^3.5.32",
154
- "vue-i18n": "^11.4.0"
158
+ "vue-i18n": "^11.3.2"
155
159
  },
156
160
  "volta": {
157
161
  "node": "24.12.0",
@@ -11,13 +11,13 @@
11
11
  </template>
12
12
 
13
13
  <script lang="ts" setup>
14
- import { UseLocaleInjector } from '../../../composables/useLocaleInjector/UseLocaleInjector'
14
+ import { useLocaleInjector } from '../../../composables/useLocaleInjector/useLocaleInjector'
15
15
 
16
16
  defineProps<{
17
17
  title: string
18
18
  }>()
19
19
 
20
- const { t } = UseLocaleInjector()
20
+ const { t } = useLocaleInjector()
21
21
  </script>
22
22
 
23
23
  <style lang="scss" scoped>
@@ -1,6 +1,6 @@
1
1
  import type { FormInstance } from 'element-plus'
2
2
 
3
- import { UseLocaleInjector } from '../../composables/useLocaleInjector/UseLocaleInjector'
3
+ import { useLocaleInjector } from '../../composables/useLocaleInjector/useLocaleInjector'
4
4
 
5
5
  export type ValidateFieldsError = { [K: string]: { message?: string }[] }
6
6
 
@@ -8,7 +8,7 @@ export type ValidateFieldsError = { [K: string]: { message?: string }[] }
8
8
  * @returns Translated error message based on active locale
9
9
  */
10
10
  export function formFieldErrorMessageFormatter(errors: ValidateFieldsError) {
11
- const { t, locale } = UseLocaleInjector()
11
+ const { t, locale } = useLocaleInjector()
12
12
  const keys = Object.keys(errors)
13
13
 
14
14
  if (keys.length) {
@@ -31,7 +31,7 @@ export function formFieldErrorMessageFormatter(errors: ValidateFieldsError) {
31
31
  const otherErrorsLength = otherErrors.length
32
32
 
33
33
  if (requiredFieldsLength >= 1) {
34
- const joinedList = new Intl.ListFormat(locale, {
34
+ const joinedList = new Intl.ListFormat(locale.value, {
35
35
  style: 'long',
36
36
  type: 'conjunction'
37
37
  }).format(requiredFieldNames.filter((item): item is string => Boolean(item)))
@@ -1,6 +1,3 @@
1
- export * from './input-renderers/form-item-renderer'
2
- export * from './input-renderers/input-renderer'
3
-
4
- export type { T_InputRendererBase } from './input-renderers/input-renderer.types'
1
+ export * from './input-renderers'
5
2
  export * from './input-validators'
6
3
  export * from './form.utils'
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <el-select
3
+ v-if="options.length"
4
+ v-model="inputProxy"
5
+ style="width: 100%"
6
+ filterable
7
+ clearable
8
+ :disabled="!country || !state"
9
+ @change="(value: string) => emit('change', value)"
10
+ @blur="emit('blur')"
11
+ @focus="emit('focus')"
12
+ >
13
+ <el-option v-for="city in options" :key="city.name" :value="city.name" :label="city.name" />
14
+ </el-select>
15
+
16
+ <el-input
17
+ v-else
18
+ v-model="inputProxy"
19
+ style="width: 100%"
20
+ show-word-limit
21
+ :disabled="!country || !state"
22
+ @change="(value: string) => emit('change', value)"
23
+ @blur="emit('blur')"
24
+ @focus="emit('focus')"
25
+ />
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { computed, watch } from 'vue'
30
+
31
+ import { ElOption, ElSelect } from 'element-plus'
32
+
33
+ import { City } from 'country-state-city'
34
+
35
+ import '../select/FlySelect.scss'
36
+
37
+ const emit = defineEmits<{
38
+ (e: 'update:modelValue', value: string | undefined): void
39
+ (e: 'change', value: string | undefined): void
40
+ (e: 'blur'): void
41
+ (e: 'focus'): void
42
+ }>()
43
+
44
+ const props = defineProps<{
45
+ modelValue?: string
46
+ country?: string
47
+ state?: string
48
+ }>()
49
+
50
+ const options = computed(() => {
51
+ if (!props.country || !props.state) return []
52
+
53
+ return City.getCitiesOfState(props.country.toUpperCase(), props.state.toUpperCase())
54
+ })
55
+
56
+ const inputProxy = computed({
57
+ get: () => props.modelValue,
58
+ set: (value: string | undefined) => {
59
+ emit('update:modelValue', value)
60
+ }
61
+ })
62
+
63
+ watch([() => props.country, () => props.state], () => {
64
+ if (!props.modelValue) return
65
+
66
+ const cityStillExists = options.value.some((city) => city.name === props.modelValue)
67
+
68
+ if (!cityStillExists) {
69
+ emit('update:modelValue', undefined)
70
+ emit('change', undefined)
71
+ }
72
+ })
73
+ </script>
@@ -0,0 +1,4 @@
1
+ export type T_CountryValueLabel = {
2
+ label: string
3
+ value: string
4
+ }
@@ -0,0 +1,76 @@
1
+ <template>
2
+ <el-select
3
+ v-model="inputProxy"
4
+ class="fly-country-select"
5
+ filterable
6
+ clearable
7
+ @change="(val) => emit('change', val)"
8
+ @blur="() => emit('blur')"
9
+ @focus="() => emit('focus')"
10
+ >
11
+ <template #label="valueObject: T_CountryValueLabel">
12
+ <slot name="label" :scope="valueObject">
13
+ <span>{{ valueObject.label }}</span>
14
+ </slot>
15
+ </template>
16
+ <el-option
17
+ v-for="country in countryList"
18
+ :key="country.cca2"
19
+ :label="country.name.common"
20
+ :value="country.cca2"
21
+ class="flex items-center justify-between space-x-2"
22
+ >
23
+ <div class="fly-country-select-option">
24
+ <span>{{ country.name.common }}</span>
25
+ <img :src="country.flags.svg" loading="lazy" />
26
+ </div>
27
+ <!-- <span class="text-xs text-gray-500">
28
+ {{ country.cca2 }}
29
+ </span> -->
30
+ </el-option>
31
+ </el-select>
32
+ </template>
33
+
34
+ <script setup lang="ts">
35
+ import { computed } from 'vue'
36
+
37
+ import { ElOption, ElSelect } from 'element-plus'
38
+
39
+ import '../select/FlySelect.scss'
40
+
41
+ import type { T_CountryValueLabel } from './FlyCountrySelect.types'
42
+ import { countryList } from './countries'
43
+
44
+ const emit = defineEmits<{
45
+ (e: 'update:modelValue', v?: string | undefined): void
46
+ (e: 'change', v: string | undefined): void
47
+ (e: 'blur'): void
48
+ (e: 'focus'): void
49
+ }>()
50
+
51
+ const props = defineProps<{
52
+ modelValue?: string | undefined
53
+ }>()
54
+
55
+ const inputProxy = computed({
56
+ get: (): string | undefined => {
57
+ return props.modelValue
58
+ },
59
+ set: (v) => {
60
+ emit('update:modelValue', v)
61
+ }
62
+ })
63
+ </script>
64
+
65
+ <style scoped>
66
+ .fly-country-select-option {
67
+ display: flex;
68
+ flex-grow: 1;
69
+ justify-content: space-between;
70
+ align-items: center;
71
+
72
+ img {
73
+ width: 20px;
74
+ }
75
+ }
76
+ </style>
@@ -0,0 +1,80 @@
1
+ <template>
2
+ <el-select
3
+ v-if="options.length"
4
+ v-model="inputProxy"
5
+ style="width: 100%"
6
+ filterable
7
+ clearable
8
+ :disabled="!country"
9
+ @change="(value) => emit('change', value)"
10
+ @blur="emit('blur')"
11
+ @focus="emit('focus')"
12
+ >
13
+ <el-option
14
+ v-for="state in options"
15
+ :key="state.isoCode"
16
+ :value="state.isoCode"
17
+ :label="state.name"
18
+ />
19
+ </el-select>
20
+
21
+ <el-input
22
+ v-else
23
+ v-model="inputProxy"
24
+ style="width: 100%"
25
+ show-word-limit
26
+ :disabled="!country"
27
+ @change="(value: string) => emit('change', value)"
28
+ @blur="emit('blur')"
29
+ @focus="emit('focus')"
30
+ />
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import { computed, watch } from 'vue'
35
+
36
+ import { ElOption, ElSelect } from 'element-plus'
37
+
38
+ import { State } from 'country-state-city'
39
+
40
+ import '../select/FlySelect.scss'
41
+
42
+ const emit = defineEmits<{
43
+ (e: 'update:modelValue', value: string | undefined): void
44
+ (e: 'change', value: string | undefined): void
45
+ (e: 'blur'): void
46
+ (e: 'focus'): void
47
+ }>()
48
+
49
+ const props = defineProps<{
50
+ modelValue?: string
51
+ country?: string
52
+ }>()
53
+
54
+ const options = computed(() => {
55
+ if (!props.country) return []
56
+
57
+ return State.getStatesOfCountry(props.country.toUpperCase())
58
+ })
59
+
60
+ const inputProxy = computed({
61
+ get: () => props.modelValue,
62
+ set: (value: string | undefined) => {
63
+ emit('update:modelValue', value)
64
+ }
65
+ })
66
+
67
+ watch(
68
+ () => props.country,
69
+ () => {
70
+ if (!props.modelValue) return
71
+
72
+ const stateStillExists = options.value.some((state) => state.isoCode === props.modelValue)
73
+
74
+ if (!stateStillExists) {
75
+ emit('update:modelValue', undefined)
76
+ emit('change', undefined)
77
+ }
78
+ }
79
+ )
80
+ </script>