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

[UI/YAF-60] 온보딩 태어난 시간, 이름 입력 UI를 구현합니다. #25

Merged
merged 14 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
Expand Up @@ -29,7 +29,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
Expand All @@ -46,6 +45,7 @@ fun OrbitTextField(
hint: String,
modifier: Modifier = Modifier,
showWarning: Boolean = false,
warningMessage: String,
onFocusChanged: (Boolean) -> Unit = {},
) {
val focusRequester = remember { FocusRequester() }
Expand Down Expand Up @@ -83,23 +83,23 @@ fun OrbitTextField(
Spacer(modifier = Modifier.height(12.dp))

if (showWarning) {
WarningMessage()
WarningMessage(warningMessage)
}
}
}
}
}

@Composable
private fun WarningMessage() {
private fun WarningMessage(message: String) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(20.dp),
contentAlignment = Alignment.Center,
) {
Text(
text = "입력한 숫자를 확인해 주세요",
text = message,
color = OrbitTheme.colors.alert,
style = OrbitTheme.typography.label1SemiBold,
)
Expand All @@ -121,17 +121,17 @@ private fun TextFieldContainer(
Box(
modifier = Modifier
.border(
width = 3.dp,
width = 1.dp,
color = when {
isFocused && showWarning -> OrbitTheme.colors.alert
isFocused -> OrbitTheme.colors.main.copy(alpha = 0.2f)
showWarning -> OrbitTheme.colors.alert
else -> Color.Transparent
else -> OrbitTheme.colors.gray_500
},
shape = RoundedCornerShape(10.dp),
shape = RoundedCornerShape(16.dp),
)
.background(OrbitTheme.colors.gray_800, shape = RoundedCornerShape(10.dp))
.height(52.dp)
.background(OrbitTheme.colors.gray_800, shape = RoundedCornerShape(16.dp))
.height(54.dp)
.fillMaxWidth()
.focusRequester(focusRequester)
.clickable(
Expand Down Expand Up @@ -197,10 +197,11 @@ private fun TextFieldContainer(
fun OrbitTextFieldPreview() {
OrbitTheme {
OrbitTextField(
text = "123",
text = "",
onTextChange = {},
showWarning = true,
showWarning = false,
hint = "이름을 입력해주세요",
warningMessage = "이름을 입력해주세요",
modifier = Modifier
.fillMaxWidth(),
)
Expand Down
16 changes: 14 additions & 2 deletions core/ui/src/main/java/com/yapp/ui/utils/ScreenPercentage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,25 @@ fun Modifier.widthForScreenPercentage(percentage: Float): Modifier {
}

@Composable
fun Modifier.paddingForScreenPercentage(horizontalPercentage: Float = 0f, verticalPercentage: Float = 0f): Modifier {
fun Modifier.paddingForScreenPercentage(
horizontalPercentage: Float = 0f,
verticalPercentage: Float = 0f,
topPercentage: Float = 0f,
bottomPercentage: Float = 0f,
): Modifier {
val configuration = LocalConfiguration.current
val screenWidth = configuration.screenWidthDp.dp
val screenHeight = configuration.screenHeightDp.dp

val horizontalPadding = screenWidth * horizontalPercentage
val verticalPadding = screenHeight * verticalPercentage
val topPadding = screenHeight * topPercentage + verticalPadding
val bottomPadding = screenHeight * bottomPercentage + verticalPadding

return this.padding(horizontal = horizontalPadding, vertical = verticalPadding)
return this.padding(
start = horizontalPadding,
top = topPadding,
end = horizontalPadding,
bottom = bottomPadding,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.kms.onboarding

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.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.yapp.designsystem.theme.OrbitTheme
import com.yapp.ui.component.timepicker.OrbitYearMonthPicker
import com.yapp.ui.utils.heightForScreenPercentage
import feature.onboarding.R

@Composable
fun BirthdayScreen(
state: OnboardingContract.State,
currentStep: Int,
totalSteps: Int,
onNextClick: () -> Unit,
onBackClick: () -> Unit,
) {
OnboardingScreen(
currentStep = currentStep,
totalSteps = totalSteps,
isButtonEnabled = true,
onNextClick = onNextClick,
onBackClick = onBackClick,
) {
Column(modifier = Modifier.fillMaxSize()) {
Spacer(modifier = Modifier.heightForScreenPercentage(0.05f))
Text(
text = stringResource(id = R.string.onboarding_step3_text_title),
style = OrbitTheme.typography.heading1SemiBold,
color = OrbitTheme.colors.white,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
)
OrbitYearMonthPicker(
modifier = Modifier.padding(top = 60.dp),
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.kms.onboarding

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
Expand Down Expand Up @@ -66,31 +68,31 @@ fun OnboardingScreen(
showTopAppBar: Boolean = true,
content: @Composable () -> Unit,
) {
Scaffold(
topBar = {
if (showTopAppBar) {
OnBoardingTopAppBar(
currentStep = currentStep,
totalSteps = totalSteps,
onBackClick = onBackClick,
)
}
},
bottomBar = {
OnboardingBottomBar(
isButtonEnabled = isButtonEnabled,
onNextClick = onNextClick,
Column(
modifier = Modifier
.fillMaxSize()
.background(OrbitTheme.colors.gray_900)
.statusBarsPadding()
.navigationBarsPadding()
.imePadding(),
) {
if (showTopAppBar) {
OnBoardingTopAppBar(
currentStep = currentStep,
totalSteps = totalSteps,
onBackClick = onBackClick,
)
},
containerColor = OrbitTheme.colors.gray_900,
) { innerPadding ->
}

Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
contentAlignment = Alignment.TopCenter,
modifier = Modifier.weight(1f),
) {
content()
}

OnboardingBottomBar(
isButtonEnabled = isButtonEnabled,
onNextClick = onNextClick,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.kms.onboarding

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.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import com.yapp.designsystem.theme.OrbitTheme
import com.yapp.ui.component.textfield.OrbitTextField
import com.yapp.ui.extensions.customClickable
import com.yapp.ui.utils.heightForScreenPercentage
import com.yapp.ui.utils.paddingForScreenPercentage
import feature.onboarding.R

@Composable
fun OnboardingNameScreen(
state: OnboardingContract.State,
currentStep: Int,
totalSteps: Int,
onNextClick: () -> Unit,
onBackClick: () -> Unit,
onTextChange: (String) -> Unit,
) {
val focusManager = LocalFocusManager.current

OnboardingScreen(
currentStep = currentStep,
totalSteps = totalSteps,
isButtonEnabled = state.isButtonEnabled,
onNextClick = onNextClick,
onBackClick = onBackClick,
) {
Column(
modifier = Modifier
.fillMaxSize()
.customClickable(
rippleEnabled = false,
onClick = { focusManager.clearFocus() },
),
) {
Spacer(modifier = Modifier.heightForScreenPercentage(0.05f))
Text(
text = stringResource(id = R.string.onboarding_step5_text_title),
style = OrbitTheme.typography.heading1SemiBold,
color = OrbitTheme.colors.white,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
)
OrbitTextField(
text = state.textFieldValue,
onTextChange = { value ->
onTextChange(value)
},
hint = "이름 입력",
showWarning = state.showWarning,
warningMessage = stringResource(id = R.string.onboarding_step5_textfield_warning),
modifier = Modifier
.fillMaxWidth()
.paddingForScreenPercentage(horizontalPercentage = 0.192f, topPercentage = 0.086f),
)
}
}
}

@Composable
@Preview
fun PreviewOnboardingNameScreen() {
OnboardingNameScreen(
state = OnboardingContract.State(
textFieldValue = "김민수",
isButtonEnabled = true,
showWarning = false,
),
currentStep = 1,
totalSteps = 5,
onNextClick = {},
onBackClick = {},
onTextChange = {},
)
}
Loading
Loading