diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_check.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_check.xml
new file mode 100644
index 0000000..d2c5b53
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_check.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_comment.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_comment.xml
new file mode 100644
index 0000000..0f22a64
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_comment.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_dislike.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_dislike.xml
new file mode 100644
index 0000000..3d2936b
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_dislike.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_empty_star.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_empty_star.xml
new file mode 100644
index 0000000..7d7bf35
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_empty_star.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_filled_star.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_filled_star.xml
new file mode 100644
index 0000000..57064b3
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_filled_star.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_half_star.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_half_star.xml
new file mode 100644
index 0000000..ed4163e
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_half_star.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_kus_blank.png b/core/designSystem/src/commonMain/composeResources/drawable/ic_kus_blank.png
new file mode 100644
index 0000000..1c8e7b4
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/drawable/ic_kus_blank.png differ
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_kus_logo.png b/core/designSystem/src/commonMain/composeResources/drawable/ic_kus_logo.png
new file mode 100644
index 0000000..66557fe
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/drawable/ic_kus_logo.png differ
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_launcher_background.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_launcher_foreground.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_like.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_like.xml
new file mode 100644
index 0000000..600fb48
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_like.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_location.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_location.xml
new file mode 100644
index 0000000..979b315
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_location.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_pencil.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_pencil.xml
new file mode 100644
index 0000000..f02a736
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_pencil.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_saved.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_saved.xml
new file mode 100644
index 0000000..cecd7d2
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_saved.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/drawable/ic_unsaved.xml b/core/designSystem/src/commonMain/composeResources/drawable/ic_unsaved.xml
new file mode 100644
index 0000000..fa77084
--- /dev/null
+++ b/core/designSystem/src/commonMain/composeResources/drawable/ic_unsaved.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/core/designSystem/src/commonMain/composeResources/font/pretendard_black.ttf b/core/designSystem/src/commonMain/composeResources/font/pretendard_black.ttf
new file mode 100644
index 0000000..d0c1db8
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/font/pretendard_black.ttf differ
diff --git a/core/designSystem/src/commonMain/composeResources/font/pretendard_bold.ttf b/core/designSystem/src/commonMain/composeResources/font/pretendard_bold.ttf
new file mode 100644
index 0000000..fb07fc6
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/font/pretendard_bold.ttf differ
diff --git a/core/designSystem/src/commonMain/composeResources/font/pretendard_extrabold.ttf b/core/designSystem/src/commonMain/composeResources/font/pretendard_extrabold.ttf
new file mode 100644
index 0000000..9d5fe07
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/font/pretendard_extrabold.ttf differ
diff --git a/core/designSystem/src/commonMain/composeResources/font/pretendard_extralight.ttf b/core/designSystem/src/commonMain/composeResources/font/pretendard_extralight.ttf
new file mode 100644
index 0000000..09e6542
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/font/pretendard_extralight.ttf differ
diff --git a/core/designSystem/src/commonMain/composeResources/font/pretendard_light.ttf b/core/designSystem/src/commonMain/composeResources/font/pretendard_light.ttf
new file mode 100644
index 0000000..2e8541d
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/font/pretendard_light.ttf differ
diff --git a/core/designSystem/src/commonMain/composeResources/font/pretendard_medium.ttf b/core/designSystem/src/commonMain/composeResources/font/pretendard_medium.ttf
new file mode 100644
index 0000000..1db67c6
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/font/pretendard_medium.ttf differ
diff --git a/core/designSystem/src/commonMain/composeResources/font/pretendard_regular.ttf b/core/designSystem/src/commonMain/composeResources/font/pretendard_regular.ttf
new file mode 100644
index 0000000..01147e9
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/font/pretendard_regular.ttf differ
diff --git a/core/designSystem/src/commonMain/composeResources/font/pretendard_semibold.ttf b/core/designSystem/src/commonMain/composeResources/font/pretendard_semibold.ttf
new file mode 100644
index 0000000..9f2690f
Binary files /dev/null and b/core/designSystem/src/commonMain/composeResources/font/pretendard_semibold.ttf differ
diff --git a/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Color.kt b/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Color.kt
new file mode 100644
index 0000000..b483c21
--- /dev/null
+++ b/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Color.kt
@@ -0,0 +1,143 @@
+package com.kus.designsystem.theme
+
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.graphics.Color
+
+val C_43AB38 = Color(0xFF43AB38)
+val C_046B40 = Color(0xFF046B40)
+val C_FFFFFF = Color(0xFFFFFFFF)
+val C_F5F5F5 = Color(0xFFF5F5F5)
+val C_EAEAEA = Color(0xFFEAEAEA)
+val C_E0E0E0 = Color(0xFFE0E0E0)
+val C_AAAAAA = Color(0xFFAAAAAA)
+val C_666666 = Color(0xFF666666)
+val C_323232 = Color(0xFF323232)
+val C_353535 = Color(0xFF353535)
+val C_000000 = Color(0xFF000000)
+val C_0093FF = Color(0xFF0093FF)
+val C_01BAA6 = Color(0xFF01BAA6)
+val C_FFB900 = Color(0xFFFFB900)
+val C_9BA5B0 = Color(0xFF9BA5B0)
+
+@Stable
+class KusColors(
+ c_43AB38: Color,
+ c_046B40: Color,
+ c_FFFFFF: Color,
+ c_F5F5F5: Color,
+ c_EAEAEA: Color,
+ c_E0E0E0: Color,
+ c_AAAAAA: Color,
+ c_666666: Color,
+ c_323232: Color,
+ c_353535: Color,
+ c_000000: Color,
+ c_0093FF: Color,
+ c_01BAA6: Color,
+ c_FFB900: Color,
+ c_9BA5B0: Color,
+) {
+ var c_43AB38 by mutableStateOf(c_43AB38)
+ private set
+ var c_046B40 by mutableStateOf(c_046B40)
+ private set
+ var c_FFFFFF by mutableStateOf(c_FFFFFF)
+ private set
+ var c_F5F5F5 by mutableStateOf(c_F5F5F5)
+ private set
+ var c_EAEAEA by mutableStateOf(c_EAEAEA)
+ private set
+ var c_E0E0E0 by mutableStateOf(c_E0E0E0)
+ private set
+ var c_AAAAAA by mutableStateOf(c_AAAAAA)
+ private set
+ var c_666666 by mutableStateOf(c_666666)
+ private set
+ var c_323232 by mutableStateOf(c_323232)
+ private set
+ var c_353535 by mutableStateOf(c_353535)
+ private set
+ var c_000000 by mutableStateOf(c_000000)
+ private set
+ var c_0093FF by mutableStateOf(c_0093FF)
+ private set
+ var c_01BAA6 by mutableStateOf(c_01BAA6)
+ private set
+ var c_FFB900 by mutableStateOf(c_FFB900)
+ private set
+ var c_9BA5B0 by mutableStateOf(c_9BA5B0)
+ private set
+
+ fun copy(): KusColors = KusColors(
+ c_43AB38,
+ c_046B40,
+ c_FFFFFF,
+ c_F5F5F5,
+ c_EAEAEA,
+ c_E0E0E0,
+ c_AAAAAA,
+ c_666666,
+ c_323232,
+ c_353535,
+ c_000000,
+ c_0093FF,
+ c_01BAA6,
+ c_FFB900,
+ c_9BA5B0,
+ )
+
+ fun update(other: KusColors) {
+ c_43AB38 = other.c_43AB38
+ c_046B40 = other.c_046B40
+ c_FFFFFF = other.c_FFFFFF
+ c_F5F5F5 = other.c_F5F5F5
+ c_EAEAEA = other.c_EAEAEA
+ c_E0E0E0 = other.c_E0E0E0
+ c_AAAAAA = other.c_AAAAAA
+ c_666666 = other.c_666666
+ c_323232 = other.c_323232
+ c_353535 = other.c_353535
+ c_000000 = other.c_000000
+ c_0093FF = other.c_0093FF
+ c_01BAA6 = other.c_01BAA6
+ c_FFB900 = other.c_FFB900
+ c_9BA5B0 = other.c_9BA5B0
+ }
+}
+
+fun KusLightColors(
+ c_43AB38: Color = C_43AB38,
+ c_046B40: Color = C_046B40,
+ c_FFFFFF: Color = C_FFFFFF,
+ c_F5F5F5: Color = C_F5F5F5,
+ c_EAEAEA: Color = C_EAEAEA,
+ c_E0E0E0: Color = C_E0E0E0,
+ c_AAAAAA: Color = C_AAAAAA,
+ c_666666: Color = C_666666,
+ c_323232: Color = C_323232,
+ c_353535: Color = C_353535,
+ c_000000: Color = C_000000,
+ c_0093FF: Color = C_0093FF,
+ c_01BAA6: Color = C_01BAA6,
+ c_FFB900: Color = C_FFB900,
+ c_9BA5B0: Color = C_9BA5B0,
+) = KusColors(
+ c_43AB38,
+ c_046B40,
+ c_FFFFFF,
+ c_F5F5F5,
+ c_EAEAEA,
+ c_E0E0E0,
+ c_AAAAAA,
+ c_666666,
+ c_323232,
+ c_353535,
+ c_000000,
+ c_0093FF,
+ c_01BAA6,
+ c_FFB900,
+ c_9BA5B0,
+)
diff --git a/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Theme.kt b/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Theme.kt
new file mode 100644
index 0000000..3726c69
--- /dev/null
+++ b/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Theme.kt
@@ -0,0 +1,58 @@
+package com.kus.designsystem.theme
+
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.staticCompositionLocalOf
+
+private val LocalKusColors = staticCompositionLocalOf {
+ error("No KusColors provided")
+}
+
+private val LocalKusTypography = staticCompositionLocalOf {
+ error("No KusTypography provided")
+}
+
+object KusTheme {
+ val colors: KusColors
+ @Composable
+ @ReadOnlyComposable
+ get() = LocalKusColors.current
+ val typography: KusTypography
+ @Composable
+ @ReadOnlyComposable
+ get() = LocalKusTypography.current
+}
+
+@Composable
+fun ProvideKusColorsAndTypography(
+ colors: KusColors,
+ typography: KusTypography,
+ content: @Composable () -> Unit
+) {
+ val provideColors = remember { colors.copy() }.apply { update(colors) }
+ CompositionLocalProvider(
+ LocalKusColors provides provideColors,
+ LocalKusTypography provides typography,
+ content = content
+ )
+}
+
+@Composable
+fun KusTheme(
+ content: @Composable () -> Unit
+) {
+ val colors = KusLightColors()
+ val typography = createKusTypography()
+
+ ProvideKusColorsAndTypography(
+ colors = colors,
+ typography = typography
+ ) {
+ MaterialTheme(
+ content = content
+ )
+ }
+}
diff --git a/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Type.kt b/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Type.kt
new file mode 100644
index 0000000..a53c626
--- /dev/null
+++ b/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Type.kt
@@ -0,0 +1,146 @@
+package com.kus.designsystem.theme
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.LineHeightStyle
+import androidx.compose.ui.unit.TextUnit
+import androidx.compose.ui.unit.em
+import androidx.compose.ui.unit.sp
+import kustaurant.core.designsystem.generated.resources.Res
+import kustaurant.core.designsystem.generated.resources.pretendard_bold
+import kustaurant.core.designsystem.generated.resources.pretendard_medium
+import kustaurant.core.designsystem.generated.resources.pretendard_regular
+import kustaurant.core.designsystem.generated.resources.pretendard_semibold
+import org.jetbrains.compose.resources.Font
+
+private val PretendardRegular: FontFamily
+ @Composable
+ get() =
+ FontFamily(Font(Res.font.pretendard_regular, FontWeight.Normal))
+
+private val PretendardMedium: FontFamily
+ @Composable
+ get() =
+ FontFamily(Font(Res.font.pretendard_medium, FontWeight.Medium))
+
+private val PretendardSemiBold: FontFamily
+ @Composable
+ get() =
+ FontFamily(Font(Res.font.pretendard_semibold, FontWeight.SemiBold))
+
+private val PretendardBold: FontFamily
+ @Composable
+ get() =
+ FontFamily(Font(Res.font.pretendard_bold, FontWeight.Bold))
+
+private fun KusTextStyle(
+ fontFamily: FontFamily,
+ fontSize: TextUnit,
+ lineHeight: TextUnit = 1.28.em,
+ letterSpacing: TextUnit = 0.02.em,
+): TextStyle = TextStyle(
+ fontFamily = fontFamily,
+ fontSize = fontSize,
+ lineHeight = lineHeight,
+ letterSpacing = letterSpacing,
+ lineHeightStyle = LineHeightStyle(
+ alignment = LineHeightStyle.Alignment.Center,
+ trim = LineHeightStyle.Trim.None
+ ),
+)
+
+@Immutable
+class KusTypography(
+ val type20b: TextStyle,
+ val type16b: TextStyle,
+ val type13b: TextStyle,
+ val type18sb: TextStyle,
+ val type17sb: TextStyle,
+ val type16sb: TextStyle,
+ val type15sb: TextStyle,
+ val type18m: TextStyle,
+ val type16m: TextStyle,
+ val type15m: TextStyle,
+ val type12m: TextStyle,
+ val type11m: TextStyle,
+ val type14r: TextStyle,
+ val type13r: TextStyle,
+ val type12r: TextStyle,
+ val type11r: TextStyle,
+ val type10r: TextStyle,
+)
+
+@Composable
+fun createKusTypography() = KusTypography(
+ type20b = KusTextStyle(
+ fontFamily = PretendardBold,
+ fontSize = 20.sp,
+ ),
+ type16b = KusTextStyle(
+ fontFamily = PretendardBold,
+ fontSize = 16.sp,
+ ),
+ type13b = KusTextStyle(
+ fontFamily = PretendardBold,
+ fontSize = 13.sp,
+ ),
+ type18sb = KusTextStyle(
+ fontFamily = PretendardSemiBold,
+ fontSize = 18.sp,
+ ),
+ type17sb = KusTextStyle(
+ fontFamily = PretendardSemiBold,
+ fontSize = 17.sp,
+ ),
+ type16sb = KusTextStyle(
+ fontFamily = PretendardSemiBold,
+ fontSize = 16.sp,
+ ),
+ type15sb = KusTextStyle(
+ fontFamily = PretendardSemiBold,
+ fontSize = 15.sp,
+ ),
+ type18m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 18.sp,
+ ),
+ type16m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 16.sp,
+ ),
+ type15m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 15.sp,
+ ),
+ type12m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 12.sp,
+ ),
+ type11m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 11.sp,
+ ),
+ type14r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 14.sp,
+ ),
+ type13r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 13.sp,
+ ),
+ type12r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 12.sp,
+ ),
+ type11r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 11.sp,
+ ),
+ type10r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 10.sp,
+ ),
+)
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 6f8e6ea..76a3ace 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,10 +3,14 @@ kotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx3072M
#Gradle
-org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8
-org.gradle.configuration-cache=true
+org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8 -XX:+UseG1GC -XX:MaxMetaspaceSize=512m
+org.gradle.configuration-cache=false
org.gradle.caching=true
#Android
android.nonTransitiveRClass=true
-android.useAndroidX=true
\ No newline at end of file
+android.useAndroidX=true
+
+org.gradle.parallel=true
+org.gradle.daemon=true
+org.gradle.configureondemand=true
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ee27a37..4904cd6 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -33,6 +33,7 @@ material = "1.12.0"
uiautomator = "2.3.0"
benchmarkMacroJunit4 = "1.4.1"
napier = "2.7.1"
+kamel = "0.9.4"
[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
@@ -85,6 +86,8 @@ androidx-benchmark-macro-junit4 = { group = "androidx.benchmark", name = "benchm
napier-log = { group = "io.github.aakira", name = "napier", version.ref = "napier" }
+kamel-image = { module = "media.kamel:kamel-image", version.ref = "kamel" }
+
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }
diff --git a/shared/core/designSystem/build.gradle.kts b/shared/core/designSystem/build.gradle.kts
index 21fdde4..ce1bf0b 100644
--- a/shared/core/designSystem/build.gradle.kts
+++ b/shared/core/designSystem/build.gradle.kts
@@ -47,6 +47,7 @@ kotlin {
implementation(compose.components.uiToolingPreview)
implementation(libs.koin.core)
implementation(libs.koin.compose)
+ implementation(libs.kamel.image)
}
}
diff --git a/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_black.ttf b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_black.ttf
new file mode 100644
index 0000000..d0c1db8
Binary files /dev/null and b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_black.ttf differ
diff --git a/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_bold.ttf b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_bold.ttf
new file mode 100644
index 0000000..fb07fc6
Binary files /dev/null and b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_bold.ttf differ
diff --git a/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_extrabold.ttf b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_extrabold.ttf
new file mode 100644
index 0000000..9d5fe07
Binary files /dev/null and b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_extrabold.ttf differ
diff --git a/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_extralight.ttf b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_extralight.ttf
new file mode 100644
index 0000000..09e6542
Binary files /dev/null and b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_extralight.ttf differ
diff --git a/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_light.ttf b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_light.ttf
new file mode 100644
index 0000000..2e8541d
Binary files /dev/null and b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_light.ttf differ
diff --git a/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_medium.ttf b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_medium.ttf
new file mode 100644
index 0000000..1db67c6
Binary files /dev/null and b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_medium.ttf differ
diff --git a/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_regular.ttf b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_regular.ttf
new file mode 100644
index 0000000..01147e9
Binary files /dev/null and b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_regular.ttf differ
diff --git a/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_semibold.ttf b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_semibold.ttf
new file mode 100644
index 0000000..9f2690f
Binary files /dev/null and b/shared/core/designSystem/src/commonMain/composeResources/font/pretendard_semibold.ttf differ
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusButton.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusButton.kt
new file mode 100644
index 0000000..71dd5b3
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusButton.kt
@@ -0,0 +1,168 @@
+package com.kus.designsystem.component
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.unit.dp
+import com.kus.designsystem.theme.KusTheme
+import kustaurant.shared.core.designsystem.generated.resources.Res
+import org.jetbrains.compose.resources.vectorResource
+import org.jetbrains.compose.ui.tooling.preview.Preview
+
+/**
+ * 쿠스토랑 버튼
+ *
+ * @param enabled 버튼 활성화 여부
+ * @param buttonName 버튼 내용
+ * @param roundedCornerShape 버튼 테두리 모양
+ * @param modifier 내용에 적용되는 수정자
+ * @param textStyle 내용 텍스트 style(default: type18sb)
+ * @param contentColor 내용 색상(default: White)
+ * @param containerColor 버튼 배경 색상(default: c_43AB38)
+ * @param borderColor 버튼 테두리 색상(default: c_43AB38)
+ * @param contentPadding 내용과 버튼 사이 패딩(default: PaddingValues(vertical = 13.dp))
+ * @param icon 버튼에 들어가는 좌측 아이콘(default: null)
+ * @param isShadowVisible 새도우 포함 여부(default: false)
+ * @param onClick 버튼 클릭 시 호출 되는 콜백 함수
+ */
+@Composable
+fun KusButton(
+ enabled: Boolean,
+ buttonName: String,
+ roundedCornerShape: RoundedCornerShape,
+ modifier: Modifier = Modifier,
+ textStyle: TextStyle = KusTheme.typography.type18sb,
+ contentColor: Color = Color.White,
+ containerColor: Color = KusTheme.colors.c_43AB38,
+ borderColor: Color = KusTheme.colors.c_43AB38,
+ contentPadding: PaddingValues = PaddingValues(vertical = 13.dp),
+ icon: ImageVector? = null,
+ isShadowVisible: Boolean = false,
+ onClick: () -> Unit,
+) {
+ Box {
+ if (isShadowVisible) {
+ Box(
+ modifier = Modifier
+ .matchParentSize()
+ .shadow(
+ elevation = 4.dp,
+ shape = roundedCornerShape,
+ ambientColor = Color.Transparent,
+ )
+ )
+ }
+
+ Button(
+ onClick = onClick,
+ enabled = enabled,
+ modifier = Modifier,
+ shape = roundedCornerShape,
+ colors = ButtonDefaults.buttonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = KusTheme.colors.c_E0E0E0,
+ disabledContentColor = KusTheme.colors.c_AAAAAA,
+ ),
+ border = BorderStroke(1.dp, borderColor),
+ contentPadding = contentPadding,
+ ) {
+ Row(
+ modifier = modifier,
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.Center,
+ ) {
+ if (icon != null) {
+ Icon(
+ imageVector = icon,
+ contentDescription = null,
+ modifier = Modifier.size(24.dp)
+ )
+
+ Spacer(Modifier.width(10.dp))
+ }
+
+ Text(
+ text = buttonName,
+ style = textStyle,
+ )
+ }
+ }
+ }
+}
+
+//@Preview
+//@Composable
+//private fun KusButtonPreview() {
+// KusTheme {
+// KusButton(
+// buttonName = "랜덤 뽑기",
+// enabled = false,
+// roundedCornerShape = RoundedCornerShape(50.dp),
+// modifier = Modifier.fillMaxWidth(),
+// borderColor = KusTheme.colors.c_E0E0E0,
+// onClick = {},
+// )
+// }
+//}
+//
+//@Preview
+//@Composable
+//private fun KusButtonPreview2() {
+// KusTheme {
+// KusButton(
+// buttonName = "다시 뽑기",
+// enabled = true,
+// roundedCornerShape = RoundedCornerShape(100.dp),
+// modifier = Modifier,
+// textStyle = KusTheme.typography.type14r,
+// contentPadding = PaddingValues(horizontal = 16.dp, vertical = 4.dp),
+// icon = vectorResource(Res.drawable.ic_like),
+// onClick = {},
+// )
+// }
+//}
+//
+//@Preview(showBackground = true)
+//@Composable
+//private fun KusButtonPreview3() {
+// KusTheme {
+// Column(
+// modifier = Modifier.fillMaxSize(),
+// verticalArrangement = Arrangement.Center,
+// ) {
+// KusButton(
+// buttonName = "카테고리 재설정",
+// enabled = true,
+// roundedCornerShape = RoundedCornerShape(100.dp),
+// modifier = Modifier,
+// textStyle = KusTheme.typography.type14r,
+// contentPadding = PaddingValues(horizontal = 16.dp, vertical = 4.dp),
+// contentColor = KusTheme.colors.c_43AB38,
+// containerColor = Color.White,
+// isShadowVisible = true,
+// onClick = {},
+// )
+// }
+// }
+//}
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusCategoryImageButton.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusCategoryImageButton.kt
new file mode 100644
index 0000000..c9f8869
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusCategoryImageButton.kt
@@ -0,0 +1,108 @@
+package com.kus.designsystem.component
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
+import com.kus.designsystem.theme.KusTheme
+
+/**
+ * 카테고리 버튼
+ *
+ * @param modifier 수정자
+ * @param categoryName 카테고리명
+ * @param categoryImage 카테고리 이미지 ImageVector
+ * @param isSelected 버튼 선택 유무 (default : false)
+ * @param onClick 버튼 클릭 시 호출 되는 콜백 함수
+ */
+@Composable
+fun KusCategoryImageButton(
+ modifier: Modifier = Modifier,
+ categoryName: String,
+ categoryImage: ImageVector,
+ isSelected: Boolean = false,
+ onClick: () -> Unit,
+) {
+ val roundedCornerShape = RoundedCornerShape(15.dp)
+ val borderColor =
+ if (isSelected) KusTheme.colors.c_43AB38
+ else KusTheme.colors.c_F5F5F5
+
+ Box {
+ if (isSelected) {
+ Box(
+ modifier = Modifier
+ .matchParentSize()
+ .shadow(
+ elevation = 20.dp,
+ shape = RoundedCornerShape(15.dp),
+ ambientColor = borderColor.copy(alpha = 0.6f),
+ )
+ )
+ }
+
+ Column(
+ modifier = modifier
+ .border(width = 1.dp, color = borderColor, shape = roundedCornerShape)
+ .clip(roundedCornerShape)
+ .background(KusTheme.colors.c_F5F5F5)
+ .clickable(onClick = onClick)
+ .padding(6.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ Image(
+ imageVector = categoryImage,
+ contentDescription = null,
+ modifier = Modifier.size(60.dp),
+ )
+
+ Text(
+ text = categoryName,
+ style = KusTheme.typography.type11m,
+ color = KusTheme.colors.c_323232,
+ )
+ }
+ }
+}
+
+//@Preview
+//@Composable
+//private fun KusCategoryImageButtonPreview() {
+// KusTheme {
+// KusCategoryImageButton(
+// categoryName = "전체",
+// categoryImage = vectorResource(Res.drawable.ic_like),
+// modifier = Modifier,
+// onClick = {},
+// )
+// }
+//}
+//
+//@Preview(showBackground = true)
+//@Composable
+//private fun KusCategoryImageButtonSelectablePreview() {
+// var isSelected by remember { mutableStateOf(false) }
+//
+// KusTheme {
+// KusCategoryImageButton(
+// categoryName = "전체",
+// categoryImage = vectorResource(Res.drawable.ic_like),
+// isSelected = isSelected,
+// modifier = Modifier,
+// onClick = { isSelected = !isSelected },
+// )
+// }
+//}
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusChip.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusChip.kt
index 6179fd9..af29e9a 100644
--- a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusChip.kt
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusChip.kt
@@ -1,81 +1,71 @@
package com.kus.designsystem.component
-
-import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.layout.Arrangement
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
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.graphics.Color
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import com.kus.designsystem.color.KusColor.Signature1
-import com.kus.designsystem.util.noRippleClickable
+import com.kus.designsystem.theme.KusTheme
import org.jetbrains.compose.ui.tooling.preview.Preview
-private val UnselectedStroke = Color(0xFFAAAAAA)
-
+/**
+ * 티어표 상단 필터 칩
+ *
+ * @param modifier chip 영역 수정자
+ * @param chipName chip 이름
+ * @param isSelected chip 선택 유무
+ * @param onClick chip 클릭 시 호출 되는 콜백 함수
+ */
@Composable
fun KusChip(
- text: String,
+ modifier: Modifier = Modifier,
+ chipName: String,
+ isSelected: Boolean = false,
onClick: () -> Unit,
- selected: Boolean,
- isSelectable: Boolean,
- modifier: Modifier = Modifier
) {
- val strokeColor = if (selected) Signature1 else UnselectedStroke
- val bgColor = if (selected) Signature1.copy(alpha = 0.2f) else Color.Transparent
+ val roundedCornerShape = RoundedCornerShape(100.dp)
+ val mainColor =
+ if (isSelected) KusTheme.colors.c_43AB38
+ else KusTheme.colors.c_AAAAAA
+ val backgroundColor =
+ if (isSelected) KusTheme.colors.c_43AB38.copy(alpha = 0.2f)
+ else Color.White
- Surface(
- modifier = modifier.then(
- if (isSelectable) Modifier.noRippleClickable(onClick) else Modifier
- ),
- shape = RoundedCornerShape(16.dp),
- color = bgColor,
- border = BorderStroke(1.dp, strokeColor)
+ Box(
+ modifier = modifier
+ .background(backgroundColor, roundedCornerShape)
+ .border(1.dp, mainColor, roundedCornerShape)
+ .padding(horizontal = 16.dp, vertical = 4.dp)
+ .clickable(onClick = onClick),
) {
- Box(
- modifier = Modifier.padding(horizontal = 14.dp, vertical = 6.dp),
- contentAlignment = Alignment.Center
- ) {
- Text(
- text = text,
- color = strokeColor,
- fontSize = 14.sp
- )
- }
+ Text(
+ text = chipName,
+ style = KusTheme.typography.type14r,
+ color = mainColor,
+ )
}
}
-
-@Preview(showBackground = true)
+@Preview
@Composable
-fun PreviewKusChip() {
- var isSelected1 by remember { mutableStateOf(true) }
- var isSelected2 by remember { mutableStateOf(true) }
+private fun KusChipPreview() {
+ var isSelected by remember { mutableStateOf(false) }
- Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
+ KusTheme {
KusChip(
- text = "Selectable",
- selected = isSelected1,
- isSelectable = true,
- onClick = { isSelected1 = !isSelected1 }
- )
-
- KusChip(
- text = "Locked (selected but not clickable)",
- selected = isSelected2,
- isSelectable = false,
- onClick = { isSelected2 = !isSelected2 } // 호출 안 됨
+ chipName = "전체",
+ isSelected = isSelected,
+ onClick = { isSelected = !isSelected },
)
}
-}
\ No newline at end of file
+}
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusRatingBar.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusRatingBar.kt
new file mode 100644
index 0000000..eb580b2
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusRatingBar.kt
@@ -0,0 +1,142 @@
+package com.kus.designsystem.component
+
+import androidx.compose.foundation.gestures.detectDragGestures
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Icon
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.unit.dp
+import kustaurant.shared.core.designsystem.generated.resources.Res
+//import kustaurant.core.designsystem.generated.resources.ic_empty_star
+//import kustaurant.core.designsystem.generated.resources.ic_filled_star
+//import kustaurant.core.designsystem.generated.resources.ic_half_star
+import org.jetbrains.compose.resources.vectorResource
+import org.jetbrains.compose.ui.tooling.preview.Preview
+import kotlin.math.round
+
+/**
+ * 쿠스토랑 별점 바
+ * @param modifier : 별점 전체 컴포넌트 modifier
+ * @param rating : 초기 rating 값
+ * @param isEnabled : 별점 변경 가능 불가능
+ * @param onRatingChange : 별점 변경에 따른 함수 반환
+ * @param starModifier : 각 별의 modifier
+ */
+@Composable
+fun KusRatingBar(
+ modifier: Modifier = Modifier,
+ rating: Float = 0f,
+ isEnabled: Boolean = true,
+ onRatingChange: (Float) -> Unit = {},
+ starModifier: Modifier = Modifier.size(24.dp)
+) {
+ var currentRating by remember { mutableFloatStateOf(rating.coerceIn(0f, 5f)) }
+ var containerWidth by remember { mutableIntStateOf(0) }
+
+ LaunchedEffect(rating, isEnabled) {
+ if (!isEnabled) {
+ currentRating = rating.coerceIn(0f, 5f)
+ }
+ }
+
+ Row(
+ modifier = modifier
+ .onSizeChanged { size ->
+ containerWidth = size.width
+ }
+ .then(
+ if (isEnabled) {
+ Modifier.pointerInput(Unit) {
+ detectDragGestures(
+ onDrag = { change, _ ->
+ val x = change.position.x
+ if (containerWidth > 0) {
+ val newRating = (x / containerWidth * 5).coerceIn(0f, 5f)
+ // 0.5 단위 반올림
+ val roundedRating = (round(newRating * 2) / 2).coerceIn(0f, 5f)
+ if (roundedRating != currentRating) {
+ currentRating = roundedRating
+ onRatingChange(roundedRating)
+ }
+ }
+ }
+ )
+ }
+ } else {
+ Modifier
+ }
+ ),
+ horizontalArrangement = Arrangement.spacedBy(1.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ repeat(5) { index ->
+ val starIndex = index + 1
+ val starRating = currentRating - index
+
+ when {
+ starRating >= 1f -> {
+ // 완전히 채워진 별
+ Icon(
+ imageVector = vectorResource(Res.drawable.ic_filled_star),
+ contentDescription = "별점 $starIndex",
+ modifier = starModifier,
+ tint = Color.Unspecified
+ )
+ }
+ starRating >= 0.5f -> {
+ // 반채워진 별
+ Icon(
+ imageVector = vectorResource(Res.drawable.ic_half_star),
+ contentDescription = "별점 $starIndex",
+ modifier = starModifier,
+ tint = Color.Unspecified
+ )
+ }
+ else -> {
+ // 빈 별
+ Icon(
+ imageVector = vectorResource(Res.drawable.ic_empty_star),
+ contentDescription = "별점 $starIndex",
+ modifier = starModifier,
+ tint = Color.Unspecified
+ )
+ }
+ }
+ }
+ }
+}
+
+@Preview(showBackground = true, name = "드래그 가능 별점")
+@Composable
+fun KusRatingBarInteractivePreview() {
+ KusRatingBar(
+ modifier = Modifier.padding(16.dp),
+ rating = 2.5f,
+ isEnabled = true,
+ onRatingChange = { },
+ starModifier = Modifier.size(40.dp)
+ )
+}
+
+@Preview(showBackground = true, name = "읽기 전용 별점")
+@Composable
+fun KusRatingBarReadOnlyPreview() {
+ KusRatingBar(
+ modifier = Modifier.padding(16.dp),
+ rating = 3.5f,
+ isEnabled = false
+ )
+}
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusReactionButton.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusReactionButton.kt
new file mode 100644
index 0000000..7215fb9
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusReactionButton.kt
@@ -0,0 +1,181 @@
+package com.kus.designsystem.component
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+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.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
+import com.kus.designsystem.theme.KusTheme
+import kustaurant.shared.core.designsystem.generated.resources.Res
+//import kustaurant.core.designsystem.generated.resources.ic_dislike
+//import kustaurant.core.designsystem.generated.resources.ic_like
+import org.jetbrains.compose.resources.vectorResource
+import org.jetbrains.compose.ui.tooling.preview.Preview
+
+/**
+ * 좋아요/싫어요 반응 타입
+ */
+enum class ReactionType {
+ Like,
+ DisLike
+}
+
+/**
+ * 쿠스토랑 반응 버튼
+ * @param modifier : 버튼 전체 컴포넌트 modifier
+ * @param likeText : 좋아요 개수
+ * @param dislikeText : 싫어요 개수
+ * @param selectedType : 현재 선택된 타입 (null 선택 안됨)
+ * @param enabled : 클릭 가능 여부
+ * @param onLikeClick : 좋아요 클릭 시 호출되는 함수
+ * @param onDislikeClick : 싫어요 클릭 시 호출되는 함수
+ */
+@Composable
+fun KusReactionButton(
+ modifier: Modifier = Modifier,
+ likeText: String,
+ dislikeText: String,
+ selectedType: ReactionType? = null,
+ enabled: Boolean = true,
+ onLikeClick: () -> Unit = {},
+ onDislikeClick: () -> Unit = {},
+) {
+ val isLikeSelected = selectedType == ReactionType.Like
+ val isDislikeSelected = selectedType == ReactionType.DisLike
+
+ Row(
+ modifier = modifier,
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ // 좋아요 버튼
+ ReactionButtonItem(
+ iconRes = vectorResource(Res.drawable.ic_like),
+ text = likeText,
+ selected = isLikeSelected,
+ enabled = enabled,
+ onClick = onLikeClick,
+ contentDescription = "좋아요"
+ )
+
+ // 싫어요 버튼
+ ReactionButtonItem(
+ iconRes = vectorResource(Res.drawable.ic_dislike),
+ text = dislikeText,
+ selected = isDislikeSelected,
+ enabled = enabled,
+ onClick = onDislikeClick,
+ contentDescription = "싫어요"
+ )
+ }
+}
+
+@Composable
+private fun ReactionButtonItem(
+ iconRes: ImageVector,
+ text: String,
+ selected: Boolean,
+ enabled: Boolean,
+ onClick: () -> Unit,
+ contentDescription: String
+) {
+ val iconColor = if (selected) {
+ KusTheme.colors.c_43AB38
+ } else {
+ KusTheme.colors.c_AAAAAA
+ }
+
+ val textColor = if (selected) {
+ KusTheme.colors.c_43AB38
+ } else {
+ KusTheme.colors.c_AAAAAA
+ }
+
+ Row(
+ modifier = Modifier
+ .then(
+ if (enabled) {
+ Modifier.clickable { onClick() }
+ } else {
+ Modifier
+ }
+ ),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(
+ imageVector = iconRes,
+ contentDescription = contentDescription,
+ modifier = Modifier.size(16.dp),
+ tint = iconColor
+ )
+
+ Spacer(modifier = Modifier.width(4.dp))
+
+ Text(
+ text = text,
+ style = KusTheme.typography.type14r.copy(
+ color = textColor
+ )
+ )
+ }
+}
+
+@Preview(showBackground = true, name = "클릭 인터랙션 테스트")
+@Composable
+fun KusReactionButtonInteractivePreview() {
+ KusTheme {
+ var selectedType by remember { mutableStateOf(null) }
+ var likeCount by remember { mutableIntStateOf(123) }
+ var dislikeCount by remember { mutableIntStateOf(45) }
+
+ KusReactionButton(
+ likeText = likeCount.toString(),
+ dislikeText = dislikeCount.toString(),
+ selectedType = selectedType,
+ enabled = true,
+ onLikeClick = {
+ if (selectedType == ReactionType.Like) {
+ // 이미 선택된 경우 취소
+ selectedType = null
+ likeCount--
+ } else {
+ // 좋아요 선택
+ if (selectedType == ReactionType.DisLike) {
+ // 싫어요가 선택되어 있었다면 취소
+ dislikeCount--
+ }
+ selectedType = ReactionType.Like
+ likeCount++
+ }
+ },
+ onDislikeClick = {
+ if (selectedType == ReactionType.DisLike) {
+ // 이미 선택된 경우 취소
+ selectedType = null
+ dislikeCount--
+ } else {
+ // 싫어요 선택
+ if (selectedType == ReactionType.Like) {
+ // 좋아요가 선택되어 있었다면 취소
+ likeCount--
+ }
+ selectedType = ReactionType.DisLike
+ dislikeCount++
+ }
+ }
+ )
+ }
+}
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusRestThumbnail.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusRestThumbnail.kt
new file mode 100644
index 0000000..256d541
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusRestThumbnail.kt
@@ -0,0 +1,254 @@
+package com.kus.designsystem.component
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+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.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import com.kus.designsystem.theme.KusTheme
+import kustaurant.shared.core.designsystem.generated.resources.Res
+//import kustaurant.core.designsystem.generated.resources.ic_check
+//import kustaurant.core.designsystem.generated.resources.ic_kus_blank
+//import kustaurant.core.designsystem.generated.resources.ic_location
+//import kustaurant.core.designsystem.generated.resources.ic_saved
+//import kustaurant.core.designsystem.generated.resources.ic_unsaved
+import org.jetbrains.compose.resources.vectorResource
+import org.jetbrains.compose.ui.tooling.preview.Preview
+import io.kamel.image.KamelImage
+import io.kamel.image.asyncPainterResource
+
+@Composable
+fun KusRestThumbnail(
+ modifier: Modifier = Modifier,
+ tier: Int? = null,
+ restName: String,
+ restThumbnail: String? = null,
+ restAlliance: String? = null,
+ categories: ArrayList? = null,
+ location: String? = null,
+ isSaved: Boolean,
+ isEvaluated: Boolean,
+ onClick: () -> Unit = {},
+) {
+ val locationText = location ?: "위치정보 없음"
+ val allianceText = restAlliance ?: "해당사항 없음"
+ val tierText = tier?.toString() ?: "-"
+ val tierColor = when (tier) {
+ 1 -> KusTheme.colors.c_0093FF
+ 2 -> KusTheme.colors.c_01BAA6
+ 3 -> KusTheme.colors.c_FFB900
+ 4 -> KusTheme.colors.c_9BA5B0
+ else -> KusTheme.colors.c_AAAAAA
+ }
+ val savedModel = if (isSaved) Res.drawable.ic_saved else Res.drawable.ic_unsaved
+
+ Row(
+ modifier = modifier
+ .background(
+ color = KusTheme.colors.c_FFFFFF,
+ shape = RoundedCornerShape(16.dp)
+ )
+ .padding(8.dp)
+ ) {
+ Box(
+ modifier = Modifier
+ .size(80.dp)
+ .clip(RoundedCornerShape(11.dp))
+ ) {
+ if (restThumbnail.isNullOrBlank()) {
+ Image(
+ imageVector = vectorResource(Res.drawable.ic_kus_blank),
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = Modifier.size(80.dp)
+ )
+ } else {
+ KamelImage(
+ resource = asyncPainterResource(restThumbnail),
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = Modifier.size(80.dp),
+ onFailure = {
+ Image(
+ imageVector = vectorResource(Res.drawable.ic_kus_blank),
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = Modifier.size(80.dp)
+ )
+ }
+ )
+ }
+
+ Icon(
+ imageVector = vectorResource(savedModel),
+ contentDescription = null,
+ modifier = Modifier
+ .size(20.dp)
+ .padding(top = 2.dp),
+ tint = Color.Unspecified
+ )
+ }
+
+ Column(
+ modifier = Modifier
+ .padding(start = 17.dp, end = 8.dp)
+ .weight(1f)
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ text = restName,
+ style = KusTheme.typography.type16b.copy(
+ color = KusTheme.colors.c_000000
+ )
+ )
+
+ if (isEvaluated) {
+ Icon(
+ imageVector = vectorResource(Res.drawable.ic_check),
+ contentDescription = null,
+ modifier = Modifier.padding(start = 6.dp),
+ tint = Color.Unspecified
+ )
+ }
+ }
+
+ Row(
+ modifier = Modifier.padding(top = 5.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(
+ imageVector = vectorResource(Res.drawable.ic_location),
+ contentDescription = null,
+ modifier = Modifier.size(12.dp),
+ tint = KusTheme.colors.c_AAAAAA
+ )
+
+ Text(
+ text = locationText,
+ style = KusTheme.typography.type12m.copy(
+ color = KusTheme.colors.c_AAAAAA
+ ),
+ modifier = Modifier.padding(start = 4.dp)
+ )
+ }
+
+
+ if (categories != null) {
+ val categoryItems = categories.filter { it.isNotBlank() }
+ LazyRow(
+ modifier = Modifier
+ .padding(top = 4.dp),
+ horizontalArrangement = Arrangement.spacedBy(4.dp)
+ ) {
+ items(categoryItems) { tag ->
+ Text(
+ text = "#$tag",
+ style = KusTheme.typography.type12r.copy(
+ color = KusTheme.colors.c_AAAAAA
+ )
+ )
+ }
+ }
+ }
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.padding(top = 8.dp)
+ ) {
+ Text(
+ text = "제휴",
+ modifier = Modifier
+ .border(
+ width = 1.dp,
+ color = KusTheme.colors.c_AAAAAA,
+ shape = RoundedCornerShape(16.dp)
+ )
+ .background(
+ color = KusTheme.colors.c_FFFFFF
+ )
+ .padding(horizontal = 4.dp, vertical = 1.dp),
+ style = KusTheme.typography.type10r.copy(
+ color = KusTheme.colors.c_AAAAAA
+ )
+ )
+
+ Text(
+ text = allianceText,
+ modifier = Modifier.padding(start = 4.dp),
+ style = KusTheme.typography.type10r.copy(
+ color = KusTheme.colors.c_AAAAAA
+ ),
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1
+ )
+
+ }
+
+ }
+
+ Box(
+ modifier = Modifier
+ .align(Alignment.Bottom)
+ .size(20.dp)
+ .border(
+ width = 1.dp,
+ color = tierColor,
+ shape = RoundedCornerShape(16.dp)
+ )
+ .padding(2.dp)
+ .background(tierColor, RoundedCornerShape(100.dp)),
+ contentAlignment = Alignment.Center
+ ) {
+ Text(
+ text = tierText,
+ style = KusTheme.typography.type16sb.copy(
+ color = KusTheme.colors.c_FFFFFF,
+ lineHeight = androidx.compose.ui.unit.TextUnit.Unspecified
+ ),
+ textAlign = TextAlign.Center
+ )
+ }
+
+
+ }
+}
+
+//@Preview
+//@Composable
+//fun KusRestThumbnailPreview() {
+// KusTheme {
+// KusRestThumbnail(
+// modifier = Modifier
+// .fillMaxWidth()
+// .padding(horizontal = 16.dp),
+// tier = 3,
+// restName = "꾸아 건대점",
+// restAlliance = "어디대 학생증 제시하면 10% 할인이 된다네요 대박 개쩔어",
+// categories = arrayListOf("한식", "분식", "가성비"),
+// location = "서울 성동구",
+// isSaved = true,
+// isEvaluated = true,
+// )
+// }
+//}
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusTopBar.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusTopBar.kt
new file mode 100644
index 0000000..ebc221a
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/component/KusTopBar.kt
@@ -0,0 +1,130 @@
+package com.kus.designsystem.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+
+/**
+ * 쿠스토랑 top bar
+ * @param modifier : 전체 modifier
+ * @param leftIcon : 좌측 아이콘
+ * @param rightFirstIcon : 우측 왼쪽 첫번째 아이콘
+ * @param rightSecondIcon : 우측 오른쪽 두번째 아이콘
+ * @param onLeftClicked : 좌측 아이콘 클릭 로직
+ * @param onRightFirstClicked : 우측 왼쪽 첫번째 아이콘 클릭 로직
+ * @param onRightSecondClicked : 우측 오른쪽 첫번째 아이콘 클릭 로직
+ * @param leftIconModifier : 좌측 아이콘 modifier
+ * @param rightFirstIconModifier : 우측 왼쪽 첫번째 아이콘 modifier
+ * @param rightSecondIconModifier : 우측 오른쪽 두번째 아이콘 modifier
+ * @param content : 가운데 표시되는 content
+ */
+@Composable
+fun KusTopBar(
+ modifier: Modifier = Modifier,
+ leftIcon: ImageVector? = null,
+ rightFirstIcon: ImageVector? = null,
+ rightSecondIcon: ImageVector? = null,
+ onLeftClicked: () -> Unit = {},
+ onRightFirstClicked: () -> Unit = {},
+ onRightSecondClicked: () -> Unit = {},
+ leftIconModifier: Modifier = Modifier,
+ rightFirstIconModifier: Modifier = Modifier,
+ rightSecondIconModifier: Modifier = Modifier,
+ content: @Composable () -> Unit = {},
+) {
+ Box(
+ modifier = modifier
+ ) {
+ // 가운데 컨텐츠
+ Row(
+ modifier = Modifier.align(Alignment.Center),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.Center
+ ) {
+ content()
+ }
+
+ // 왼쪽 아이콘
+ if (leftIcon != null) {
+ IconButton(
+ onClick = onLeftClicked,
+ modifier = Modifier
+ .align(Alignment.CenterStart)
+ .then(leftIconModifier)
+ ) {
+ Icon(
+ imageVector = leftIcon,
+ contentDescription = null
+ )
+ }
+ }
+
+ // 오른쪽 아이콘들
+ Row(
+ modifier = Modifier.align(Alignment.CenterEnd),
+ horizontalArrangement = Arrangement.End
+ ) {
+ if (rightFirstIcon != null) {
+ IconButton(
+ onClick = onRightFirstClicked,
+ modifier = rightFirstIconModifier
+ ) {
+ Icon(
+ imageVector = rightFirstIcon,
+ contentDescription = null
+ )
+ }
+ }
+ if (rightSecondIcon != null) {
+ IconButton(
+ onClick = onRightSecondClicked,
+ modifier = rightSecondIconModifier
+ ) {
+ Icon(
+ imageVector = rightSecondIcon,
+ contentDescription = null
+ )
+ }
+ }
+ }
+ }
+}
+
+//@Preview(showBackground = true, name = "오른쪽 아이콘 1개")
+//@Composable
+//fun KusTopBarPreviewOneRightIcon(){
+// KusTheme {
+// KusTopBar(
+// modifier = Modifier
+// .fillMaxWidth(),
+// leftIcon = Icons.Default.ArrowBack,
+// rightFirstIcon = Icons.Default.Search,
+// content = {
+// Text("제목")
+// }
+// )
+// }
+//}
+//
+//@Preview(showBackground = true, name = "오른쪽 아이콘 2개")
+//@Composable
+//fun KusTopBarPreviewTwoRightIcons(){
+// KusTheme {
+// KusTopBar(
+// modifier = Modifier
+// .fillMaxWidth(),
+// leftIcon = Icons.Default.ArrowBack,
+// rightFirstIcon = Icons.Default.Search,
+// rightSecondIcon = Icons.Default.Menu,
+// content = {
+// Text("제목")
+// }
+// )
+// }
+//}
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Color.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Color.kt
new file mode 100644
index 0000000..b483c21
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Color.kt
@@ -0,0 +1,143 @@
+package com.kus.designsystem.theme
+
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.graphics.Color
+
+val C_43AB38 = Color(0xFF43AB38)
+val C_046B40 = Color(0xFF046B40)
+val C_FFFFFF = Color(0xFFFFFFFF)
+val C_F5F5F5 = Color(0xFFF5F5F5)
+val C_EAEAEA = Color(0xFFEAEAEA)
+val C_E0E0E0 = Color(0xFFE0E0E0)
+val C_AAAAAA = Color(0xFFAAAAAA)
+val C_666666 = Color(0xFF666666)
+val C_323232 = Color(0xFF323232)
+val C_353535 = Color(0xFF353535)
+val C_000000 = Color(0xFF000000)
+val C_0093FF = Color(0xFF0093FF)
+val C_01BAA6 = Color(0xFF01BAA6)
+val C_FFB900 = Color(0xFFFFB900)
+val C_9BA5B0 = Color(0xFF9BA5B0)
+
+@Stable
+class KusColors(
+ c_43AB38: Color,
+ c_046B40: Color,
+ c_FFFFFF: Color,
+ c_F5F5F5: Color,
+ c_EAEAEA: Color,
+ c_E0E0E0: Color,
+ c_AAAAAA: Color,
+ c_666666: Color,
+ c_323232: Color,
+ c_353535: Color,
+ c_000000: Color,
+ c_0093FF: Color,
+ c_01BAA6: Color,
+ c_FFB900: Color,
+ c_9BA5B0: Color,
+) {
+ var c_43AB38 by mutableStateOf(c_43AB38)
+ private set
+ var c_046B40 by mutableStateOf(c_046B40)
+ private set
+ var c_FFFFFF by mutableStateOf(c_FFFFFF)
+ private set
+ var c_F5F5F5 by mutableStateOf(c_F5F5F5)
+ private set
+ var c_EAEAEA by mutableStateOf(c_EAEAEA)
+ private set
+ var c_E0E0E0 by mutableStateOf(c_E0E0E0)
+ private set
+ var c_AAAAAA by mutableStateOf(c_AAAAAA)
+ private set
+ var c_666666 by mutableStateOf(c_666666)
+ private set
+ var c_323232 by mutableStateOf(c_323232)
+ private set
+ var c_353535 by mutableStateOf(c_353535)
+ private set
+ var c_000000 by mutableStateOf(c_000000)
+ private set
+ var c_0093FF by mutableStateOf(c_0093FF)
+ private set
+ var c_01BAA6 by mutableStateOf(c_01BAA6)
+ private set
+ var c_FFB900 by mutableStateOf(c_FFB900)
+ private set
+ var c_9BA5B0 by mutableStateOf(c_9BA5B0)
+ private set
+
+ fun copy(): KusColors = KusColors(
+ c_43AB38,
+ c_046B40,
+ c_FFFFFF,
+ c_F5F5F5,
+ c_EAEAEA,
+ c_E0E0E0,
+ c_AAAAAA,
+ c_666666,
+ c_323232,
+ c_353535,
+ c_000000,
+ c_0093FF,
+ c_01BAA6,
+ c_FFB900,
+ c_9BA5B0,
+ )
+
+ fun update(other: KusColors) {
+ c_43AB38 = other.c_43AB38
+ c_046B40 = other.c_046B40
+ c_FFFFFF = other.c_FFFFFF
+ c_F5F5F5 = other.c_F5F5F5
+ c_EAEAEA = other.c_EAEAEA
+ c_E0E0E0 = other.c_E0E0E0
+ c_AAAAAA = other.c_AAAAAA
+ c_666666 = other.c_666666
+ c_323232 = other.c_323232
+ c_353535 = other.c_353535
+ c_000000 = other.c_000000
+ c_0093FF = other.c_0093FF
+ c_01BAA6 = other.c_01BAA6
+ c_FFB900 = other.c_FFB900
+ c_9BA5B0 = other.c_9BA5B0
+ }
+}
+
+fun KusLightColors(
+ c_43AB38: Color = C_43AB38,
+ c_046B40: Color = C_046B40,
+ c_FFFFFF: Color = C_FFFFFF,
+ c_F5F5F5: Color = C_F5F5F5,
+ c_EAEAEA: Color = C_EAEAEA,
+ c_E0E0E0: Color = C_E0E0E0,
+ c_AAAAAA: Color = C_AAAAAA,
+ c_666666: Color = C_666666,
+ c_323232: Color = C_323232,
+ c_353535: Color = C_353535,
+ c_000000: Color = C_000000,
+ c_0093FF: Color = C_0093FF,
+ c_01BAA6: Color = C_01BAA6,
+ c_FFB900: Color = C_FFB900,
+ c_9BA5B0: Color = C_9BA5B0,
+) = KusColors(
+ c_43AB38,
+ c_046B40,
+ c_FFFFFF,
+ c_F5F5F5,
+ c_EAEAEA,
+ c_E0E0E0,
+ c_AAAAAA,
+ c_666666,
+ c_323232,
+ c_353535,
+ c_000000,
+ c_0093FF,
+ c_01BAA6,
+ c_FFB900,
+ c_9BA5B0,
+)
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Theme.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Theme.kt
new file mode 100644
index 0000000..3726c69
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Theme.kt
@@ -0,0 +1,58 @@
+package com.kus.designsystem.theme
+
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.staticCompositionLocalOf
+
+private val LocalKusColors = staticCompositionLocalOf {
+ error("No KusColors provided")
+}
+
+private val LocalKusTypography = staticCompositionLocalOf {
+ error("No KusTypography provided")
+}
+
+object KusTheme {
+ val colors: KusColors
+ @Composable
+ @ReadOnlyComposable
+ get() = LocalKusColors.current
+ val typography: KusTypography
+ @Composable
+ @ReadOnlyComposable
+ get() = LocalKusTypography.current
+}
+
+@Composable
+fun ProvideKusColorsAndTypography(
+ colors: KusColors,
+ typography: KusTypography,
+ content: @Composable () -> Unit
+) {
+ val provideColors = remember { colors.copy() }.apply { update(colors) }
+ CompositionLocalProvider(
+ LocalKusColors provides provideColors,
+ LocalKusTypography provides typography,
+ content = content
+ )
+}
+
+@Composable
+fun KusTheme(
+ content: @Composable () -> Unit
+) {
+ val colors = KusLightColors()
+ val typography = createKusTypography()
+
+ ProvideKusColorsAndTypography(
+ colors = colors,
+ typography = typography
+ ) {
+ MaterialTheme(
+ content = content
+ )
+ }
+}
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Type.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Type.kt
new file mode 100644
index 0000000..e8ebe9d
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/theme/Type.kt
@@ -0,0 +1,146 @@
+package com.kus.designsystem.theme
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.LineHeightStyle
+import androidx.compose.ui.unit.TextUnit
+import androidx.compose.ui.unit.em
+import androidx.compose.ui.unit.sp
+import kustaurant.shared.core.designsystem.generated.resources.Res
+import kustaurant.shared.core.designsystem.generated.resources.pretendard_bold
+import kustaurant.shared.core.designsystem.generated.resources.pretendard_medium
+import kustaurant.shared.core.designsystem.generated.resources.pretendard_regular
+import kustaurant.shared.core.designsystem.generated.resources.pretendard_semibold
+import org.jetbrains.compose.resources.Font
+
+private val PretendardRegular: FontFamily
+ @Composable
+ get() =
+ FontFamily(Font(Res.font.pretendard_regular, FontWeight.Normal))
+
+private val PretendardMedium: FontFamily
+ @Composable
+ get() =
+ FontFamily(Font(Res.font.pretendard_medium, FontWeight.Medium))
+
+private val PretendardSemiBold: FontFamily
+ @Composable
+ get() =
+ FontFamily(Font(Res.font.pretendard_semibold, FontWeight.SemiBold))
+
+private val PretendardBold: FontFamily
+ @Composable
+ get() =
+ FontFamily(Font(Res.font.pretendard_bold, FontWeight.Bold))
+
+private fun KusTextStyle(
+ fontFamily: FontFamily,
+ fontSize: TextUnit,
+ lineHeight: TextUnit = 1.28.em,
+ letterSpacing: TextUnit = 0.02.em,
+): TextStyle = TextStyle(
+ fontFamily = fontFamily,
+ fontSize = fontSize,
+ lineHeight = lineHeight,
+ letterSpacing = letterSpacing,
+ lineHeightStyle = LineHeightStyle(
+ alignment = LineHeightStyle.Alignment.Center,
+ trim = LineHeightStyle.Trim.None
+ ),
+)
+
+@Immutable
+class KusTypography(
+ val type20b: TextStyle,
+ val type16b: TextStyle,
+ val type13b: TextStyle,
+ val type18sb: TextStyle,
+ val type17sb: TextStyle,
+ val type16sb: TextStyle,
+ val type15sb: TextStyle,
+ val type18m: TextStyle,
+ val type16m: TextStyle,
+ val type15m: TextStyle,
+ val type12m: TextStyle,
+ val type11m: TextStyle,
+ val type14r: TextStyle,
+ val type13r: TextStyle,
+ val type12r: TextStyle,
+ val type11r: TextStyle,
+ val type10r: TextStyle,
+)
+
+@Composable
+fun createKusTypography() = KusTypography(
+ type20b = KusTextStyle(
+ fontFamily = PretendardBold,
+ fontSize = 20.sp,
+ ),
+ type16b = KusTextStyle(
+ fontFamily = PretendardBold,
+ fontSize = 16.sp,
+ ),
+ type13b = KusTextStyle(
+ fontFamily = PretendardBold,
+ fontSize = 13.sp,
+ ),
+ type18sb = KusTextStyle(
+ fontFamily = PretendardSemiBold,
+ fontSize = 18.sp,
+ ),
+ type17sb = KusTextStyle(
+ fontFamily = PretendardSemiBold,
+ fontSize = 17.sp,
+ ),
+ type16sb = KusTextStyle(
+ fontFamily = PretendardSemiBold,
+ fontSize = 16.sp,
+ ),
+ type15sb = KusTextStyle(
+ fontFamily = PretendardSemiBold,
+ fontSize = 15.sp,
+ ),
+ type18m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 18.sp,
+ ),
+ type16m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 16.sp,
+ ),
+ type15m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 15.sp,
+ ),
+ type12m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 12.sp,
+ ),
+ type11m = KusTextStyle(
+ fontFamily = PretendardMedium,
+ fontSize = 11.sp,
+ ),
+ type14r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 14.sp,
+ ),
+ type13r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 13.sp,
+ ),
+ type12r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 12.sp,
+ ),
+ type11r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 11.sp,
+ ),
+ type10r = KusTextStyle(
+ fontFamily = PretendardRegular,
+ fontSize = 10.sp,
+ ),
+)
diff --git a/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/util/ColorUtil.kt b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/util/ColorUtil.kt
new file mode 100644
index 0000000..8dd42e4
--- /dev/null
+++ b/shared/core/designSystem/src/commonMain/kotlin/com/kus/designsystem/util/ColorUtil.kt
@@ -0,0 +1,13 @@
+package com.kus.designsystem.util
+
+import androidx.compose.ui.graphics.Color
+
+/**
+ * 컬러의 투명도를 퍼센트로 설정하는 확장함수
+ * @param percent 투명도 퍼센트 (0-100)
+ * @return 해당 퍼센트의 투명도를 가진 Color
+ */
+fun Color.withOpacityPercent(percent: Int): Color {
+ val clampedPercent = percent.coerceIn(0, 100)
+ return this.copy(alpha = clampedPercent / 100f)
+}
diff --git a/shared/data/firstLaunch/build.gradle.kts b/shared/data/firstLaunch/build.gradle.kts
index 629b91d..df37dd2 100644
--- a/shared/data/firstLaunch/build.gradle.kts
+++ b/shared/data/firstLaunch/build.gradle.kts
@@ -55,6 +55,7 @@ kotlin {
implementation(project(":shared:domain:firstLaunch"))
}
+ resources.srcDirs("src/commonMain/composeResources")
}
commonTest {