A Modern Country Code Picker for Jetpack Compose
In various apps, we need to use a country code picker. There are several libraries available for this purpose. In XML we have a CCP created by hbb20, which is great. In Jetpack Compose there are few libraries but they lack some features and updates. So, I created this library to use in Jetpack Compose.
CountryCodePickerCompose is a modern, Material 3 compliant country code picker library built specifically for Jetpack Compose. It provides a beautiful, highly customizable solution for selecting country codes with phone number validation and formatting capabilities.
The library is designed to be production-ready with comprehensive testing (38 unit tests), proper ProGuard rules, and full Material You design system compliance. It supports 19 languages for country names with automatic detection based on device locale.
Add this to your settings.gradle.kts file:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("https://jitpack.io")
}
}
}
Add this to your module's build.gradle.kts file:
dependencies {
implementation("com.github.ahmmedrejowan:CountryCodePickerCompose:0.2")
}
// In your gradle/libs.versions.toml or build.gradle.kts
kotlin = "2.1.0"
composeBom = "2024.12.01"
// In your build.gradle.kts (Project level)
plugins {
id("org.jetbrains.kotlin.plugin.compose") version "2.1.0" apply false
}
// In your build.gradle.kts (Module level)
plugins {
id("org.jetbrains.kotlin.plugin.compose")
}
var selectedCountry by remember { mutableStateOf(Country.UnitedStates) }
CountryCodePicker(
selectedCountry = selectedCountry,
onCountrySelected = { selectedCountry = it },
modifier = Modifier.fillMaxWidth()
)
CountryCodePicker(
selectedCountry = selectedCountry,
onCountrySelected = { selectedCountry = it },
viewCustomization = ViewCustomization(
showFlag = true,
showCountryIso = false,
showCountryName = false,
showCountryCode = true,
showArrow = true
),
showSheet = true
)
var phoneNumber by remember { mutableStateOf("") }
var selectedCountry by remember { mutableStateOf(Country.UnitedStates) }
CountryCodePickerTextField(
number = phoneNumber,
onValueChange = { country, number, isValid ->
selectedCountry = country
phoneNumber = number
},
selectedCountry = selectedCountry,
modifier = Modifier.fillMaxWidth(),
label = { Text("Phone Number") },
showError = true,
showSheet = true
)
var isDialogOpen by remember { mutableStateOf(false) }
if (isDialogOpen) {
CountryPickerDialog(
onDismissRequest = { isDialogOpen = false },
onItemClicked = { country ->
selectedCountry = country
isDialogOpen = false
},
selectedCountry = selectedCountry
)
}
LaunchedEffect(Unit) {
CCPUtils.getCountryAutomatically(LocalContext.current)?.let {
selectedCountry = it
}
}
val validator = remember { CCPValidator(LocalContext.current) }
var isValid by remember { mutableStateOf(false) }
OutlinedTextField(
value = phoneNumber,
onValueChange = { newNumber ->
phoneNumber = newNumber
isValid = validator(number = newNumber, countryCode = selectedCountry.countryCode)
},
isError = phoneNumber.isNotEmpty() && !isValid
)
OutlinedTextField(
value = phoneNumber,
onValueChange = { phoneNumber = it },
visualTransformation = CCPTransformer(
context = LocalContext.current,
countryIso = selectedCountry.countryIso
),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone)
)
// ViewCustomization
ViewCustomization(
showFlag = true,
showCountryIso = false,
showCountryName = false,
showCountryCode = true,
showArrow = true
)
// PickerCustomization
PickerCustomization(
showCountryCode = true,
showFlag = true,
showSearchClearIcon = true
)
Major Improvements:
Migration from 0.1.x:
Initial Release:
API 24