VxInputPhone
Input de telefone internacional com selector de país (bandeira + DDI) e validação via libphonenumber-js. Layout horizontal: selector de país (largura fixa ~120px) + campo numérico (flex-1). Baseado na biblioteca MazPhoneNumberInput customizada para o design Pedbot.
Com Label (padrão de formulário)
Variante dominante no codebase. Sempre usa label + :preferredCountries="['BR']" + @update="setInternational" + :reload sincronizado com o estado de abertura do componente pai (sidebar/popup).
<vx-input-phone
label="Número de Telefone"
class="mt-5 w-full"
name="telefone"
v-model="customer.phone_number"
:reload="isActive"
:preferredCountries="['BR']"
@update="setInternational"
v-validate="'required'"
/>
<span class="text-danger text-sm" v-show="errors.has('telefone')">
{{ errors.first('telefone') }}
</span>
Com Condição v-if
Exibido apenas para clientes sem messenger_id ou instagram_id (apenas WhatsApp). :reload sincronizado com o estado do sidebar para resetar o campo ao reabrir.
<vx-input-phone
label="Número de Telefone"
class="mt-5 w-full"
name="telefone"
v-if="!customer.messenger_id && !customer.instagram_id"
v-model="customer.phone_number"
:reload="isSidebarActiveLocal"
/>
Sem Bandeiras
Modo inline — exibido via v-else substituindo texto mascarado. :noFlags="true" remove bandeiras, :noUseBrowserLocale="true" evita detecção automática de país pelo browser.
<vx-input-phone
v-else
class="w-full"
:noFlags="true"
:noUseBrowserLocale="true"
:preferredCountries="['BR']"
v-model="customerData.phone_number"
:reload="activeLocal"
@update="setInternational"
v-validate="'required'"
/>
Sem Seletor de País
Exibe apenas o InputTel — CountrySelector oculto. Útil quando o país já é conhecido e não deve ser alterado pelo usuário.
<!-- Exemplo sintético — sem uso real encontrado no admin -->
<vx-input-phone
label="Número de Telefone"
v-model="phone"
:noCountrySelector="true"
:defaultCountryCode="'BR'"
/>
Dropdown de Países (estado aberto)
Ao clicar no CountrySelector, abre dropdown com lista de países, campo de busca e destaque dos preferredCountries no topo. Emite @onOpen e @onClose.
@update — emitido a cada mudança no número:
"countryCode": "BR",
"isValid": true,
"phoneNumber": "(11) 99876-5432",
"countryCallingCode": "55",
"e164": "+5511998765432",
"nationalNumber": "11998765432",
"formatInternational": "+55 11 99876-5432",
"type": "MOBILE"
}
Estados
Todos os estados visuais controlados automaticamente por libphonenumber-js (valid, error) ou por props (:error, :disabled).
Default
Focused (.is-focused)
Valid (.is-valid)
Error (.has-error)
Disabled (.is-disabled)
Dark (:dark="true")
API
<!-- Exemplo com principais props -->
<!-- v-model: número digitado; @update: objeto completo do libphonenumber-js
:reload — sincroniza reset com abertura de modal/sidebar -->
<vx-input-phone
label="Número de Telefone"
v-model="customer.phone_number"
:reload="isModalActive"
:preferredCountries="['BR']"
:defaultCountryCode="'BR'"
:noUseBrowserLocale="true"
:noValidatorState="false"
@update="setInternational"
v-validate="'required'"
/>
Props principais
| Nome | Tipo | Default | Descrição |
|---|---|---|---|
value | String | — | v-model — número digitado (sem DDI). Emite via @input. |
defaultCountryCode | String | — | Código ISO do país inicial. Ex: 'BR'. Auto-detectado pelo browser se omitido. |
label | String | — | Label acima do campo. |
disabled | Boolean | false | Desabilita CountrySelector e InputTel. |
error | Boolean | false | Estado de erro manual — borda errorColor. |
required | Boolean | false | Marca o campo como obrigatório. |
size | String | — | 'sm' (110px) | 'lg' (130px). Afeta largura do CountrySelector. |
noValidatorState | Boolean | false | Quando true, não exibe indicadores visuais de válido/inválido. |
noFlags | Boolean | false | Oculta bandeiras no CountrySelector. |
noCountrySelector | Boolean | false | Oculta o CountrySelector — apenas InputTel visível. |
noExample | Boolean | false | Oculta placeholder de exemplo do número. |
preferredCountries | Array | — | Países no topo da lista. Ex: ['BR', 'US']. |
onlyCountries | Array | — | Whitelist de países exibidos. |
ignoredCountries | Array | [] | Blacklist de países. |
color | String | 'dodgerblue' | Cor de foco/ativo. Atenção: default não é primary — substituir manualmente. |
validColor | String | 'primary' | Cor quando número é válido. |
errorColor | String | 'danger' | Cor quando há erro. |
dark | Boolean | false | Dark mode interno (independente do dark global). |
darkColor | String | '#424242' | Cor de fundo no dark mode. |
noUseBrowserLocale | Boolean | false | Quando true, não detecta país pelo navigator.language. |
reload | Boolean | false | Toggle false→true reseta os valores do campo. Sincronizar com abertura do modal/sidebar. |
borderRadius | Number | 4 | Border radius dos campos em px. |
countriesHeight | Number | 30 | Altura de cada item da lista em px. |
Slots
| Nome | Descrição |
|---|---|
arrow | Ícone customizado para o toggle do CountrySelector. Default é um SVG de seta para baixo. |
Eventos
| Evento | Payload | Descrição |
|---|---|---|
@input | String | v-model. Número formatado AsYouType enquanto digita. |
@update |
Object | Resultado completo do libphonenumber-js: { countryCode, isValid, phoneNumber, countryCallingCode, formattedNumber, nationalNumber, type, formatInternational, formatNational, uri, e164 }. Capturar isValid e e164 para salvar no backend. |
@onOpen | — | Dropdown de países aberto. |
@onClose | — | Dropdown de países fechado. |
@phone-number-focused | — | Campo de número recebeu foco. |
@phone-number-blur | — | Campo de número perdeu foco. |
Dependências
libphonenumber-js — parsePhoneNumberFromString, AsYouType
assets/js/phoneCodeCountries.js, assets/locales/
CountrySelector (dropdown com flags), InputTel (input numérico)
Onde é usado
A prop color tem default 'dodgerblue', não 'primary'. Nos 6 usos do codebase essa prop nunca foi sobrescrita — o design system usa azul primário (#0491FF), mas o foco dos campos mostra azul dodger browser. Para corrigir: :color="'primary'".