Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REFACTOR/#215] ConstraintLayout 사용을 제거하고 UI 리팩토링을 실시합니다. #217

Merged
merged 12 commits into from
Feb 2, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[REFACTOR/#215] HandleColor 수정 및 error조건 추가
  • Loading branch information
MoonsuKang committed Sep 14, 2024
commit 55e1f3153bea8054086c5301503adf3f1f4d433f
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.selection.LocalTextSelectionColors
import androidx.compose.foundation.text.selection.TextSelectionColors
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
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
Expand Down Expand Up @@ -49,125 +52,138 @@ fun WriteDiaryTextField(
) {
var isTextValid by remember { mutableStateOf(text.replace("\\s".toRegex(), "").matches(Regex("^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣\\W]{2,50}$"))) }
var isFocused by remember { mutableStateOf(false) }
var isTextTooLong by remember { mutableStateOf(false) }

Column(
modifier = modifier
.fillMaxWidth()
) {
Box(
modifier = Modifier
.background(
if (isFocused || (showWarning && text.isEmpty())) ClodyTheme.colors.white
else ClodyTheme.colors.gray09,
shape = RoundedCornerShape(10.dp)
)
.border(
if (isFocused || showWarning) {
1.dp
} else {
0.dp
},
when {
showWarning && !isTextValid -> ClodyTheme.colors.red
isFocused -> ClodyTheme.colors.mainYellow
showWarning && text.isEmpty() -> ClodyTheme.colors.red
else -> Color.Transparent
},
RoundedCornerShape(10.dp)
)
.heightIn(min = 50.dp) // 최소 높이를 50dp로 설정
.fillMaxWidth() // 너비를 부모의 너비로 채움
.padding(vertical = 12.dp, horizontal = 8.dp)
val customTextSelectionColors = TextSelectionColors(
handleColor = ClodyTheme.colors.mainYellow,
backgroundColor = ClodyTheme.colors.mainYellow.copy(alpha = 0.4f)
)

CompositionLocalProvider(LocalTextSelectionColors provides customTextSelectionColors) {
Column(
modifier = modifier
.fillMaxWidth()
) {
Row(
verticalAlignment = Alignment.CenterVertically,
Box(
modifier = Modifier
.fillMaxWidth() // Row의 너비를 Box의 너비로 채움
.background(
if (isFocused || (showWarning && text.isEmpty())) ClodyTheme.colors.white
else ClodyTheme.colors.gray09,
shape = RoundedCornerShape(10.dp)
)
.border(
if (isFocused || showWarning || isTextTooLong) {
1.dp
} else {
0.dp
},
when {
isTextTooLong -> ClodyTheme.colors.red
showWarning && !isTextValid -> ClodyTheme.colors.red
isFocused -> ClodyTheme.colors.mainYellow
showWarning && text.isEmpty() -> ClodyTheme.colors.red
else -> Color.Transparent
},
RoundedCornerShape(10.dp)
)
.heightIn(min = 50.dp) // 최소 높이를 50dp로 설정
.fillMaxWidth() // 너비를 부모의 너비로 채움
.padding(vertical = 12.dp, horizontal = 8.dp)
) {
Text(
text = "$entryNumber.",
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.padding(start = 16.dp, top = 5.dp)
.align(Alignment.Top),
style = ClodyTheme.typography.body2SemiBold,
color = if (text.isNotEmpty()) ClodyTheme.colors.gray01 else ClodyTheme.colors.gray06
)
Spacer(modifier = Modifier.width(8.dp))
BasicTextField(
value = text,
onValueChange = {
if (it.length <= maxLength) {
onTextChange(it)
val textWithoutSpaces = it.replace("\\s".toRegex(), "")
isTextValid = textWithoutSpaces.matches(Regex("^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,50}$"))
}
},
textStyle = TextStyle(
color = if (text.isEmpty()) ClodyTheme.colors.gray06 else ClodyTheme.colors.gray01
),
cursorBrush = SolidColor(ClodyTheme.colors.gray01),
decorationBox = { innerTextField ->
if (text.isEmpty()) {
Text(
text = "일상 속 작은 감사함을 적어보세요",
style = ClodyTheme.typography.body3Medium,
color = ClodyTheme.colors.gray06
)
}
innerTextField()
},
modifier = Modifier
.weight(1f)
.onFocusChanged { isFocused = it.isFocused }
)

IconButton(
onClick = onRemove,
modifier = Modifier.size(28.dp)
.fillMaxWidth() // Row의 너비를 Box의 너비로 채움
) {
Image(
painter = painterResource(id = R.drawable.ic_writediary_kebab),
contentDescription = "Remove"
Text(
text = "$entryNumber.",
modifier = Modifier
.padding(start = 16.dp, top = 5.dp)
.align(Alignment.Top),
style = ClodyTheme.typography.body2SemiBold,
color = if (text.isNotEmpty()) ClodyTheme.colors.gray01 else ClodyTheme.colors.gray06
)
Spacer(modifier = Modifier.width(8.dp))
BasicTextField(
value = text,
onValueChange = {
if (it.length <= maxLength) {
onTextChange(it)
val textWithoutSpaces = it.replace("\\s".toRegex(), "")
isTextValid = textWithoutSpaces.matches(Regex("^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,50}$"))
isTextTooLong = false
} else {
isTextTooLong = true
}
},
textStyle = TextStyle(
color = if (text.isEmpty()) ClodyTheme.colors.gray06 else ClodyTheme.colors.gray01
),
cursorBrush = SolidColor(ClodyTheme.colors.gray01),
decorationBox = { innerTextField ->
if (text.isEmpty()) {
Text(
text = "일상 속 작은 감사함을 적어보세요",
style = ClodyTheme.typography.body3Medium,
color = ClodyTheme.colors.gray06
)
}
innerTextField()
},
modifier = Modifier
.weight(1f)
.onFocusChanged { isFocused = it.isFocused }
)
}

}
}
IconButton(
onClick = onRemove,
modifier = Modifier.size(28.dp)
) {
Image(
painter = painterResource(id = R.drawable.ic_writediary_kebab),
contentDescription = "Remove"
)
}

Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 8.dp, top = 6.dp)
) {
if (showWarning && !isTextValid && text.isNotEmpty()) {
Text(
text = "2~50자 까지 입력할 수 있어요. ",
color = ClodyTheme.colors.red,
style = ClodyTheme.typography.detail1Medium,
modifier = Modifier.weight(1f)
)
} else {
Spacer(modifier = Modifier.weight(1f))
}
}

val annotatedString = buildAnnotatedString {
withStyle(style = SpanStyle(color = ClodyTheme.colors.gray04)) {
append("${text.length}")
}
withStyle(style = SpanStyle(color = ClodyTheme.colors.gray06)) {
append(" / ")
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 8.dp, top = 6.dp)
) {
if ((showWarning && !isTextValid && text.isNotEmpty()) || isTextTooLong) {
Text(
text = "2~50자 까지 입력할 수 있어요.",
color = ClodyTheme.colors.red,
style = ClodyTheme.typography.detail1Medium,
modifier = Modifier.weight(1f)
)
} else {
Spacer(modifier = Modifier.weight(1f))
}
withStyle(style = SpanStyle(color = ClodyTheme.colors.gray06)) {
append("$maxLength")

val annotatedString = buildAnnotatedString {
withStyle(style = SpanStyle(color = ClodyTheme.colors.gray04)) {
append("${text.length}")
}
withStyle(style = SpanStyle(color = ClodyTheme.colors.gray06)) {
append(" / ")
}
withStyle(style = SpanStyle(color = ClodyTheme.colors.gray06)) {
append("$maxLength")
}
}
}

Text(
text = annotatedString,
style = ClodyTheme.typography.detail1Medium,
modifier = Modifier
.align(Alignment.CenterVertically)
)
Text(
text = annotatedString,
style = ClodyTheme.typography.detail1Medium,
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(end = 8.dp)
)
}
}
}
}
Expand Down