Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Livewire Phone Input Laravel Package

turbo-php/livewire-phone-input

A Livewire phone input component for Laravel that adds country code selection, phone number formatting, and validation to forms. It simplifies collecting international phone numbers in Livewire apps with a reusable, user-friendly field that integrates cleanly with your existing validation rules.

View on GitHub
Deep Wiki
Context7

Getting Started

The package gives you a Livewire component for phone number entry that you style entirely through a classes array rather than by editing markup. Start here:

  1. Install and (optionally) publish:
    composer require turbophp/livewire-phone-input
    php artisan vendor:publish --tag=phone-input-config   # only if you need to override
    
  2. Look first at config/phone-input.php. That file — specifically its classes key — is the package's public styling API. There is a key per structural part (wrapper, input, country selector/dropdown, dial code, validation message, etc.), and each part typically accepts state variants such as default, focus, error, valid.
  3. Drop the component into a form:
    <livewire:phone-input wire:model="phone" />
    
    and validate the resulting value in your Livewire component as a normal string.
  4. First real use case: replace a plain <input type="tel"> with this component, then map your existing utility classes into the classes array so the widget matches the rest of your design system without touching package views.

Implementation Patterns

Style through config, not views. Treat classes as the contract. Editing the published Blade view works but forks the package and puts you on the hook for every upstream markup change. Reserve view publishing for structural changes (adding a wrapper, injecting an icon slot) and express everything visual in config.

Per-part, per-state mapping. A common shape:

'classes' => [
    'wrapper' => 'relative',
    'input' => [
        'base'    => 'w-full rounded-md border px-3 py-2',
        'focus'   => '!border-indigo-500 !ring-2',
        'error'   => '!border-red-500',
    ],
    'dropdown' => ['base' => 'absolute z-50 mt-1 w-full rounded-md bg-white shadow-lg'],
],

Build one shared config fragment (or a small helper returning the array) if multiple forms need consistent styling, and keep the state keys identical across parts so a global restyle is a single edit.

Wire it into validation. Let Livewire's rules() handle the phone string and drive the error variant off $errors — you get server-side validation messaging for free rather than duplicating rules in JS.

Tailwind integration. Because classes live in config/, Tailwind's default content scan will not see them. In Tailwind v4 add the config directory as a source in your CSS entry point:

@import "tailwindcss";
@source "../../config/phone-input.php";

In Tailwind v3, add the path to content in tailwind.config.js. Do this before you spend time debugging why half your classes are missing from the compiled stylesheet.

State collisions need !. If a variant sets the same CSS property as the part's base class (e.g. base sets border-gray-300 and focus sets border-indigo-500), the two classes are equally specific. The winner is decided by emit order in the generated CSS, not the order of keys in your array — a class you wrote "later" can still lose. Prefix conflicting utilities in variants with ! (!border-indigo-500) so the variant deterministically wins. Do this proactively for any variant overriding border-*, ring-*, bg-*, or text-* set on the base.

Progressive rollout. Ship the component behind a feature flag or on one form first; the failure mode of a misconfigured classes array is a visually broken widget, not an exception, so a visual diff against the old input catches more than tests will.

Gotchas and Tips

Tailwind will silently drop config classes. config/ is outside the default scan paths, so classes values get purged and the widget renders unstyled or partially styled with no warning. Fix with @source (v4) or the content array (v3). This is the single most likely first-day bug.

Same-property variants tie and resolve by CSS order. Base and variant utilities have equal specificity; the emitted order decides. Symptom: a focus or error style "works sometimes" or applies only on some properties. Remedy: mark the variant important (!), or restructure the base so it doesn't set the property the variant needs to change.

Publishing pins the config forever. A published config/phone-input.php is your file — new keys added by later releases will not appear, so upgraded features can silently do nothing or fall back to hardcoded defaults. Prefer leaving the config unpublished and overriding only what you need (e.g. via a service provider merge or a thin wrapper). If you must publish, do a diff against the vendor config, or vendor:publish --force into version control, on every upgrade. Same applies to the published view.

Docs-only releases still change behavior for you. v1.0.1 shipped no code, but the traps above are real consumer-side behavior. Don't skip the changelog on patch bumps for this package — the notes are the release's substance.

Debugging checklist for styling issues, in order: (1) is the class present in the DOM at all? If no → config key name wrong or component cached. (2) Is it in the compiled CSS? If no → Tailwind scan path. (3) Is it in the DOM and in the CSS but not winning? → specificity/emit-order tie, add !. (4) Clear view:clear and any Livewire asset cache after config edits.

Extension points. classes for styling, published views for structure, published config for behavior defaults, and the component's public properties (value, name, wire:model binding) for integration. Reach for a wrapper Blade component that renders <livewire:phone-input> when you need app-specific defaults without publishing anything — that keeps the package's config upstream and keeps your customizations in one auditable place.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
encore2/laravel-admin2
cboxdk/laravel-console-kit
shapecode/doctrine-dbal-datetimeutc
gilads-otiannoh254/inertia-protocol
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite
faghy/laracashbook
roundly-consulting/google-places-for-laravel
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
adachsoft/cli-process-tester
adachsoft/changelog-linter
adachsoft/collection
adachsoft/php-code-style
adachsoft/api-version-bundle
cgv/localized-resource