Closed Lrochefort closed 2 months ago
Haha, I completely agree with you that we should add a Vue 3 component. I have no experience with Vue, so cannot help here, but I would welcome a pull request to add this. It could be super simple to start with - just a Vue component that imports the plugin and creates an input and initialises the plugin on it.
e.g. see v1 of the react component here - it's literally a simple react component that renders an input, and after the first render (useEffect
) it initialises the plugin, and calls an update
function when things change.
You could just put it here to start with: src/js/intl-tel-input/vue.ts. And then others could help iterate from there.
Or if you were up for a slightly more complex setup, you could imitate the react setup, with a root vue/ directory, and setup symlinks to the other required plugin files (this is a workaround so that typescript module namespacing works well).
I agree. My problem is the lack of time. I may be able to do a simple PoC next weekend. To be continuedβ¦
If you're looking for a start, this is what I've used in the past (although it'll need to be converted to TypeScript):
<script setup>
import intlTelInput from 'intl-tel-input/intlTelInputWithUtils';
import 'intl-tel-input/styles';
import { onMounted, onUnmounted, ref, watch } from 'vue';
const model = defineModel({
type: String,
default: '',
});
const props = defineProps({
options: {
type: Object,
default: () => ({}),
},
value: {
type: String,
default: '',
},
disabled: {
type: Boolean,
},
});
const emit = defineEmits(['changeNumber', 'changeCountry', 'changeValidity', 'changeErrorCode']);
const input = ref();
const instance = ref();
const wasPreviouslyValid = ref(false);
const isValid = () => {
if (instance.value) {
return props.options.strictMode ? instance.value.isValidNumberPrecise() : instance.value.isValidNumber();
}
return null;
};
const updateValidity = () => {
let isCurrentlyValid = isValid();
if (wasPreviouslyValid.value !== isCurrentlyValid) {
wasPreviouslyValid.value = isCurrentlyValid;
emit('changeValidity', !!isCurrentlyValid);
emit('changeErrorCode', isCurrentlyValid ? null : instance.value.getValidationError());
}
};
const updateValue = () => {
emit('changeNumber', instance.value?.getNumber() ?? '');
updateValidity();
};
const updateCountry = () => {
emit('changeCountry', instance.value?.getSelectedCountryData().iso2 ?? '');
updateValue();
updateValidity();
};
onMounted(() => {
if (input.value) {
instance.value = intlTelInput(input.value, props.options);
if (props.value) {
instance.value.setNumber(props.value);
}
if (props.disabled) {
instance.value.setDisabled(props.disabled);
}
}
});
watch(
() => props.disabled,
newValue => instance.value?.setDisabled(newValue)
);
onUnmounted(() => instance.value?.destroy());
defineExpose({ instance, input });
</script>
<template>
<input ref="input" v-model="model" type="tel" @countrychange="updateCountry" @input="updateValue" />
</template>
Edit: With small improvement to expose the instance and input.
Edit 2: One thing I never achieved was exposing the formatted number as the model value, e.g. <TelInput v-model="form.phone" />
where form.phone
is the formatted number from getNumber()
but the base input's value
is the raw value. Similar concept with a currency field: https://dm4t2.github.io/vue-currency-input/playground.html
If you're looking for a start, this is what I've used in the past (although it'll need to be converted to TypeScript):
Noice Matt!
Will we be reaching Monday before we have a Vue 3 component?
Letβs share this in Vue communities!
Thanks for this initial code @mdpoulter! I've literally just copied this into the project here: vue/src/intl-tel-input/IntlTelInput.vue and attempted to hook it up a bit, so you should (untested) now be able to do:
import IntlTelInput from "intl-tel-input/vue";
or
import IntlTelInput from "intl-tel-input/vueWithUtils";
That's released in ~v24.1.0~ v24.3.3
Or alternatively, you can fork the project, and run npm run vue:demo
to see a simple demo of it up and running. It seems to intialise the plugin without any errors! I don't know enough about Vue to hook up the validation button - is that something you could help with? (I was imagining it would work similarly to the react validation demo here: react/demo/validation/validation.html)
Oops, I didn't update package.json, so probably those imports didn't work. That should now be fixed in v24.3.3.
Do give it a try and let me know how it goes!
And any thoughts on how to hook up the validation demo app would be appreciated!
Early stage Vue Component readme here: https://github.com/jackocnr/intl-tel-input/blob/master/vue/README.md
@Lrochefort @mdpoulter @carlssonemil have you managed to try using the new Vue component at all yet?
@jackocnr, not yet! We use our own wrapper Vue component at work but I'm very interested in switching to the provided one if it fits our needs. Just haven't had the time yet but will I'll let you know when I do try it out! π
ππ»
We use our own wrapper Vue component
I'd be interested to hear if there are any significant differences to our one.
@jackocnr it works like a charm, sweet! The only thing we're missing is the ability to pass attributes to the <input>
element, like id
, required
, disabled
, etc. Either as an option (inputAttributes
) or as individual props, though there might be a couple that is needed so I'm not entirely sure what the best option is. I'll gladly fix it and open a PR if we decide on the best course of action that works for everyone.
I've temporarily created a method that adds these manually whenever they are needed as a workaround for now.
I'll see if I can find the time to look into fixing the validation demo!
it works like a charm, sweet!
Wahoo! Excellent news π (this is all thanks to @mdpoulter)
The only thing we're missing is the ability to pass attributes to the element [...] though there might be a couple that is needed
Yes I think easier to just support passing an object called inputProps
(like we do for the react component), as there would be so many if we wanted to support all the possible properties individually.
I'll gladly fix it and open a PR
Amazing ππ»
I'll see if I can find the time to look into fixing the validation demo!
That would be really appreciated! It should be fairly straight forward if you know Vue.
Thanks again for your work on this @carlssonemil ππ»
I think we can close this issue now π
Not that I am jealous and stuff but... A nice Vue 3 component should be the next thing after the React one, since Vue.js IS the next thing after (the decline of) React...