Shadcn Phone Input Svelte

An implementation of a Phone Input component built on top of Shadcn UI's input component.

Setup

Install shadcn-svelte via CLI

Run the shadcn-svelte init command to setup your project:

npx shadcn-svelte@next init

Install necessary components

Run the shadcn-svelte add command to add the necessary components to your project:

npx shadcn-svelte@next add button
npx shadcn-svelte@next add command
npx shadcn-svelte@next add popover
npx shadcn-svelte@next add scroll-area

Add Component

Automatic

npx jsrepo add github/ieedan/shadcn-phone-input-svelte/ui/phone-input

or

Manual

Install Svelte Tel Input

npm install svelte-tel-input@latest

Copy the code

You can find the code here. Or copy it below.

`src/lib/components/ui/phone-input`
<script lang="ts">
	import CountrySelector from './country-selector.svelte';
	import { defaultOptions, type Props } from '.';
	import { cn } from '$lib/utils';
	import { TelInput, normalizedCountries } from 'svelte-tel-input';
	import 'svelte-tel-input/styles/flags.css';

	const countries = normalizedCountries;

	let {
		class: className = undefined,
		defaultCountry = null,
		country = $bindable(defaultCountry),
		options = defaultOptions,
		placeholder = $bindable(undefined),
		readonly = $bindable(false),
		disabled = $bindable(false),
		value = $bindable(),
		valid = $bindable(false),
		detailedValue = $bindable(),
		order = undefined,
		name = undefined,
		...rest
	}: Props = $props();

	let el: HTMLInputElement | undefined = $state();

	export const focus = () => {
		// sort of an after update kinda thing
		setTimeout(() => {
			el?.focus();
		}, 0);
	};
</script>

<div class="flex place-items-center">
	<CountrySelector
		{order}
		{countries}
		bind:selected={country}
		on:select={focus}
	/>
	<TelInput
		{name}
		bind:country
		bind:detailedValue
		bind:value
		bind:valid
		bind:readonly
		bind:disabled
		bind:placeholder
		bind:el
		{options}
		required
		class={cn(
			'flex h-10 w-[212px] rounded-lg rounded-l-none border border-l-0 border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
			className
		)}
		{...rest}
	/>
</div>

Examples

Basic

Default Country

Default Value

Custom Ordering

Detailed Value

National: International: Country Code: Dial Code: