PHPackages                             lianmaymesi/livewire-phone - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. lianmaymesi/livewire-phone

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

lianmaymesi/livewire-phone
==========================

Phone input package for Laravel and Livewire applications.

v1.2.0(1mo ago)04MITPHPPHP ^8.2

Since Mar 17Pushed 1mo agoCompare

[ Source](https://github.com/lianmaymesi/livewire-phone)[ Packagist](https://packagist.org/packages/lianmaymesi/livewire-phone)[ Docs](https://github.com/lianmaymesi/livewire-phone)[ RSS](/packages/lianmaymesi-livewire-phone/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (18)Versions (6)Used By (0)

Livewire Phone
==============

[](#livewire-phone)

`lianmaymesi/livewire-phone` is a Laravel and Livewire-oriented phone input package built on top of `intl-tel-input`.

Goals
-----

[](#goals)

This package is meant to be a Flux-friendly, Livewire-first Laravel wrapper around the full `intl-tel-input` feature set, while also exposing Laravel validation and package publishing ergonomics.

Install flow
------------

[](#install-flow)

```
composer require lianmaymesi/livewire-phone
php artisan livewire-phone:install
```

The install command:

- publishes package config and translations
- publishes Vite source assets into `resources/vendor/livewire-phone`
- runs `npm install intl-tel-input`
- adds the package Vite entries to `vite.config.js`

The generated Vite entry files are:

- `resources/vendor/livewire-phone/livewire-phone.js`
- `resources/vendor/livewire-phone/livewire-phone.css`

Your custom overrides load after the package base files:

- `resources/vendor/livewire-phone/phone.custom.js`
- `resources/vendor/livewire-phone/phone.custom.css`

The component injects its CSS and JavaScript automatically with Livewire / Blaze `@assets`, so you do not need to place manual `` or `` tags in your page when using the component.

Source vs dist
--------------

[](#source-vs-dist)

The package keeps its editable frontend source in:

- `resources/stubs/vite/phone.js`
- `resources/stubs/vite/phone.css`

These files stay readable and are intended for maintenance.

The minified files used by `asset_driver = "public"` are generated into:

- `resources/dist/livewire-phone.js`
- `resources/dist/livewire-phone.css`

To rebuild the distributed assets from source:

```
npm install
npm run build:dist
```

The CSS build is PostCSS-based and Tailwind-ready, so you can introduce `@apply`later without changing the dist workflow.

Feature coverage
----------------

[](#feature-coverage)

FeatureStatusNotesAuto-select user's current country via IP lookupSupportedEnable `geoip.enabled` and provide `geoip.endpoint` in config.Example placeholder for selected countrySupportedDriven by upstream `autoPlaceholder`.Type-ahead and keyboard dropdown navigationSupportedProvided by `intl-tel-input` with `countrySearch`.Format as user typesSupportedEnabled by default and configurable.Numeric-only input and max valid length capSupportedEnforced by package JS and upstream `strictMode`.National input converted to international standard numberSupportedPackage syncs formatted output and metadata.Validation with specific error typesSupportedLaravel rule plus hidden metadata inputs/events for client-side error codes.High-resolution flag imagesSupportedBundled through the npm package and Vite asset pipeline.Accessibility via ARIASupportedUpstream behavior preserved; package adds error `aria-describedby`.TypeScript type definitionsPlannedBest shipped through a companion npm package, not the PHP package alone.CSS variable overrides and dark mode stylingSupportedFlux-compatible CSS and override-friendly selectors included.React, Vue, Angular, and Svelte componentsPlannedThese belong in companion JS packages/adapters.40+ translations, RTL, alternative numeralsPartially supportedUpstream supports this; Laravel translations are included now, deeper JS i18n is a next phase.Rich init options, methods, eventsSupportedComponent passes init options and emits `livewire-phone:change`.Current package foundation
--------------------------

[](#current-package-foundation)

- Blade component for Livewire forms: ``
- Package-managed frontend assets
- Single-property payload submission for both plain forms and Livewire
- Laravel validation rule: `new \Lianmaymesi\LivewirePhone\Rules\PhoneNumber()`
- Optional Eloquent casts for normalized string and object storage
- Validator extension: `phone_number`
- Publishable config, language files, and public assets
- Multi-language-ready translation structure
- Flux-compatible field rendering and styles
- Optional geo-IP country lookup
- Client event: `livewire-phone:change`

Example usage
-------------

[](#example-usage)

```

```

```
use Lianmaymesi\LivewirePhone\Rules\PhoneNumber;

Validator::make($data, [
    'phone' => ['required', new PhoneNumber('IN', ['IN'])],
]);
```

Flux usage
----------

[](#flux-usage)

When Flux is installed, the component renders through `flux:with-field` so it behaves like the rest of your Flux and Flux Pro form fields.

Typical Flux usage:

```

```

Supported field-style props:

- `label` shows the Flux field label
- `invalid` forces the error state
- `variant="borderless"` uses the borderless input treatment
- `placeholder` overrides the automatic example placeholder
- `disabled`, `required`, `autofocus`, and `autocomplete` are forwarded to the input

If Flux is not installed, the component falls back to the package field wrapper and still works the same way.

Format and output modes
-----------------------

[](#format-and-output-modes)

Use the `format` prop to control both the displayed phone format and the value pushed back into Livewire or submitted through a normal form. `format` is preferred over `value` so it does not clash with the native HTML `value` attribute.

String output modes:

- `format="e164"` returns one normalized string such as `+14155552671`
- `format="national"` returns one normalized string with the national digits only
- `format="significant"` returns one normalized string with the local mobile digits only
- `format="string:e164"`, `format="string:national"`, and `format="string:significant"` are explicit aliases for string output

Object output modes:

- `format="object"` returns one JSON string object and defaults `number` to `e164`
- `format="object:e164"` returns the object with `number` as normalized international format
- `format="object:national"` returns the object with `number` as normalized national digits
- `format="object:significant"` returns the object with `number` as normalized local digits

For backward compatibility, `value` is still accepted as a fallback alias.

The package submits only one field for the phone value. It does not create extra `phone_country`, `phone_valid`, `phone_error`, or `phone_type` form properties.

If you do not pass a custom `placeholder`, the component updates the example placeholder based on the selected `format`:

- `e164` shows an international-style example
- `national` shows a national example
- `significant` shows the core local mobile number example

Example object payload:

```
{
  "number": "+919944712499",
  "phone_number": "9944712499",
  "dial_code": "+91",
  "country_code": "IN"
}
```

This object format is designed to stay under one property while still giving you the normalized pieces you usually want to store:

- `number` is the normalized value for the selected mode
- `phone_number` is always the plain local number without spaces or special characters
- `dial_code` is the country calling code such as `+91`
- `country_code` is the ISO country code such as `IN`

The server-side normalizer also accepts mixed existing values such as:

- `+91 99447 12499`
- `99447-12499`
- `{"number":"+919944712499","country_code":"IN"}`
- `{"phone_number":"9944712499","dial_code":"+91"}`

So you can store or hydrate values whether the input came with spaces, punctuation, `IN`, or `+91`.

Single-property behavior
------------------------

[](#single-property-behavior)

String mode example:

```

```

Submitted value:

```
'phone' => '9944712499'
```

Object mode example:

```

```

Submitted value:

```
'phone' => '{"number":"+919944712499","phone_number":"9944712499","dial_code":"+91","country_code":"IN"}'
```

Casting helpers
---------------

[](#casting-helpers)

If you want the same normalization on save and retrieve in Eloquent, the package provides two casts:

- `Lianmaymesi\LivewirePhone\Casts\AsPhoneString`
- `Lianmaymesi\LivewirePhone\Casts\AsPhoneObject`

Example:

```
use Lianmaymesi\LivewirePhone\Casts\AsPhoneObject;
use Lianmaymesi\LivewirePhone\Casts\AsPhoneString;

protected function casts(): array
{
    return [
        'phone' => AsPhoneString::class . ':significant,IN',
        'phone_meta' => AsPhoneObject::class . ':e164,IN',
    ];
}
```

This lets the model accept values like `99447 12499`, `+91 99447 12499`, or a JSON object payload and keep them normalized consistently.

Common prop reference
---------------------

[](#common-prop-reference)

The main component props are:

- `initial-country="us"` sets the default selected country
- `country-order="us,ca,mx"` controls dropdown ordering
- `only-countries="us,ca,mx"` restricts the selectable countries
- `format="e164|national|significant|object[:...]"` controls the output shape
- `:geo-ip-lookup="true"` enables country auto-detection when configured
- `:options="[]"` overrides plugin options directly

Common plugin-related props:

- `allow-dropdown`
- `country-search`
- `fix-dropdown-width`
- `format-as-you-type`
- `format-on-display`
- `show-flags`
- `strict-mode`
- `use-fullscreen-popup`
- `national-mode`
- `separate-dial-code`
- `allow-phonewords`
- `allow-number-extensions`

Single vs multiple countries
----------------------------

[](#single-vs-multiple-countries)

The `only-countries` and `country-order` props accept either:

- a single ISO2 country code string
- a comma-separated string of ISO2 country codes
- a PHP array of ISO2 country codes

Use a single value when the field should stay locked to one country:

```

```

You can also pass the single country as an array:

```

```

For multiple allowed countries, pass an array:

```

```

If your Livewire or controller data starts as objects, map them to ISO2 strings before passing them in:

```
$onlyCountries = collect($countries)
    ->pluck('iso2')
    ->map(fn ($country) => strtolower($country))
    ->values()
    ->all();
```

```

```

The component expects country codes like `us`, `in`, `gb`, not full country objects.

Validator extension
-------------------

[](#validator-extension)

```
'phone' => ['required', 'phone_number:IN,IN']
```

The first parameter is the default parse region. The remaining parameters restrict allowed regions.

Config highlights
-----------------

[](#config-highlights)

```
return [
    'initial_country' => 'auto',
    'default_value' => 'e164',
    'options' => [
        'format_as_you_type' => true,
        'strict_mode' => true,
        'country_search' => true,
        'auto_placeholder' => 'polite',
    ],
    'geoip' => [
        'enabled' => true,
        'endpoint' => 'https://ipapi.co/json',
        'country_key' => 'country_code',
    ],
];
```

Runtime metadata
----------------

[](#runtime-metadata)

It also dispatches a browser event:

```
window.addEventListener("livewire-phone:change", (event) => {
    console.log(event.detail);
});
```

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance89

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

5

Last Release

55d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/584db91c2a3c82edc4b1a0a98e62dbd52191af28df7427e4b39a71523edf1b02?d=identicon)[lianmay.mesi](/maintainers/lianmay.mesi)

---

Top Contributors

[![lianmaymesi](https://avatars.githubusercontent.com/u/42940836?v=4)](https://github.com/lianmaymesi "lianmaymesi (7 commits)")

---

Tags

intl-tel-inputlivewirelivewire-phonelaravellianmaymesilivewire-phone

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/lianmaymesi-livewire-phone/health.svg)

```
[![Health](https://phpackages.com/badges/lianmaymesi-livewire-phone/health.svg)](https://phpackages.com/packages/lianmaymesi-livewire-phone)
```

###  Alternatives

[akaunting/laravel-money

Currency formatting and conversion package for Laravel

7825.3M18](/packages/akaunting-laravel-money)[spatie/laravel-livewire-wizard

Build wizards using Livewire

4061.0M4](/packages/spatie-laravel-livewire-wizard)[leandrocfe/filament-apex-charts

Apex Charts integration for Filament PHP.

4861.2M8](/packages/leandrocfe-filament-apex-charts)[tonysm/importmap-laravel

Use ESM with importmap to manage modern JavaScript in Laravel without transpiling or bundling.

148399.8k1](/packages/tonysm-importmap-laravel)[ralphjsmit/livewire-urls

Get the previous and current url in Livewire.

82270.3k4](/packages/ralphjsmit-livewire-urls)[dragon-code/pretty-routes

Pretty Routes for Laravel

10058.7k4](/packages/dragon-code-pretty-routes)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
