compose: add shared composable foundations
EmptyState, SectionHeader, Shimmer placeholders; TopAppBar and ScrollHint refinements to support the migrated screens.
This commit is contained in:
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Aurora OSS
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.aurora.store.compose.composable
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material3.FilledTonalButton
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.dimensionResource
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewWrapper
|
||||||
|
import com.aurora.store.R
|
||||||
|
import com.aurora.store.compose.preview.ThemePreviewProvider
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun EmptyState(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
@DrawableRes icon: Int,
|
||||||
|
@StringRes message: Int,
|
||||||
|
@StringRes actionLabel: Int? = null,
|
||||||
|
onAction: () -> Unit = {}
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier.fillMaxSize(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(
|
||||||
|
dimensionResource(R.dimen.margin_small),
|
||||||
|
Alignment.CenterVertically
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(icon),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(dimensionResource(R.dimen.icon_size_medium)),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(message),
|
||||||
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = MaterialTheme.colorScheme.onPrimary
|
||||||
|
)
|
||||||
|
|
||||||
|
if (actionLabel != null) {
|
||||||
|
FilledTonalButton(onClick = onAction) {
|
||||||
|
Text(stringResource(actionLabel))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun EmptyStatePreview() {
|
||||||
|
EmptyState(
|
||||||
|
icon = R.drawable.ic_updates,
|
||||||
|
message = R.string.details_no_updates,
|
||||||
|
actionLabel = R.string.check_updates
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -36,8 +36,8 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment.Companion.Center
|
import androidx.compose.ui.Alignment.Companion.Center
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
|
import androidx.compose.ui.res.dimensionResource
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.IntOffset
|
import androidx.compose.ui.unit.IntOffset
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.aurora.store.R
|
import com.aurora.store.R
|
||||||
@@ -48,7 +48,6 @@ import kotlinx.coroutines.launch
|
|||||||
fun ScrollHint(
|
fun ScrollHint(
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
bottomPadding: Dp = 72.dp, // keep above bottom bar
|
|
||||||
autoHideOnScroll: Boolean = true,
|
autoHideOnScroll: Boolean = true,
|
||||||
enableBounce: Boolean = true,
|
enableBounce: Boolean = true,
|
||||||
onClickScrollOffset: Float = 300f
|
onClickScrollOffset: Float = 300f
|
||||||
@@ -88,7 +87,7 @@ fun ScrollHint(
|
|||||||
visible = visible,
|
visible = visible,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(bottom = bottomPadding),
|
.padding(bottom = dimensionResource(R.dimen.scroll_hint_padding)),
|
||||||
enter = fadeIn() + slideInVertically { it / 2 },
|
enter = fadeIn() + slideInVertically { it / 2 },
|
||||||
exit = fadeOut()
|
exit = fadeOut()
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Aurora OSS
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.aurora.store.compose.composable
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.dimensionResource
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewWrapper
|
||||||
|
import com.aurora.store.R
|
||||||
|
import com.aurora.store.compose.preview.ThemePreviewProvider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Section header row with optional right-chevron for navigation (replaces HeaderView).
|
||||||
|
* When [browseUrl] is non-null and non-blank the row is clickable and shows a chevron.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun SectionHeader(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
title: String,
|
||||||
|
browseUrl: String? = null,
|
||||||
|
onClick: () -> Unit = {}
|
||||||
|
) {
|
||||||
|
val hasLink = !browseUrl.isNullOrBlank()
|
||||||
|
Row(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.then(if (hasLink) Modifier.clickable(onClick = onClick) else Modifier)
|
||||||
|
.padding(all = dimensionResource(R.dimen.padding_medium)),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
if (hasLink) {
|
||||||
|
Spacer(Modifier.width(dimensionResource(R.dimen.margin_small)))
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.ic_arrow_right),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(dimensionResource(R.dimen.icon_size_default)),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Section header row with a right-aligned action button (replaces UpdateHeaderView).
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun SectionHeaderWithAction(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
title: String,
|
||||||
|
action: String,
|
||||||
|
onAction: () -> Unit = {}
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
start = dimensionResource(R.dimen.padding_small),
|
||||||
|
top = dimensionResource(R.dimen.padding_xxsmall),
|
||||||
|
bottom = dimensionResource(R.dimen.padding_xxsmall)
|
||||||
|
),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
TextButton(onClick = onAction) {
|
||||||
|
Text(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun SectionHeaderPreview() {
|
||||||
|
SectionHeader(title = "Top Charts", browseUrl = "https://example.com")
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun SectionHeaderWithActionPreview() {
|
||||||
|
SectionHeaderWithAction(title = "3 updates available", action = "Update all")
|
||||||
|
}
|
||||||
274
app/src/main/java/com/aurora/store/compose/composable/Shimmer.kt
Normal file
274
app/src/main/java/com/aurora/store/compose/composable/Shimmer.kt
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Aurora OSS
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.aurora.store.compose.composable
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.LinearEasing
|
||||||
|
import androidx.compose.animation.core.RepeatMode
|
||||||
|
import androidx.compose.animation.core.animateFloat
|
||||||
|
import androidx.compose.animation.core.infiniteRepeatable
|
||||||
|
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
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.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredSize
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.res.dimensionResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewWrapper
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.aurora.store.R
|
||||||
|
import com.aurora.store.compose.preview.ThemePreviewProvider
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun shimmerBrush(): Brush {
|
||||||
|
val base = MaterialTheme.colorScheme.onSurface
|
||||||
|
val colors = listOf(
|
||||||
|
base.copy(alpha = 0.08f),
|
||||||
|
base.copy(alpha = 0.20f),
|
||||||
|
base.copy(alpha = 0.08f)
|
||||||
|
)
|
||||||
|
val transition = rememberInfiniteTransition(label = "shimmer")
|
||||||
|
val offset by transition.animateFloat(
|
||||||
|
initialValue = 0f,
|
||||||
|
targetValue = 1f,
|
||||||
|
animationSpec = infiniteRepeatable(
|
||||||
|
animation = tween(1000, easing = LinearEasing),
|
||||||
|
repeatMode = RepeatMode.Restart
|
||||||
|
),
|
||||||
|
label = "shimmer_offset"
|
||||||
|
)
|
||||||
|
val x = offset * 1200f
|
||||||
|
return Brush.linearGradient(
|
||||||
|
colors = colors,
|
||||||
|
start = Offset(x - 400f, 0f),
|
||||||
|
end = Offset(x, 400f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun ShimmerCategoryRow() {
|
||||||
|
val brush = shimmerBrush()
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
horizontal = dimensionResource(R.dimen.padding_medium),
|
||||||
|
vertical = dimensionResource(R.dimen.padding_small)
|
||||||
|
),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_large))
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredSize(dimensionResource(R.dimen.icon_size_category))
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.height(24.dp)
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun ShimmerAppRow() {
|
||||||
|
val brush = shimmerBrush()
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
horizontal = dimensionResource(R.dimen.padding_small),
|
||||||
|
vertical = dimensionResource(R.dimen.padding_xsmall)
|
||||||
|
),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredSize(dimensionResource(R.dimen.icon_size_medium))
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(horizontal = dimensionResource(R.dimen.margin_small))
|
||||||
|
) {
|
||||||
|
repeat(3) { i ->
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(if (i == 0) 0.75f else 0.5f)
|
||||||
|
.height(14.dp)
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
if (i < 2) Spacer(Modifier.height(dimensionResource(R.dimen.padding_xxsmall)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun ShimmerUpdateItem() {
|
||||||
|
val brush = shimmerBrush()
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
horizontal = dimensionResource(R.dimen.padding_small),
|
||||||
|
vertical = dimensionResource(R.dimen.padding_xsmall)
|
||||||
|
),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_small))
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredSize(dimensionResource(R.dimen.icon_size_medium))
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
|
repeat(3) { i ->
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(if (i == 0) 0.7f else 0.5f)
|
||||||
|
.height(14.dp)
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
if (i < 2) Spacer(Modifier.height(dimensionResource(R.dimen.padding_xxsmall)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(80.dp)
|
||||||
|
.height(36.dp)
|
||||||
|
.clip(RoundedCornerShape(50))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun ShimmerCarouselSection() {
|
||||||
|
val brush = shimmerBrush()
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(all = dimensionResource(R.dimen.padding_small)),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_small))
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth(0.42f)
|
||||||
|
.height(16.dp)
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_small))
|
||||||
|
) {
|
||||||
|
repeat(5) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(
|
||||||
|
dimensionResource(R.dimen.padding_xsmall)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(dimensionResource(R.dimen.icon_size_cluster))
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_medium)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(dimensionResource(R.dimen.icon_size_cluster) * 0.75f)
|
||||||
|
.height(11.dp)
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(dimensionResource(R.dimen.icon_size_cluster) * 0.5f)
|
||||||
|
.height(11.dp)
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_small)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun ShimmerAppListItem() {
|
||||||
|
val brush = shimmerBrush()
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(dimensionResource(R.dimen.padding_xsmall))
|
||||||
|
.size(dimensionResource(R.dimen.icon_size_cluster))
|
||||||
|
.clip(RoundedCornerShape(dimensionResource(R.dimen.radius_medium)))
|
||||||
|
.background(brush)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun ShimmerCategoryRowPreview() {
|
||||||
|
ShimmerCategoryRow()
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun ShimmerAppRowPreview() {
|
||||||
|
ShimmerAppRow()
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun ShimmerUpdateItemPreview() {
|
||||||
|
ShimmerUpdateItem()
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun ShimmerCarouselSectionPreview() {
|
||||||
|
ShimmerCarouselSection()
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreviewWrapper(ThemePreviewProvider::class)
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun ShimmerAppListItemPreview() {
|
||||||
|
ShimmerAppListItem()
|
||||||
|
}
|
||||||
@@ -5,11 +5,15 @@
|
|||||||
|
|
||||||
package com.aurora.store.compose.composable
|
package com.aurora.store.compose.composable
|
||||||
|
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.compose.LocalActivity
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
@@ -25,7 +29,7 @@ import com.aurora.store.compose.preview.ThemePreviewProvider
|
|||||||
* @param modifier The modifier to be applied to the composable
|
* @param modifier The modifier to be applied to the composable
|
||||||
* @param title Title of the screen
|
* @param title Title of the screen
|
||||||
* @param navigationIcon Icon for the navigation button
|
* @param navigationIcon Icon for the navigation button
|
||||||
* @param onNavigateUp Action when user clicks the navigation icon
|
* @param showNavigationIcon Whether to show the navigation (back) icon button
|
||||||
* @param actions Actions to display on the top app bar (for e.g. menu)
|
* @param actions Actions to display on the top app bar (for e.g. menu)
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
@@ -33,15 +37,17 @@ fun TopAppBar(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
navigationIcon: Painter = painterResource(R.drawable.ic_arrow_back),
|
navigationIcon: Painter = painterResource(R.drawable.ic_arrow_back),
|
||||||
onNavigateUp: (() -> Unit)? = null,
|
showNavigationIcon: Boolean = true,
|
||||||
|
windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
|
||||||
actions: @Composable (RowScope.() -> Unit) = {}
|
actions: @Composable (RowScope.() -> Unit) = {}
|
||||||
) {
|
) {
|
||||||
|
val activity = LocalActivity.current as? ComponentActivity
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
title = { if (title != null) Text(text = title) },
|
title = { if (title != null) Text(text = title) },
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
if (onNavigateUp != null) {
|
if (showNavigationIcon) {
|
||||||
IconButton(onClick = onNavigateUp) {
|
IconButton(onClick = { activity?.onBackPressedDispatcher?.onBackPressed() }) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = navigationIcon,
|
painter = navigationIcon,
|
||||||
contentDescription = stringResource(R.string.action_back)
|
contentDescription = stringResource(R.string.action_back)
|
||||||
@@ -49,6 +55,7 @@ fun TopAppBar(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
windowInsets = windowInsets,
|
||||||
actions = actions
|
actions = actions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -58,7 +65,6 @@ fun TopAppBar(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun TopAppBarPreview() {
|
private fun TopAppBarPreview() {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = stringResource(R.string.title_about),
|
title = stringResource(R.string.title_about)
|
||||||
onNavigateUp = {}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user