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

Add BadgeList component #290

Merged
merged 1 commit into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.kiwi.navigationcompose.typed.createRoutePattern
import com.kiwi.navigationcompose.typed.dialog
import com.kiwi.navigationcompose.typed.navigate
import kiwi.orbit.compose.catalog.screens.AlertScreen
import kiwi.orbit.compose.catalog.screens.BadgeListScreen
import kiwi.orbit.compose.catalog.screens.BadgeScreen
import kiwi.orbit.compose.catalog.screens.ButtonScreen
import kiwi.orbit.compose.catalog.screens.CheckboxScreen
Expand Down Expand Up @@ -91,6 +92,7 @@ private fun NavGraph(

composable<Destinations.Alert> { AlertScreen(navController::navigateUp) }
composable<Destinations.Badge> { BadgeScreen(navController::navigateUp) }
composable<Destinations.BadgeList> { BadgeListScreen(navController::navigateUp) }
composable<Destinations.Button> { ButtonScreen(navController::navigateUp) }
composable<Destinations.Checkbox> { CheckboxScreen(navController::navigateUp) }
composable<Destinations.ChoiceTile> { ChoiceTileScreen(navController::navigateUp) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ sealed interface Destinations : Destination {
@Serializable
object Badge : Destinations

@Serializable
object BadgeList : Destinations

@Serializable
object Button : Destinations

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package kiwi.orbit.compose.catalog.screens

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.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kiwi.orbit.compose.icons.Icons
import kiwi.orbit.compose.ui.OrbitTheme
import kiwi.orbit.compose.ui.controls.BadgeItemCritical
import kiwi.orbit.compose.ui.controls.BadgeItemInfo
import kiwi.orbit.compose.ui.controls.BadgeItemNeutral
import kiwi.orbit.compose.ui.controls.BadgeItemSuccess
import kiwi.orbit.compose.ui.controls.BadgeItemWarning
import kiwi.orbit.compose.ui.controls.BadgeList
import kiwi.orbit.compose.ui.controls.BadgeListSmall
import kiwi.orbit.compose.ui.controls.Scaffold
import kiwi.orbit.compose.ui.controls.Surface
import kiwi.orbit.compose.ui.controls.Text
import kiwi.orbit.compose.ui.controls.TopAppBar
import kiwi.orbit.compose.ui.foundation.ContentEmphasis

@Composable
internal fun BadgeListScreen(onNavigateUp: () -> Unit) {
Scaffold(
topBar = {
TopAppBar(
title = { Text("BadgeList") },
onNavigateUp = onNavigateUp,
)
},
) { contentPadding: PaddingValues ->
Box(
Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(contentPadding),
) {
BadgeListScreenInner()
}
}
}

@Composable
private fun BadgeListScreenInner() {
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Text(
text = "Badge List Small",
style = OrbitTheme.typography.title4,
)

BadgeListSmall {
BadgeItemNeutral(icon = Icons.AirConditioning) {
Text(text = "This is simple BadgeList item")
}
BadgeItemInfo(icon = Icons.Airplane) {
Text(text = "This is simple BadgeList item")
}
BadgeItemSuccess(icon = Icons.Check) {
Text(text = "This is simple BadgeList item")
}
BadgeItemWarning(icon = Icons.Terminal) {
Text(text = "This is simple BadgeList item")
}
BadgeItemCritical(icon = Icons.Alert) {
Text(text = "This is simple BadgeList item")
}
}

Text(
text = "Badge List Normal",
style = OrbitTheme.typography.title4,
)

BadgeList {
BadgeItemNeutral(icon = Icons.AirConditioning) {
Text(text = "This is simple BadgeList item")
}
BadgeItemInfo(icon = Icons.Airplane) {
Text(text = "This is simple BadgeList item")
}
BadgeItemSuccess(icon = Icons.Check) {
Text(text = "This is simple BadgeList item")
}
BadgeItemWarning(icon = Icons.Terminal) {
Text(text = "This is simple BadgeList item")
}
BadgeItemCritical(icon = Icons.Alert) {
Text(text = "This is simple BadgeList item")
}
}

Text(
text = "Badge List Normal Minor",
style = OrbitTheme.typography.title4,
)

BadgeList(contentEmphasis = ContentEmphasis.Minor) {
BadgeItemNeutral(icon = Icons.AirConditioning) {
Text(text = "This is simple BadgeList item")
}
BadgeItemInfo(icon = Icons.Airplane) {
Text(text = "This is simple BadgeList item")
}
BadgeItemSuccess(icon = Icons.Check) {
Text(text = "This is simple BadgeList item")
}
BadgeItemWarning(icon = Icons.Terminal) {
Text(text = "This is simple BadgeList item")
}
BadgeItemCritical(icon = Icons.Alert) {
Text(text = "This is simple BadgeList item")
}
}

Text(
text = "Badge List Small Minor",
style = OrbitTheme.typography.title4,
)

BadgeListSmall(contentEmphasis = ContentEmphasis.Minor) {
hrach marked this conversation as resolved.
Show resolved Hide resolved
BadgeItemNeutral(icon = Icons.AirConditioning) {
Text(text = "This is simple BadgeList item")
}
BadgeItemInfo(icon = Icons.Airplane) {
Text(text = "This is simple BadgeList item")
}
BadgeItemSuccess(icon = Icons.Check) {
Text(text = "This is simple BadgeList item")
}
BadgeItemWarning(icon = Icons.Terminal) {
Text(text = "This is simple BadgeList item")
}
BadgeItemCritical(icon = Icons.Alert) {
Text(text = "This is simple BadgeList item")
}
}

Text(
text = "Badge List Multi-lined",
style = OrbitTheme.typography.title4,
)

BadgeListSmall {
BadgeItemNeutral(icon = Icons.AirConditioning) {
Text(text = "This is simple BadgeList item, but text is really long. \nMore than one line is needed.")
}
BadgeItemInfo(icon = Icons.Airplane) {
Text(text = "This is simple BadgeList item, but text is really long. \nMore than one line is needed.")
}
BadgeItemSuccess(icon = Icons.Check) {
Text(text = "This is simple BadgeList item, but text is really long. \nMore than one line is needed.")
}
BadgeItemWarning(icon = Icons.Terminal) {
Text(text = "This is simple BadgeList item, but text is really long. \nMore than one line is needed.")
}
BadgeItemCritical(icon = Icons.Alert) {
Text(text = "This is simple BadgeList item, but text is really long. \nMore than one line is needed.")
}
}
}
}

@Preview
@Composable
private fun BadgeScreenPreview() {
Surface {
Column(Modifier.verticalScroll(rememberScrollState())) {
BadgeListScreenInner()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ internal fun MainScreen(
val controls = listOf(
MenuItem("Alert", Icons.Alert) { Destinations.Alert },
MenuItem("Badge", Icons.Deals) { Destinations.Badge },
MenuItem("BadgeList", Icons.List) { Destinations.BadgeList },
MenuItem("Button", MIcons.SmartButton) { Destinations.Button },
MenuItem("Checkbox", MIcons.CheckBox) { Destinations.Checkbox },
MenuItem("Choice Tile", MIcons.Ballot) { Destinations.ChoiceTile },
Expand Down
2 changes: 1 addition & 1 deletion component-status.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- component: Badge
android: Released
- component: BadgeList
android: Planned
android: Released
- component: BadgePrimitive
android: Planned
- component: Button
Expand Down
163 changes: 163 additions & 0 deletions ui/src/main/java/kiwi/orbit/compose/ui/controls/BadgeList.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package kiwi.orbit.compose.ui.controls

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.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kiwi.orbit.compose.icons.Icons
import kiwi.orbit.compose.ui.OrbitTheme
import kiwi.orbit.compose.ui.controls.internal.OrbitPreviews
import kiwi.orbit.compose.ui.controls.internal.Preview
import kiwi.orbit.compose.ui.foundation.ContentEmphasis
import kiwi.orbit.compose.ui.foundation.LocalTextStyle
import kiwi.orbit.compose.ui.foundation.ProvideContentEmphasis
import kiwi.orbit.compose.ui.foundation.ProvideMergedTextStyle
import kiwi.orbit.compose.ui.foundation.contentColorFor
import kiwi.orbit.compose.ui.layout.size

@Composable
public fun BadgeList(
modifier: Modifier = Modifier,
contentEmphasis: ContentEmphasis = ContentEmphasis.Normal,
verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(8.dp),
content: @Composable ColumnScope.() -> Unit,
) {
ProvideMergedTextStyle(OrbitTheme.typography.bodyNormal) {
ProvideContentEmphasis(contentEmphasis) {
Column(
modifier = modifier,
verticalArrangement = verticalArrangement,
content = content,
)
}
}
}

@Composable
public fun BadgeListSmall(
modifier: Modifier = Modifier,
contentEmphasis: ContentEmphasis = ContentEmphasis.Normal,
verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(8.dp),
content: @Composable ColumnScope.() -> Unit,
) {
ProvideMergedTextStyle(OrbitTheme.typography.bodySmall) {
ProvideContentEmphasis(contentEmphasis) {
Column(
modifier = modifier,
verticalArrangement = verticalArrangement,
content = content,
)
}
}
}

@Composable
public fun BadgeItemNeutral(
icon: Painter,
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
BadgeItem(icon, OrbitTheme.colors.surface.subtle, modifier, content)
}

@Composable
public fun BadgeItemInfo(
icon: Painter,
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
BadgeItem(icon, OrbitTheme.colors.info.subtle, modifier, content)
}

@Composable
public fun BadgeItemSuccess(
icon: Painter,
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
BadgeItem(icon, OrbitTheme.colors.success.subtle, modifier, content)
}

@Composable
public fun BadgeItemWarning(
icon: Painter,
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
BadgeItem(icon, OrbitTheme.colors.warning.subtle, modifier, content)
}

@Composable
public fun BadgeItemCritical(
icon: Painter,
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
BadgeItem(icon, OrbitTheme.colors.critical.subtle, modifier, content)
}

@Composable
private fun BadgeItem(
icon: Painter,
iconBackgroundColor: Color,
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
val iconTint = contentColorFor(iconBackgroundColor)
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Icon(
painter = icon,
contentDescription = null,
tint = iconTint,
modifier = Modifier
.background(iconBackgroundColor, shape = CircleShape)
.padding(4.dp)
.size(16.sp),
)
val padding = (24f - LocalTextStyle.current.lineHeight.value).div(2).dp
Box(
modifier = Modifier.padding(padding),
content = { content() },
)
}
}

@Composable
@OrbitPreviews
internal fun BadgeListPreview() {
Preview {
BadgeList {
BadgeItemInfo(Icons.Check) {
Text("This is a simple BadgeListItem.")
}
BadgeItemSuccess(Icons.Check) {
Text("This is a simple BadgeListItem.")
}
BadgeItemWarning(Icons.Check) {
Text("This is a simple BadgeListItem. \nBut two rows are needed.")
}
}

BadgeListSmall(contentEmphasis = ContentEmphasis.Minor) {
BadgeItemNeutral(Icons.Check) {
Text("This is a simple BadgeListItem.")
}
BadgeItemCritical(Icons.Check) {
Text("This is a simple BadgeListItem.")
}
}
}
}
Loading