Skip to content

Commit

Permalink
Feat/accept initial country code and phone number (#26)
Browse files Browse the repository at this point in the history
* feat/ evaluate country data from a country dialing phone code

* feat/ allow client code to pass initial data for input fields

Fix #25

* feat/ make initial country the default country

* doc/ Document initial data customization for library users
  • Loading branch information
itstanany authored Sep 28, 2023
1 parent efe2a50 commit 32c6e10
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 20 deletions.
32 changes: 18 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,24 @@ See [MainActivity in the sample app](https://github.com/jump-sdk/jetpack_compose
```


| Parameter | Description |
|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| onValueChange | Called when the text in the text field changes. The first parameter is string pair of (country code, phone number) and the second parameter is a boolean indicating whether the phone number is valid. |
| modifier | Modifier to be applied to the inner OutlinedTextField. |
| enabled | Boolean indicating whether the field is enabled. |
| shape | Shape of the text field. |
| showCountryCode | Whether to show the country code in the text field. |
| showCountryFlag | Whether to show the country flag in the text field. |
| colors | Colors to be used for the text field. |
| fallbackCountryCode | The country to be used as a fallback if the user's country cannot be determined. |
| showPlaceholder | Whether to show the placeholder number in the text field. |
| includeOnly | A set of 2 digit country codes to be included in the list of countries. Set to null to include all supported countries. |
| clearIcon | The icon to be used for the clear button. Set to null to disable the clear button. |
| label | An optional composable to be used as a label for input field. |
| Parameter | Description |
|--------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| onValueChange | Called when the text in the text field changes. The first parameter is string pair of (country code, phone number) and the second parameter is a boolean indicating whether the phone number is valid. |
| modifier | Modifier to be applied to the inner OutlinedTextField. |
| enabled | Boolean indicating whether the field is enabled. |
| shape | Shape of the text field. |
| showCountryCode | Whether to show the country code in the text field. |
| showCountryFlag | Whether to show the country flag in the text field. |
| colors | Colors to be used for the text field. |
| fallbackCountryCode | The country to be used as a fallback if the user's country cannot be determined. |
| showPlaceholder | Whether to show the placeholder number in the text field. |
| includeOnly | A set of 2 digit country codes to be included in the list of countries. Set to null to include all supported countries. |
| clearIcon | The icon to be used for the clear button. Set to null to disable the clear button. |
| initialPhoneNumber | An optional phone number to be initial value of the input field. |
| initialCountryCode | An optional ISO-3166-1 alpha-2 country code equivalent of the MCC (Mobile Country Code) of the initially selected country. |
| initialCountryPhoneCode | An optional Phone calling code of initially selected country.
| label | An optional composable to be used as a label for input field. |



## How to add in your project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import com.togitech.ccp.R
import com.togitech.ccp.data.CountryData
import com.togitech.ccp.data.utils.ValidatePhoneNumber
import com.togitech.ccp.data.utils.countryDataMap
import com.togitech.ccp.data.utils.countryDataMapPhoneCode
import com.togitech.ccp.data.utils.getDefaultCountryAndPhoneCode
import com.togitech.ccp.data.utils.numberHint
import com.togitech.ccp.data.utils.unitedStates
Expand All @@ -70,7 +71,12 @@ private val DEFAULT_TEXT_FIELD_SHAPE = RoundedCornerShape(24.dp)
* @param includeOnly A set of 2 digit country codes to be included in the list of countries.
* Set to null to include all supported countries.
* @param clearIcon The icon to be used for the clear button. Set to null to disable the clear button.
* @param initialPhoneNumber an optional phone number to be initial value of the input field
* @param initialCountryCode an optional ISO-3166-1 alpha-2 country code equivalent of the MCC (Mobile Country Code)
* of the initially selected country.
* @param initialCountryPhoneCode an optional Phone calling code of initially selected country
* @param label An optional composable to be used as a label for input field
*/
@OptIn(ExperimentalComposeUiApi::class)
@Suppress("LongMethod")
Expand All @@ -87,20 +93,29 @@ fun TogiCountryCodePicker(
showPlaceholder: Boolean = true,
includeOnly: ImmutableSet<String>? = null,
clearIcon: ImageVector? = Icons.Filled.Clear,
initialPhoneNumber: String? = null,
initialCountryCode: String? = null,
initialCountryPhoneCode: String? = null,
label:
@Composable()
(() -> Unit)? = null,
) {
val context = LocalContext.current
val focusRequester = remember { FocusRequester() }

var phoneNumber by rememberSaveable { mutableStateOf("") }
var phoneNumber by rememberSaveable(initialPhoneNumber) { mutableStateOf(initialPhoneNumber.orEmpty()) }
val keyboardController = LocalSoftwareKeyboardController.current
val fallbackCountry = countryDataMap[fallbackCountryCode] ?: unitedStates
var langAndCode by rememberSaveable {
mutableStateOf(getDefaultCountryAndPhoneCode(context, fallbackCountry))
val fallbackCountry = countryDataMap[fallbackCountryCode]
?: unitedStates
val initialCountry: CountryData? = countryDataMapPhoneCode[initialCountryPhoneCode]
?: countryDataMap[initialCountryCode]
var langAndCode by rememberSaveable(
context,
fallbackCountry,
initialCountry,
) {
mutableStateOf(getDefaultCountryAndPhoneCode(context, fallbackCountry, initialCountry))
}
var isNumberValid: Boolean by rememberSaveable { mutableStateOf(false) }

val phoneNumberTransformation = remember(langAndCode) {
PhoneNumberTransformation(
countryDataMap.getOrDefault(langAndCode.first, fallbackCountry).countryCode.uppercase(),
Expand All @@ -109,6 +124,14 @@ fun TogiCountryCodePicker(
}
val validatePhoneNumber = remember(context) { ValidatePhoneNumber(context) }

var isNumberValid: Boolean by rememberSaveable(langAndCode.second, phoneNumber) {
mutableStateOf(
validatePhoneNumber(
fullPhoneNumber = langAndCode.second + phoneNumber,
),
)
}

OutlinedTextField(
value = phoneNumber,
onValueChange = { enteredPhoneNumber ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,9 @@ internal val getLibCountries: List<CountryData> = listOf(

internal val countryDataMap: Map<String, CountryData> =
getLibCountries.associateBy { it.countryCode }

/**
* Retrieve Country Data using country phone code.
*/
internal val countryDataMapPhoneCode: Map<String, CountryData> =
getLibCountries.associateBy { it.countryPhoneCode }
7 changes: 7 additions & 0 deletions ccp/src/main/java/com/togitech/ccp/data/utils/TogiUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ private fun getDefaultLangCode(context: Context): String {
internal fun getDefaultCountryAndPhoneCode(
context: Context,
fallbackCountryData: CountryData,
initialCountryData: CountryData?,
): Pair<String, String> {
// return initial country data if passed
if (initialCountryData != null) {
val initialCountryCode = initialCountryData.countryCode
val initialCountryPhoneCode = initialCountryData.countryPhoneCode
return initialCountryCode to initialCountryPhoneCode
}
val defaultCountry = getDefaultLangCode(context)
val defaultCode: CountryData? = getLibCountries.firstOrNull { it.countryCode == defaultCountry }
return defaultCountry to (
Expand Down

0 comments on commit 32c6e10

Please sign in to comment.