diff --git a/.gitignore b/.gitignore index aa724b7..f58c803 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.iml .gradle +.idea/ /local.properties /.idea/caches /.idea/libraries diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index b589d56..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml deleted file mode 100644 index b268ef3..0000000 --- a/.idea/deploymentTargetSelector.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index bb0078e..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 44ca2d9..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml deleted file mode 100644 index fdf8d99..0000000 --- a/.idea/kotlinc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml deleted file mode 100644 index f8051a6..0000000 --- a/.idea/migrations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 8978d23..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/other.xml b/.idea/other.xml deleted file mode 100644 index 94c96f6..0000000 --- a/.idea/other.xml +++ /dev/null @@ -1,318 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/kotlin/com/yourssu/handy/demo/TopBarPreview.kt b/app/src/main/kotlin/com/yourssu/handy/demo/TopBarPreview.kt new file mode 100644 index 0000000..330e1b6 --- /dev/null +++ b/app/src/main/kotlin/com/yourssu/handy/demo/TopBarPreview.kt @@ -0,0 +1,132 @@ +package com.yourssu.handy.demo + +import android.util.Log +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.yourssu.handy.compose.CenterAlignedTopAppBar +import com.yourssu.handy.compose.HandyTheme +import com.yourssu.handy.compose.Icon +import com.yourssu.handy.compose.LeftAlignedTopAppBar +import com.yourssu.handy.compose.Text +import com.yourssu.handy.compose.icons.HandyIcons +import com.yourssu.handy.compose.icons.line.Add +import com.yourssu.handy.compose.icons.line.ArrowsChevronLeft + +@Preview(showBackground = true) +@Composable +fun CenterAlignedTopAppBarPreview() { + Column { + CenterAlignedTopAppBar( + title = "Centered", + navIcon = HandyIcons.Line.ArrowsChevronLeft, + onNavIconClick = { Log.d("TopBarPreview", "ArrowsChevronLeft clicked") }, + actions = {} + ) + + Spacer(modifier = Modifier.height(10.dp)) + + CenterAlignedTopAppBar( + title = "Back Example", + navIcon = HandyIcons.Line.ArrowsChevronLeft, + onNavIconClick = { Log.d("TopBarPreview", "ArrowsChevronLeft clicked") }, + actions = { + Text( + text = "Share", + color = HandyTheme.colors.textBrandPrimary, + modifier = Modifier.clickable { Log.d("TopBarPreview", "Share clicked") }) + } + ) + + Spacer(modifier = Modifier.height(10.dp)) + + CenterAlignedTopAppBar( + title = "최대8자까지가능", + navIcon = HandyIcons.Line.ArrowsChevronLeft, + onNavIconClick = { Log.d("TopBarPreview", "ArrowsChevronLeft clicked") }, + actions = { + Icon( + imageVector = HandyIcons.Line.Add, + contentDescription = "Add", + modifier = Modifier.clickable { Log.d("TopBarPreview", "Add clicked") } + ) + Text( + text = "Text", + color = HandyTheme.colors.textBrandPrimary, + modifier = Modifier.clickable { Log.d("TopBarPreview", "Share clicked") }) + + } + ) + } +} + + +@Preview(showBackground = true) +@Composable +fun LeftAlignedTopBarPreview() { + Column { + LeftAlignedTopAppBar( + title = "Title", + actions = {} + ) + + Spacer(modifier = Modifier.height(10.dp)) + + LeftAlignedTopAppBar( + title = "Title", + actions = { + Icon( + imageVector = HandyIcons.Line.Add, + contentDescription = "Add", + modifier = Modifier.clickable { Log.d("TopBarPreview", "Add clicked") } + ) + } + ) + + Spacer(modifier = Modifier.height(10.dp)) + + LeftAlignedTopAppBar( + title = "Title", + actions = { + Icon( + imageVector = HandyIcons.Line.Add, + contentDescription = "Add", + modifier = Modifier.clickable { Log.d("TopBarPreview", "Add clicked") } + ) + Icon( + imageVector = HandyIcons.Line.Add, + contentDescription = "Add", + modifier = Modifier.clickable { Log.d("TopBarPreview", "Add clicked") } + ) + } + ) + + Spacer(modifier = Modifier.height(10.dp)) + + LeftAlignedTopAppBar( + title = "Title", + actions = { + Icon( + imageVector = HandyIcons.Line.Add, + contentDescription = "Add", + modifier = Modifier.clickable { Log.d("TopBarPreview", "Add clicked") } + ) + Icon( + imageVector = HandyIcons.Line.Add, + contentDescription = "Add", + modifier = Modifier.clickable { Log.d("TopBarPreview", "Add clicked") } + ) + Icon( + imageVector = HandyIcons.Line.Add, + contentDescription = "Add", + modifier = Modifier.clickable { Log.d("TopBarPreview", "Add clicked") } + ) + } + ) + } +} \ No newline at end of file diff --git a/compose/src/main/kotlin/com/yourssu/handy/compose/TopAppBar.kt b/compose/src/main/kotlin/com/yourssu/handy/compose/TopAppBar.kt new file mode 100644 index 0000000..a702fb2 --- /dev/null +++ b/compose/src/main/kotlin/com/yourssu/handy/compose/TopAppBar.kt @@ -0,0 +1,141 @@ +package com.yourssu.handy.compose + +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.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import com.yourssu.handy.compose.TopBarDefaults.topBarActionsInsidePadding +import com.yourssu.handy.compose.TopBarDefaults.topBarHeight +import com.yourssu.handy.compose.TopBarDefaults.topBarHorizontalPadding +import com.yourssu.handy.compose.TopBarDefaults.topBarIconPadding +import com.yourssu.handy.compose.foundation.HandyTypography + + +/** + * Center-Aligned Top App Bar + * + * 타이틀이 중앙에 위치한 탑앱바입니다. 좌측에 메뉴 아이콘 및 뒤로 가기 아이콘이 요구될 경우 사용합니다. + * 아이콘으로 기능을 명확하게 표현하지 못하거나 확실하게 기능을 설명하고 싶을 때 아이콘 대신 Text를 사용할 수 있습니다. + * 이때, 텍스트의 사용은 한 개까지만 가능하며, 텍스트가 공백 포함 5자일 경우 우측에 아이콘을 같이 쓸 수 없습니다. + * + * + * @param title headline or Logo 최대 9자(공백 포함) + * @param navIcon 왼쪽 아이콘 + * @param actions 오른쪽 아이콘 or 텍스트 (아이콘은 임의로 변경할 수 있으며 Center-aligned의 우측엔 최대 2개의 아이콘 버튼) + **/ +@Composable +fun CenterAlignedTopAppBar( + title: String, + navIcon: ImageVector, + onNavIconClick: () -> Unit, + modifier: Modifier = Modifier, + actions: @Composable (RowScope.() -> Unit)? = null +) { + Box( + modifier = modifier + .fillMaxWidth() + .background(color = HandyTheme.colors.bgBasicDefault) + .height(topBarHeight) //Top App Bar의 높이값을 임의로 변경하지 않습니다. + .padding(horizontal = topBarHorizontalPadding), + contentAlignment = Alignment.Center + ) { + + // CenterAligned 일 때는 좌측 아이콘이 항상 있음. + Box( + modifier = Modifier + .align(Alignment.CenterStart) + ) { + Icon( + imageVector = navIcon, + modifier = Modifier + .clickable { onNavIconClick() } + .padding(topBarIconPadding) // 터치영역을 8dp만큼 확장 + ) + } + + Text( + text = title, + color = HandyTheme.colors.textBasicPrimary, + style = HandyTypography.T2Sb18, + textAlign = TextAlign.Center, + ) + + actions?.let { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(topBarActionsInsidePadding), // 요소 사이에 24dp 간격 추가 + modifier = Modifier.fillMaxHeight() + ) { + Spacer(modifier = Modifier.weight(1f)) + actions() + } + } + } +} + + +/** + * Left-aligned + * + * 타이틀이 좌측에 위치한 탑앱바입니다. 기능의 첫 페이지에 사용되는 탑앱바로, + * 현재 페이지의 제목을 나타낼 때 사용합니다. 아이콘으로 기능을 명확하게 표현하지 못하거나 확실하게 기능을 설명하고 싶을 때 아이콘 대신 Text를 사용할 수 있습니다. + * + * @param title headline or Logo 최대 9자(공백 포함) + * @param actions 오른쪽 아이콘 or 텍스트 (아이콘은 임의로 변경할 수 있으며 Left-aligned의 우측엔 최대 3개의 아이콘 버튼) + **/ +@Composable +fun LeftAlignedTopAppBar( + title: String, + actions: @Composable (RowScope.() -> Unit)? = null +) { + + Box( + modifier = Modifier + .fillMaxWidth() + .background(color = HandyTheme.colors.bgBasicDefault) + .height(topBarHeight) + .padding(horizontal = topBarHorizontalPadding), + + contentAlignment = Alignment.Center + ) { + + Text( + text = title, + style = HandyTypography.H3Sb24, + color = HandyTheme.colors.textBasicPrimary, + modifier = Modifier.align(Alignment.CenterStart) + + ) + + actions?.let { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(topBarActionsInsidePadding), // 요소 사이에 24dp 간격 추가 + ) { + Spacer(modifier = Modifier.weight(1f)) + actions() + } + } + } +} + + +object TopBarDefaults { + val topBarHeight = 56.dp + val topBarHorizontalPadding = 16.dp + val topBarActionsInsidePadding = 24.dp + val topBarIconPadding = 8.dp +} diff --git a/compose/src/main/kotlin/com/yourssu/handy/compose/button/BoxButton.kt b/compose/src/main/kotlin/com/yourssu/handy/compose/button/BoxButton.kt index e6f69c2..c395a35 100644 --- a/compose/src/main/kotlin/com/yourssu/handy/compose/button/BoxButton.kt +++ b/compose/src/main/kotlin/com/yourssu/handy/compose/button/BoxButton.kt @@ -69,7 +69,7 @@ fun BoxButton( colors = boxButtonColorByType( type = buttonType, ), - modifier = Modifier.height(height), + modifier = modifier.height(height), enabled = enabled, showBorder = (buttonType == BoxButtonType.Tertiary), interactionSource = interactionSource,