From ada945db9ef6bdfcca360c357b4925874baef7f3 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 3 Mar 2026 23:06:57 +0900 Subject: [PATCH 1/8] =?UTF-8?q?refactor:=20PrezelTextFieldState=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EB=A1=9C=EC=A7=81=20=EB=8B=A8=EC=88=9C?= =?UTF-8?q?=ED=99=94=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelTextFieldState` 내부의 색상 결정 로직을 간소화하고 가독성을 개선했습니다. * `textColor` 함수에서 다크 모드 여부(`isDarkTheme`) 및 피드백 상태(`feedback`)에 따른 분기 로직을 제거하고, 입력이 완료된(`TYPED`) 상태에서도 일관되게 `colors.textLarge`를 반환하도록 수정했습니다. * 불필요한 파라미터(`isDarkTheme`)와 관련 import(`isSystemInDarkTheme`, `PrezelColorScheme`)를 제거했습니다. * `iconColor` 및 `borderStroke` 함수의 내부 `when` 문 코드 포맷을 정리했습니다. --- .../component/textfield/PrezelTextFieldState.kt | 14 +++----------- 1 file changed, 3 insertions(+), 11 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 b78e6df3..5e72a4aa 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 @@ -1,7 +1,6 @@ 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 @@ -15,7 +14,6 @@ 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 @@ -131,18 +129,12 @@ data class PrezelTextFieldState( * 다크 모드 여부에 따라 일부 색상이 달라질 수 있습니다. */ @Composable - internal fun textColor( - colors: PrezelColors = PrezelTheme.colors, - isDarkTheme: Boolean = isSystemInDarkTheme(), - ): Color = + internal fun textColor(colors: PrezelColors = PrezelTheme.colors): Color = when (interaction) { - PrezelTextFieldInteraction.DEFAULT -> colors.textSmall PrezelTextFieldInteraction.DISABLED -> colors.textDisabled + PrezelTextFieldInteraction.DEFAULT -> colors.textSmall PrezelTextFieldInteraction.TYPING -> colors.textLarge - PrezelTextFieldInteraction.TYPED -> when (feedback) { - is PrezelTextFieldFeedback.Default -> colors.textRegular - else -> if (isDarkTheme) PrezelColorScheme.Light.textLarge else colors.textLarge - } + PrezelTextFieldInteraction.TYPED -> colors.textLarge } /** From 639b04bf7a8db167603d7aeb45a522eb19c9db4e Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 3 Mar 2026 23:07:38 +0900 Subject: [PATCH 2/8] =?UTF-8?q?refactor:=20PreviewScaffold=EC=9D=98=20?= =?UTF-8?q?=EC=88=98=EC=A7=81=20=EC=A0=95=EB=A0=AC=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=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 `PreviewScaffold` 컴포저블에 `verticalArrangement` 파라미터를 추가하여 내부 레이아웃의 수직 정렬 방식을 외부에서 제어할 수 있도록 개선했습니다. * `verticalArrangement` 파라미터 추가 (기본값: `Arrangement.spacedBy(16.dp)`) * 기존에 하드코딩되어 있던 `Arrangement.spacedBy(16.dp)`를 전달받은 파라미터로 교체하여 유연성을 높임 --- .../prezel/core/designsystem/preview/PreviewComponent.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt index 2accea96..f91eaf85 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt @@ -25,7 +25,10 @@ import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.ImmutableList @Composable -internal fun PreviewScaffold(content: @Composable () -> Unit) { +internal fun PreviewScaffold( + verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(16.dp), + content: @Composable () -> Unit, +) { Scaffold( containerColor = PrezelTheme.colors.bgRegular, contentColor = PrezelTheme.colors.textLarge, @@ -36,7 +39,7 @@ internal fun PreviewScaffold(content: @Composable () -> Unit) { .fillMaxSize() .verticalScroll(rememberScrollState()) .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = verticalArrangement, ) { content() } From 9c0f9c1566350453ad44201f2f766fcf6a345ccf Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 3 Mar 2026 23:07:58 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20PrezelTextField=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8(Label,=20Suppo?= =?UTF-8?q?rtingText)=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PrezelTextField에서 공통으로 사용될 라벨과 보조 문구 컴포넌트를 추가했습니다. * **feat: PrezelTextFieldLabel 컴포넌트 추가** * 텍스트 필드 상단 등에 사용될 라벨 UI 구현 * `body3Medium` 타이포그래피 및 `textMedium` 색상 적용 * 컴포넌트 확인을 위한 `PrezelTextFieldLabelPreview` 추가 * **feat: PrezelTextFieldSupportingText 컴포넌트 추가** * `PrezelTextFieldState`에 따라 텍스트 색상이 동적으로 변경되는 보조 문구 UI 구현 * `body3Regular` 타이포그래피 적용 * 기본(Default), 오류(Bad), 성공(Good) 피드백 상태별 미리보기 추가 --- .../component/PrezelTextFieldLabel.kt | 31 ++++++++++ .../PrezelTextFieldSupportingText.kt | 60 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt new file mode 100644 index 00000000..2d4c46a9 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt @@ -0,0 +1,31 @@ +package com.team.prezel.core.designsystem.component.textfield.component + +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +internal fun PrezelTextFieldLabel( + label: String, + modifier: Modifier = Modifier, +) { + Text( + text = label, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + modifier = modifier, + maxLines = 1, + ) +} + +@ThemePreview +@Composable +private fun PrezelTextFieldLabelPreview() { + PrezelTheme { + PrezelTextFieldLabel(label = "Label", modifier = Modifier.padding(8.dp)) + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt new file mode 100644 index 00000000..e953fd62 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt @@ -0,0 +1,60 @@ +package com.team.prezel.core.designsystem.component.textfield.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldFeedback +import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldInteraction +import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldState +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +internal 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 PrezelTextFieldSupportingTextPreview() { + PrezelTheme { + Column( + modifier = Modifier.padding(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), + ), + ) + + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Bad("헬퍼 메시지"), + ), + ) + + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Good("헬퍼 메시지"), + ), + ) + } + } +} From 35c883bceee3bc40167058204dc8cc4527ff1111 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 3 Mar 2026 23:08:20 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20PrezelTextArea=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 디자인 시스템에 여러 줄 입력을 위한 `PrezelTextArea` 컴포넌트를 추가했습니다. * `BasicTextField`를 기반으로 하여 디자인 시스템의 레이블, 플레이스홀더, 글자 수 제한(`maxLength`) 및 카운터 표시 기능을 포함합니다. * `PrezelTextFieldState`와 연동하여 포커스 상태, 에러/성공 피드백 메세지, 비활성화 상태에 따른 스타일 처리를 구현했습니다. * `PrezelTextAreaDecorationBox`를 통해 배경색, 테두리, 패딩 등 일관된 입력창 디자인을 적용했습니다. * 다양한 상태(Default, Disabled, Typing, Feedback 등)를 확인할 수 있는 미리보기 코드를 추가했습니다. --- .../component/textfield/PrezelTextArea.kt | 302 ++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt new file mode 100644 index 00000000..294a281e --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt @@ -0,0 +1,302 @@ +package com.team.prezel.core.designsystem.component.textfield + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.text.style.LineHeightStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.button.PrezelButton +import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldLabel +import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldSupportingText +import com.team.prezel.core.designsystem.preview.PreviewScaffold +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +fun PrezelTextArea( + value: String, + onValueChange: (String) -> Unit, + placeholder: String, + maxLength: Int, + modifier: Modifier = Modifier, + label: String? = null, + feedback: PrezelTextFieldFeedback = PrezelTextFieldFeedback.NO_MESSAGE, + enabled: Boolean = true, + showCount: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, +) { + var focused by remember { mutableStateOf(false) } + + val state = rememberPrezelTextFieldInteraction( + value = value, + enabled = enabled, + focused = focused, + ).let { interaction -> PrezelTextFieldState(interaction = interaction, feedback = feedback) } + + PrezelTextArea( + value = value, + onValueChange = { newValue -> + if (newValue.length <= maxLength) onValueChange(newValue) + }, + placeholder = if (focused) "" else placeholder, + state = state, + maxLength = maxLength, + onFocusChange = { isFocused -> focused = isFocused }, + modifier = modifier, + label = label, + enabled = enabled, + showCount = showCount, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + ) +} + +@Composable +private fun PrezelTextArea( + value: String, + onValueChange: (String) -> Unit, + placeholder: String, + maxLength: Int, + state: PrezelTextFieldState, + onFocusChange: (Boolean) -> Unit, + label: String?, + enabled: Boolean, + showCount: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + modifier: Modifier = Modifier, +) { + 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() + .heightIn(min = 72.dp) + .onFocusChanged { focusState -> onFocusChange(focusState.isFocused) }, + textStyle = PrezelTheme.typography.body2Regular.copy(color = state.textColor()), + cursorBrush = SolidColor(PrezelTheme.colors.interactiveRegular), + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + decorationBox = { innerTextField -> + PrezelTextAreaDecorationBox( + innerTextField = innerTextField, + showPlaceholder = value.isEmpty(), + placeholder = placeholder, + state = state, + counter = { + if (showCount) { + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V16)) + Counter(currentLength = value.length, maxLength = maxLength, state = state) + } + }, + modifier = Modifier.heightIn(min = 72.dp), + ) + }, + ) + + if (state.supportingText.isNotEmpty()) { + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V8)) + PrezelTextFieldSupportingText(state = state) + } + } +} + +@Composable +private fun Counter( + currentLength: Int, + maxLength: Int, + state: PrezelTextFieldState, + modifier: Modifier = Modifier, +) { + Text( + text = "$currentLength / $maxLength", + style = PrezelTheme.typography.caption1Medium, + color = state.textColor(), + modifier = modifier.fillMaxWidth(), + textAlign = TextAlign.End, + ) +} + +@Composable +private fun PrezelTextAreaDecorationBox( + showPlaceholder: Boolean, + innerTextField: @Composable () -> Unit, + counter: @Composable () -> Unit, + placeholder: String, + state: PrezelTextFieldState, + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier.fillMaxWidth(), + color = state.containerColor(), + shape = PrezelTheme.shapes.V8, + border = state.borderStroke(), + contentColor = state.textColor(), + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(PrezelTheme.spacing.V12), + verticalArrangement = Arrangement.SpaceBetween, + ) { + Box { + innerTextField() + if (showPlaceholder) { + Text( + text = placeholder, + maxLines = 1, + style = PrezelTheme.typography.body2Regular.copy( + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + ), + color = PrezelTheme.colors.textSmall, + modifier = Modifier.fillMaxSize(), + ) + } + } + + counter() + } + } +} + +@ThemePreview +@Composable +private fun PrezelTextAreaPrezelPreview() { + PrezelTheme { + PreviewScaffold(verticalArrangement = Arrangement.spacedBy(4.dp)) { + PrezelTextAreaPreviewItem( + label = "Interaction - Default / Feedback - Default", + value = "", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.DEFAULT, + ), + ) + + PrezelTextAreaPreviewItem( + label = "Interaction - Disabled / Feedback - Default", + value = "typed", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.DISABLED, + ), + ) + + PrezelTextAreaPreviewItem( + label = "Interaction - Typing / Feedback - Default", + value = "typing...", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPING, + ), + ) + + PrezelTextAreaPreviewItem( + label = "Interaction - Typed / Feedback - Default", + value = "typed", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), + ), + ) + PrezelTextAreaPreviewItem( + label = "Interaction - Typed / Feedback - Good", + value = "typed", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Good("헬퍼 메시지"), + ), + ) + + PrezelTextAreaPreviewItem( + label = "Interaction - Typed / Feedback - Bad", + value = "typed", + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Bad("헬퍼 메시지"), + ), + ) + } + } +} + +@ThemePreview +@Composable +private fun MainPrezelTextAreaPreview() { + var value by remember { mutableStateOf("") } + val focusManager = LocalFocusManager.current + + PrezelTheme { + PreviewScaffold { + PrezelTextArea( + value = value, + onValueChange = { newValue -> value = newValue }, + maxLength = 100, + placeholder = "플레이스홀더", + label = "레이블", + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), + showCount = true, + ) + + Spacer(modifier = Modifier.height(20.dp)) + PrezelButton( + text = "포커스 제거", + onClick = { focusManager.clearFocus() }, + ) + } + } +} + +@Composable +private fun PrezelTextAreaPreviewItem( + label: String, + value: String, + state: PrezelTextFieldState, + modifier: Modifier = Modifier, +) { + PrezelTextArea( + value = value, + onValueChange = {}, + placeholder = "Placeholder", + label = label, + state = state, + maxLength = 100, + modifier = modifier, + onFocusChange = {}, + enabled = true, + showCount = true, + keyboardOptions = KeyboardOptions.Default, + keyboardActions = KeyboardActions.Default, + ) + + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V16)) +} From ff3bd1cfe6a469f8a7d61da3db0497f360ac4216 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 3 Mar 2026 23:30:31 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20PrezelTextField=20=EB=B0=8F=20P?= =?UTF-8?q?rezelTextArea=20=EC=9E=85=EB=A0=A5=20=EC=A0=95=EC=B1=85=20?= =?UTF-8?q?=EA=B0=95=ED=99=94=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 입력 필드 컴포넌트의 가독성을 높이고, 공통적인 입력 정책(줄바꿈 방지 및 최대 길이 제한)을 적용하였습니다. * **feat: TextField 및 TextArea 입력 정책 추가** * `applyTextFieldPolicy`, `applyTextAreaPolicy`를 추가하여 모든 입력값에서 줄바꿈(`\n`)을 제거하고 `maxLength`에 맞춰 문자열을 자르도록 로직을 공용화했습니다. * `PrezelTextField`에 `maxLength` 파라미터를 추가했습니다. * **refactor: PrezelTextField 내부 구현 및 레이아웃 최적화** * `PrezelTextField`의 접근 제어자를 `internal`에서 `private`으로 변경했습니다. * `PrezelTextFieldDecorationBox`에 `value` 대신 `showPlaceholder` boolean 값을 전달하도록 변경하여 역할을 단순화했습니다. * 플레이스홀더 텍스트에 `LineHeightStyle`을 적용하고 `fillMaxSize()`를 설정하여 텍스트 정렬 및 레이아웃 안정성을 개선했습니다. * 별도 파일로 분리된 `PrezelTextFieldLabel`, `PrezelTextFieldSupportingText` 컴포넌트를 사용하도록 수정했습니다. * **style: 미리보기(Preview) 코드 정리** * `PrezelTextFieldPreview` 내의 중복된 섹션 타이틀을 제거하고 `Arrangement.spacedBy(8.dp)`를 적용하여 가독성을 높였습니다. * 프리뷰 아이템의 레이블을 인터랙션 상태와 피드백 상태를 명시하도록 업데이트했습니다. * `PrezelTextArea` 프리뷰의 불필요한 초기 입력값을 제거했습니다. --- .../component/textfield/PrezelTextArea.kt | 13 ++- .../component/textfield/PrezelTextField.kt | 108 +++++++----------- 2 files changed, 55 insertions(+), 66 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt index 294a281e..3f1ce3ff 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt @@ -58,7 +58,8 @@ fun PrezelTextArea( PrezelTextArea( value = value, onValueChange = { newValue -> - if (newValue.length <= maxLength) onValueChange(newValue) + val applied = applyTextAreaPolicy(newValue, maxLength) + if (applied != value) onValueChange(applied) }, placeholder = if (focused) "" else placeholder, state = state, @@ -73,6 +74,14 @@ fun PrezelTextArea( ) } +private fun applyTextAreaPolicy( + value: String, + maxLength: Int, +): String = + value + .replace("\n", "") + .take(maxLength) + @Composable private fun PrezelTextArea( value: String, @@ -206,7 +215,7 @@ private fun PrezelTextAreaPrezelPreview() { PrezelTextAreaPreviewItem( label = "Interaction - Disabled / Feedback - Default", - value = "typed", + value = "", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.DISABLED, ), 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 679def53..fce4de46 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 @@ -1,10 +1,12 @@ package com.team.prezel.core.designsystem.component.textfield import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement 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.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -30,11 +32,13 @@ 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.text.style.LineHeightStyle import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.button.PrezelButton +import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldLabel +import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldSupportingText 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 @@ -48,6 +52,7 @@ fun PrezelTextField( trailingIcon: @Composable (() -> Unit)? = null, feedback: PrezelTextFieldFeedback = PrezelTextFieldFeedback.NO_MESSAGE, enabled: Boolean = true, + maxLength: Int = Int.MAX_VALUE, keyboardOptions: KeyboardOptions = KeyboardOptions.Default, keyboardActions: KeyboardActions = KeyboardActions.Default, ) { @@ -61,7 +66,10 @@ fun PrezelTextField( PrezelTextField( value = value, - onValueChange = onValueChange, + onValueChange = { newValue -> + val applied = applyTextFieldPolicy(newValue, maxLength) + if (applied != value) onValueChange(applied) + }, placeholder = if (focused) "" else placeholder, state = state, onFocusChange = { isFocused -> focused = isFocused }, @@ -74,8 +82,16 @@ fun PrezelTextField( ) } +private fun applyTextFieldPolicy( + value: String, + maxLength: Int, +): String = + value + .replace("\n", "") + .take(maxLength) + @Composable -internal fun PrezelTextField( +private fun PrezelTextField( value: String, onValueChange: (String) -> Unit, placeholder: String, @@ -110,7 +126,7 @@ internal fun PrezelTextField( decorationBox = { innerTextField -> PrezelTextFieldDecorationBox( innerTextField = innerTextField, - value = value, + showPlaceholder = value.isEmpty(), placeholder = placeholder, trailingIcon = trailingIcon, state = state, @@ -127,8 +143,8 @@ internal fun PrezelTextField( @Composable private fun PrezelTextFieldDecorationBox( + showPlaceholder: Boolean, innerTextField: @Composable () -> Unit, - value: String, placeholder: String, trailingIcon: @Composable (() -> Unit)?, state: PrezelTextFieldState, @@ -149,12 +165,18 @@ private fun PrezelTextFieldDecorationBox( ) { Box(modifier = Modifier.weight(1f)) { innerTextField() - if (value.isEmpty()) { + if (showPlaceholder) { Text( text = placeholder, maxLines = 1, - style = PrezelTheme.typography.body2Regular, + style = PrezelTheme.typography.body2Regular.copy( + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + ), color = PrezelTheme.colors.textSmall, + modifier = Modifier.fillMaxSize(), ) } } @@ -170,41 +192,13 @@ private fun PrezelTextFieldDecorationBox( } } -@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() { +private fun PrezelTextFieldPreview() { PrezelTheme { - PreviewScaffold { - SectionTitle(title = "Default / Disabled") + PreviewScaffold(verticalArrangement = Arrangement.spacedBy(8.dp)) { PreviewTextFieldItem( + label = "Interaction - Default / Feedback - Default", value = "", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.DEFAULT, @@ -213,48 +207,32 @@ private fun DefaultPrezelTextFieldPreview() { ) PreviewTextFieldItem( + label = "Interaction - Disabled / Feedback - Default", value = "", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.DISABLED, feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), ), ) - } - } -} - -@ThemePreview -@Composable -private fun TypingPrezelTextFieldPreview() { - PrezelTheme { - PreviewScaffold { - SectionTitle(title = "Typing") PreviewTextFieldItem( - value = "입력 중...", + label = "Interaction - Typing / Feedback - Default", + value = "typing...", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.TYPING, feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), ), ) - } - } -} - -@ThemePreview -@Composable -private fun TypedPrezelTextFieldPreview() { - PrezelTheme { - PreviewScaffold { - SectionTitle(title = "Typed") PreviewTextFieldItem( - value = "입력함", + label = "Interaction - Typed / Feedback - Default", + value = "typed", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.TYPED, feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), ), ) PreviewTextFieldItem( - value = "입력함", + label = "Interaction - Typed / Feedback - Good", + value = "typed", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.TYPED, feedback = PrezelTextFieldFeedback.Good("헬퍼 메시지"), @@ -262,7 +240,8 @@ private fun TypedPrezelTextFieldPreview() { ) PreviewTextFieldItem( - value = "입력함", + label = "Interaction - Typed / Feedback - Bad", + value = "typed", state = PrezelTextFieldState( interaction = PrezelTextFieldInteraction.TYPED, feedback = PrezelTextFieldFeedback.Bad("헬퍼 메시지"), @@ -312,6 +291,7 @@ private fun MainPrezelTextFieldPreview() { @Composable private fun PreviewTextFieldItem( + label: String, value: String, state: PrezelTextFieldState, modifier: Modifier = Modifier, @@ -319,8 +299,8 @@ private fun PreviewTextFieldItem( PrezelTextField( value = value, onValueChange = {}, - placeholder = "플레이스홀더", - label = "레이블", + placeholder = "Placeholder", + label = label, state = state, modifier = modifier, onFocusChange = {}, From 5e56b942066b0707e2b55552d4fba26c0f703168 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 3 Mar 2026 23:42:02 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20PrezelTextField=20=EB=B0=8F=20P?= =?UTF-8?q?rezelTextArea=20=EB=82=B4=20Placeholder=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 중복되는 Placeholder UI 코드를 별도의 컴포넌트로 분리하여 재사용성을 높이고 코드를 정렬했습니다. * **feat: PrezelTextFieldPlaceholder 컴포넌트 추가** * `PrezelTextField`와 `PrezelTextArea`에서 공통으로 사용되는 Placeholder UI를 `PrezelTextFieldPlaceholder`로 추출했습니다. * 디자인 시스템의 `body2Regular` 타이포그래피와 `textSmall` 색상 토큰을 적용했습니다. * **refactor: 기존 텍스트 필드 컴포넌트에 공통 Placeholder 적용** * `PrezelTextField`: 하드코딩된 `Text` 컴포저블을 `PrezelTextFieldPlaceholder`로 교체하고 불필요한 `Modifier.fillMaxSize()`를 제거했습니다. * `PrezelTextArea`: 하드코딩된 `Text` 컴포저블을 `PrezelTextFieldPlaceholder`로 교체하고 관련 import 문을 정리했습니다. --- .../component/textfield/PrezelTextArea.kt | 18 +-------- .../component/textfield/PrezelTextField.kt | 19 +-------- .../component/PrezelTextFieldPlaceholder.kt | 40 +++++++++++++++++++ 3 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt index 3f1ce3ff..ed4da54f 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt @@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn @@ -23,11 +22,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.text.style.LineHeightStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.button.PrezelButton import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldLabel +import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldPlaceholder import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldSupportingText import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.preview.ThemePreview @@ -179,20 +178,7 @@ private fun PrezelTextAreaDecorationBox( ) { Box { innerTextField() - if (showPlaceholder) { - Text( - text = placeholder, - maxLines = 1, - style = PrezelTheme.typography.body2Regular.copy( - lineHeightStyle = LineHeightStyle( - alignment = LineHeightStyle.Alignment.Center, - trim = LineHeightStyle.Trim.None, - ), - ), - color = PrezelTheme.colors.textSmall, - modifier = Modifier.fillMaxSize(), - ) - } + if (showPlaceholder) PrezelTextFieldPlaceholder(placeholder = placeholder) } counter() 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 fce4de46..10250799 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 @@ -6,7 +6,6 @@ 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.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -17,7 +16,6 @@ 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 @@ -32,10 +30,10 @@ 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.text.style.LineHeightStyle import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.button.PrezelButton import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldLabel +import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldPlaceholder import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldSupportingText import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.PreviewScaffold @@ -165,20 +163,7 @@ private fun PrezelTextFieldDecorationBox( ) { Box(modifier = Modifier.weight(1f)) { innerTextField() - if (showPlaceholder) { - Text( - text = placeholder, - maxLines = 1, - style = PrezelTheme.typography.body2Regular.copy( - lineHeightStyle = LineHeightStyle( - alignment = LineHeightStyle.Alignment.Center, - trim = LineHeightStyle.Trim.None, - ), - ), - color = PrezelTheme.colors.textSmall, - modifier = Modifier.fillMaxSize(), - ) - } + if (showPlaceholder) PrezelTextFieldPlaceholder(placeholder = placeholder) } trailingIcon?.let { content -> diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt new file mode 100644 index 00000000..c32ac194 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt @@ -0,0 +1,40 @@ +package com.team.prezel.core.designsystem.component.textfield.component + +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.LineHeightStyle +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +internal fun PrezelTextFieldPlaceholder( + placeholder: String, + modifier: Modifier = Modifier, +) { + Text( + text = placeholder, + maxLines = 1, + style = PrezelTheme.typography.body2Regular.copy( + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + ), + color = PrezelTheme.colors.textSmall, + modifier = modifier, + ) +} + +@ThemePreview +@Composable +private fun PrezelTextFieldPlaceholderPreview() { + PrezelTheme { + PrezelTextFieldPlaceholder( + placeholder = "Placeholder", + modifier = Modifier.padding(16.dp), + ) + } +} From 4777c41ce60abc090d3efcd8659b2e2080acc07b Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 3 Mar 2026 23:51:26 +0900 Subject: [PATCH 7/8] =?UTF-8?q?chore:=20detekt=20LongMethod=20=EC=9E=84?= =?UTF-8?q?=EA=B3=84=EC=B9=98=20=EC=99=84=ED=99=94=20=EB=B0=8F=20Preview?= =?UTF-8?q?=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EB=AC=B4?= =?UTF-8?q?=EC=8B=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `detekt-config.yml`의 `LongMethod` 규칙 설정을 변경하여 코드 검사 기준을 완화했습니다. * `LongMethod` 임계치(threshold)를 40에서 50으로 상향 조정했습니다. * `Preview` 및 `ThemePreview` 어노테이션이 붙은 메서드는 `LongMethod` 검사 대상에서 제외되도록 설정했습니다. --- Prezel/detekt-config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Prezel/detekt-config.yml b/Prezel/detekt-config.yml index fb220f26..b7597b2f 100644 --- a/Prezel/detekt-config.yml +++ b/Prezel/detekt-config.yml @@ -33,7 +33,10 @@ complexity: active: true LongMethod: active: true - threshold: 40 + threshold: 50 + ignoreAnnotated: + - Preview + - ThemePreview LongParameterList: active: false CyclomaticComplexMethod: From 1882b368ba60e23c1ef7e28ac69a8cb3e8108386 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 4 Mar 2026 00:12:13 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20PrezelTextArea=20=EB=B0=8F=20Pr?= =?UTF-8?q?ezelTextField=20=EB=82=B4=20maxLength=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 텍스트 입력 컴포넌트의 정책 적용 로직에서 발생할 수 있는 잠재적인 오류를 방지하기 위해 유효성 검사 로직을 강화했습니다. * `applyTextAreaPolicy` 및 `applyTextFieldPolicy` 함수에 `maxLength`가 0 이상인지 확인하는 `require` 구문을 추가했습니다. * 가독성을 위해 단일 표현식 형태의 함수 구조를 블록 형태로 변경했습니다. --- .../core/designsystem/component/textfield/PrezelTextArea.kt | 6 ++++-- .../designsystem/component/textfield/PrezelTextField.kt | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt index ed4da54f..b8c84d08 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt @@ -76,10 +76,12 @@ fun PrezelTextArea( private fun applyTextAreaPolicy( value: String, maxLength: Int, -): String = - value +): String { + require(maxLength >= 0) { "maxLength must be >= 0" } + return value .replace("\n", "") .take(maxLength) +} @Composable private fun PrezelTextArea( 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 10250799..e754dbc5 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 @@ -83,10 +83,12 @@ fun PrezelTextField( private fun applyTextFieldPolicy( value: String, maxLength: Int, -): String = - value +): String { + require(maxLength >= 0) { "maxLength must be >= 0" } + return value .replace("\n", "") .take(maxLength) +} @Composable private fun PrezelTextField(