From 0b82df989eb7989e551aa7c30025fd752a9cdf77 Mon Sep 17 00:00:00 2001 From: gaeulzzang Date: Fri, 4 Oct 2024 16:48:09 +0900 Subject: [PATCH] #1 [ADD] add base components --- core/build.gradle.kts | 1 - .../component/bottomsheet/BaseBottomSheet.kt | 24 +++++ .../component/dialog/BaseDialog.kt | 77 ++++++++++++++++ .../component/textfield/BaseTextField.kt | 24 ++--- .../{appbar => topappbar}/BaseTopAppBar.kt | 2 +- .../com/sopt/core/extension/ModifierExt.kt | 89 +++++++++++++++++++ data/build.gradle.kts | 1 - .../sopt/presentation/example/ExampleRoute.kt | 2 +- .../com/sopt/presentation/group/GroupRoute.kt | 2 +- .../sopt/presentation/main/MainActivity.kt | 2 + .../sopt/presentation/mypage/MyPageRoute.kt | 2 - presentation/src/main/res/values/strings.xml | 2 +- 12 files changed, 202 insertions(+), 26 deletions(-) create mode 100644 core/src/main/java/com/sopt/core/designsystem/component/bottomsheet/BaseBottomSheet.kt create mode 100644 core/src/main/java/com/sopt/core/designsystem/component/dialog/BaseDialog.kt rename core/src/main/java/com/sopt/core/designsystem/component/{appbar => topappbar}/BaseTopAppBar.kt (96%) create mode 100644 core/src/main/java/com/sopt/core/extension/ModifierExt.kt diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 6f8c056..540d32d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -41,7 +41,6 @@ android { } dependencies { - implementation(libs.kotlin) implementation(libs.core.ktx) implementation(libs.material) diff --git a/core/src/main/java/com/sopt/core/designsystem/component/bottomsheet/BaseBottomSheet.kt b/core/src/main/java/com/sopt/core/designsystem/component/bottomsheet/BaseBottomSheet.kt new file mode 100644 index 0000000..7a424d3 --- /dev/null +++ b/core/src/main/java/com/sopt/core/designsystem/component/bottomsheet/BaseBottomSheet.kt @@ -0,0 +1,24 @@ +package com.sopt.core.designsystem.component.bottomsheet + +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.SheetState +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun BaseBottomSheet( + content: @Composable () -> Unit, + onDismissRequest: () -> Unit, + sheetState: SheetState = rememberModalBottomSheetState() +) { + ModalBottomSheet( + onDismissRequest = { onDismissRequest() }, + sheetState = sheetState, + containerColor = Color.White, + ) { + content() + } +} \ No newline at end of file diff --git a/core/src/main/java/com/sopt/core/designsystem/component/dialog/BaseDialog.kt b/core/src/main/java/com/sopt/core/designsystem/component/dialog/BaseDialog.kt new file mode 100644 index 0000000..ab05732 --- /dev/null +++ b/core/src/main/java/com/sopt/core/designsystem/component/dialog/BaseDialog.kt @@ -0,0 +1,77 @@ +package com.sopt.core.designsystem.component.dialog + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.sopt.core.R +import com.sopt.core.designsystem.theme.NoostakAndroidTheme + +@Composable +fun BaseDialog( + onDismissRequest: () -> Unit, + properties: DialogProperties = DialogProperties( + usePlatformDefaultWidth = false, + decorFitsSystemWindows = true, + dismissOnBackPress = true, + dismissOnClickOutside = true, + ), + content: @Composable () -> Unit, +) { + Dialog( + onDismissRequest = { onDismissRequest() }, + properties = properties, + ) { + Box( + modifier = Modifier + .wrapContentSize() + .padding(horizontal = 30.dp) + .background( + color = Color.White, + shape = RoundedCornerShape(20.dp) + ), + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 18.dp, bottom = 16.dp) + .padding(horizontal = 16.dp), + horizontalArrangement = Arrangement.End + ) { + Icon( + painter = painterResource(id = R.drawable.ic_back), + contentDescription = null, + tint = Color.Gray, + modifier = Modifier + .clickable { onDismissRequest() } + ) + } + content() + } + } +} + +@Preview +@Composable +fun BaseDialogPreview() { + NoostakAndroidTheme { + BaseDialog( + onDismissRequest = {}, + content = {} + ) + } +} \ No newline at end of file diff --git a/core/src/main/java/com/sopt/core/designsystem/component/textfield/BaseTextField.kt b/core/src/main/java/com/sopt/core/designsystem/component/textfield/BaseTextField.kt index b793dcf..1825574 100644 --- a/core/src/main/java/com/sopt/core/designsystem/component/textfield/BaseTextField.kt +++ b/core/src/main/java/com/sopt/core/designsystem/component/textfield/BaseTextField.kt @@ -15,8 +15,6 @@ fun BaseTextField( onValueChange: (String) -> Unit, label: String, placeholder: String, - isError: Boolean, - errorMessage: String, isEnabled: Boolean = true, modifier: Modifier ) { @@ -24,6 +22,12 @@ fun BaseTextField( modifier = modifier, value = value, onValueChange = { onValueChange(it) }, + label = { + Text( + text = label, + color = Color.Black + ) + }, placeholder = { Text( text = placeholder, @@ -38,19 +42,3 @@ fun BaseTextField( ) ) } - -@Preview -@Composable -fun BaseTextFieldPreview() { - NoostakAndroidTheme { - BaseTextField( - value = "Value", - onValueChange = {}, - label = "Label", - placeholder = "Placeholder", - isError = false, - errorMessage = "Error message", - modifier = Modifier - ) - } -} diff --git a/core/src/main/java/com/sopt/core/designsystem/component/appbar/BaseTopAppBar.kt b/core/src/main/java/com/sopt/core/designsystem/component/topappbar/BaseTopAppBar.kt similarity index 96% rename from core/src/main/java/com/sopt/core/designsystem/component/appbar/BaseTopAppBar.kt rename to core/src/main/java/com/sopt/core/designsystem/component/topappbar/BaseTopAppBar.kt index 2fb466e..52d842c 100644 --- a/core/src/main/java/com/sopt/core/designsystem/component/appbar/BaseTopAppBar.kt +++ b/core/src/main/java/com/sopt/core/designsystem/component/topappbar/BaseTopAppBar.kt @@ -1,4 +1,4 @@ -package com.sopt.core.designsystem.component.appbar +package com.sopt.core.designsystem.component.topappbar import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.padding diff --git a/core/src/main/java/com/sopt/core/extension/ModifierExt.kt b/core/src/main/java/com/sopt/core/extension/ModifierExt.kt new file mode 100644 index 0000000..880021b --- /dev/null +++ b/core/src/main/java/com/sopt/core/extension/ModifierExt.kt @@ -0,0 +1,89 @@ +package com.sopt.core.extension + +import android.annotation.SuppressLint +import android.graphics.BlurMaskFilter +import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.focus.FocusManager +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +@SuppressLint("ModifierFactoryUnreferencedReceiver") +inline fun Modifier.noRippleClickable(crossinline onClick: () -> Unit): Modifier = composed { + clickable(indication = null, + interactionSource = remember { MutableInteractionSource() }) { + onClick() + } +} + +fun Modifier.addFocusCleaner(focusManager: FocusManager): Modifier { + return this.pointerInput(Unit) { + detectTapGestures(onTap = { + focusManager.clearFocus() + }) + } +} + +@Composable +fun Modifier.customShadow( + color: Color = Color.Gray, + shadowRadius: Dp = 0.dp, + shadowWidth: Dp = 2.dp, + offsetX: Dp = 0.dp, + offsetY: Dp = 0.dp, +) = composed { + val paint: Paint = remember { Paint() } + val density = LocalDensity.current + val radius = shadowRadius + shadowWidth + val blurRadiusPx = with(density) { radius.toPx() } + val maskFilter = remember { + BlurMaskFilter(blurRadiusPx, BlurMaskFilter.Blur.NORMAL) + } + drawBehind { + drawIntoCanvas { canvas -> + val frameworkPaint = paint.asFrameworkPaint() + if (radius != 0.dp) { + frameworkPaint.maskFilter = maskFilter + } + frameworkPaint.color = color.toArgb() + + val leftPixel = offsetX.toPx() + val topPixel = offsetY.toPx() + val rightPixel = size.width + leftPixel + val bottomPixel = size.height + topPixel + + if (radius > 0.dp) { + val radiusPx = radius.toPx() + canvas.drawRoundRect( + left = leftPixel, + top = topPixel, + right = rightPixel, + bottom = bottomPixel, + radiusX = radiusPx, + radiusY = radiusPx, + paint = paint, + ) + } else { + canvas.drawRect( + left = leftPixel, + top = topPixel, + right = rightPixel, + bottom = bottomPixel, + paint = paint, + ) + } + } + } +} \ No newline at end of file diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 0e96c1c..e3d5004 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -37,7 +37,6 @@ android { } dependencies { - implementation(project(":domain")) // Kotlin diff --git a/presentation/src/main/java/com/sopt/presentation/example/ExampleRoute.kt b/presentation/src/main/java/com/sopt/presentation/example/ExampleRoute.kt index edf2adb..215638d 100644 --- a/presentation/src/main/java/com/sopt/presentation/example/ExampleRoute.kt +++ b/presentation/src/main/java/com/sopt/presentation/example/ExampleRoute.kt @@ -26,7 +26,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.sopt.core.designsystem.component.appbar.BaseTopAppBar +import com.sopt.core.designsystem.component.topappbar.BaseTopAppBar import com.sopt.core.designsystem.component.button.BaseButton import com.sopt.core.designsystem.theme.NoostakAndroidTheme import com.sopt.core.extension.toast diff --git a/presentation/src/main/java/com/sopt/presentation/group/GroupRoute.kt b/presentation/src/main/java/com/sopt/presentation/group/GroupRoute.kt index cc73a33..38118d9 100644 --- a/presentation/src/main/java/com/sopt/presentation/group/GroupRoute.kt +++ b/presentation/src/main/java/com/sopt/presentation/group/GroupRoute.kt @@ -36,7 +36,7 @@ fun GroupScreen( @Preview(showBackground = true) @Composable -fun AppointmentScreenPreview() { +fun GroupScreenPreview() { NoostakAndroidTheme { GroupScreen() } diff --git a/presentation/src/main/java/com/sopt/presentation/main/MainActivity.kt b/presentation/src/main/java/com/sopt/presentation/main/MainActivity.kt index 43b3dd6..4d55e86 100644 --- a/presentation/src/main/java/com/sopt/presentation/main/MainActivity.kt +++ b/presentation/src/main/java/com/sopt/presentation/main/MainActivity.kt @@ -4,12 +4,14 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import com.sopt.core.designsystem.theme.NoostakAndroidTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { + installSplashScreen() super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { diff --git a/presentation/src/main/java/com/sopt/presentation/mypage/MyPageRoute.kt b/presentation/src/main/java/com/sopt/presentation/mypage/MyPageRoute.kt index ea6c2bc..e86d8dc 100644 --- a/presentation/src/main/java/com/sopt/presentation/mypage/MyPageRoute.kt +++ b/presentation/src/main/java/com/sopt/presentation/mypage/MyPageRoute.kt @@ -71,8 +71,6 @@ fun MyPageScreen( onValueChange = { text = it }, label = "텍스트 입력칸", placeholder = "텍스트를 적어주세요", - isError = false, - errorMessage = "", modifier = Modifier.padding(bottom = 10.dp) ) BaseButton( diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index cc21743..e567367 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -3,7 +3,7 @@ 캘린더 - 약속 + 그룹 내정보