diff --git a/jobisdesignsystemv2/build.gradle.kts b/jobisdesignsystemv2/build.gradle.kts index 8ac851c..6a8e52a 100644 --- a/jobisdesignsystemv2/build.gradle.kts +++ b/jobisdesignsystemv2/build.gradle.kts @@ -46,7 +46,7 @@ afterEvaluate { from(components["release"]) groupId = "team.return.jobis.android" artifactId = "design-system-v2" - version = "1.0.1" + version = "1.1.0" } } } diff --git a/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/appbar/JobisTopAppBar.kt b/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/appbar/JobisTopAppBar.kt index 3f3ea98..b541f57 100644 --- a/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/appbar/JobisTopAppBar.kt +++ b/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/appbar/JobisTopAppBar.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -20,14 +19,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import team.returm.jobisdesignsystemv2.R import team.returm.jobisdesignsystemv2.button.JobisIconButton -import team.returm.jobisdesignsystemv2.foundation.JobisColor import team.returm.jobisdesignsystemv2.foundation.JobisIcon import team.returm.jobisdesignsystemv2.foundation.JobisTheme import team.returm.jobisdesignsystemv2.foundation.JobisTypography diff --git a/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/button/ButtonColors.kt b/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/button/ButtonColors.kt index 8157699..4d671d0 100644 --- a/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/button/ButtonColors.kt +++ b/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/button/ButtonColors.kt @@ -12,6 +12,7 @@ data class ButtonColorSet( enum class ButtonColor { Primary, + Secondary, Default, } @@ -24,6 +25,13 @@ internal object ButtonColors { text = JobisColor.Light.gray100, ) + @Composable + fun secondary() = ButtonColorSet( + background = JobisColor.Light.primary100, + pressed = JobisColor.Light.gray400, + text = JobisColor.Light.primary200, + ) + @Composable fun default() = ButtonColorSet( background = JobisColor.Light.gray300, @@ -40,6 +48,13 @@ internal object ButtonColors { text = JobisColor.Dark.gray100, ) + @Composable + fun secondary() = ButtonColorSet( + background = JobisColor.Dark.primary100, + pressed = JobisColor.Dark.gray300, + text = JobisColor.Dark.primary200, + ) + @Composable fun default() = ButtonColorSet( background = JobisColor.Light.gray300, diff --git a/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/button/JobisButton.kt b/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/button/JobisButton.kt index 59ea701..6a09c2e 100644 --- a/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/button/JobisButton.kt +++ b/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/button/JobisButton.kt @@ -33,28 +33,19 @@ import team.returm.jobisdesignsystemv2.text.JobisText import team.returm.jobisdesignsystemv2.utils.DURATION_MILLIS import team.returm.jobisdesignsystemv2.utils.clickable -private val buttonShape = RoundedCornerShape(12.dp) +private val largeButtonShape = RoundedCornerShape(12.dp) +private val smallButtonShape = RoundedCornerShape(8.dp) @Composable private fun BasicButton( modifier: Modifier, - text: String, backgroundColor: Color, - textColor: Color, + shape: RoundedCornerShape, enabled: Boolean, onPressed: (pressed: Boolean) -> Unit, onClick: () -> Unit, + content: @Composable () -> Unit, ) { - val contentColor by animateColorAsState( - targetValue = if (!enabled) { - JobisTheme.colors.background - } else { - textColor - }, - animationSpec = tween(durationMillis = DURATION_MILLIS), - label = "", - ) - Surface( modifier = modifier .clickable( @@ -62,62 +53,24 @@ private fun BasicButton( onPressed = onPressed, onClick = onClick, ), - shape = buttonShape, + shape = shape, color = backgroundColor, - ) { - Row( - modifier = Modifier - .padding( - start = 28.dp, - end = 16.dp, - top = 16.dp, - bottom = 16.dp, - ), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center, - ) { - JobisText( - text = text, - style = JobisTypography.SubHeadLine, - color = contentColor, - ) - Spacer(modifier = Modifier.width(4.dp)) - Icon( - painter = painterResource(id = JobisIcon.LongArrow), - tint = contentColor, - contentDescription = stringResource(id = R.string.content_description_long_arrow), - ) - } - } + content = content, + ) } @Composable private fun ColoredButton( modifier: Modifier, - text: String, color: ButtonColor, + shape: RoundedCornerShape, enabled: Boolean, pressed: () -> Boolean, onPressed: (pressed: Boolean) -> Unit, onClick: () -> Unit, + content: @Composable (contentColor: Color) -> Unit, ) { - val themeColor = when (color) { - ButtonColor.Primary -> { - if (isSystemInDarkTheme()) { - ButtonColors.Dark.primary() - } else { - ButtonColors.Light.primary() - } - } - - ButtonColor.Default -> { - if (isSystemInDarkTheme()) { - ButtonColors.Dark.default() - } else { - ButtonColors.Light.default() - } - } - } + val themeColor = getThemeColor(color = color) val background by animateColorAsState( targetValue = if (!enabled) { @@ -130,15 +83,55 @@ private fun ColoredButton( label = "", ) + val contentColor by animateColorAsState( + targetValue = if (!enabled) { + JobisTheme.colors.background + } else { + themeColor.text + }, + animationSpec = tween(durationMillis = DURATION_MILLIS), + label = "", + ) + BasicButton( modifier = modifier, - text = text, backgroundColor = background, - textColor = themeColor.text, + shape = shape, enabled = enabled, onPressed = onPressed, onClick = onClick, + content = { content(contentColor) }, + ) +} + +@Composable +private fun getThemeColor(color: ButtonColor) = when (color) { + ButtonColor.Primary -> checkDarkTheme( + lightColor = ButtonColors.Light.primary(), + darkColor = ButtonColors.Dark.primary(), ) + + ButtonColor.Secondary -> checkDarkTheme( + lightColor = ButtonColors.Light.secondary(), + darkColor = ButtonColors.Dark.secondary(), + ) + + ButtonColor.Default -> checkDarkTheme( + lightColor = ButtonColors.Light.default(), + darkColor = ButtonColors.Dark.default(), + ) +} + +@Composable +private fun checkDarkTheme( + lightColor: ButtonColorSet, + darkColor: ButtonColorSet, +): ButtonColorSet { + return if (isSystemInDarkTheme()) { + darkColor + } else { + lightColor + } } @Composable @@ -154,14 +147,70 @@ private fun LargeButton( ColoredButton( modifier = modifier .fillMaxWidth() - .clip(buttonShape), - text = text, + .clip(largeButtonShape), color = color, + shape = largeButtonShape, enabled = enabled, pressed = { pressed }, onPressed = { pressed = it }, onClick = onClick, - ) + ) { contentColor -> + Row( + modifier = Modifier + .padding( + start = 28.dp, + end = 16.dp, + top = 16.dp, + bottom = 16.dp, + ), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + ) { + JobisText( + text = text, + style = JobisTypography.SubHeadLine, + color = contentColor, + ) + Spacer(modifier = Modifier.width(4.dp)) + Icon( + painter = painterResource(id = JobisIcon.LongArrow), + tint = contentColor, + contentDescription = stringResource(id = R.string.content_description_long_arrow), + ) + } + } +} + +@Composable +private fun SmallButton( + modifier: Modifier, + text: String, + color: ButtonColor, + enabled: Boolean, + onClick: () -> Unit, +) { + var pressed by remember { mutableStateOf(false) } + + ColoredButton( + modifier = modifier.clip(smallButtonShape), + color = color, + shape = smallButtonShape, + enabled = enabled, + pressed = { pressed }, + onPressed = { pressed = it }, + onClick = onClick, + ) { contentColor -> + JobisText( + modifier = Modifier + .padding( + horizontal = 8.dp, + vertical = 4.dp, + ), + text = text, + style = JobisTypography.SubBody, + color = contentColor, + ) + } } /** @@ -189,3 +238,20 @@ fun JobisButton( onClick = onClick, ) } + +@Composable +fun JobisSmallButton( + modifier: Modifier = Modifier, + text: String, + color: ButtonColor = ButtonColor.Secondary, + enabled: Boolean = true, + onClick: () -> Unit, +) { + SmallButton( + modifier = modifier, + text = text, + color = color, + enabled = enabled, + onClick = onClick, + ) +} diff --git a/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/textfield/JobisTextField.kt b/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/textfield/JobisTextField.kt index 732dbde..cbe0096 100644 --- a/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/textfield/JobisTextField.kt +++ b/jobisdesignsystemv2/src/main/java/team/returm/jobisdesignsystemv2/textfield/JobisTextField.kt @@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Icon import androidx.compose.material3.Surface import androidx.compose.runtime.Composable @@ -34,6 +35,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.ImeAction +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.unit.dp @@ -102,8 +105,12 @@ private fun TextField( hint: String, onValueChange: (String) -> Unit, singleLine: Boolean, + imeAction: ImeAction, + keyboardType: KeyboardType, + maxLength: Int, showEmailHint: Boolean, showVisibleIcon: Boolean, + content: @Composable () -> Unit, ) { val hintAlpha by animateFloatAsState( targetValue = if (value().isEmpty()) { @@ -114,9 +121,10 @@ private fun TextField( label = "", ) var visible by remember { mutableStateOf(false) } - val (visualTransformation, icon) = when (visible) { - true -> PasswordVisualTransformation() to JobisIcon.EyeOn - else -> VisualTransformation.None to JobisIcon.EyeOff + val (visualTransformation, icon) = if (visible || !showVisibleIcon) { + VisualTransformation.None to JobisIcon.EyeOn + } else { + PasswordVisualTransformation() to JobisIcon.EyeOff } Surface( @@ -125,7 +133,7 @@ private fun TextField( color = JobisTheme.colors.inverseSurface, ) { BasicTextField( - value = value(), + value = value().take(maxLength), onValueChange = onValueChange, modifier = Modifier.padding( horizontal = 16.dp, @@ -134,6 +142,10 @@ private fun TextField( textStyle = style, singleLine = singleLine, visualTransformation = visualTransformation, + keyboardOptions = KeyboardOptions( + keyboardType = keyboardType, + imeAction = imeAction, + ), ) { innerTextField -> Row( modifier = Modifier.fillMaxWidth(), @@ -162,6 +174,7 @@ private fun TextField( color = JobisTheme.colors.onSurfaceVariant, ) } + content() if (showVisibleIcon) { JobisIconButton( painter = painterResource(id = icon), @@ -251,9 +264,13 @@ fun JobisTextField( titleStyle: TextStyle = JobisTypography.Description, titleColor: Color = JobisTheme.colors.onSurface, style: TextStyle = JobisTypography.Body, + imeAction: ImeAction = ImeAction.Done, + keyboardType: KeyboardType = KeyboardType.Text, singleLine: Boolean = true, + maxLength: Int = Int.MAX_VALUE, showEmailHint: Boolean = false, showVisibleIcon: Boolean = false, + content: @Composable () -> Unit = { }, ) { Column( modifier = Modifier @@ -268,14 +285,20 @@ fun JobisTextField( color = titleColor, ) TextField( - modifier = modifier.fillMaxWidth().defaultMinSize(minHeight = 48.dp), + modifier = modifier + .fillMaxWidth() + .defaultMinSize(minHeight = 48.dp), style = style, value = value, hint = hint, onValueChange = onValueChange, singleLine = singleLine, + imeAction = imeAction, + keyboardType = keyboardType, + maxLength = maxLength, showEmailHint = showEmailHint, showVisibleIcon = showVisibleIcon, + content = content, ) AnimatedVisibility( visible = showDescription(),