Skip to content

Commit

Permalink
Merge branch 'develop' into feature/MZ-176-ledger-filter
Browse files Browse the repository at this point in the history
# Conflicts:
#	core/ui/src/main/res/values/strings.xml
#	feature/navigator/src/main/java/com/susu/feature/navigator/MainNavigator.kt
#	feature/navigator/src/main/java/com/susu/feature/navigator/MainScreen.kt
#	feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt
#	feature/received/src/main/java/com/susu/feature/received/received/ReceivedScreen.kt
#	feature/received/src/main/res/values/strings.xml
  • Loading branch information
jinukeu committed Jan 12, 2024
2 parents 3cb588c + 3d0787e commit b721de2
Show file tree
Hide file tree
Showing 14 changed files with 576 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.susu.core.designsystem.R
import com.susu.core.designsystem.component.button.ClearIconButton
import com.susu.core.designsystem.component.button.FilledButtonColor
import com.susu.core.designsystem.component.button.LargeButtonStyle
import com.susu.core.designsystem.component.button.SusuFilledButton
import com.susu.core.designsystem.component.textfieldbutton.style.InnerButtonStyle
import com.susu.core.designsystem.component.textfieldbutton.style.LargeTextFieldButtonStyle
import com.susu.core.designsystem.component.textfieldbutton.style.SmallTextFieldButtonStyle
Expand All @@ -60,30 +63,33 @@ fun SusuTextFieldFillMaxButton(
style: @Composable () -> TextFieldButtonStyle,
color: TextFieldButtonColor = TextFieldButtonColor.Black,
isSaved: Boolean = false,
isFocused: Boolean = true,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
showCloseIcon: Boolean = true,
showClearIcon: Boolean = true,
onClickClearIcon: () -> Unit = {},
onClickCloseIcon: () -> Unit = {},
onClickButton: () -> Unit = {},
onClickFilledButton: () -> Unit = {},
onClickButton: (isFocused: Boolean) -> Unit = {},
) {
val (backgroundColor, textColor) = with(color) {
if (isSaved) {
(savedBackgroundColor to savedTextColor)
} else {
(editBackgroundColor to editTextColor)
when {
isFocused.not() -> (unFocusedBackgroundColor to unFocusedTextColor)
isSaved -> (savedBackgroundColor to savedTextColor)
else -> (editBackgroundColor to editTextColor)
}
}

with(style()) {
BasicTextField(
modifier = modifier
.fillMaxWidth(),
.fillMaxWidth()
.susuClickable { onClickButton(isFocused) },
value = text,
onValueChange = onTextChange,
enabled = isSaved.not(),
enabled = isSaved.not() && isFocused,
singleLine = maxLines == 1,
maxLines = if (minLines > maxLines) minLines else maxLines,
minLines = minLines,
Expand Down Expand Up @@ -142,13 +148,14 @@ fun SusuTextFieldFillMaxButton(
showClearIcon = showClearIcon,
isSaved = isSaved,
isActive = text.isNotEmpty(),
isFocused = isFocused,
color = color.buttonColor,
buttonStyle = innerButtonStyle,
clearIconSize = clearIconSize,
closeIconSize = closeIconSize,
onClickClearIcon = onClickClearIcon,
onClickCloseIcon = onClickCloseIcon,
onClickButton = onClickButton,
onClickFilledButton = onClickFilledButton,
)
}
},
Expand All @@ -169,20 +176,22 @@ fun SusuTextFieldWrapContentButton(
style: @Composable () -> TextFieldButtonStyle,
color: TextFieldButtonColor = TextFieldButtonColor.Black,
isSaved: Boolean = false,
isFocused: Boolean = true,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
showCloseIcon: Boolean = true,
showClearIcon: Boolean = true,
onClickClearIcon: () -> Unit = {},
onClickCloseIcon: () -> Unit = {},
onClickButton: () -> Unit = {},
onClickFilledButton: () -> Unit = {},
onClickButton: (isFocused: Boolean) -> Unit = {},
) {
val (backgroundColor, textColor) = with(color) {
if (isSaved) {
(savedBackgroundColor to savedTextColor)
} else {
(editBackgroundColor to editTextColor)
when {
isFocused.not() -> (unFocusedBackgroundColor to unFocusedTextColor)
isSaved -> (savedBackgroundColor to savedTextColor)
else -> (editBackgroundColor to editTextColor)
}
}

Expand All @@ -191,6 +200,7 @@ fun SusuTextFieldWrapContentButton(
modifier = modifier
.clip(shape)
.background(backgroundColor)
.susuClickable { onClickButton(isFocused) }
.padding(paddingValues),
horizontalArrangement = Arrangement.spacedBy(iconSpacing),
verticalAlignment = Alignment.CenterVertically,
Expand All @@ -206,9 +216,10 @@ fun SusuTextFieldWrapContentButton(
* BasicTextField의 기본 width를 없애기 위해 IntrinsicSize.Min을 사용함.
* see -> https://stackoverflow.com/questions/67719981/resizeable-basictextfield-in-jetpack-compose
*/
.width(IntrinsicSize.Min),
.width(IntrinsicSize.Min)
.susuClickable(rippleEnabled = false, runIf = isFocused.not(), onClick = { onClickButton(isFocused) }),
value = text,
enabled = isSaved.not(),
enabled = isSaved.not() && isFocused,
onValueChange = onTextChange,
singleLine = maxLines == 1,
maxLines = if (minLines > maxLines) minLines else maxLines,
Expand Down Expand Up @@ -256,13 +267,14 @@ fun SusuTextFieldWrapContentButton(
showClearIcon = showClearIcon,
isSaved = isSaved,
isActive = text.isNotEmpty(),
isFocused = isFocused,
color = color.buttonColor,
buttonStyle = innerButtonStyle,
clearIconSize = clearIconSize,
closeIconSize = closeIconSize,
onClickClearIcon = onClickClearIcon,
onClickCloseIcon = onClickCloseIcon,
onClickButton = onClickButton,
onClickFilledButton = onClickFilledButton,
)
}
}
Expand All @@ -274,6 +286,7 @@ private fun InnerButtons(
shape: Shape = RoundedCornerShape(4.dp),
isSaved: Boolean,
isActive: Boolean,
isFocused: Boolean,
showCloseIcon: Boolean = true,
showClearIcon: Boolean = true,
color: TextButtonInnerButtonColor,
Expand All @@ -282,13 +295,13 @@ private fun InnerButtons(
buttonStyle: @Composable () -> InnerButtonStyle,
onClickClearIcon: () -> Unit = {},
onClickCloseIcon: () -> Unit = {},
onClickButton: () -> Unit = {},
onClickFilledButton: () -> Unit = {},
) {
val (innerButtonTextColor, innerButtonBackgroundColor) = with(color) {
if (isActive || isSaved) {
(activeContentColor to activeBackgroundColor)
} else {
(inactiveContentColor to inactiveBackgroundColor)
when {
isFocused.not() -> (unFocusedContentColor to unFocusedBackgroundColor)
isActive || isSaved -> (activeContentColor to activeBackgroundColor)
else -> (inactiveContentColor to inactiveBackgroundColor)
}
}

Expand All @@ -315,7 +328,7 @@ private fun InnerButtons(
.susuClickable(
runIf = isActive || isSaved,
rippleColor = color.rippleColor,
onClick = onClickButton,
onClick = onClickFilledButton,
)
.padding(paddingValues),
) {
Expand Down Expand Up @@ -351,6 +364,10 @@ fun TextFieldButtonPreview() {
mutableStateOf(false)
}

var isFocused by remember {
mutableStateOf(true)
}

Column(
verticalArrangement = Arrangement.spacedBy(10.dp),
) {
Expand All @@ -362,8 +379,10 @@ fun TextFieldButtonPreview() {
maxLines = 1,
minLines = 1,
showClearIcon = true,
isFocused = isFocused,
onClickButton = { isFocused = !isFocused },
style = LargeTextFieldButtonStyle.height46,
onClickButton = { isSaved = isSaved.not() },
onClickFilledButton = { isSaved = isSaved.not() },
onClickClearIcon = { text = "" },
isSaved = isSaved,
)
Expand All @@ -377,8 +396,10 @@ fun TextFieldButtonPreview() {
placeholder = "Button",
maxLines = 1,
minLines = 1,
isFocused = !isFocused,
onClickButton = { isFocused = !isFocused },
style = LargeTextFieldButtonStyle.height46,
onClickButton = { isSaved = isSaved.not() },
onClickFilledButton = { isSaved = isSaved.not() },
onClickClearIcon = { text = "" },
isSaved = isSaved,
)
Expand All @@ -392,11 +413,13 @@ fun TextFieldButtonPreview() {
placeholder = "Button",
maxLines = 1,
minLines = 1,
isFocused = !isFocused,
onClickButton = { isFocused = !isFocused },
showClearIcon = false,
showCloseIcon = false,
color = TextFieldButtonColor.Orange,
style = LargeTextFieldButtonStyle.height46,
onClickButton = { isSaved = isSaved.not() },
onClickFilledButton = { isSaved = isSaved.not() },
onClickClearIcon = { text = "" },
isSaved = isSaved,
)
Expand All @@ -410,14 +433,91 @@ fun TextFieldButtonPreview() {
overflow = TextOverflow.Ellipsis,
onTextChange = { text = it },
placeholder = "Button",
isFocused = !isFocused,
onClickButton = { isFocused = !isFocused },
maxLines = 1,
minLines = 1,
color = TextFieldButtonColor.Orange,
style = SmallTextFieldButtonStyle.height32,
onClickButton = { isSaved = isSaved.not() },
onClickFilledButton = { isSaved = isSaved.not() },
onClickClearIcon = { text = "" },
isSaved = isSaved,
)
}
}
}

@Preview(showBackground = true, backgroundColor = 0x000000)
@Composable
fun TextFieldButtonFocusedPreview() {
SusuTheme {
var text by remember {
mutableStateOf("Button")
}

var isSaved by remember {
mutableStateOf(false)
}

var isFocusedTextFieldButton by remember {
mutableStateOf(true)
}

var isFocusedButton1 by remember {
mutableStateOf(false)
}

var isFocusedButton2 by remember {
mutableStateOf(false)
}

Column(
verticalArrangement = Arrangement.spacedBy(10.dp),
) {
Text(text = "텍스트 길이에 딱 맞는 너비 (wrap)")
SusuTextFieldWrapContentButton(
color = TextFieldButtonColor.Orange,
text = text,
onTextChange = { text = it },
placeholder = "",
maxLines = 1,
minLines = 1,
showClearIcon = true,
isFocused = isFocusedTextFieldButton,
onClickButton = {
isFocusedTextFieldButton = true
isFocusedButton1 = false
isFocusedButton2 = false
},
style = LargeTextFieldButtonStyle.height46,
onClickFilledButton = { isSaved = isSaved.not() },
onClickClearIcon = { text = "" },
isSaved = isSaved,
)

SusuFilledButton(
color = FilledButtonColor.Orange,
style = LargeButtonStyle.height46,
text = "테스트1",
isActive = isFocusedButton1,
onClick = {
isFocusedTextFieldButton = false
isFocusedButton1 = true
isFocusedButton2 = false
},
)

SusuFilledButton(
color = FilledButtonColor.Orange,
style = LargeButtonStyle.height46,
text = "테스트2",
isActive = isFocusedButton2,
onClick = {
isFocusedTextFieldButton = false
isFocusedButton1 = false
isFocusedButton2 = true
},
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import androidx.compose.ui.graphics.Color
import com.susu.core.designsystem.theme.Gray10
import com.susu.core.designsystem.theme.Gray100
import com.susu.core.designsystem.theme.Gray30
import com.susu.core.designsystem.theme.Gray40
import com.susu.core.designsystem.theme.Orange20
import com.susu.core.designsystem.theme.Orange60

enum class TextFieldButtonColor(
val buttonColor: TextButtonInnerButtonColor,
val savedBackgroundColor: Color,
val editBackgroundColor: Color,
val unFocusedBackgroundColor: Color,
val unFocusedTextColor: Color,
val editTextColor: Color,
val savedTextColor: Color,
val placeholderColor: Color,
Expand All @@ -18,32 +22,40 @@ enum class TextFieldButtonColor(
buttonColor = TextButtonInnerButtonColor.Black,
savedBackgroundColor = Gray10,
editBackgroundColor = Gray10,
unFocusedBackgroundColor = Gray10,
editTextColor = Gray100,
savedTextColor = Gray100,
placeholderColor = Gray30,
unFocusedTextColor = Gray30,
),
Orange(
buttonColor = TextButtonInnerButtonColor.Black,
savedBackgroundColor = Orange60,
editBackgroundColor = Gray10,
unFocusedBackgroundColor = Orange20,
editTextColor = Gray100,
savedTextColor = Gray10,
placeholderColor = Gray30,
unFocusedTextColor = Gray10,
),
}

enum class TextButtonInnerButtonColor(
val activeContentColor: Color,
val inactiveContentColor: Color,
val unFocusedContentColor: Color,
val activeBackgroundColor: Color,
val inactiveBackgroundColor: Color,
val unFocusedBackgroundColor: Color,
val rippleColor: Color,
) {
Black(
activeContentColor = Gray10,
inactiveContentColor = Gray10,
unFocusedContentColor = Gray10,
activeBackgroundColor = Gray100,
inactiveBackgroundColor = Gray30,
inactiveBackgroundColor = Gray40,
unFocusedBackgroundColor = Gray40,
rippleColor = Gray10,
),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.susu.core.ui.extension

import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.ContentTransform
import androidx.compose.animation.core.tween
import androidx.compose.animation.togetherWith

fun <S> AnimatedContentTransitionScope<S>.susuDefaultAnimatedContentTransitionSpec(leftDirectionCondition: Boolean): ContentTransform {
val direction = if (leftDirectionCondition) {
AnimatedContentTransitionScope.SlideDirection.Left
} else {
AnimatedContentTransitionScope.SlideDirection.Right
}
return slideIntoContainer(
towards = direction,
animationSpec = tween(500),
) togetherWith slideOutOfContainer(
towards = direction,
animationSpec = tween(500),
)
}
1 change: 1 addition & 0 deletions core/ui/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<string name="word_date">날짜</string>
<string name="content_description_add_button">더하기 버튼</string>
<string name="content_description_close_icon">닫기 아이콘</string>
<string name="word_input_yourself">직접 입력</string>
<string name="word_male">남성</string>
<string name="word_female">여성</string>
<string name="word_birth">출생년도</string>
Expand Down
Loading

0 comments on commit b721de2

Please sign in to comment.