From d144a71f565d919c3cc1a58cbdfe6a85bd2c87de Mon Sep 17 00:00:00 2001 From: harry Date: Thu, 2 Nov 2023 00:35:59 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[YDS-#205]=20SimpleTextField=20Jetpack=20Co?= =?UTF-8?q?mpose=EB=A1=9C=20=EA=B5=AC=ED=98=84=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/compose/atom/SimpleTextField.kt | 131 ++++++++++++++++++ compose/src/main/res/drawable/ic_x_line.xml | 24 ++++ 2 files changed, 155 insertions(+) create mode 100644 compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt create mode 100644 compose/src/main/res/drawable/ic_x_line.xml diff --git a/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt b/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt new file mode 100644 index 00000000..184716dc --- /dev/null +++ b/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt @@ -0,0 +1,131 @@ +package com.yourssu.design.system.compose.atom + +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.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.IconButton +import androidx.compose.material.OutlinedTextField +import androidx.compose.material.TextFieldDefaults +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.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.yourssu.design.system.compose.R +import com.yourssu.design.system.compose.YdsTheme +import com.yourssu.design.system.compose.base.Icon +import com.yourssu.design.system.compose.base.IconSize +import com.yourssu.design.system.compose.base.YdsText +@Composable +fun SimpleTextField( + modifier: Modifier = Modifier, + isError: Boolean = false, + isEnabled: Boolean = true, + onValueChange: (value: String) -> Unit, + placeHolder: String = "", + hintText: String = "", +) { + var text by rememberSaveable { mutableStateOf("") } + Column(modifier = modifier) { + OutlinedTextField( + value = text, + onValueChange = { value: String -> + text = value + onValueChange(value) + }, + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(8.dp), + colors = TextFieldDefaults.outlinedTextFieldColors( + backgroundColor = YdsTheme.colors.inputFieldElevated, + cursorColor = YdsTheme.colors.textPointed, + errorBorderColor = YdsTheme.colors.textWarned, + unfocusedBorderColor = Color.Transparent, + focusedBorderColor = YdsTheme.colors.textPointed, + disabledTextColor = YdsTheme.colors.textDisabled, + disabledBorderColor = Color.Transparent, + textColor = YdsTheme.colors.textSecondary + ), + isError = isError, + enabled = isEnabled, + placeholder = { + YdsText( + text = placeHolder, + style = YdsTheme.typography.body1, + color = YdsTheme.colors.textTertiary, + ) + }, + trailingIcon = { + if (text.isNotEmpty()) { + IconButton(onClick = { text = "" }) { + Icon( + id = R.drawable.ic_x_line, + iconSize = IconSize.ExtraSmall + ) + } + } + }, + textStyle = YdsTheme.typography.body1.toTextStyle(), + ) + if (hintText.isNotEmpty()) { + Row(modifier = Modifier.padding(top = 8.dp)) { + Spacer( + modifier = Modifier + .width(16.dp) + .padding(0.dp), + ) + YdsText( + text = hintText, style = YdsTheme.typography.caption1, + color = if (isError) { + YdsTheme.colors.textPointed + } else if (!isEnabled) { + YdsTheme.colors.textDisabled + } else { + YdsTheme.colors.textTertiary + }, + ) + + } + } + } +} + +@Preview +@Composable +fun PreviewSimpleTextField() { + var isError by remember { mutableStateOf(false) } + Column { + SimpleTextField( + isError = isError, isEnabled = true, + placeHolder = "플레이스 홀더", + onValueChange = { value -> + if(value.equals("x")) + isError = true + else + isError = false + }, + hintText = "힌트 텍스트", + modifier = Modifier.padding(10.dp), + ) + + SimpleTextField( + isEnabled = false, + onValueChange = { value -> + + }, + modifier = Modifier.padding(bottom = 10.dp), + hintText = "힌트 텍스트", + ) + + SimpleTextField(isError = true, onValueChange = { value -> }) + + } +} \ No newline at end of file diff --git a/compose/src/main/res/drawable/ic_x_line.xml b/compose/src/main/res/drawable/ic_x_line.xml new file mode 100644 index 00000000..00870224 --- /dev/null +++ b/compose/src/main/res/drawable/ic_x_line.xml @@ -0,0 +1,24 @@ + + + + + + + From 00aeb7f6743d9c6a282301eac2379716021ae6fb Mon Sep 17 00:00:00 2001 From: Harry Date: Fri, 3 Nov 2023 10:53:55 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[YDS-#205]=20feat:=20SimpleTextField?= =?UTF-8?q?=EC=97=90=20inputType=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/system/compose/atom/SimpleTextField.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt b/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt index 184716dc..96392d20 100644 --- a/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt +++ b/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.IconButton import androidx.compose.material.OutlinedTextField import androidx.compose.material.TextFieldDefaults @@ -18,6 +19,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.yourssu.design.system.compose.R @@ -33,6 +35,7 @@ fun SimpleTextField( onValueChange: (value: String) -> Unit, placeHolder: String = "", hintText: String = "", + keyboardOptions: KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), ) { var text by rememberSaveable { mutableStateOf("") } Column(modifier = modifier) { @@ -74,6 +77,8 @@ fun SimpleTextField( } }, textStyle = YdsTheme.typography.body1.toTextStyle(), + keyboardOptions = keyboardOptions, + singleLine = true, ) if (hintText.isNotEmpty()) { Row(modifier = Modifier.padding(top = 8.dp)) { @@ -107,10 +112,7 @@ fun PreviewSimpleTextField() { isError = isError, isEnabled = true, placeHolder = "플레이스 홀더", onValueChange = { value -> - if(value.equals("x")) - isError = true - else - isError = false + isError = value.equals("x") }, hintText = "힌트 텍스트", modifier = Modifier.padding(10.dp), From 0f96a1366abc1809254add3ce0811b7497306688 Mon Sep 17 00:00:00 2001 From: Harry Date: Fri, 3 Nov 2023 11:23:20 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[YDS-#205]=20feat:=20PasswordTextField=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20SimpleTextField=20Error=20Hanlding=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/compose/atom/PasswordTextField.kt | 148 ++++++++++++++++++ .../system/compose/atom/SimpleTextField.kt | 28 +++- .../main/res/drawable/ic_eyeclosed_line.xml | 25 +++ .../src/main/res/drawable/ic_eyeopen_line.xml | 20 +++ 4 files changed, 216 insertions(+), 5 deletions(-) create mode 100644 compose/src/main/java/com/yourssu/design/system/compose/atom/PasswordTextField.kt create mode 100644 compose/src/main/res/drawable/ic_eyeclosed_line.xml create mode 100644 compose/src/main/res/drawable/ic_eyeopen_line.xml diff --git a/compose/src/main/java/com/yourssu/design/system/compose/atom/PasswordTextField.kt b/compose/src/main/java/com/yourssu/design/system/compose/atom/PasswordTextField.kt new file mode 100644 index 00000000..e22e9ad0 --- /dev/null +++ b/compose/src/main/java/com/yourssu/design/system/compose/atom/PasswordTextField.kt @@ -0,0 +1,148 @@ +package com.yourssu.design.system.compose.atom + +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.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.IconButton +import androidx.compose.material.OutlinedTextField +import androidx.compose.material.TextFieldDefaults +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.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.yourssu.design.system.compose.R +import com.yourssu.design.system.compose.YdsTheme +import com.yourssu.design.system.compose.base.Icon +import com.yourssu.design.system.compose.base.IconSize +import com.yourssu.design.system.compose.base.YdsText + +@Composable +fun PasswordTextField( + modifier: Modifier = Modifier, + isError: Boolean = false, + isEnabled: Boolean = true, + onValueChange: (value: String) -> Unit, + placeHolder: String = "", + hintText: String = "", +) { + var text by rememberSaveable { mutableStateOf("") } + var showPassword by remember { mutableStateOf(value = false) } + Column(modifier = modifier) { + OutlinedTextField( + value = text, + onValueChange = { value: String -> + text = value + onValueChange(value) + }, + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(8.dp), + colors = TextFieldDefaults.outlinedTextFieldColors( + backgroundColor = YdsTheme.colors.inputFieldElevated, + cursorColor = YdsTheme.colors.textPointed, + errorBorderColor = YdsTheme.colors.textWarned, + unfocusedBorderColor = Color.Transparent, + focusedBorderColor = YdsTheme.colors.textPointed, + disabledTextColor = YdsTheme.colors.textDisabled, + disabledBorderColor = Color.Transparent, + textColor = YdsTheme.colors.textSecondary + ), + isError = isError, + enabled = isEnabled, + placeholder = { + YdsText( + text = placeHolder, + style = YdsTheme.typography.body1, + color = YdsTheme.colors.textTertiary, + ) + }, + visualTransformation = if (showPassword) { + VisualTransformation.None + } else { + PasswordVisualTransformation() + }, + trailingIcon = { + if (showPassword) { + IconButton(onClick = { showPassword = false}) { + Icon( + id = R.drawable.ic_eyeclosed_line, + iconSize = IconSize.Medium + ) + } + } else { + IconButton(onClick = { showPassword = true}) { + Icon( + id = R.drawable.ic_eyeopen_line, + iconSize = IconSize.Medium + ) + } + } + }, + textStyle = YdsTheme.typography.body1.toTextStyle(), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + singleLine = true, + ) + if (hintText.isNotEmpty()) { + Row(modifier = Modifier.padding(top = 8.dp)) { + Spacer( + modifier = Modifier + .width(16.dp) + .padding(0.dp), + ) + YdsText( + text = hintText, style = YdsTheme.typography.caption1, + color = if (isError) { + YdsTheme.colors.textWarned + } else if (!isEnabled) { + YdsTheme.colors.textDisabled + } else { + YdsTheme.colors.textTertiary + }, + ) + + } + } + } +} + +@Preview +@Composable +fun PreviewPasswordTextField() { + var isError by remember { mutableStateOf(false) } + Column { + PasswordTextField( + isError = isError, isEnabled = true, + placeHolder = "플레이스 홀더", + onValueChange = { value -> + isError = value.equals("x") + }, + hintText = "힌트 텍스트", + modifier = Modifier.padding(10.dp), + ) + + PasswordTextField( + isEnabled = false, + onValueChange = { value -> + + }, + modifier = Modifier.padding(bottom = 10.dp), + hintText = "힌트 텍스트", + ) + + PasswordTextField(isError = true, onValueChange = { value -> }) + + } +} \ No newline at end of file diff --git a/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt b/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt index 96392d20..5c17e38b 100644 --- a/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt +++ b/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt @@ -27,6 +27,7 @@ import com.yourssu.design.system.compose.YdsTheme import com.yourssu.design.system.compose.base.Icon import com.yourssu.design.system.compose.base.IconSize import com.yourssu.design.system.compose.base.YdsText + @Composable fun SimpleTextField( modifier: Modifier = Modifier, @@ -36,6 +37,7 @@ fun SimpleTextField( placeHolder: String = "", hintText: String = "", keyboardOptions: KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), + onErrorChange: (Boolean) -> Unit, ) { var text by rememberSaveable { mutableStateOf("") } Column(modifier = modifier) { @@ -55,7 +57,7 @@ fun SimpleTextField( focusedBorderColor = YdsTheme.colors.textPointed, disabledTextColor = YdsTheme.colors.textDisabled, disabledBorderColor = Color.Transparent, - textColor = YdsTheme.colors.textSecondary + textColor = YdsTheme.colors.textSecondary, ), isError = isError, enabled = isEnabled, @@ -68,10 +70,15 @@ fun SimpleTextField( }, trailingIcon = { if (text.isNotEmpty()) { - IconButton(onClick = { text = "" }) { + IconButton( + onClick = { + text = "" + onErrorChange(false) + }, + ) { Icon( id = R.drawable.ic_x_line, - iconSize = IconSize.ExtraSmall + iconSize = IconSize.ExtraSmall, ) } } @@ -90,7 +97,7 @@ fun SimpleTextField( YdsText( text = hintText, style = YdsTheme.typography.caption1, color = if (isError) { - YdsTheme.colors.textPointed + YdsTheme.colors.textWarned } else if (!isEnabled) { YdsTheme.colors.textDisabled } else { @@ -116,6 +123,9 @@ fun PreviewSimpleTextField() { }, hintText = "힌트 텍스트", modifier = Modifier.padding(10.dp), + onErrorChange = { error -> + isError = error + }, ) SimpleTextField( @@ -125,9 +135,17 @@ fun PreviewSimpleTextField() { }, modifier = Modifier.padding(bottom = 10.dp), hintText = "힌트 텍스트", + onErrorChange = { error -> + isError = error + }, ) - SimpleTextField(isError = true, onValueChange = { value -> }) + SimpleTextField( + isError = true, onValueChange = { value -> }, + onErrorChange = { error -> + isError = error + }, + ) } } \ No newline at end of file diff --git a/compose/src/main/res/drawable/ic_eyeclosed_line.xml b/compose/src/main/res/drawable/ic_eyeclosed_line.xml new file mode 100644 index 00000000..c22e3cf2 --- /dev/null +++ b/compose/src/main/res/drawable/ic_eyeclosed_line.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/compose/src/main/res/drawable/ic_eyeopen_line.xml b/compose/src/main/res/drawable/ic_eyeopen_line.xml new file mode 100644 index 00000000..e83bf579 --- /dev/null +++ b/compose/src/main/res/drawable/ic_eyeopen_line.xml @@ -0,0 +1,20 @@ + + + + From 83b14311591c8220c48ab9e074ea5d03674bd4cb Mon Sep 17 00:00:00 2001 From: harry Date: Sat, 4 Nov 2023 14:31:03 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[YDS-#205]=20improve:=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/compose/atom/PasswordTextField.kt | 16 +++++++++------- .../system/compose/atom/SimpleTextField.kt | 18 +++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/compose/src/main/java/com/yourssu/design/system/compose/atom/PasswordTextField.kt b/compose/src/main/java/com/yourssu/design/system/compose/atom/PasswordTextField.kt index e22e9ad0..4785f3e0 100644 --- a/compose/src/main/java/com/yourssu/design/system/compose/atom/PasswordTextField.kt +++ b/compose/src/main/java/com/yourssu/design/system/compose/atom/PasswordTextField.kt @@ -58,7 +58,7 @@ fun PasswordTextField( focusedBorderColor = YdsTheme.colors.textPointed, disabledTextColor = YdsTheme.colors.textDisabled, disabledBorderColor = Color.Transparent, - textColor = YdsTheme.colors.textSecondary + textColor = YdsTheme.colors.textSecondary, ), isError = isError, enabled = isEnabled, @@ -76,17 +76,17 @@ fun PasswordTextField( }, trailingIcon = { if (showPassword) { - IconButton(onClick = { showPassword = false}) { + IconButton(onClick = { showPassword = false }) { Icon( id = R.drawable.ic_eyeclosed_line, - iconSize = IconSize.Medium + iconSize = IconSize.Medium, ) } } else { - IconButton(onClick = { showPassword = true}) { + IconButton(onClick = { showPassword = true }) { Icon( id = R.drawable.ic_eyeopen_line, - iconSize = IconSize.Medium + iconSize = IconSize.Medium, ) } } @@ -100,10 +100,10 @@ fun PasswordTextField( Spacer( modifier = Modifier .width(16.dp) - .padding(0.dp), ) YdsText( - text = hintText, style = YdsTheme.typography.caption1, + text = hintText, + style = YdsTheme.typography.caption1, color = if (isError) { YdsTheme.colors.textWarned } else if (!isEnabled) { @@ -122,12 +122,14 @@ fun PasswordTextField( @Composable fun PreviewPasswordTextField() { var isError by remember { mutableStateOf(false) } + var text by rememberSaveable { mutableStateOf("") } Column { PasswordTextField( isError = isError, isEnabled = true, placeHolder = "플레이스 홀더", onValueChange = { value -> isError = value.equals("x") + text = value }, hintText = "힌트 텍스트", modifier = Modifier.padding(10.dp), diff --git a/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt b/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt index 5c17e38b..3c3715b6 100644 --- a/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt +++ b/compose/src/main/java/com/yourssu/design/system/compose/atom/SimpleTextField.kt @@ -30,6 +30,7 @@ import com.yourssu.design.system.compose.base.YdsText @Composable fun SimpleTextField( + text: String = "", modifier: Modifier = Modifier, isError: Boolean = false, isEnabled: Boolean = true, @@ -39,14 +40,10 @@ fun SimpleTextField( keyboardOptions: KeyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), onErrorChange: (Boolean) -> Unit, ) { - var text by rememberSaveable { mutableStateOf("") } Column(modifier = modifier) { OutlinedTextField( value = text, - onValueChange = { value: String -> - text = value - onValueChange(value) - }, + onValueChange = onValueChange, modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(8.dp), colors = TextFieldDefaults.outlinedTextFieldColors( @@ -72,7 +69,7 @@ fun SimpleTextField( if (text.isNotEmpty()) { IconButton( onClick = { - text = "" + onValueChange("") onErrorChange(false) }, ) { @@ -92,10 +89,10 @@ fun SimpleTextField( Spacer( modifier = Modifier .width(16.dp) - .padding(0.dp), ) YdsText( - text = hintText, style = YdsTheme.typography.caption1, + text = hintText, + style = YdsTheme.typography.caption1, color = if (isError) { YdsTheme.colors.textWarned } else if (!isEnabled) { @@ -114,12 +111,15 @@ fun SimpleTextField( @Composable fun PreviewSimpleTextField() { var isError by remember { mutableStateOf(false) } + var text by rememberSaveable { mutableStateOf("") } Column { SimpleTextField( + text = text, isError = isError, isEnabled = true, placeHolder = "플레이스 홀더", onValueChange = { value -> - isError = value.equals("x") + isError = value == "x" + text = value }, hintText = "힌트 텍스트", modifier = Modifier.padding(10.dp),