-
Notifications
You must be signed in to change notification settings - Fork 3
[REFACTOR] QA 반영 #111
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] QA 반영 #111
Changes from all commits
633557a
8e5cee4
a0bb368
ce25137
616608a
ba47bd9
ef4b7e9
98c5953
a7e7dd6
ff4da7d
67d7cdc
60ecacb
20222ef
b000d81
619cae4
80711ea
c82b822
ca77fa2
db817d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,5 @@ | ||||||||||||||||||||||||||
| package com.texthip.thip.ui.common.forms | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| import android.view.KeyEvent | ||||||||||||||||||||||||||
| import androidx.compose.foundation.background | ||||||||||||||||||||||||||
| import androidx.compose.foundation.border | ||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Box | ||||||||||||||||||||||||||
|
|
@@ -12,16 +11,16 @@ import androidx.compose.foundation.text.KeyboardOptions | |||||||||||||||||||||||||
| import androidx.compose.runtime.Composable | ||||||||||||||||||||||||||
| 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.ui.Alignment | ||||||||||||||||||||||||||
| import androidx.compose.ui.Modifier | ||||||||||||||||||||||||||
| import androidx.compose.ui.graphics.Color | ||||||||||||||||||||||||||
| import androidx.compose.ui.graphics.SolidColor | ||||||||||||||||||||||||||
| import androidx.compose.ui.input.key.KeyEventType | ||||||||||||||||||||||||||
| import androidx.compose.ui.input.key.onKeyEvent | ||||||||||||||||||||||||||
| import androidx.compose.ui.input.key.type | ||||||||||||||||||||||||||
| import androidx.compose.ui.text.TextRange | ||||||||||||||||||||||||||
| import androidx.compose.ui.text.input.KeyboardType | ||||||||||||||||||||||||||
| import androidx.compose.ui.text.input.TextFieldValue | ||||||||||||||||||||||||||
| import androidx.compose.ui.text.style.TextAlign | ||||||||||||||||||||||||||
| import androidx.compose.ui.tooling.preview.Preview | ||||||||||||||||||||||||||
| import androidx.compose.ui.unit.dp | ||||||||||||||||||||||||||
|
|
@@ -39,6 +38,15 @@ fun SingleDigitBox( | |||||||||||||||||||||||||
| containerColor: Color = colors.darkGray01, | ||||||||||||||||||||||||||
| borderColor: Color = Color.Transparent | ||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||
| // TextFieldValue로 커서 위치 제어 | ||||||||||||||||||||||||||
| val textFieldValue = remember(value) { | ||||||||||||||||||||||||||
| val displayText = value.ifEmpty { "\u200B" } // Zero Width Space | ||||||||||||||||||||||||||
| TextFieldValue( | ||||||||||||||||||||||||||
| text = displayText, | ||||||||||||||||||||||||||
| selection = TextRange(displayText.length) // 커서를 맨 끝에 위치 | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| val myStyle = typography.smalltitle_sb600_s18_h24.copy( | ||||||||||||||||||||||||||
| lineHeight = 20.sp, | ||||||||||||||||||||||||||
| textAlign = TextAlign.Center, | ||||||||||||||||||||||||||
|
|
@@ -53,37 +61,32 @@ fun SingleDigitBox( | |||||||||||||||||||||||||
| contentAlignment = Alignment.Center | ||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||
| BasicTextField( | ||||||||||||||||||||||||||
| value = value, | ||||||||||||||||||||||||||
| onValueChange = { input -> | ||||||||||||||||||||||||||
| val filtered = input.filter { it.isDigit() }.take(1) | ||||||||||||||||||||||||||
| value = textFieldValue, | ||||||||||||||||||||||||||
| onValueChange = { newValue -> | ||||||||||||||||||||||||||
| val cleaned = newValue.text.replace("\u200B", "") | ||||||||||||||||||||||||||
|
Comment on lines
63
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 포커스 이동이 동작하지 않음/크래시 가능성: FocusRequester가 BasicTextField에 연결되지 않았습니다 현재 FocusRequester는 호출 측에서 SingleDigitBox의 modifier에 붙고, 내부에서는 그 modifier를 Box에만 적용합니다. Box는 포커스 타겟이 아니므로 requestFocus() 시 IllegalStateException이 발생하거나 포커스가 무시될 수 있습니다. BasicTextField에 modifier를 전달해 FocusRequester가 실제 포커스 타겟에 연결되도록 해야 합니다. 다음 최소 수정으로 해결 가능합니다(공개 API 변경 없음): BasicTextField(
+ modifier = modifier,
value = textFieldValue,
onValueChange = { newValue ->📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||
| val filtered = cleaned.filter { it.isDigit() }.take(1) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // 백스페이스 감지: Zero Width Space가 지워졌을 때 | ||||||||||||||||||||||||||
| if (newValue.text.isEmpty() && value.isEmpty()) { | ||||||||||||||||||||||||||
| onBackspace?.invoke() | ||||||||||||||||||||||||||
| return@BasicTextField | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| onValueChange(filtered) | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| textStyle = myStyle, | ||||||||||||||||||||||||||
| textStyle = myStyle.copy( | ||||||||||||||||||||||||||
| color = if (value.isEmpty()) Color.Transparent else colors.White | ||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||
| singleLine = true, | ||||||||||||||||||||||||||
| keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword), | ||||||||||||||||||||||||||
| modifier = modifier | ||||||||||||||||||||||||||
| .background(containerColor, RoundedCornerShape(12.dp)) | ||||||||||||||||||||||||||
| .border(1.dp, borderColor, RoundedCornerShape(12.dp)) | ||||||||||||||||||||||||||
| .onKeyEvent { keyEvent -> | ||||||||||||||||||||||||||
| if (keyEvent.nativeKeyEvent.keyCode == KeyEvent.KEYCODE_DEL && | ||||||||||||||||||||||||||
| keyEvent.type == KeyEventType.KeyDown | ||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||
| if (value.isEmpty()) { | ||||||||||||||||||||||||||
| onBackspace?.invoke() | ||||||||||||||||||||||||||
| true | ||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||
| false | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||
| false | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| cursorBrush = SolidColor(colors.NeonGreen), | ||||||||||||||||||||||||||
| decorationBox = { innerTextField -> | ||||||||||||||||||||||||||
| Box( | ||||||||||||||||||||||||||
| Modifier.fillMaxSize(), | ||||||||||||||||||||||||||
| contentAlignment = Alignment.Center | ||||||||||||||||||||||||||
| ) { innerTextField() } | ||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||
| innerTextField() | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
저자명과 ‘저’를 분리한 건 👍. 다음 두 가지를 개선해 주세요 (현지화/접근성 친화).
TextAlign.Right대신TextAlign.End를 사용해 레이아웃 방향을 따른 정렬을 권장합니다.padding(start = …)로 간격을 주는 방식으로 정리하는 것을 권장합니다.아래 diff는 컴포넌트 내에서 가능한 최소 변경입니다(문자열 리소스의 선행 공백 제거가 전제되면 시각적 일관성이 좋아집니다).
추가로,
widthIn(max = 80.dp)는 폰트 스케일이 큰 환경에서 너무 촘촘할 수 있습니다. 필요시 96dp 정도로 여유를 주거나, 상황에 따라 조건부로 완화하는 것도 고려해 볼 수 있습니다.문자열 리소스에 선행 공백이나 따옴표가 포함되어 있는지 확인해 주세요. 포함되어 있다면 제거하는 것을 권장합니다.
🏁 Script executed:
Length of output: 192
RTL 정렬 및 문자열 리소스 정리 필수 반영
•
TextAlign.Right→TextAlign.End(RTL 안전 정렬)• 두 번째
Text에Modifier.padding(start = 4.dp)추가 (문자열 리소스에 공백 제거)• (선택) 첫 번째
Text의widthIn(max = 80.dp)를96.dp로 여유 부여 고려•
<string name="author">" 저"</string>→<string name="author">저</string>🤖 Prompt for AI Agents