Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom text styles and dialog picker #18

Merged
merged 3 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ plugins {
}

android {
compileSdk 33
compileSdk 34
namespace 'com.canopas.campose.countypickerdemo'

defaultConfig {
applicationId "com.canopas.campose.countypickerdemo"
minSdk 21
targetSdk 33

versionCode 1
versionName "1.0"

Expand Down Expand Up @@ -52,17 +52,17 @@ android {

dependencies {
implementation project(":countrypicker")
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.core:core-ktx:1.13.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'com.google.android.material:material:1.11.0'

implementation platform("androidx.compose:compose-bom:$compose_bom_version")
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.material3:material3"
implementation "androidx.compose.ui:ui-tooling-preview"

implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
implementation 'androidx.activity:activity-compose:1.7.2'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
implementation 'androidx.activity:activity-compose:1.9.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ package com.canopas.campose.jetcountypicker
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
Expand All @@ -16,19 +23,20 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.canopas.campose.countrypicker.CountryPickerBottomSheet
import com.canopas.campose.countrypicker.CountryPickerView
import com.canopas.campose.countrypicker.CountryTextField
import com.canopas.campose.countrypicker.countryList
import com.canopas.campose.countrypicker.model.Country
import com.canopas.campose.countrypicker.model.PickerType
import com.canopas.campose.countypickerdemo.R
import com.canopas.campose.jetcountypicker.ui.theme.JetCountyPickerTheme

Expand All @@ -38,7 +46,9 @@ class MainActivity : ComponentActivity() {
setContent {
JetCountyPickerTheme {
Surface(color = MaterialTheme.colorScheme.background) {
SampleCountryPicker()
Column {
SampleCountryPickerDialog()
}
}
}
}
Expand All @@ -47,27 +57,66 @@ class MainActivity : ComponentActivity() {

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SampleCountryPicker() {
var openBottomSheet by rememberSaveable { mutableStateOf(false) }
fun SampleCountryPickerDialog() {
var showCountryPicker by rememberSaveable { mutableStateOf(false) }
var selectedCountry by remember { mutableStateOf<Country?>(null) }
var pickerType by remember {
mutableStateOf(PickerType.DIALOG)
}

Box {
CountryTextField(
label = stringResource(R.string.select_country_text),
modifier = Modifier
.fillMaxWidth()
.padding(top = 50.dp, start = 40.dp, end = 40.dp),
textStyle = MaterialTheme.typography.bodyMedium,
labelTextStyle = MaterialTheme.typography.labelMedium,
selectedCountry = selectedCountry,
defaultCountry = countryList(LocalContext.current).firstOrNull { it.code == "IN" },
onShowCountryPicker = {
openBottomSheet = true
}, isPickerVisible = openBottomSheet
showCountryPicker = true
}, isPickerVisible = showCountryPicker
)
}

if (openBottomSheet) {
CountryPickerBottomSheet(
bottomSheetTitle = {
Column(horizontalAlignment = Alignment.Start) {
Spacer(modifier = Modifier.height(28.dp))
Text(
text = stringResource(R.string.picker_type),
modifier = Modifier.padding(16.dp),
style = MaterialTheme.typography.bodyMedium
)
PickerType.entries.forEach {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(
onClick = {
pickerType = it
}
),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = pickerType == it,
onClick = {
pickerType = it
}
)
Text(
text = stringResource(it.value),
modifier = Modifier.padding(start = 8.dp),
style = MaterialTheme.typography.bodyMedium
)
}
}
}

if (showCountryPicker) {
CountryPickerView(
pickerTitle = {
Text(
modifier = Modifier
.fillMaxWidth()
Expand All @@ -78,12 +127,16 @@ fun SampleCountryPicker() {
fontSize = 20.sp
)
},
containerColor = Color.White,
searchFieldTextStyle = MaterialTheme.typography.bodyMedium,
placeholderTextStyle = MaterialTheme.typography.labelMedium,
countriesTextStyle = MaterialTheme.typography.bodyMedium,
onItemSelected = {
selectedCountry = it
openBottomSheet = false
}, onDismissRequest = {
openBottomSheet = false
showCountryPicker = false
},
pickerType = pickerType,
onDismissRequest = {
showCountryPicker = false
}
)
}
Expand All @@ -93,6 +146,6 @@ fun SampleCountryPicker() {
@Composable
fun DefaultPreview() {
JetCountyPickerTheme {
SampleCountryPicker()
SampleCountryPickerDialog()
}
}
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<resources>
<string name="app_name">JetCountyPicker</string>
<string name="select_country_text">Select country</string>
<string name="picker_type">Picker Type</string>
</resources>
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
compose_compiler_version = "1.5.0"
compose_bom_version = "2023.06.01"
compose_compiler_version = "1.5.12"
compose_bom_version = "2024.04.01"
}
}
plugins {
id 'com.android.application' version '8.1.0' apply false
id 'com.android.library' version '8.1.0' apply false
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
id 'com.android.application' version '8.3.2' apply false
id 'com.android.library' version '8.3.2' apply false
id 'org.jetbrains.kotlin.android' version '1.9.23' apply false
id 'io.github.gradle-nexus.publish-plugin' version "1.3.0"
}
apply from: "${rootDir}/scripts/publish-root.gradle"
Expand Down
7 changes: 3 additions & 4 deletions countrypicker/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ ext {
apply from: "${rootDir}/scripts/publish-module.gradle"

android {
compileSdk 33
compileSdk 34
namespace 'com.canopas.campose.countrypicker'

defaultConfig {
minSdk 21
targetSdk 33

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
Expand Down Expand Up @@ -50,9 +49,9 @@ android {

dependencies {

implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.core:core-ktx:1.13.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'com.google.android.material:material:1.11.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SheetState
import androidx.compose.material3.Text
Expand All @@ -25,22 +27,46 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.canopas.campose.countrypicker.model.Country
import kotlinx.coroutines.launch

/**
* Composable for displaying a bottom sheet country picker.
*
* @param sheetState The state of the bottom sheet.
* @param shape The shape of the bottom sheet.
* @param containerColor The color of the bottom sheet container.
* @param contentColor The color of the bottom sheet content.
* @param tonalElevation The elevation of the bottom sheet.
* @param scrimColor The color of the bottom sheet scrim.
* @param bottomSheetTitle The title composable for the bottom sheet.
* @param onItemSelected Callback when a country is selected.
* @param searchFieldTextStyle The text style for the search field.
* @param placeholderTextStyle The text style for the search field placeholder.
* @param countriesTextStyle The text style for the countries list.
* @param onDismissRequest Callback when the bottom sheet is dismissed.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CountryPickerBottomSheet(
sheetState: SheetState = rememberModalBottomSheetState(skipPartiallyExpanded = false),
shape: Shape = BottomSheetDefaults.ExpandedShape,
shape: Shape = MaterialTheme.shapes.medium,
containerColor: Color = BottomSheetDefaults.ContainerColor,
contentColor: Color = contentColorFor(containerColor),
tonalElevation: Dp = BottomSheetDefaults.Elevation,
scrimColor: Color = BottomSheetDefaults.ScrimColor,
bottomSheetTitle: @Composable () -> Unit,
onItemSelected: (country: Country) -> Unit,
searchFieldTextStyle: TextStyle = LocalTextStyle.current.copy(fontSize = 14.sp),
placeholderTextStyle: TextStyle = MaterialTheme.typography.labelMedium.copy(
color = Color.Gray,
fontSize = 16.sp,
),
countriesTextStyle: TextStyle = TextStyle(),
onDismissRequest: () -> Unit
) {
var searchValue by rememberSaveable { mutableStateOf("") }
Expand All @@ -57,11 +83,11 @@ fun CountryPickerBottomSheet(
) {
bottomSheetTitle()

CountrySearchView(searchValue) {
CountrySearchView(searchValue, searchFieldTextStyle, placeholderTextStyle) {
searchValue = it
}

Countries(searchValue) {
Countries(searchValue, countriesTextStyle) {
scope.launch {
sheetState.hide()
onItemSelected(it)
Expand All @@ -70,9 +96,17 @@ fun CountryPickerBottomSheet(
}
}

/**
* Composable for displaying a list of countries.
*
* @param searchValue The search value for filtering countries.
* @param textStyle The text style for the country list.
* @param onItemSelected Callback when a country is selected.
*/
@Composable
fun Countries(
internal fun Countries(
searchValue: String,
textStyle: TextStyle = TextStyle(),
onItemSelected: (country: Country) -> Unit
) {
val context = LocalContext.current
Expand All @@ -92,21 +126,25 @@ fun Countries(
.clickable { onItemSelected(country) }
.padding(12.dp)
) {
Text(text = localeToEmoji(country.code))
Text(
text = localeToEmoji(country.code),
style = textStyle
)
Text(
text = country.name,
modifier = Modifier
.padding(start = 8.dp)
.weight(2f)
.weight(2f),
style = textStyle
)
Text(
text = country.dial_code,
modifier = Modifier
.padding(start = 8.dp)
.padding(start = 8.dp),
style = textStyle
)
}
Divider(color = Color.LightGray, thickness = 0.5.dp)
}
}

}
Loading
Loading