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

[#28 feature] 텍스트 필드 추가 #39

Merged
merged 10 commits into from
Jun 29, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.mashup.dorabangs.core.designsystem.component.textfield

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.mashup.dorabangs.core.designsystem.theme.DoraTypoTokens
import com.mashup.dorabangs.core.designsystem.theme.ErrorLabelColorTokens

@Composable
fun DoraErrorLabel(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ahn-seokjoo
DoraTextFieldErrorLabel 해주면 안되나 ?

errorText: String,
modifier: Modifier = Modifier,
) {
Text(
modifier = modifier,
text = errorText,
color = ErrorLabelColorTokens.LabelColor,
style = DoraTypoTokens.SMedium,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.mashup.dorabangs.core.designsystem.component.textfield

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.mashup.dorabangs.core.designsystem.theme.DoraTypoTokens
import com.mashup.dorabangs.core.designsystem.theme.LabelColorTokens

@Composable
fun DoraLabel(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ahn-seokjoo
DoraTextFieldLabel 이라고 해주면 안되냐 ?!

labelText: String,
modifier: Modifier = Modifier,
) {
Text(
modifier = modifier,
text = labelText,
style = DoraTypoTokens.caption1Medium,
color = LabelColorTokens.LabelColor,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package com.mashup.dorabangs.core.designsystem.component.textfield

import androidx.compose.foundation.background
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.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
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
import com.mashup.dorabangs.core.designsystem.R
import com.mashup.dorabangs.core.designsystem.component.snackbar.doraiconclose.CloseCircle
import com.mashup.dorabangs.core.designsystem.component.snackbar.doraiconclose.DoraIconClose
import com.mashup.dorabangs.core.designsystem.theme.DoraRoundTokens
import com.mashup.dorabangs.core.designsystem.theme.DoraTypoTokens
import com.mashup.dorabangs.core.designsystem.theme.TextFieldColorTokens

@Composable
fun DoraTextField(
text: String,
hintText: String,
labelText: String,
modifier: Modifier = Modifier,
errorText: String = "",
) {
var textFieldValue by remember {
mutableStateOf(
TextFieldValue(
text = text,
selection = TextRange(text.length),
),
)
}
val focusRequester = remember { FocusRequester() }
LaunchedEffect(key1 = Unit) {
focusRequester.requestFocus()
}

Column(
modifier = modifier.padding(horizontal = 20.dp),
) {
DoraLabel(labelText = labelText)
Spacer(modifier = Modifier.height(height = 8.dp))
Column(
modifier = Modifier
.size(width = 350.dp, height = 48.dp)
.clip(DoraRoundTokens.Round8)
.background(TextFieldColorTokens.TextFieldBackGroundColor),
) {
BasicTextField(
modifier = Modifier
.focusRequester(focusRequester)
.fillMaxHeight()
.padding(horizontal = 12.dp, vertical = 13.dp),
value = textFieldValue,
singleLine = true,
textStyle = DoraTypoTokens.caption1Medium,
onValueChange = {
textFieldValue = it
},
decorationBox = { innerTextField ->
Box(
modifier = Modifier.width(326.dp),
contentAlignment = Alignment.CenterStart,
) {
if (textFieldValue.text.isBlank()) {
Text(
modifier = Modifier.fillMaxWidth(),
text = hintText,
maxLines = 1,
color = TextFieldColorTokens.TextFieldHintTextColor,
style = DoraTypoTokens.caption1Medium,
textAlign = TextAlign.Start,
)
} else {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween, // 양끝 배치
) {
Box(
modifier = Modifier.weight(1f), // innerTextField가 가로로 확장되지 않도록 설정
) {
innerTextField()
}
Spacer(modifier = Modifier.width(width = 4.dp))
IconButton(
modifier = Modifier.size(size = 24.dp),
onClick = { textFieldValue = TextFieldValue("") },
) {
Icon(
imageVector = DoraIconClose.CloseCircle,
contentDescription = stringResource(id = R.string.url_text_clear),
tint = TextFieldColorTokens.TextFieldClearButtonColor,
)
}
}
}
}
},
)
}
Spacer(modifier = Modifier.height(height = 8.dp))
if (errorText.isNotBlank()) {
DoraErrorLabel(errorText = errorText)
}
}
}

@Composable
@Preview
fun DoraTextFieldLongPreview() {
DoraTextField(
text = "테스트용 이다 어쩔래 ? ? ? asogihasio gasiofhgaioshgioashgaosighoasihg",
hintText = "URL을 입력해주세요.",
labelText = "바보",
errorText = "유효한 링크를 입력해주세요.",
)
}

@Composable
@Preview
fun DoraTextFieldShortPreview() {
DoraTextField(
text = "테스트용 이다 어쩔래 ? ? ?",
hintText = "URL을 입력해주세요.",
labelText = "바보",
errorText = "유효한 링크를 입력해주세요.",
)
}

@Composable
@Preview
fun DoraTextFieldPreviewWithHint() {
DoraTextField(
text = "",
hintText = "URL을 입력해주세요.",
labelText = "링크",
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ object ClipBoardColorTokens {
val ArrowColor = DoraColorTokens.G3
}

object TextFieldColorTokens {
val TextFieldBackGroundColor = DoraColorTokens.G1
val TextFieldHintTextColor = DoraColorTokens.G4
val TextFieldClearButtonColor = DoraColorTokens.G4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 TextField 빼도 될듯??
object에 이미 네이밍됨

}

object LabelColorTokens {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기는 Prefix에 TextField 추가하면 좋을 듯 ??

val LabelColor = DoraColorTokens.G9
}

object ErrorLabelColorTokens {
val LabelColor = DoraColorTokens.Alert
}

object TopBarColorTokens {
val ContainerColor = DoraColorTokens.White
val OnContainerColor = DoraColorTokens.G9
Expand Down
1 change: 1 addition & 0 deletions core/designsystem/src/main/res/values/string.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
<string name="home_empty_feed">테스트 테스트 테스트 테스트</string>
<string name="snack_bar_title">클립보드에 복사한 링크 저장</string>
<string name="snack_bar_cancel_description">스낵바 취소</string>
<string name="url_text_clear">url 모두 지우기</string>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ahn-seokjoo
사용되는 곳을 prefix 붙여주셈

</resources>
1 change: 1 addition & 0 deletions feature/save/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
78 changes: 78 additions & 0 deletions feature/save/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.com.android.library)
alias(libs.plugins.org.jetbrains.kotlin.android)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.kapt)
}

android {
namespace = "com.dorabangs.feature.save"
compileSdk = 34

defaultConfig {
minSdk = 24

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_18
targetCompatibility = JavaVersion.VERSION_18
}
kotlinOptions {
jvmTarget = "18"
}
}

dependencies {
implementation(project(":domain"))
implementation(project(":core:coroutine"))
implementation(project(":core:designsystem"))
implementation(project(":core:navigation"))

// Compose
implementation(libs.ui)
implementation(libs.ui.graphics)
implementation(libs.ui.tooling.preview)
implementation(libs.material3)
implementation(platform(libs.compose.bom))
implementation(libs.material)
implementation(libs.lifecycle.compose.ktx)

// Test
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.espresso.core)
androidTestImplementation(platform(libs.compose.bom))
androidTestImplementation(libs.ui.test.junit4)
debugImplementation(libs.ui.tooling)
debugImplementation(libs.ui.test.manifest)
testImplementation(libs.junit)

// Hilt
implementation(libs.hilt.android)
kapt(libs.hilt.compiler)
implementation(libs.hilt.navigation.compose)

// Orbit
implementation(libs.orbit.core)
implementation(libs.orbit.viewmodel)
implementation(libs.orbit.compose)
}
Empty file.
21 changes: 21 additions & 0 deletions feature/save/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.dorabangs.feature.save

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import junit.framework.TestCase.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.dorabangs.feature.save.test", appContext.packageName)
}
}
4 changes: 4 additions & 0 deletions feature/save/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.dorabangs.feature.save

import junit.framework.TestCase.assertEquals
import org.junit.Test

/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
1 change: 1 addition & 0 deletions save/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
Loading
Loading