-
Notifications
You must be signed in to change notification settings - Fork 1
SCRUM-254 design: search input component #24
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
Merged
gdaegeun539
merged 12 commits into
project-lyrics:develop
from
gdaegeun539:feature/SCRUM-254-search-input
Dec 14, 2025
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
3a2ed53
design: add xcircle icon asset
gdaegeun539 23ef82d
design: add search icon asset
gdaegeun539 cecdb85
refactor: remove redundant xcircle dark icon asset
gdaegeun539 675f52e
design: add search inputfield component
gdaegeun539 465c029
refactor: change search inputfield text style
gdaegeun539 8941da1
refactor: remove unused variable
gdaegeun539 ee4db52
refactor: enhance searchinputfield component
gdaegeun539 8abd70b
refactor: update code lint
gdaegeun539 018e170
refactor: make inner textfield to component
gdaegeun539 abefb88
refactor: restore modifier parameter at InnerTextFieldComponent
gdaegeun539 5790342
Merge branch 'develop' into feature/SCRUM-254-search-input
gdaegeun539 3d3d7cd
refactor: decouple M3 typo, color at new component
gdaegeun539 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
128 changes: 128 additions & 0 deletions
128
app/src/main/java/com/lyrics/feelin/core/designsystem/component/FeelinSearchInputField.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| package com.lyrics.feelin.core.designsystem.component | ||
|
|
||
| import android.content.res.Configuration | ||
| import androidx.compose.foundation.background | ||
| import androidx.compose.foundation.interaction.MutableInteractionSource | ||
| import androidx.compose.foundation.layout.Row | ||
| import androidx.compose.foundation.layout.Spacer | ||
| import androidx.compose.foundation.layout.fillMaxWidth | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.foundation.layout.size | ||
| import androidx.compose.foundation.layout.width | ||
| import androidx.compose.foundation.shape.RoundedCornerShape | ||
| import androidx.compose.foundation.text.BasicTextField | ||
| import androidx.compose.foundation.text.KeyboardOptions | ||
| import androidx.compose.foundation.text.input.InputTransformation | ||
| import androidx.compose.foundation.text.input.TextFieldLineLimits | ||
| import androidx.compose.foundation.text.input.TextFieldState | ||
| import androidx.compose.foundation.text.input.clearText | ||
| import androidx.compose.foundation.text.input.maxLength | ||
| import androidx.compose.material3.Icon | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.runtime.remember | ||
| import androidx.compose.ui.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.graphics.SolidColor | ||
| import androidx.compose.ui.text.input.ImeAction | ||
| import androidx.compose.ui.text.input.KeyboardType | ||
| import androidx.compose.ui.tooling.preview.Preview | ||
| import androidx.compose.ui.unit.dp | ||
| import com.lyrics.feelin.core.designsystem.icon.SearchIcon | ||
| import com.lyrics.feelin.presentation.designsystem.theme.FeelinTheme | ||
| import com.lyrics.feelin.presentation.designsystem.theme.FeelinTypography | ||
| import com.lyrics.feelin.presentation.designsystem.theme.LocalFeelinColors | ||
|
|
||
| private const val MAX_INPUT_LENGTH: Int = 100 | ||
|
|
||
| /** | ||
| * Feelin 앱의 검색 입력 필드 컴포넌트입니다. | ||
| * | ||
| * 라이트/다크 모드에 따라 자동으로 색상이 변경됩니다. | ||
| * | ||
| * @param state 텍스트 입력 상태 | ||
| * @param modifier 컴포넌트 수정자 | ||
| * @param placeholder 입력 필드의 플레이스홀더 텍스트 | ||
| * @param onClearClick 클리어 버튼 클릭 시 호출되는 콜백 | ||
| */ | ||
| @Composable | ||
| fun FeelinSearchInputField( | ||
| state: TextFieldState, | ||
| modifier: Modifier = Modifier, | ||
| placeholder: String = "", | ||
| onSearchClick: () -> Unit = {}, | ||
| onClearClick: () -> Unit = {} | ||
| ) { | ||
| val feelinColors = LocalFeelinColors.current | ||
|
|
||
| val backgroundColor = feelinColors.inputField | ||
| val textColor = feelinColors.gray09 | ||
| val placeholderColor = feelinColors.gray04 | ||
| val iconTintColor = feelinColors.gray05 | ||
| val clearButtonColor = feelinColors.gray03 | ||
|
|
||
| val interactionSource = remember { MutableInteractionSource() } | ||
|
|
||
| BasicTextField( | ||
| state = state, | ||
| modifier = modifier, | ||
| lineLimits = TextFieldLineLimits.SingleLine, | ||
| inputTransformation = InputTransformation.maxLength(MAX_INPUT_LENGTH), | ||
| keyboardOptions = KeyboardOptions( | ||
| imeAction = ImeAction.Search, | ||
| keyboardType = KeyboardType.Text, | ||
| autoCorrectEnabled = false | ||
| ), | ||
| onKeyboardAction = { onSearchClick.invoke() }, | ||
| textStyle = FeelinTypography.body3.copy(color = textColor), | ||
| cursorBrush = SolidColor(textColor), | ||
| decorator = { innerTextField -> | ||
| Row( | ||
| modifier = Modifier | ||
| .fillMaxWidth() | ||
| .background( | ||
| color = backgroundColor, | ||
| shape = RoundedCornerShape(8.dp), | ||
| ) | ||
| .padding(all = 12.dp), | ||
| verticalAlignment = Alignment.CenterVertically, | ||
| ) { | ||
| // 검색 아이콘 | ||
| Icon( | ||
| painter = SearchIcon, | ||
| contentDescription = null, | ||
| modifier = Modifier.size(20.dp), | ||
| tint = iconTintColor, | ||
| ) | ||
|
|
||
| Spacer(modifier = Modifier.width(8.dp)) | ||
|
|
||
| // 텍스트 입력 영역 | ||
| InnerTextFieldComponent( | ||
| isTextEmpty = state.text.isEmpty(), | ||
| placeholder = placeholder, | ||
| placeholderColor = placeholderColor, | ||
| placeholderTextStyle = FeelinTypography.body3, | ||
| clearIconColor = clearButtonColor, | ||
| innerTextField = innerTextField, | ||
| onClearButtonClick = { onClearClick.invoke() }, | ||
| clearButtonInteractionSource = interactionSource | ||
| ) | ||
| } | ||
| }, | ||
| ) | ||
| } | ||
|
|
||
| @Preview(name = "Light mode", showBackground = true, backgroundColor = 0xff000000) | ||
| @Preview(name = "Dark mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) | ||
| @Composable | ||
| private fun FeelinSearchInputFieldPreview() { | ||
| val state = remember { TextFieldState() } | ||
| FeelinTheme { | ||
| FeelinSearchInputField( | ||
| state = state, | ||
| placeholder = "텍스트", | ||
| onSearchClick = { println("onSearchClick invoke") }, | ||
| onClearClick = { state.clearText() } | ||
| ) | ||
| } | ||
| } | ||
60 changes: 60 additions & 0 deletions
60
app/src/main/java/com/lyrics/feelin/core/designsystem/component/InnerTextFieldComponent.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| package com.lyrics.feelin.core.designsystem.component | ||
|
|
||
| import androidx.compose.foundation.clickable | ||
| import androidx.compose.foundation.interaction.MutableInteractionSource | ||
| import androidx.compose.foundation.layout.Box | ||
| import androidx.compose.foundation.layout.RowScope | ||
| import androidx.compose.foundation.layout.Spacer | ||
| import androidx.compose.foundation.layout.size | ||
| import androidx.compose.foundation.layout.width | ||
| import androidx.compose.material3.Icon | ||
| import androidx.compose.material3.Text | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.graphics.Color | ||
| import androidx.compose.ui.text.TextStyle | ||
| import androidx.compose.ui.unit.dp | ||
| import com.lyrics.feelin.core.designsystem.icon.XCircleIcon | ||
|
|
||
| /** | ||
| * BasicTextField 기반의 입력창에서 텍스트필드에 공통된 디자인을 사용하기 위한 컴포넌트입니다. | ||
| * */ | ||
| @Composable | ||
| fun RowScope.InnerTextFieldComponent( | ||
| isTextEmpty: Boolean, | ||
| placeholder: String, | ||
| placeholderTextStyle: TextStyle, | ||
| placeholderColor: Color, | ||
| clearIconColor: Color, | ||
| innerTextField: @Composable (() -> Unit), | ||
| onClearButtonClick: () -> Unit, | ||
| clearButtonInteractionSource: MutableInteractionSource?, | ||
| modifier: Modifier = Modifier | ||
| ) { | ||
| Box(modifier = Modifier.weight(1f)) { | ||
| if (isTextEmpty) { | ||
| Text( | ||
| text = placeholder, | ||
| style = placeholderTextStyle, | ||
| color = placeholderColor, | ||
| ) | ||
| } | ||
| innerTextField() | ||
| } | ||
|
|
||
| // 클리어 버튼 (입력값 있을 때만 표시) | ||
| if (!isTextEmpty) { | ||
| Spacer(modifier = Modifier.width(8.dp)) | ||
|
|
||
| Icon( | ||
| painter = XCircleIcon, | ||
| contentDescription = "입력 내용 지우기", | ||
| tint = clearIconColor, | ||
| modifier = Modifier.size(20.dp).clickable( | ||
| interactionSource = clearButtonInteractionSource, | ||
| indication = null, | ||
| onClick = onClearButtonClick, | ||
| ) | ||
| ) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:width="24dp" | ||
| android:height="24dp" | ||
| android:viewportWidth="24" | ||
| android:viewportHeight="24"> | ||
| <path | ||
| android:pathData="M21.795,20.204L17.343,15.75C18.678,14.01 19.301,11.828 19.086,9.646C18.872,7.464 17.835,5.445 16.186,3.999C14.538,2.553 12.401,1.789 10.209,1.861C8.018,1.932 5.935,2.835 4.385,4.385C2.834,5.936 1.932,8.018 1.86,10.21C1.788,12.401 2.553,14.538 3.999,16.187C5.445,17.835 7.463,18.872 9.645,19.087C11.828,19.302 14.01,18.678 15.749,17.344L20.205,21.801C20.31,21.905 20.434,21.988 20.571,22.045C20.708,22.101 20.854,22.131 21.002,22.131C21.15,22.131 21.297,22.101 21.434,22.045C21.57,21.988 21.694,21.905 21.799,21.801C21.904,21.696 21.987,21.572 22.043,21.435C22.1,21.298 22.129,21.152 22.129,21.004C22.129,20.856 22.1,20.709 22.043,20.572C21.987,20.436 21.904,20.311 21.799,20.207L21.795,20.204ZM4.124,10.5C4.124,9.239 4.498,8.006 5.199,6.958C5.899,5.91 6.895,5.093 8.06,4.61C9.225,4.128 10.507,4.001 11.743,4.247C12.98,4.493 14.116,5.101 15.007,5.992C15.899,6.884 16.506,8.02 16.752,9.256C16.998,10.493 16.872,11.775 16.389,12.939C15.907,14.104 15.09,15.1 14.041,15.8C12.993,16.501 11.76,16.875 10.499,16.875C8.809,16.873 7.189,16.201 5.994,15.006C4.798,13.811 4.126,12.19 4.124,10.5Z" | ||
| android:fillColor="#101223"/> | ||
| <path | ||
| android:pathData="M21.795,20.204L17.343,15.75C18.678,14.01 19.301,11.828 19.086,9.646C18.872,7.464 17.835,5.445 16.186,3.999C14.538,2.553 12.401,1.789 10.209,1.861C8.018,1.932 5.935,2.835 4.385,4.385C2.834,5.936 1.932,8.018 1.86,10.21C1.788,12.401 2.553,14.538 3.999,16.187C5.445,17.835 7.463,18.872 9.645,19.087C11.828,19.302 14.01,18.678 15.749,17.344L20.205,21.801C20.31,21.905 20.434,21.988 20.571,22.045C20.708,22.101 20.854,22.131 21.002,22.131C21.15,22.131 21.297,22.101 21.434,22.045C21.57,21.988 21.694,21.905 21.799,21.801C21.904,21.696 21.987,21.572 22.043,21.435C22.1,21.298 22.129,21.152 22.129,21.004C22.129,20.856 22.1,20.709 22.043,20.572C21.987,20.436 21.904,20.311 21.799,20.207L21.795,20.204ZM4.124,10.5C4.124,9.239 4.498,8.006 5.199,6.958C5.899,5.91 6.895,5.093 8.06,4.61C9.225,4.128 10.507,4.001 11.743,4.247C12.98,4.493 14.116,5.101 15.007,5.992C15.899,6.884 16.506,8.02 16.752,9.256C16.998,10.493 16.872,11.775 16.389,12.939C15.907,14.104 15.09,15.1 14.041,15.8C12.993,16.501 11.76,16.875 10.499,16.875C8.809,16.873 7.189,16.201 5.994,15.006C4.798,13.811 4.126,12.19 4.124,10.5Z" | ||
| android:fillColor="#000000" | ||
| android:fillAlpha="0.2"/> | ||
| <path | ||
| android:pathData="M21.795,20.204L17.343,15.75C18.678,14.01 19.301,11.828 19.086,9.646C18.872,7.464 17.835,5.445 16.186,3.999C14.538,2.553 12.401,1.789 10.209,1.861C8.018,1.932 5.935,2.835 4.385,4.385C2.834,5.936 1.932,8.018 1.86,10.21C1.788,12.401 2.553,14.538 3.999,16.187C5.445,17.835 7.463,18.872 9.645,19.087C11.828,19.302 14.01,18.678 15.749,17.344L20.205,21.801C20.31,21.905 20.434,21.988 20.571,22.045C20.708,22.101 20.854,22.131 21.002,22.131C21.15,22.131 21.297,22.101 21.434,22.045C21.57,21.988 21.694,21.905 21.799,21.801C21.904,21.696 21.987,21.572 22.043,21.435C22.1,21.298 22.129,21.152 22.129,21.004C22.129,20.856 22.1,20.709 22.043,20.572C21.987,20.436 21.904,20.311 21.799,20.207L21.795,20.204ZM4.124,10.5C4.124,9.239 4.498,8.006 5.199,6.958C5.899,5.91 6.895,5.093 8.06,4.61C9.225,4.128 10.507,4.001 11.743,4.247C12.98,4.493 14.116,5.101 15.007,5.992C15.899,6.884 16.506,8.02 16.752,9.256C16.998,10.493 16.872,11.775 16.389,12.939C15.907,14.104 15.09,15.1 14.041,15.8C12.993,16.501 11.76,16.875 10.499,16.875C8.809,16.873 7.189,16.201 5.994,15.006C4.798,13.811 4.126,12.19 4.124,10.5Z" | ||
| android:fillColor="#000000" | ||
| android:fillAlpha="0.2"/> | ||
| <path | ||
| android:pathData="M21.795,20.204L17.343,15.75C18.678,14.01 19.301,11.828 19.086,9.646C18.872,7.464 17.835,5.445 16.186,3.999C14.538,2.553 12.401,1.789 10.209,1.861C8.018,1.932 5.935,2.835 4.385,4.385C2.834,5.936 1.932,8.018 1.86,10.21C1.788,12.401 2.553,14.538 3.999,16.187C5.445,17.835 7.463,18.872 9.645,19.087C11.828,19.302 14.01,18.678 15.749,17.344L20.205,21.801C20.31,21.905 20.434,21.988 20.571,22.045C20.708,22.101 20.854,22.131 21.002,22.131C21.15,22.131 21.297,22.101 21.434,22.045C21.57,21.988 21.694,21.905 21.799,21.801C21.904,21.696 21.987,21.572 22.043,21.435C22.1,21.298 22.129,21.152 22.129,21.004C22.129,20.856 22.1,20.709 22.043,20.572C21.987,20.436 21.904,20.311 21.799,20.207L21.795,20.204ZM4.124,10.5C4.124,9.239 4.498,8.006 5.199,6.958C5.899,5.91 6.895,5.093 8.06,4.61C9.225,4.128 10.507,4.001 11.743,4.247C12.98,4.493 14.116,5.101 15.007,5.992C15.899,6.884 16.506,8.02 16.752,9.256C16.998,10.493 16.872,11.775 16.389,12.939C15.907,14.104 15.09,15.1 14.041,15.8C12.993,16.501 11.76,16.875 10.499,16.875C8.809,16.873 7.189,16.201 5.994,15.006C4.798,13.811 4.126,12.19 4.124,10.5Z" | ||
| android:fillColor="#000000" | ||
| android:fillAlpha="0.2"/> | ||
| <path | ||
| android:pathData="M21.795,20.204L17.343,15.75C18.678,14.01 19.301,11.828 19.086,9.646C18.872,7.464 17.835,5.445 16.186,3.999C14.538,2.553 12.401,1.789 10.209,1.861C8.018,1.932 5.935,2.835 4.385,4.385C2.834,5.936 1.932,8.018 1.86,10.21C1.788,12.401 2.553,14.538 3.999,16.187C5.445,17.835 7.463,18.872 9.645,19.087C11.828,19.302 14.01,18.678 15.749,17.344L20.205,21.801C20.31,21.905 20.434,21.988 20.571,22.045C20.708,22.101 20.854,22.131 21.002,22.131C21.15,22.131 21.297,22.101 21.434,22.045C21.57,21.988 21.694,21.905 21.799,21.801C21.904,21.696 21.987,21.572 22.043,21.435C22.1,21.298 22.129,21.152 22.129,21.004C22.129,20.856 22.1,20.709 22.043,20.572C21.987,20.436 21.904,20.311 21.799,20.207L21.795,20.204ZM4.124,10.5C4.124,9.239 4.498,8.006 5.199,6.958C5.899,5.91 6.895,5.093 8.06,4.61C9.225,4.128 10.507,4.001 11.743,4.247C12.98,4.493 14.116,5.101 15.007,5.992C15.899,6.884 16.506,8.02 16.752,9.256C16.998,10.493 16.872,11.775 16.389,12.939C15.907,14.104 15.09,15.1 14.041,15.8C12.993,16.501 11.76,16.875 10.499,16.875C8.809,16.873 7.189,16.201 5.994,15.006C4.798,13.811 4.126,12.19 4.124,10.5Z" | ||
| android:fillColor="#000000" | ||
| android:fillAlpha="0.2"/> | ||
| </vector> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:width="24dp" | ||
| android:height="24dp" | ||
| android:viewportWidth="24" | ||
| android:viewportHeight="24"> | ||
| <path | ||
| android:pathData="M12,2.25C10.072,2.25 8.187,2.822 6.583,3.893C4.98,4.965 3.73,6.487 2.992,8.269C2.254,10.05 2.061,12.011 2.437,13.902C2.814,15.793 3.742,17.531 5.106,18.894C6.469,20.258 8.207,21.187 10.098,21.563C11.989,21.939 13.95,21.746 15.731,21.008C17.513,20.27 19.035,19.02 20.107,17.417C21.178,15.813 21.75,13.928 21.75,12C21.747,9.415 20.719,6.937 18.891,5.109C17.063,3.281 14.585,2.253 12,2.25ZM15.531,14.469C15.6,14.539 15.656,14.622 15.693,14.713C15.731,14.804 15.75,14.901 15.75,15C15.75,15.099 15.731,15.196 15.693,15.287C15.656,15.378 15.6,15.461 15.531,15.531C15.461,15.6 15.378,15.656 15.287,15.693C15.196,15.731 15.099,15.75 15,15.75C14.901,15.75 14.804,15.731 14.713,15.693C14.622,15.656 14.539,15.6 14.469,15.531L12,13.06L9.531,15.531C9.461,15.6 9.378,15.656 9.287,15.693C9.196,15.731 9.099,15.75 9,15.75C8.901,15.75 8.804,15.731 8.713,15.693C8.622,15.656 8.539,15.6 8.469,15.531C8.4,15.461 8.344,15.378 8.307,15.287C8.269,15.196 8.25,15.099 8.25,15C8.25,14.901 8.269,14.804 8.307,14.713C8.344,14.622 8.4,14.539 8.469,14.469L10.94,12L8.469,9.531C8.329,9.39 8.25,9.199 8.25,9C8.25,8.801 8.329,8.61 8.469,8.469C8.61,8.329 8.801,8.25 9,8.25C9.199,8.25 9.39,8.329 9.531,8.469L12,10.94L14.469,8.469C14.539,8.4 14.622,8.344 14.713,8.307C14.804,8.269 14.901,8.25 15,8.25C15.099,8.25 15.196,8.269 15.287,8.307C15.378,8.344 15.461,8.4 15.531,8.469C15.6,8.539 15.656,8.622 15.693,8.713C15.731,8.804 15.75,8.901 15.75,9C15.75,9.099 15.731,9.196 15.693,9.287C15.656,9.378 15.6,9.461 15.531,9.531L13.06,12L15.531,14.469Z" | ||
| android:fillColor="#B3B5BD"/> | ||
| </vector> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.