From 598adec8bd89cdea91afab1ea0a37d057b2266b3 Mon Sep 17 00:00:00 2001 From: yangsooplus Date: Wed, 24 Jan 2024 19:47:44 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20SusuDatePicker=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=EC=9C=BC=EB=A1=9C=20=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bottomsheet/datepicker/InfiniteColumn.kt | 20 ++++++++++++- .../datepicker/SusuDatePickerBottomSheet.kt | 29 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/core/designsystem/src/main/java/com/susu/core/designsystem/component/bottomsheet/datepicker/InfiniteColumn.kt b/core/designsystem/src/main/java/com/susu/core/designsystem/component/bottomsheet/datepicker/InfiniteColumn.kt index 33560044..d738b431 100644 --- a/core/designsystem/src/main/java/com/susu/core/designsystem/component/bottomsheet/datepicker/InfiniteColumn.kt +++ b/core/designsystem/src/main/java/com/susu/core/designsystem/component/bottomsheet/datepicker/InfiniteColumn.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.unit.dp import com.susu.core.designsystem.theme.Gray100 import com.susu.core.designsystem.theme.Gray30 import com.susu.core.designsystem.theme.SusuTheme +import com.susu.core.ui.extension.susuClickable @OptIn(ExperimentalFoundationApi::class) @Composable @@ -41,14 +42,16 @@ fun InfiniteColumn( textColor: Color = Gray30, selectedTextColor: Color = Gray100, onItemSelected: (index: Int, item: T) -> Unit = { _, _ -> }, + onItemClicked: (item: T) -> Unit = { }, ) { val itemHalfHeight = LocalDensity.current.run { itemHeight.toPx() / 2f } var lastSelectedIndex by remember { mutableStateOf(0) } var itemsState by remember { mutableStateOf(items) } val lazyListState = rememberLazyListState(0) val flingBehavior: FlingBehavior = rememberSnapFlingBehavior(lazyListState) + var clickedIndex: Int? by remember { mutableStateOf(null) } - LaunchedEffect(items) { + LaunchedEffect(key1 = items) { var targetIndex = items.indexOf(initialItem) targetIndex += ((Int.MAX_VALUE / 2) / items.size) * items.size itemsState = items @@ -56,6 +59,14 @@ fun InfiniteColumn( lazyListState.scrollToItem(targetIndex - 2, scrollOffset = (itemHeight.value * 0.6f).toInt()) } + LaunchedEffect(clickedIndex) { + if (clickedIndex != null) { + lastSelectedIndex = clickedIndex!! + val targetIndex = clickedIndex!! - 2 + lazyListState.animateScrollToItem(targetIndex, scrollOffset = (itemHeight.value * 0.6f).toInt()) + } + } + LazyColumn( modifier = modifier.height(itemHeight * numberOfDisplayedItems), state = lazyListState, @@ -85,6 +96,13 @@ fun InfiniteColumn( contentAlignment = Alignment.Center, ) { Text( + modifier = Modifier.susuClickable( + onClick = { + clickedIndex = i + onItemClicked(item) + }, + rippleEnabled = false, + ), text = item.toString(), style = if (lastSelectedIndex == i) { selectedTextStyle diff --git a/core/designsystem/src/main/java/com/susu/core/designsystem/component/bottomsheet/datepicker/SusuDatePickerBottomSheet.kt b/core/designsystem/src/main/java/com/susu/core/designsystem/component/bottomsheet/datepicker/SusuDatePickerBottomSheet.kt index 4ffee172..46a59d61 100644 --- a/core/designsystem/src/main/java/com/susu/core/designsystem/component/bottomsheet/datepicker/SusuDatePickerBottomSheet.kt +++ b/core/designsystem/src/main/java/com/susu/core/designsystem/component/bottomsheet/datepicker/SusuDatePickerBottomSheet.kt @@ -78,6 +78,9 @@ fun SusuDatePickerBottomSheet( } onItemSelected(selectedYear, selectedMonth, selectedDay) }, + onItemClicked = { item -> + selectedYear = item.dropLast(1).toIntOrNull() ?: currentDate.year + }, ) InfiniteColumn( modifier = Modifier.width(100.dp), @@ -95,6 +98,9 @@ fun SusuDatePickerBottomSheet( } onItemSelected(selectedYear, selectedMonth, selectedDay) }, + onItemClicked = { item -> + selectedMonth = item.dropLast(1).toIntOrNull() ?: currentDate.monthValue + }, ) InfiniteColumn( modifier = Modifier.width(100.dp), @@ -106,6 +112,9 @@ fun SusuDatePickerBottomSheet( selectedDay = item.dropLast(1).toIntOrNull() ?: 1 onItemSelected(selectedYear, selectedMonth, selectedDay) }, + onItemClicked = { item -> + selectedMonth = item.dropLast(1).toIntOrNull() ?: 1 + }, ) } } @@ -234,6 +243,9 @@ fun SusuLimitDatePickerBottomSheet( selectedYear = item.dropLast(1).toIntOrNull() ?: criteriaYear onItemSelected(selectedYear, selectedMonth, selectedDay) }, + onItemClicked = { item -> + selectedYear = item.dropLast(1).toIntOrNull() ?: criteriaYear + }, ) if (monthRange.count() > 1) { InfiniteColumn( @@ -246,6 +258,9 @@ fun SusuLimitDatePickerBottomSheet( selectedMonth = item.dropLast(1).toIntOrNull() ?: criteriaMonth onItemSelected(selectedYear, selectedMonth, selectedDay) }, + onItemClicked = { item -> + selectedMonth = item.dropLast(1).toIntOrNull() ?: criteriaMonth + }, ) } else { selectedMonth = criteriaMonth @@ -276,6 +291,9 @@ fun SusuLimitDatePickerBottomSheet( selectedDay = item.dropLast(1).toIntOrNull() ?: 1 onItemSelected(selectedYear, selectedMonth, selectedDay) }, + onItemClicked = { item -> + selectedDay = item.dropLast(1).toIntOrNull() ?: 1 + }, ) } else { selectedDay = criteriaDay @@ -312,6 +330,7 @@ fun SusuYearPickerBottomSheet( cornerRadius: Dp = 24.dp, onDismissRequest: (Int) -> Unit = {}, onItemSelected: (Int) -> Unit = {}, + onItemClicked: (Int) -> Unit = {}, ) { val currentYear = remember { LocalDate.now().year } var selectedYear by remember { mutableIntStateOf(initialYear ?: currentYear) } @@ -334,6 +353,7 @@ fun SusuYearPickerBottomSheet( selectedYear = item.dropLast(1).toIntOrNull() ?: currentYear onItemSelected(selectedYear) }, + onItemClicked = { onItemClicked(it.dropLast(1).toIntOrNull() ?: currentYear) }, ) } } @@ -367,3 +387,12 @@ fun SusuLimitDatePickerBottomSheetPreview() { ) } } + +@OptIn(ExperimentalMaterial3Api::class) +@Preview +@Composable +fun SusuYearPickerBottomSheetPreview() { + SusuTheme { + SusuYearPickerBottomSheet(maximumContainerHeight = 300.dp) + } +}