From a79a6a6b61760297672abb0920ba87d695c2d49a Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 27 Jan 2026 23:36:34 +0900 Subject: [PATCH 01/11] =?UTF-8?q?style:=20Detekt=20`LongParameterList`=20?= =?UTF-8?q?=EA=B7=9C=EC=B9=99=20=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detekt의 `LongParameterList` 규칙을 비활성화하여 함수 및 생성자의 파라미터 개수 제한을 제거합니다. --- Prezel/detekt-config.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Prezel/detekt-config.yml b/Prezel/detekt-config.yml index 9660790..284eb2b 100644 --- a/Prezel/detekt-config.yml +++ b/Prezel/detekt-config.yml @@ -35,9 +35,7 @@ complexity: active: true threshold: 40 LongParameterList: - active: true - functionThreshold: 8 - constructorThreshold: 8 + active: false CyclomaticComplexMethod: active: true threshold: 15 From de246d35c32d969e5834f5f9320a31e69600fdf0 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 27 Jan 2026 23:46:19 +0900 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20PrezelTextField=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=B0=8F=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 디자인 시스템에 `PrezelTextField`의 상태와 그에 따른 스타일을 관리하기 위한 `PrezelTextFieldStyle`을 추가했습니다. 이 클래스는 TextField의 상호작용 상태와 피드백 상태를 조합하여 동적으로 스타일을 결정합니다. * **상태 정의**: * `PrezelTextFieldInteraction`: TextField의 상호작용 상태(`DEFAULT`, `TYPING`, `TYPED`, `DISABLED`)를 정의하는 `enum`을 추가했습니다. * `PrezelTextFieldFeedback`: 입력 완료 후의 피드백 상태(`DEFAULT`, `GOOD`, `BAD`)를 정의하는 `enum`을 추가했습니다. * **스타일 계산 로직 구현**: * `PrezelTextFieldStyle` 데이터 클래스를 통해 `interaction`과 `feedback` 상태를 관리합니다. * 상태에 따라 배경색(`containerColor`), 텍스트 색상(`textColor`), 아이콘 색상(`trailingIconColor`), 테두리 스타일(`borderStroke`)을 동적으로 계산하는 `@Composable` 확장 함수를 구현했습니다. --- .../textfield/PrezelTextFieldStyle.kt | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldStyle.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldStyle.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldStyle.kt new file mode 100644 index 0000000..46d8c2c --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldStyle.kt @@ -0,0 +1,155 @@ +package com.team.prezel.core.designsystem.component.textfield + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.foundation.color.PrezelColors +import com.team.prezel.core.designsystem.theme.PrezelColorScheme +import com.team.prezel.core.designsystem.theme.PrezelTheme + +/** + * Prezel TextField의 상호작용 상태를 나타냅니다. + * + * TextField가 현재 어떤 사용자 입력 상태에 놓여 있는지를 정의하며, + * 테두리 두께, 색상, 텍스트 색상 등의 스타일 계산에 사용됩니다. + */ +enum class PrezelTextFieldInteraction { + /** 기본 상태 (포커스 및 입력이 없는 상태) */ + DEFAULT, + + /** 사용자가 입력 중인 상태 */ + TYPING, + + /** 입력이 완료된 상태 */ + TYPED, + + /** 비활성화된 상태 */ + DISABLED, +} + +/** + * Prezel TextField 입력 결과에 대한 피드백 상태를 나타냅니다. + * + * 입력이 완료된 이후(`TYPED`) 상태에서 시각적인 피드백을 제공하기 위해 사용됩니다. + */ +enum class PrezelTextFieldFeedback { + /** 기본 상태 (피드백 없음) */ + DEFAULT, + + /** 긍정적인 입력 결과 */ + GOOD, + + /** 부정적인 입력 결과 */ + BAD, +} + +/** + * Prezel TextField의 상태 기반 스타일 정보를 정의합니다. + * + * [interaction]과 [feedback] 조합을 통해 컨테이너 색상, 텍스트 색상, + * 아이콘 색상, 테두리 스타일 등의 파생 스타일을 계산합니다. + * + * 이 객체는 UI 상태를 표현하는 값 객체로 사용되며, + * 실제 색상 및 두께 계산 로직은 내부 함수에서 처리합니다. + * + * @property interaction TextField의 현재 상호작용 상태 + * @property feedback 입력 결과에 대한 피드백 상태 + */ +data class PrezelTextFieldStyle( + val interaction: PrezelTextFieldInteraction = PrezelTextFieldInteraction.DEFAULT, + val feedback: PrezelTextFieldFeedback = PrezelTextFieldFeedback.DEFAULT, +) { + /** + * TextField 컨테이너의 배경 색상을 반환합니다. + * + * 입력 완료(`TYPED`) 상태에서만 피드백에 따라 배경 색상이 적용되며, + * 그 외 상태에서는 투명한 색상을 반환합니다. + */ + @Composable + internal fun containerColor(colors: PrezelColors = PrezelTheme.colors): Color = + when (interaction) { + PrezelTextFieldInteraction.TYPED -> when (feedback) { + PrezelTextFieldFeedback.DEFAULT -> Color.Transparent + PrezelTextFieldFeedback.GOOD -> colors.feedbackGoodSmall + PrezelTextFieldFeedback.BAD -> colors.feedbackBadSmall + } + + else -> Color.Transparent + } + + /** + * TextField 내부 텍스트 색상을 반환합니다. + * + * 상호작용 상태와 피드백 상태에 따라 텍스트 대비를 조정하며, + * 다크 모드 여부에 따라 일부 색상이 달라질 수 있습니다. + */ + @Composable + internal fun textColor( + colors: PrezelColors = PrezelTheme.colors, + isDarkTheme: Boolean = isSystemInDarkTheme(), + ): Color = + when (interaction) { + PrezelTextFieldInteraction.DEFAULT -> colors.textSmall + PrezelTextFieldInteraction.DISABLED -> colors.textDisabled + PrezelTextFieldInteraction.TYPING -> colors.textLarge + PrezelTextFieldInteraction.TYPED -> when (feedback) { + PrezelTextFieldFeedback.DEFAULT -> colors.textRegular + else -> if (isDarkTheme) PrezelColorScheme.Light.textLarge else colors.textLarge + } + } + + /** + * TextField 우측 트레일링 아이콘의 색상을 반환합니다. + * + * 비활성화 상태에서는 비활성 색상을 사용하며, + * 입력 완료 상태에서는 피드백에 따라 아이콘 색상이 변경됩니다. + */ + @Composable + internal fun trailingIconColor(colors: PrezelColors = PrezelTheme.colors): Color = + when (interaction) { + PrezelTextFieldInteraction.DISABLED, + PrezelTextFieldInteraction.DEFAULT, + -> colors.iconDisabled + + PrezelTextFieldInteraction.TYPING -> colors.iconRegular + PrezelTextFieldInteraction.TYPED -> when (feedback) { + PrezelTextFieldFeedback.DEFAULT -> colors.iconRegular + PrezelTextFieldFeedback.GOOD -> colors.interactiveRegular + PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular + } + } + + /** + * TextField 테두리 스타일을 반환합니다. + * + * 상호작용 상태에 따라 테두리 두께가 달라지며, + * 입력 완료 상태에서는 피드백에 따라 테두리 색상이 변경됩니다. + */ + @Composable + internal fun borderStroke(colors: PrezelColors = PrezelTheme.colors): BorderStroke { + val borderWidth = when (interaction) { + PrezelTextFieldInteraction.DEFAULT, + PrezelTextFieldInteraction.DISABLED, + -> 1.dp + + PrezelTextFieldInteraction.TYPING, + PrezelTextFieldInteraction.TYPED, + -> 2.dp + } + + val borderColor = when (interaction) { + PrezelTextFieldInteraction.DISABLED -> colors.borderDisabled + PrezelTextFieldInteraction.DEFAULT -> colors.borderSmall + PrezelTextFieldInteraction.TYPING -> colors.borderMedium + PrezelTextFieldInteraction.TYPED -> when (feedback) { + PrezelTextFieldFeedback.DEFAULT -> colors.borderRegular + PrezelTextFieldFeedback.GOOD -> colors.interactiveRegular + PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular + } + } + + return BorderStroke(width = borderWidth, color = borderColor) + } +} From bf35a29153d7e2b8d037ffb4cf120e01f7010011 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 27 Jan 2026 23:53:04 +0900 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20`PrezelTextField`=20=EA=B3=B5?= =?UTF-8?q?=ED=86=B5=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 디자인 시스템에 사용될 공통 텍스트 필드 컴포넌트인 `PrezelTextField`를 추가했습니다. --- .../component/textfield/PrezelTextField.kt | 331 ++++++++++++++++++ ...tFieldStyle.kt => PrezelTextFieldState.kt} | 114 +++++- 2 files changed, 429 insertions(+), 16 deletions(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt rename Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/{PrezelTextFieldStyle.kt => PrezelTextFieldState.kt} (58%) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt new file mode 100644 index 0000000..daa2852 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt @@ -0,0 +1,331 @@ +package com.team.prezel.core.designsystem.component.textfield + +import androidx.compose.foundation.clickable +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.foundation.layout.width +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Icon +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.ripple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +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.draw.clip +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.button.PrezelButton +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.PreviewScaffold +import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +fun PrezelTextField( + value: String, + onValueChange: (String) -> Unit, + placeholder: String, + modifier: Modifier = Modifier, + label: String? = null, + trailingIcon: @Composable (() -> Unit)? = null, + feedback: PrezelTextFieldFeedback = PrezelTextFieldFeedback.NO_MESSAGE, + enabled: Boolean = true, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, +) { + var focused by remember { mutableStateOf(false) } + + val state = rememberPrezelTextFieldState( + value = value, + enabled = enabled, + focused = focused, + feedback = feedback, + ) + + PrezelTextField( + value = value, + onValueChange = onValueChange, + placeholder = if (focused) "" else placeholder, + state = state, + onFocusChange = { isFocused -> focused = isFocused }, + modifier = modifier, + label = label, + trailingIcon = trailingIcon, + enabled = enabled, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + ) +} + +@Composable +internal fun PrezelTextField( + value: String, + onValueChange: (String) -> Unit, + placeholder: String, + state: PrezelTextFieldState, + onFocusChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + label: String? = null, + trailingIcon: @Composable (() -> Unit)? = null, + enabled: Boolean = true, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, +) { + Column(modifier = modifier.fillMaxWidth()) { + label?.let { + PrezelTextFieldLabel(label = it) + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V8)) + } + + BasicTextField( + value = value, + onValueChange = onValueChange, + enabled = enabled, + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + .onFocusChanged { focusState -> onFocusChange(focusState.isFocused) }, + singleLine = true, + textStyle = PrezelTheme.typography.body2Regular.copy(color = state.textColor()), + cursorBrush = SolidColor(PrezelTheme.colors.interactiveRegular), + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + decorationBox = { innerTextField -> + PrezelTextFieldDecorationBox( + innerTextField = innerTextField, + value = value, + placeholder = placeholder, + trailingIcon = trailingIcon, + state = state, + ) + }, + ) + + if (state.supportingText.isNotEmpty()) { + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V8)) + PrezelTextFieldSupportingText(state = state) + } + } +} + +@Composable +private fun PrezelTextFieldDecorationBox( + innerTextField: @Composable () -> Unit, + value: String, + placeholder: String, + trailingIcon: @Composable (() -> Unit)?, + state: PrezelTextFieldState, + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier.fillMaxWidth(), + color = state.containerColor(), + shape = PrezelTheme.shapes.V8, + border = state.borderStroke(), + contentColor = state.textColor(), + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(PrezelTheme.spacing.V12), + verticalAlignment = Alignment.CenterVertically, + ) { + Box(modifier = Modifier.weight(1f)) { + innerTextField() + value.ifEmpty { + Text( + text = placeholder, + maxLines = 1, + style = PrezelTheme.typography.body2Regular, + color = PrezelTheme.colors.textSmall, + ) + } + } + + trailingIcon?.let { content -> + Spacer(modifier = Modifier.width(PrezelTheme.spacing.V8)) + CompositionLocalProvider( + LocalContentColor provides state.trailingIconColor(), + content = content, + ) + } + } + } +} + +@Composable +private fun PrezelTextFieldLabel( + label: String, + modifier: Modifier = Modifier, +) { + Text( + text = label, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + modifier = modifier, + maxLines = 1, + ) +} + +@Composable +private fun PrezelTextFieldSupportingText( + state: PrezelTextFieldState, + modifier: Modifier = Modifier, +) { + Text( + text = state.supportingText, + style = PrezelTheme.typography.body3Regular, + color = state.supportingTextColor(), + modifier = modifier, + maxLines = 1, + ) +} + +@ThemePreview +@Composable +private fun DefaultPrezelTextFieldPreview() { + PrezelTheme { + PreviewScaffold { + SectionTitle(title = "Default / Disabled") + PreviewTextFieldItem( + value = "", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.DEFAULT, + feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + ), + ) + + PreviewTextFieldItem( + value = "", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.DISABLED, + feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + ), + ) + } + } +} + +@ThemePreview +@Composable +private fun TypingPrezelTextFieldPreview() { + PrezelTheme { + PreviewScaffold { + SectionTitle(title = "Typing") + PreviewTextFieldItem( + value = "입력 중...", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPING, + feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + ), + ) + } + } +} + +@ThemePreview +@Composable +private fun TypedPrezelTextFieldPreview() { + PrezelTheme { + PreviewScaffold { + SectionTitle(title = "Typed") + PreviewTextFieldItem( + value = "입력함", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + ), + ) + PreviewTextFieldItem( + value = "입력함", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.GOOD("헬퍼 메시지"), + ), + ) + + PreviewTextFieldItem( + value = "입력함", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.BAD("헬퍼 메시지"), + ), + ) + } + } +} + +@ThemePreview +@Composable +private fun MainPrezelTextFieldPreview() { + var value by remember { mutableStateOf("") } + val focusManager = LocalFocusManager.current + + PrezelTheme { + PreviewScaffold { + PrezelTextField( + value = value, + onValueChange = { newValue -> value = newValue }, + placeholder = "플레이스홀더", + label = "레이블", + trailingIcon = { + Icon( + painter = painterResource(PrezelIcons.Cancel), + contentDescription = null, + modifier = Modifier + .clip(PrezelTheme.shapes.V6) + .clickable( + indication = ripple(), + interactionSource = null, + onClick = { value = "" }, + ), + ) + }, + feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + ) + + Spacer(modifier = Modifier.height(20.dp)) + PrezelButton( + text = "포커스 제거", + onClick = { focusManager.clearFocus() }, + ) + } + } +} + +@Composable +private fun PreviewTextFieldItem( + value: String, + state: PrezelTextFieldState, + modifier: Modifier = Modifier, +) { + PrezelTextField( + value = value, + onValueChange = {}, + placeholder = "플레이스홀더", + label = "레이블", + state = state, + modifier = modifier, + onFocusChange = {}, + ) + + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V16)) +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldStyle.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt similarity index 58% rename from Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldStyle.kt rename to Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt index 46d8c2c..a9d8441 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldStyle.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt @@ -3,11 +3,26 @@ package com.team.prezel.core.designsystem.component.textfield import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.foundation.color.PrezelColors import com.team.prezel.core.designsystem.theme.PrezelColorScheme import com.team.prezel.core.designsystem.theme.PrezelTheme +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.onEach /** * Prezel TextField의 상호작용 상태를 나타냅니다. @@ -34,15 +49,28 @@ enum class PrezelTextFieldInteraction { * * 입력이 완료된 이후(`TYPED`) 상태에서 시각적인 피드백을 제공하기 위해 사용됩니다. */ -enum class PrezelTextFieldFeedback { +@Stable +sealed interface PrezelTextFieldFeedback { + val message: String + /** 기본 상태 (피드백 없음) */ - DEFAULT, + data class DEFAULT( + override val message: String, + ) : PrezelTextFieldFeedback /** 긍정적인 입력 결과 */ - GOOD, + data class GOOD( + override val message: String, + ) : PrezelTextFieldFeedback /** 부정적인 입력 결과 */ - BAD, + data class BAD( + override val message: String, + ) : PrezelTextFieldFeedback + + companion object { + val NO_MESSAGE = DEFAULT(message = "") + } } /** @@ -57,10 +85,13 @@ enum class PrezelTextFieldFeedback { * @property interaction TextField의 현재 상호작용 상태 * @property feedback 입력 결과에 대한 피드백 상태 */ -data class PrezelTextFieldStyle( +@Immutable +data class PrezelTextFieldState( val interaction: PrezelTextFieldInteraction = PrezelTextFieldInteraction.DEFAULT, - val feedback: PrezelTextFieldFeedback = PrezelTextFieldFeedback.DEFAULT, + val feedback: PrezelTextFieldFeedback = PrezelTextFieldFeedback.NO_MESSAGE, ) { + val supportingText: String = feedback.message + /** * TextField 컨테이너의 배경 색상을 반환합니다. * @@ -71,9 +102,9 @@ data class PrezelTextFieldStyle( internal fun containerColor(colors: PrezelColors = PrezelTheme.colors): Color = when (interaction) { PrezelTextFieldInteraction.TYPED -> when (feedback) { - PrezelTextFieldFeedback.DEFAULT -> Color.Transparent - PrezelTextFieldFeedback.GOOD -> colors.feedbackGoodSmall - PrezelTextFieldFeedback.BAD -> colors.feedbackBadSmall + is PrezelTextFieldFeedback.DEFAULT -> Color.Transparent + is PrezelTextFieldFeedback.GOOD -> colors.feedbackGoodSmall + is PrezelTextFieldFeedback.BAD -> colors.feedbackBadSmall } else -> Color.Transparent @@ -95,11 +126,26 @@ data class PrezelTextFieldStyle( PrezelTextFieldInteraction.DISABLED -> colors.textDisabled PrezelTextFieldInteraction.TYPING -> colors.textLarge PrezelTextFieldInteraction.TYPED -> when (feedback) { - PrezelTextFieldFeedback.DEFAULT -> colors.textRegular + is PrezelTextFieldFeedback.DEFAULT -> colors.textRegular else -> if (isDarkTheme) PrezelColorScheme.Light.textLarge else colors.textLarge } } + /** + * TextField Supporting 텍스트 색상을 반환합니다. + */ + @Composable + internal fun supportingTextColor(colors: PrezelColors = PrezelTheme.colors): Color = + when (interaction) { + PrezelTextFieldInteraction.TYPED -> when (feedback) { + is PrezelTextFieldFeedback.DEFAULT -> colors.textRegular + is PrezelTextFieldFeedback.GOOD -> colors.feedbackGoodRegular + is PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular + } + + else -> PrezelTheme.colors.textRegular + } + /** * TextField 우측 트레일링 아이콘의 색상을 반환합니다. * @@ -115,9 +161,9 @@ data class PrezelTextFieldStyle( PrezelTextFieldInteraction.TYPING -> colors.iconRegular PrezelTextFieldInteraction.TYPED -> when (feedback) { - PrezelTextFieldFeedback.DEFAULT -> colors.iconRegular - PrezelTextFieldFeedback.GOOD -> colors.interactiveRegular - PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular + is PrezelTextFieldFeedback.DEFAULT -> colors.iconRegular + is PrezelTextFieldFeedback.GOOD -> colors.interactiveRegular + is PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular } } @@ -144,12 +190,48 @@ data class PrezelTextFieldStyle( PrezelTextFieldInteraction.DEFAULT -> colors.borderSmall PrezelTextFieldInteraction.TYPING -> colors.borderMedium PrezelTextFieldInteraction.TYPED -> when (feedback) { - PrezelTextFieldFeedback.DEFAULT -> colors.borderRegular - PrezelTextFieldFeedback.GOOD -> colors.interactiveRegular - PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular + is PrezelTextFieldFeedback.DEFAULT -> colors.borderRegular + is PrezelTextFieldFeedback.GOOD -> colors.interactiveRegular + is PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular } } return BorderStroke(width = borderWidth, color = borderColor) } } + +@OptIn(FlowPreview::class) +@Composable +internal fun rememberPrezelTextFieldState( + value: String, + enabled: Boolean, + focused: Boolean, + feedback: PrezelTextFieldFeedback, + idleMillis: Long = 1000L, +): PrezelTextFieldState { + var idleTyped by rememberSaveable { mutableStateOf(false) } + + LaunchedEffect(focused) { + if (!focused) idleTyped = false + } + + LaunchedEffect(value, focused, enabled) { + snapshotFlow { value } + .distinctUntilChanged() + .onEach { idleTyped = false } + .debounce(idleMillis) + .filter { focused && enabled } + .collectLatest { idleTyped = true } + } + + val interaction = remember(value, enabled, focused, idleTyped) { + when { + !enabled -> PrezelTextFieldInteraction.DISABLED + focused && !idleTyped -> PrezelTextFieldInteraction.TYPING + focused && idleTyped -> PrezelTextFieldInteraction.TYPED + else -> PrezelTextFieldInteraction.DEFAULT + } + } + + return remember(interaction, feedback) { PrezelTextFieldState(interaction = interaction, feedback = feedback) } +} From 97335ff5e299e44fe5c9b405d478cdc226cfb82d Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 28 Jan 2026 03:55:39 +0900 Subject: [PATCH 04/11] =?UTF-8?q?refactor:=20`PrezelTextFieldInteraction`?= =?UTF-8?q?=20=EC=83=81=ED=83=9C=20=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelTextField`의 상태(`PrezelTextFieldInteraction`)를 결정하는 로직을 `remember` 블록에서 `PrezelTextFieldInteraction`의 `companion object` 내 `calculate` 함수로 분리하여 재사용성과 가독성을 높였습니다. * **리팩토링**: `PrezelTextFieldInteraction`에 `calculate` 함수를 추가하고, `rememberPrezelTextFieldState` 내에서 이 함수를 호출하도록 변경했습니다. * **기타**: 코드 스타일에 맞춰 일부 `when` 표현식의 포맷팅을 수정했습니다. --- .../textfield/PrezelTextFieldState.kt | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt index a9d8441..cb92175 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt @@ -42,6 +42,21 @@ enum class PrezelTextFieldInteraction { /** 비활성화된 상태 */ DISABLED, + ; + + companion object { + fun calculate( + enabled: Boolean, + focused: Boolean, + idleTyped: Boolean, + ): PrezelTextFieldInteraction = + when { + !enabled -> PrezelTextFieldInteraction.DISABLED + focused && !idleTyped -> PrezelTextFieldInteraction.TYPING + focused && idleTyped -> PrezelTextFieldInteraction.TYPED + else -> PrezelTextFieldInteraction.DEFAULT + } + } } /** @@ -224,13 +239,8 @@ internal fun rememberPrezelTextFieldState( .collectLatest { idleTyped = true } } - val interaction = remember(value, enabled, focused, idleTyped) { - when { - !enabled -> PrezelTextFieldInteraction.DISABLED - focused && !idleTyped -> PrezelTextFieldInteraction.TYPING - focused && idleTyped -> PrezelTextFieldInteraction.TYPED - else -> PrezelTextFieldInteraction.DEFAULT - } + val interaction = remember(enabled, focused, idleTyped) { + PrezelTextFieldInteraction.calculate(enabled = enabled, focused = focused, idleTyped = idleTyped) } return remember(interaction, feedback) { PrezelTextFieldState(interaction = interaction, feedback = feedback) } From e7062c410d101e5f6e1b9cbc72bd318a2b2ec371 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 28 Jan 2026 03:56:36 +0900 Subject: [PATCH 05/11] =?UTF-8?q?style:=20PrezelTextFieldState=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelTextFieldState.kt` 파일 내 `when` 표현식의 코딩 스타일을 일관성 있게 수정했습니다. * `PrezelTextFieldInteraction.from` 메서드 내에서 불필요한 클래스 이름 반복을 제거했습니다. * `when` 블록의 화살표(->) 정렬을 통일하여 가독성을 개선했습니다. --- .../component/textfield/PrezelTextFieldState.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt index cb92175..79c4546 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt @@ -51,10 +51,10 @@ enum class PrezelTextFieldInteraction { idleTyped: Boolean, ): PrezelTextFieldInteraction = when { - !enabled -> PrezelTextFieldInteraction.DISABLED - focused && !idleTyped -> PrezelTextFieldInteraction.TYPING - focused && idleTyped -> PrezelTextFieldInteraction.TYPED - else -> PrezelTextFieldInteraction.DEFAULT + !enabled -> DISABLED + focused && !idleTyped -> TYPING + focused && idleTyped -> TYPED + else -> DEFAULT } } } From 902f52c73ebc0486859915e2678cdb4173b69213 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 28 Jan 2026 04:03:06 +0900 Subject: [PATCH 06/11] =?UTF-8?q?fix:=20`PrezelTextField`=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=9D=98=20=ED=94=84=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelTextField`의 `TrailingIconFilledEnabled` 프리뷰에서 `trailingIcon` 파라미터가 누락되어 발생하는 렌더링 오류를 수정했습니다. * `trailingIcon`에 `PrezelIcons.Blank`를 기본값으로 추가하여 컴포저블이 정상적으로 렌더링되도록 수정 --- .../designsystem/component/textfield/PrezelTextField.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt index daa2852..5323b58 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt @@ -325,6 +325,12 @@ private fun PreviewTextFieldItem( state = state, modifier = modifier, onFocusChange = {}, + trailingIcon = { + Icon( + painter = painterResource(PrezelIcons.Blank), + contentDescription = null, + ) + }, ) Spacer(modifier = Modifier.height(PrezelTheme.spacing.V16)) From 704906458f7b351abb1916e15c8abdbb9be61da6 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 29 Jan 2026 15:34:38 +0900 Subject: [PATCH 07/11] =?UTF-8?q?refactor:=20PrezelTextField=20=ED=94=8C?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=8A=A4=ED=99=80=EB=8D=94=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelTextField` 컴포넌트 내에서 플레이스홀더(`Text`)가 표시되는 조건을 기존의 확장 함수 `value.ifEmpty { ... }`에서 표준 `if (value.isEmpty()) { ... }` 조건문으로 변경했습니다. 이로 인해 코드의 명확성이 향상되었습니다. --- .../core/designsystem/component/textfield/PrezelTextField.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt index 5323b58..db697dc 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt @@ -150,7 +150,7 @@ private fun PrezelTextFieldDecorationBox( ) { Box(modifier = Modifier.weight(1f)) { innerTextField() - value.ifEmpty { + if (value.isEmpty()) { Text( text = placeholder, maxLines = 1, From dabab6e8e04780b83dd709e9079ad2a26efcd145 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 29 Jan 2026 15:35:49 +0900 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20`PrezelTextFieldState`=EC=9D=98=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EC=B0=B8=EC=A1=B0=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelTextFieldState` 내부에서 `PrezelTheme.colors`를 직접 참조하던 부분을 파라미터로 주입된 `colors` 객체를 사용하도록 수정하여, 컴포넌트가 올바른 테마 색상을 참조하도록 수정했습니다. --- .../designsystem/component/textfield/PrezelTextFieldState.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt index 79c4546..a2aa9ae 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt @@ -158,7 +158,7 @@ data class PrezelTextFieldState( is PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular } - else -> PrezelTheme.colors.textRegular + else -> colors.textRegular } /** From fd77d646a355471405440e0820f26cfd1f733e7d Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 29 Jan 2026 16:44:13 +0900 Subject: [PATCH 09/11] =?UTF-8?q?refactor:=20`PrezelTextField`=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EA=B4=80=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelTextField`의 상태 관리 로직을 개선하여 `Interaction` 계산과 `State` 생성을 분리하고, 타이핑 후 유휴 상태를 판별하는 로직을 최적화했습니다. * **관심사 분리**: 기존 `rememberPrezelTextFieldState` 함수를 `rememberPrezelTextFieldInteraction`으로 변경하여 상호작용(Interaction) 상태 계산을 전담하도록 수정했습니다. * **상태 감지 최적화**: `snapshotFlow`와 `rememberUpdatedState`를 사용하여 `value`, `enabled`, `focused`의 최신 상태를 안정적으로 감지하고, 이를 기반으로 유휴 상태(`isIdle`)를 판별하는 로직을 개선했습니다. * **로직 명료화**: `idleTyped` 파라미터를 `isIdle`로 변경하여 유휴 상태 여부를 더 명확하게 표현했습니다. * **상태 생성**: `PrezelTextField` 컴포저블 내에서 `rememberPrezelTextFieldInteraction`을 통해 얻은 `interaction` 값과 `feedback`을 조합하여 최종 `PrezelTextFieldState`를 생성하도록 구조를 변경했습니다. * **기타**: 디버깅 목적으로 추가되었던 `supportingText`의 임시 코드를 확인했습니다. (실제 텍스트 대신 `interaction` 상태를 표시하도록 변경됨) --- .../component/textfield/PrezelTextField.kt | 8 +-- .../textfield/PrezelTextFieldState.kt | 50 +++++++++---------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt index db697dc..000db88 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt @@ -53,12 +53,11 @@ fun PrezelTextField( ) { var focused by remember { mutableStateOf(false) } - val state = rememberPrezelTextFieldState( + val state = rememberPrezelTextFieldInteraction( value = value, enabled = enabled, focused = focused, - feedback = feedback, - ) + ).let { interaction -> PrezelTextFieldState(interaction = interaction, feedback = feedback) } PrezelTextField( value = value, @@ -191,7 +190,8 @@ private fun PrezelTextFieldSupportingText( modifier: Modifier = Modifier, ) { Text( - text = state.supportingText, +// text = state.supportingText, + text = state.interaction.toString(), style = PrezelTheme.typography.body3Regular, color = state.supportingTextColor(), modifier = modifier, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt index a2aa9ae..319a1cf 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt @@ -9,7 +9,7 @@ import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.graphics.Color @@ -21,7 +21,6 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.onEach /** @@ -48,13 +47,13 @@ enum class PrezelTextFieldInteraction { fun calculate( enabled: Boolean, focused: Boolean, - idleTyped: Boolean, + isIdle: Boolean, ): PrezelTextFieldInteraction = when { !enabled -> DISABLED - focused && !idleTyped -> TYPING - focused && idleTyped -> TYPED - else -> DEFAULT + !focused -> DEFAULT + !isIdle -> TYPING + else -> TYPED } } } @@ -172,7 +171,7 @@ data class PrezelTextFieldState( when (interaction) { PrezelTextFieldInteraction.DISABLED, PrezelTextFieldInteraction.DEFAULT, - -> colors.iconDisabled + -> colors.iconDisabled PrezelTextFieldInteraction.TYPING -> colors.iconRegular PrezelTextFieldInteraction.TYPED -> when (feedback) { @@ -193,11 +192,11 @@ data class PrezelTextFieldState( val borderWidth = when (interaction) { PrezelTextFieldInteraction.DEFAULT, PrezelTextFieldInteraction.DISABLED, - -> 1.dp + -> 1.dp PrezelTextFieldInteraction.TYPING, PrezelTextFieldInteraction.TYPED, - -> 2.dp + -> 2.dp } val borderColor = when (interaction) { @@ -217,31 +216,32 @@ data class PrezelTextFieldState( @OptIn(FlowPreview::class) @Composable -internal fun rememberPrezelTextFieldState( +internal fun rememberPrezelTextFieldInteraction( value: String, enabled: Boolean, focused: Boolean, - feedback: PrezelTextFieldFeedback, - idleMillis: Long = 1000L, -): PrezelTextFieldState { - var idleTyped by rememberSaveable { mutableStateOf(false) } + idleMillis: Long = 800L, +): PrezelTextFieldInteraction { + var isIdle by remember { mutableStateOf(false) } + val latestValue by rememberUpdatedState(value) + val latestEnabled by rememberUpdatedState(enabled) + val latestFocused by rememberUpdatedState(focused) LaunchedEffect(focused) { - if (!focused) idleTyped = false + if (!focused) isIdle = false } - LaunchedEffect(value, focused, enabled) { - snapshotFlow { value } + LaunchedEffect(idleMillis) { + snapshotFlow { latestValue } .distinctUntilChanged() - .onEach { idleTyped = false } + .onEach { isIdle = false } .debounce(idleMillis) - .filter { focused && enabled } - .collectLatest { idleTyped = true } + .collectLatest { if (latestEnabled && latestFocused) isIdle = true } } - val interaction = remember(enabled, focused, idleTyped) { - PrezelTextFieldInteraction.calculate(enabled = enabled, focused = focused, idleTyped = idleTyped) - } - - return remember(interaction, feedback) { PrezelTextFieldState(interaction = interaction, feedback = feedback) } + return PrezelTextFieldInteraction.calculate( + enabled = enabled, + focused = focused, + isIdle = isIdle, + ) } From 1ffe56556c549a64ae6ef5c48c0255d8cb2451f8 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 29 Jan 2026 16:45:42 +0900 Subject: [PATCH 10/11] =?UTF-8?q?refactor:=20PrezelTextFieldFeedback=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=AA=85=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EB=B0=8D=20=EC=BB=A8=EB=B2=A4=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelTextFieldFeedback`의 하위 데이터 클래스(`DEFAULT`, `GOOD`, `BAD`)의 이름을 PascalCase 네이밍 컨벤션에 맞춰 `Default`, `Good`, `Bad`로 변경했습니다. 이는 Kotlin의 클래스 및 객체 네이밍 표준을 따르기 위함이며, 코드의 일관성과 가독성을 개선합니다. 관련 클래스를 사용하는 `PrezelTextFieldState`와 `PrezelTextField`의 Preview 코드도 새로운 이름에 맞게 수정되었습니다. --- .../component/textfield/PrezelTextField.kt | 14 +++---- .../textfield/PrezelTextFieldState.kt | 40 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt index 000db88..497fa86 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt @@ -209,7 +209,7 @@ private fun DefaultPrezelTextFieldPreview() { value = "", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.DEFAULT, - feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), ), ) @@ -217,7 +217,7 @@ private fun DefaultPrezelTextFieldPreview() { value = "", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.DISABLED, - feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), ), ) } @@ -234,7 +234,7 @@ private fun TypingPrezelTextFieldPreview() { value = "입력 중...", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.TYPING, - feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), ), ) } @@ -251,14 +251,14 @@ private fun TypedPrezelTextFieldPreview() { value = "입력함", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), ), ) PreviewTextFieldItem( value = "입력함", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.GOOD("헬퍼 메시지"), + feedback = PrezelTextFieldFeedback.Good("헬퍼 메시지"), ), ) @@ -266,7 +266,7 @@ private fun TypedPrezelTextFieldPreview() { value = "입력함", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.BAD("헬퍼 메시지"), + feedback = PrezelTextFieldFeedback.Bad("헬퍼 메시지"), ), ) } @@ -299,7 +299,7 @@ private fun MainPrezelTextFieldPreview() { ), ) }, - feedback = PrezelTextFieldFeedback.DEFAULT("헬퍼 메시지"), + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), ) Spacer(modifier = Modifier.height(20.dp)) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt index 319a1cf..b78e6df 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextFieldState.kt @@ -68,22 +68,22 @@ sealed interface PrezelTextFieldFeedback { val message: String /** 기본 상태 (피드백 없음) */ - data class DEFAULT( + data class Default( override val message: String, ) : PrezelTextFieldFeedback /** 긍정적인 입력 결과 */ - data class GOOD( + data class Good( override val message: String, ) : PrezelTextFieldFeedback /** 부정적인 입력 결과 */ - data class BAD( + data class Bad( override val message: String, ) : PrezelTextFieldFeedback companion object { - val NO_MESSAGE = DEFAULT(message = "") + val NO_MESSAGE = Default(message = "") } } @@ -116,9 +116,9 @@ data class PrezelTextFieldState( internal fun containerColor(colors: PrezelColors = PrezelTheme.colors): Color = when (interaction) { PrezelTextFieldInteraction.TYPED -> when (feedback) { - is PrezelTextFieldFeedback.DEFAULT -> Color.Transparent - is PrezelTextFieldFeedback.GOOD -> colors.feedbackGoodSmall - is PrezelTextFieldFeedback.BAD -> colors.feedbackBadSmall + is PrezelTextFieldFeedback.Default -> Color.Transparent + is PrezelTextFieldFeedback.Good -> colors.feedbackGoodSmall + is PrezelTextFieldFeedback.Bad -> colors.feedbackBadSmall } else -> Color.Transparent @@ -140,7 +140,7 @@ data class PrezelTextFieldState( PrezelTextFieldInteraction.DISABLED -> colors.textDisabled PrezelTextFieldInteraction.TYPING -> colors.textLarge PrezelTextFieldInteraction.TYPED -> when (feedback) { - is PrezelTextFieldFeedback.DEFAULT -> colors.textRegular + is PrezelTextFieldFeedback.Default -> colors.textRegular else -> if (isDarkTheme) PrezelColorScheme.Light.textLarge else colors.textLarge } } @@ -152,9 +152,9 @@ data class PrezelTextFieldState( internal fun supportingTextColor(colors: PrezelColors = PrezelTheme.colors): Color = when (interaction) { PrezelTextFieldInteraction.TYPED -> when (feedback) { - is PrezelTextFieldFeedback.DEFAULT -> colors.textRegular - is PrezelTextFieldFeedback.GOOD -> colors.feedbackGoodRegular - is PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular + is PrezelTextFieldFeedback.Default -> colors.textRegular + is PrezelTextFieldFeedback.Good -> colors.feedbackGoodRegular + is PrezelTextFieldFeedback.Bad -> colors.feedbackBadRegular } else -> colors.textRegular @@ -171,13 +171,13 @@ data class PrezelTextFieldState( when (interaction) { PrezelTextFieldInteraction.DISABLED, PrezelTextFieldInteraction.DEFAULT, - -> colors.iconDisabled + -> colors.iconDisabled PrezelTextFieldInteraction.TYPING -> colors.iconRegular PrezelTextFieldInteraction.TYPED -> when (feedback) { - is PrezelTextFieldFeedback.DEFAULT -> colors.iconRegular - is PrezelTextFieldFeedback.GOOD -> colors.interactiveRegular - is PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular + is PrezelTextFieldFeedback.Default -> colors.iconRegular + is PrezelTextFieldFeedback.Good -> colors.interactiveRegular + is PrezelTextFieldFeedback.Bad -> colors.feedbackBadRegular } } @@ -192,11 +192,11 @@ data class PrezelTextFieldState( val borderWidth = when (interaction) { PrezelTextFieldInteraction.DEFAULT, PrezelTextFieldInteraction.DISABLED, - -> 1.dp + -> 1.dp PrezelTextFieldInteraction.TYPING, PrezelTextFieldInteraction.TYPED, - -> 2.dp + -> 2.dp } val borderColor = when (interaction) { @@ -204,9 +204,9 @@ data class PrezelTextFieldState( PrezelTextFieldInteraction.DEFAULT -> colors.borderSmall PrezelTextFieldInteraction.TYPING -> colors.borderMedium PrezelTextFieldInteraction.TYPED -> when (feedback) { - is PrezelTextFieldFeedback.DEFAULT -> colors.borderRegular - is PrezelTextFieldFeedback.GOOD -> colors.interactiveRegular - is PrezelTextFieldFeedback.BAD -> colors.feedbackBadRegular + is PrezelTextFieldFeedback.Default -> colors.borderRegular + is PrezelTextFieldFeedback.Good -> colors.interactiveRegular + is PrezelTextFieldFeedback.Bad -> colors.feedbackBadRegular } } From 494d2c5c65248f6c86327391253a06e0d03c9881 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 29 Jan 2026 17:23:41 +0900 Subject: [PATCH 11/11] =?UTF-8?q?fix:=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EB=B3=B4=EC=A1=B0=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 디버깅 목적으로 `state.interaction.toString()`을 출력하던 코드를 원래 의도인 `state.supportingText`로 복원하여 텍스트 필드의 보조 텍스트가 올바르게 표시되도록 수정했습니다. --- .../core/designsystem/component/textfield/PrezelTextField.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt index 497fa86..679def5 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt @@ -190,8 +190,7 @@ private fun PrezelTextFieldSupportingText( modifier: Modifier = Modifier, ) { Text( -// text = state.supportingText, - text = state.interaction.toString(), + text = state.supportingText, style = PrezelTheme.typography.body3Regular, color = state.supportingTextColor(), modifier = modifier,