Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-31 12:38:56 +03:00
parent ba9e686371
commit 22318a9ab7
2 changed files with 45 additions and 6 deletions

View file

@ -4,6 +4,7 @@ import android.content.res.Configuration
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.expandVertically
@ -16,9 +17,11 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.tooling.preview.Devices
@ -51,8 +54,10 @@ private enum class SlotId { Start, Content, Group, End }
* [TangemTopNavigation.DefaultContentPadding] (top 8, bottom 16, horizontal 16). Override a single
* edge via [com.tangem.core.ui.extensions.copy], e.g. `DefaultContentPadding.copy(top = 16.dp)`.
* @param blurBackground Whether the fade behind the row should blur the content below.
* @param fadeEnabled Whether the fade behind the row is shown. Alpha is animated on change. Defaults to true.
* @param startButton Leading slot. Typically a back button (see [TangemButton.Back]).
* @param endButtonsGroup Optional pill-grouped secondary actions placed just before [endButton].
* @param isEndButtonsGroupBackgroundShown Whether the pill-grouped secondary actions should have a background. Defaults to true.
* @param endButton Trailing slot. Typically, a close button (see [TangemButton.Close]).
* @param contentColumn Center slot. Place title/subtitle children here.
*/
@ -64,6 +69,8 @@ fun TangemTopNavigation(
windowInsets: WindowInsets = WindowInsets.statusBars,
contentPadding: PaddingValues = TangemTopNavigation.DefaultContentPadding,
blurBackground: Boolean = true,
fadeEnabled: Boolean = true,
isEndButtonsGroupBackgroundShown: Boolean = true,
startButton: (@Composable () -> Unit)? = null,
endButtonsGroup: (@Composable RowScope.() -> Unit)? = null,
endButton: (@Composable () -> Unit)? = null,
@ -79,10 +86,17 @@ fun TangemTopNavigation(
val slotExit = remember(slotSizeSpec, slotAlphaSpec) {
fadeOut(animationSpec = slotAlphaSpec) + shrinkHorizontally(animationSpec = slotSizeSpec)
}
val fadeAlpha by animateFloatAsState(
targetValue = if (fadeEnabled) 1f else 0f,
animationSpec = slotAlphaSpec,
label = "TangemTopNavigation.fadeAlpha",
)
Box(modifier) {
TangemFade(
modifier = Modifier.matchParentSize(),
modifier = Modifier
.graphicsLayer { alpha = fadeAlpha }
.matchParentSize(),
position = TangemFade.Position.Top,
variant = TangemFade.Variant.Soft,
blur = blurBackground,
@ -125,11 +139,24 @@ fun TangemTopNavigation(
exit = slotExit,
) {
displayedGroup?.let { group ->
TangemSurface(isMaterial = true, shape = CircleShape) {
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
content = group,
)
AnimatedContent(
targetState = isEndButtonsGroupBackgroundShown,
transitionSpec = { fadeIn() togetherWith fadeOut() },
label = "TangemTopNavigation.endButtonsGroupBackground",
) { shown ->
if (shown) {
TangemSurface(isMaterial = true, shape = CircleShape) {
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
content = group,
)
}
} else {
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
content = group,
)
}
}
}
}
@ -209,6 +236,8 @@ fun TangemTopNavigation(
windowInsets: WindowInsets = WindowInsets.statusBars,
contentPadding: PaddingValues = TangemTopNavigation.DefaultContentPadding,
blurBackground: Boolean = true,
fadeEnabled: Boolean = true,
isEndButtonsGroupBackgroundShown: Boolean = true,
onBack: (() -> Unit)? = null,
endButtonsGroup: (@Composable RowScope.() -> Unit)? = null,
onClose: (() -> Unit)? = null,
@ -219,6 +248,8 @@ fun TangemTopNavigation(
windowInsets = windowInsets,
contentPadding = contentPadding,
blurBackground = blurBackground,
fadeEnabled = fadeEnabled,
isEndButtonsGroupBackgroundShown = isEndButtonsGroupBackgroundShown,
startButton = onBack?.let { { TangemButton.Back(onClick = it) } },
endButtonsGroup = endButtonsGroup,
endButton = onClose?.let { { TangemButton.Close(onClick = it) } },
@ -236,6 +267,8 @@ fun TangemTopNavigation(
windowInsets: WindowInsets = WindowInsets.statusBars,
contentPadding: PaddingValues = TangemTopNavigation.DefaultContentPadding,
blurBackground: Boolean = true,
fadeEnabled: Boolean = true,
isEndButtonsGroupBackgroundShown: Boolean = true,
endButtonsGroup: (@Composable RowScope.() -> Unit)? = null,
onClose: (() -> Unit)? = null,
startButton: @Composable () -> Unit,
@ -246,6 +279,8 @@ fun TangemTopNavigation(
windowInsets = windowInsets,
contentPadding = contentPadding,
blurBackground = blurBackground,
fadeEnabled = fadeEnabled,
isEndButtonsGroupBackgroundShown = isEndButtonsGroupBackgroundShown,
startButton = startButton,
endButtonsGroup = endButtonsGroup,
endButton = onClose?.let { { TangemButton.Close(onClick = it) } },
@ -263,6 +298,7 @@ fun TangemTopNavigation(
windowInsets: WindowInsets = WindowInsets.statusBars,
contentPadding: PaddingValues = TangemTopNavigation.DefaultContentPadding,
blurBackground: Boolean = true,
fadeEnabled: Boolean = true,
onBack: (() -> Unit)? = null,
endButton: @Composable () -> Unit,
) {
@ -272,6 +308,7 @@ fun TangemTopNavigation(
windowInsets = windowInsets,
contentPadding = contentPadding,
blurBackground = blurBackground,
fadeEnabled = fadeEnabled,
startButton = onBack?.let { { TangemButton.Back(onClick = it) } },
endButton = endButton,
contentColumn = { TitleSubtitle(title = title, subtitle = subtitle) },