Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YDS-#228] Component - Toast 구현 #233

Merged
merged 12 commits into from
Jan 8, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fun Badge(

@Preview(showBackground = true, showSystemUi = true)
@Composable
fun BadgePreview() {
private fun BadgePreview() {
var text by remember { mutableStateOf("에메랄드 뱃지") }
var itemColor by remember { mutableStateOf(ItemColor.Emerald) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private fun BottomSheet(
@OptIn(ExperimentalMaterialApi::class)
@Preview(showSystemUi = true)
@Composable
fun BottomSheetPreview() {
private fun BottomSheetPreview() {
val coroutineScope = rememberCoroutineScope()
val sheetState = rememberYdsBottomSheetState()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ fun BoxButton(

@Preview(showBackground = true)
@Composable
fun BoxButtonPreview() {
private fun BoxButtonPreview() {
var text by remember { mutableStateOf("Default") }

YdsTheme {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ fun CheckBox(

@Preview(showBackground = true)
@Composable
fun CheckBoxPreview() {
private fun CheckBoxPreview() {
var checked1 by remember { mutableStateOf(false) }
var disabled by remember { mutableStateOf(false) }
var checked2 by remember { mutableStateOf(false) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fun Divider(

@Preview(showBackground = true, backgroundColor = 0xFFFFFF)
@Composable
fun DividerPreview() {
private fun DividerPreview() {
YdsTheme {
Column(modifier = Modifier.height(IntrinsicSize.Min)) {
YdsText(text = "one")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ fun ListItem(

@Preview(showBackground = true)
@Composable
fun ListItemPreview() {
private fun ListItemPreview() {

YdsTheme {
Column {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fun ListToggleItem(

@Preview
@Composable
fun ListToggleItemPreview() {
private fun ListToggleItemPreview() {
var checked1 by remember { mutableStateOf(false) }
var checked2 by remember { mutableStateOf(false) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ fun PasswordTextField(

@Preview
@Composable
fun PreviewPasswordTextField() {
private fun PreviewPasswordTextField() {
var isError by remember { mutableStateOf(false) }
var text by rememberSaveable { mutableStateOf("") }
Column {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ fun UpdateEffect(key: Any, block: suspend CoroutineScope.() -> Unit) {

@Preview(showBackground = true)
@Composable
fun PickerPreview() {
private fun PickerPreview() {
val items1 = listOf("오전", "오후")
val items2 = (1..100).map { "$it" }.toList()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ fun PlainButton(

@Preview(showBackground = true)
@Composable
fun PlainButtonPreview() {
private fun PlainButtonPreview() {

var sizeState by rememberSaveable { mutableStateOf(PlainButtonSize.Large) }
var pointed by remember { mutableStateOf(false) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ fun ProfileImageView(

@Preview(showSystemUi = true)
@Composable
fun ProfileImageViewPreview() {
private fun ProfileImageViewPreview() {
val sizeList = listOf(
ProfileImageViewSize.ExtraSmall,
ProfileImageViewSize.Small,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fun SimpleTextField(

@Preview
@Composable
fun PreviewSimpleTextField() {
private fun PreviewSimpleTextField() {
var isError by remember { mutableStateOf(false) }
var text by rememberSaveable { mutableStateOf("") }
Column {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ fun Toggle(

@Preview(showBackground = true)
@Composable
fun TogglePreview() {
private fun TogglePreview() {
var checked1 by remember { mutableStateOf(false) }
var disabled by remember { mutableStateOf(false) }
var checked2 by remember { mutableStateOf(false) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,202 @@
package com.yourssu.design.system.compose.base

import androidx.compose.foundation.background
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.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.SubcomposeLayout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.yourssu.design.system.compose.R
import com.yourssu.design.system.compose.YdsTheme
import com.yourssu.design.system.compose.atom.BoxButton
import com.yourssu.design.system.compose.atom.TopBarButton
import com.yourssu.design.system.compose.component.TopBar
import com.yourssu.design.system.compose.foundation.LocalContentColor
import com.yourssu.design.system.compose.foundation.ToastDuration
import com.yourssu.design.system.compose.foundation.ToastHost
import com.yourssu.design.system.compose.foundation.ToastHostState
import kotlinx.coroutines.launch

private enum class ScaffoldLayoutContent { TopBar, MainContent, Snackbar, BottomBar }

@Composable
fun YdsScaffold(
modifier: Modifier = Modifier,
toastHostState: ToastHostState = remember { ToastHostState() },
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
toastHost: @Composable (ToastHostState) -> Unit = { ToastHost(it) },
backgroundColor: Color = YdsTheme.colors.bgNormal,
contentColor: Color = LocalContentColor.current,
content: @Composable () -> Unit
content: @Composable (PaddingValues) -> Unit
) {
Surface(modifier = modifier, color = backgroundColor, contentColor = contentColor) {
ScaffoldLayout(
topBar = topBar,
bottomBar = bottomBar,
toast = { toastHost(toastHostState) },
content = content
)
}
}

@Composable
private fun ScaffoldLayout(
topBar: @Composable () -> Unit,
bottomBar: @Composable () -> Unit,
toast: @Composable () -> Unit,
content: @Composable (PaddingValues) -> Unit
) {
// TODO: Toast 추가
Surface(
modifier = modifier,
color = backgroundColor,
contentColor = contentColor,
) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween,
) {
topBar()
Box(Modifier.weight(1f)) {
content()
}
bottomBar()
val pxValue = LocalDensity.current.run { ToastApartFromBottom.toPx() }.toInt()

SubcomposeLayout { constraints ->
val layoutWidth = constraints.maxWidth
val layoutHeight = constraints.maxHeight

val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)

layout(layoutWidth, layoutHeight) {

val topBarPlaceables = subcompose(ScaffoldLayoutContent.TopBar, topBar).map {
it.measure(looseConstraints)
}


val topBarHeight = topBarPlaceables.maxByOrNull { it.height }?.height ?: 0

val toastPlaceables = subcompose(ScaffoldLayoutContent.Snackbar, toast).map {
it.measure(looseConstraints)
}

val toastHeight = toastPlaceables.maxByOrNull { it.height }?.height ?: 0

val bottomBarPlaceables = subcompose(ScaffoldLayoutContent.BottomBar, bottomBar).map {
it.measure(looseConstraints)
}

val bottomBarHeight = bottomBarPlaceables.maxByOrNull { it.height }?.height ?: 0

val snackbarOffsetFromBottom = if (toastHeight != 0) {
toastHeight + pxValue
} else {
0
}

val bodyContentHeight = layoutHeight - topBarHeight

val bodyContentPlaceables = subcompose(ScaffoldLayoutContent.MainContent) {
val innerPadding = PaddingValues(bottom = bottomBarHeight.toDp())
content(innerPadding)
}.map { it.measure(looseConstraints.copy(maxHeight = bodyContentHeight)) }

bodyContentPlaceables.forEach {
it.place(0, topBarHeight)
}
topBarPlaceables.forEach {
it.place(0, 0)
}
toastPlaceables.forEach {
it.place(0, layoutHeight - snackbarOffsetFromBottom)
}
// The bottom bar is always at the bottom of the layout
bottomBarPlaceables.forEach {
it.place(0, layoutHeight - bottomBarHeight)
}
}
}
}

private val ToastApartFromBottom = 72.dp


@Preview
@Composable
private fun YdsScaffoldPreview() {
val toastHostState: ToastHostState = remember { ToastHostState() }
cometj03 marked this conversation as resolved.
Show resolved Hide resolved
val scope = rememberCoroutineScope()

YdsScaffold(
toastHostState = toastHostState,
topBar = {
TopBar(
title = "타이틀",
navigationIcon = {
TopBarButton(
icon = R.drawable.ic_arrow_left_line,
isDisabled = false,
)
},
actions = {
TopBarButton(
icon = R.drawable.ic_bell_line,
isDisabled = false,
)
TopBarButton(
icon = R.drawable.ic_search_line,
isDisabled = false,
onClick = {
scope.launch {
toastHostState.showToast(
message = "Snackbar",
duration = ToastDuration.SHORT
)
}
}
)
}
)
},
bottomBar = {
Box(
modifier = Modifier
.size(72.dp)
.background(Color.Black),
contentAlignment = Alignment.Center,
) {
YdsText(
text = "This is 72.dp",
style = YdsTheme.typography.body1,
color = Color.White
)
}
},
toastHost = { ToastHost(it) },
content = {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxSize()
) {
YdsText(text = "content", style = YdsTheme.typography.body1)
BoxButton(onClick = {
scope.launch {
toastHostState.showToast(
message = "잠, 아스라히 노새, 멀듯이, 흙으로 봅니다.",
duration = ToastDuration.SHORT
)
}
}, text = "짧은 토스트 버튼")
BoxButton(onClick = {
scope.launch {
toastHostState.showToast(
message = "잠, 아스라히 노새, 멀듯이, 흙으로 봅니다. 때 불러 가슴속에 나의 풀이 이름과 언덕 오면 가을 봅니다.",
duration = ToastDuration.LONG
)
}
}, text = "긴 토스트 버튼")
}
}
)
}

Loading