diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9d53d40c..3f59ce61 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -107,4 +107,5 @@ dependencies { implementation(libs.timber) implementation(libs.lottie.compose) + implementation(libs.pebble) } diff --git a/app/src/main/java/com/flint/core/designsystem/component/textfield/FlintBasicTextField.kt b/app/src/main/java/com/flint/core/designsystem/component/textfield/FlintBasicTextField.kt index 53915123..084038e2 100644 --- a/app/src/main/java/com/flint/core/designsystem/component/textfield/FlintBasicTextField.kt +++ b/app/src/main/java/com/flint/core/designsystem/component/textfield/FlintBasicTextField.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import com.chattymin.pebble.graphemeLength import com.flint.core.designsystem.theme.FlintTheme @Composable @@ -39,6 +40,7 @@ fun FlintBasicTextField( value: String, onValueChange: (String) -> Unit, modifier: Modifier = Modifier, + singleLine: Boolean = true, maxLines: Int = 1, maxLength: Int = Int.MAX_VALUE, height: Dp = 40.dp, @@ -71,7 +73,7 @@ fun FlintBasicTextField( value = value, textStyle = textStyle.copy(color = FlintTheme.colors.white), onValueChange = { - if (it.length <= maxLength) { // TODO: 글자수 제한 정책 기획 확인 필요 + if (it.graphemeLength <= maxLength) { onValueChange(it) } }, @@ -79,6 +81,7 @@ fun FlintBasicTextField( keyboardActions = keyboardActions, visualTransformation = visualTransformation, interactionSource = interactionSource, + singleLine = singleLine, maxLines = maxLines, cursorBrush = SolidColor(FlintTheme.colors.gray300), decorationBox = { innerTextField -> diff --git a/app/src/main/java/com/flint/core/designsystem/component/textfield/FlintLongTextField.kt b/app/src/main/java/com/flint/core/designsystem/component/textfield/FlintLongTextField.kt index bc8a1462..39565563 100644 --- a/app/src/main/java/com/flint/core/designsystem/component/textfield/FlintLongTextField.kt +++ b/app/src/main/java/com/flint/core/designsystem/component/textfield/FlintLongTextField.kt @@ -3,6 +3,8 @@ package com.flint.core.designsystem.component.textfield import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -14,7 +16,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import com.chattymin.pebble.graphemeLength import com.flint.core.designsystem.theme.FlintTheme +import kotlin.math.max +import kotlin.math.sin @Composable fun FlintLongTextField( @@ -23,7 +28,10 @@ fun FlintLongTextField( maxLength: Int, placeholder: String, modifier: Modifier = Modifier, - height: Dp = 120.dp, + singleLine: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + height: Dp = 120.dp ) { Column( verticalArrangement = Arrangement.spacedBy(8.dp), @@ -34,12 +42,16 @@ fun FlintLongTextField( placeholder = placeholder, value = value, onValueChange = onValueChanged, + maxLength = maxLength, + singleLine = singleLine, maxLines = 5, height = height, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, ) Text( - text = "${value.length}/$maxLength", + text = "${value.graphemeLength}/$maxLength", style = FlintTheme.typography.caption1M12, color = FlintTheme.colors.white, ) diff --git a/app/src/main/java/com/flint/presentation/collectioncreate/AddContentScreen.kt b/app/src/main/java/com/flint/presentation/collectioncreate/AddContentScreen.kt index 433da3eb..dc833e9d 100644 --- a/app/src/main/java/com/flint/presentation/collectioncreate/AddContentScreen.kt +++ b/app/src/main/java/com/flint/presentation/collectioncreate/AddContentScreen.kt @@ -13,6 +13,8 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -21,6 +23,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel @@ -113,6 +116,14 @@ fun AddContentScreen( placeholder = "추천하고 싶은 작품을 검색해보세요", value = uiState.searchText, onValueChanged = onSearchTextChanged, + onSearchAction = {}, + onClearAction = {}, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), + keyboardActions = KeyboardActions( + onSearch = { + // TODO: 검색 진행 + } + ), modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp), diff --git a/app/src/main/java/com/flint/presentation/collectioncreate/CollectionCreateScreen.kt b/app/src/main/java/com/flint/presentation/collectioncreate/CollectionCreateScreen.kt index 65f2e015..869925d9 100644 --- a/app/src/main/java/com/flint/presentation/collectioncreate/CollectionCreateScreen.kt +++ b/app/src/main/java/com/flint/presentation/collectioncreate/CollectionCreateScreen.kt @@ -14,6 +14,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -26,6 +28,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -142,9 +145,13 @@ fun CollectionCreateScreen( modifier = Modifier.fillMaxWidth(), value = uiState.title, placeholder = "컬렉션의 제목을 입력해주세요.", + singleLine = true, onValueChanged = onTitleChanged, maxLength = 20, height = 40.dp, + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Next + ) ) } } @@ -175,6 +182,9 @@ fun CollectionCreateScreen( onValueChanged = onDescriptionChanged, maxLength = 200, height = 104.dp, + keyboardActions = KeyboardActions( + onDone = {}, + ), ) } } diff --git a/app/src/main/java/com/flint/presentation/collectioncreate/component/CollectionCreateContentItemList.kt b/app/src/main/java/com/flint/presentation/collectioncreate/component/CollectionCreateContentItemList.kt index 8e4bac9a..bb59b344 100644 --- a/app/src/main/java/com/flint/presentation/collectioncreate/component/CollectionCreateContentItemList.kt +++ b/app/src/main/java/com/flint/presentation/collectioncreate/component/CollectionCreateContentItemList.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.text.KeyboardActions import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -112,8 +113,12 @@ fun CollectionCreateContentItemList( onValueChange = onSelectedReasonChanged, modifier = Modifier.fillMaxWidth(), height = 108.dp, + singleLine = false, maxLines = Int.MAX_VALUE, textStyle = FlintTheme.typography.body1R16, + keyboardActions = KeyboardActions( + onDone = {}, + ), paddingValues = PaddingValues( horizontal = 12.dp, diff --git a/app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt b/app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt index c7c56422..809a9339 100644 --- a/app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt +++ b/app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt @@ -23,6 +23,9 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -286,13 +289,19 @@ private fun OnboardingContentScreenListPreview() { @Preview(showBackground = true, name = "검색 결과 없음 상태") @Composable private fun OnboardingContentScreenEmptyPreview() { + var text by remember { mutableStateOf("") } + FlintTheme { OnboardingContentScreen( nickname = "안비", - contentUiState = OnboardingContentUiState(), + contentUiState = OnboardingContentUiState( + searchKeyword = text + ), onBackClick = {}, onNextClick = {}, - onSearchKeywordChanged = {}, + onSearchKeywordChanged = { + text = it + }, onSearchAction = {}, onClearAction = {}, onContentClick = {}, diff --git a/app/src/main/java/com/flint/presentation/onboarding/OnboardingProfileScreen.kt b/app/src/main/java/com/flint/presentation/onboarding/OnboardingProfileScreen.kt index a45b5753..94289116 100644 --- a/app/src/main/java/com/flint/presentation/onboarding/OnboardingProfileScreen.kt +++ b/app/src/main/java/com/flint/presentation/onboarding/OnboardingProfileScreen.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.chattymin.pebble.graphemeLength import com.flint.R import com.flint.core.designsystem.component.button.FlintBasicButton import com.flint.core.designsystem.component.button.FlintButtonState @@ -145,6 +146,7 @@ fun OnboardingProfileScreen( .fillMaxHeight(), placeholder = "닉네임", value = nickname, + singleLine = true, maxLines = 1, maxLength = OnboardingProfileUiState.MAX_LENGTH, onValueChange = onNicknameChange, @@ -155,7 +157,7 @@ fun OnboardingProfileScreen( }, trailingContent = { Text( - text = "${nickname.length}/${OnboardingProfileUiState.MAX_LENGTH}", + text = "${nickname.graphemeLength}/${OnboardingProfileUiState.MAX_LENGTH}", style = FlintTheme.typography.body1R16, color = FlintTheme.colors.gray300, ) @@ -252,16 +254,18 @@ private fun OnboardingProfileScreenDuplicateErrorPreview() { @Preview(showBackground = true) @Composable private fun OnboardingProfileScreenFormatErrorPreview() { + var text by remember { mutableStateOf("") } + FlintTheme { OnboardingProfileScreen( - nickname = "안비123", + nickname = text, isValid = true, isFormatValid = false, isNicknameAvailable = null, canProceed = false, hasError = true, errorMessage = "사용할 수 없는 닉네임입니다", - onNicknameChange = {}, + onNicknameChange = { text = it }, onCheckNickname = {}, onClearError = {}, onBackClick = {}, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f7a8674f..b520136b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,6 +37,7 @@ espressoCore = "3.7.0" lottieCompose = "6.6.6" coil = "3.3.0" ktlint = "14.0.1" +pebble = "0.1.0" # Network okhttp = "5.1.0" @@ -81,6 +82,7 @@ androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-co kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } kotlinx-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version.ref = "kotlinxImmutable" } lottie-compose = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "lottieCompose" } +pebble = { group = "io.github.chattymin", name = "pebble", version.ref = "pebble" } # Coil coil-compose = { group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil" }