@@ -5,7 +5,9 @@ import androidx.compose.foundation.BorderStroke
55import androidx.compose.foundation.ScrollState
66import androidx.compose.foundation.clickable
77import androidx.compose.foundation.interaction.MutableInteractionSource
8+ import androidx.compose.foundation.layout.Arrangement
89import androidx.compose.foundation.layout.Box
10+ import androidx.compose.foundation.layout.Column
911import androidx.compose.foundation.layout.fillMaxWidth
1012import androidx.compose.foundation.layout.height
1113import androidx.compose.foundation.layout.padding
@@ -56,6 +58,8 @@ import kotlinx.coroutines.delay
5658 * @param selectedIds 메뉴 아이템의 selected 상태 표시에 쓰이며, 외부에서 제어합니다. 선택된 아이템 객체의 id 프로퍼티를 넣어줍니다.
5759 * @param searchType 서치 타입에 따라 메뉴 최대 길이가 조정됩니다. 아티스트 검색 시 ARTIST, 상품 등록을 위한 상품명 검색 시 PRODUCT를 사용합니다.
5860 * @param modifier
61+ * @param label 필드 상단에 표시됩니다.
62+ * @param error emptyString이 아닌 경우 필드 하단에 에러 메시지를 노출하고, borderColor를 변경합니다.
5963 * @param focusRequester 포커스를 외부에서 제어하고 싶을 때 사용합니다. 예: 화면 진입 시 필드에 포커스 가도록
6064 * @param scrollState 메뉴 스크롤을 외부에서 제어하고 싶을 때 사용합니다.
6165 * @param offset 필드 하단으로부터 메뉴까지의 간격입니다. 기본값 12dp이며, y값만 조정 가능합니다.
@@ -73,6 +77,8 @@ fun PotiSearchField(
7377 selectedIds : Set <String >,
7478 searchType : SearchType ,
7579 modifier : Modifier = Modifier ,
80+ label : String = "",
81+ error : String = "",
7682 focusRequester : FocusRequester = remember { FocusRequester () },
7783 scrollState : ScrollState = rememberScrollState(),
7884 offset : DpOffset = DpOffset (x = 0.dp, y = 12.dp),
@@ -121,46 +127,58 @@ fun PotiSearchField(
121127 }
122128 }
123129
130+ val borderColor = when {
131+ error.isNotEmpty() -> PotiTheme .colors.sementicRed
132+ expandedState.currentState || expandedState.targetState -> PotiTheme .colors.gray700
133+ else -> PotiTheme .colors.gray300
134+ }
135+
124136 Box (
125137 modifier = modifier
126138 .fillMaxWidth(),
127139 ) {
128- PotiBasicField (
129- value = value,
130- onValueChaged = {
131- isTyping = true
132- onValueChange(it)
133- },
134- placeholder = placeholder,
135- modifier = Modifier
136- .fillMaxWidth()
137- .height(52 .dp)
138- .onGloballyPositioned { coordinates ->
139- parentWidth = coordinates.size.width
140+ Column (
141+ verticalArrangement = Arrangement .spacedBy(8 .dp)
142+ ) {
143+ FieldLabel (label)
144+
145+ PotiBasicField (
146+ value = value,
147+ onValueChaged = {
148+ isTyping = true
149+ onValueChange(it)
140150 },
141- onFocusChanged = { isFieldFocused = it },
142- borderColor = when {
143- isFieldFocused -> PotiTheme .colors.gray700
144- else -> PotiTheme .colors.gray300
145- },
146- backgroundColor = White ,
147- imeAction = ImeAction .Search ,
148- onSearchAction = { onSearch() },
149- trailingIcon = {
150- Icon (
151- imageVector = ImageVector .vectorResource(R .drawable.ic_search),
152- contentDescription = null ,
153- modifier = Modifier
154- .size(24 .dp)
155- .clickable(
156- indication = null ,
157- interactionSource = remember { MutableInteractionSource () },
158- ) { onSearch() },
159- tint = PotiTheme .colors.gray700,
160- )
161- },
162- focusRequester = focusRequester,
163- )
151+ placeholder = placeholder,
152+ modifier = Modifier
153+ .fillMaxWidth()
154+ .height(52 .dp)
155+ .onGloballyPositioned { coordinates ->
156+ parentWidth = coordinates.size.width
157+ },
158+ onFocusChanged = { isFieldFocused = it },
159+ borderColor = borderColor,
160+ backgroundColor = White ,
161+ imeAction = ImeAction .Search ,
162+ onSearchAction = { onSearch() },
163+ trailingIcon = {
164+ Icon (
165+ imageVector = ImageVector .vectorResource(R .drawable.ic_search),
166+ contentDescription = null ,
167+ modifier = Modifier
168+ .size(24 .dp)
169+ .clickable(
170+ indication = null ,
171+ interactionSource = remember { MutableInteractionSource () },
172+ ) { onSearch() },
173+ tint = PotiTheme .colors.gray700,
174+ )
175+ },
176+ focusRequester = focusRequester,
177+ )
178+
179+ // TODO: [도연] Display>errorMessage로 대체
180+ FieldErrorMessage (error)
181+ }
164182
165183 PotiDropdownMenu (
166184 expandedState = expandedState,
@@ -241,7 +259,8 @@ private fun PotiSearchFieldPreview() {
241259 .padding(horizontal = 20 .dp)
242260 .padding(top = 40 .dp),
243261 onSearchClick = { },
244- searchType = SearchType .ARTIST
262+ searchType = SearchType .ARTIST ,
263+ error = " 에러 메시지"
245264 )
246265 }
247266}
0 commit comments