feature: add ValueChangeTimedVisibility composable for dynamic content display

This commit is contained in:
2026-01-27 19:16:01 +01:00
parent 380ae9d056
commit b97867d9f1

View File

@@ -1,10 +1,14 @@
package hu.bbara.purefin.common.ui.components package hu.bbara.purefin.common.ui.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.runtime.setValue
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
/** /**
@@ -18,12 +22,12 @@ import kotlinx.coroutines.delay
* @param content The composable content to display, receiving the current non-null value. * @param content The composable content to display, receiving the current non-null value.
*/ */
@Composable @Composable
fun TimedVisibility( fun <T> EmptyValueTimedVisibility(
value: Long?, value: T?,
hideAfterMillis: Long = 1_000, hideAfterMillis: Long = 1_000,
content: @Composable (Long) -> Unit, content: @Composable (T) -> Unit,
) { ) {
val shownValue = remember { mutableStateOf<Long?>(null) } val shownValue = remember { mutableStateOf<T?>(null) }
LaunchedEffect(value) { LaunchedEffect(value) {
if (value == null) { if (value == null) {
@@ -36,4 +40,44 @@ fun TimedVisibility(
shownValue.value?.let { shownValue.value?.let {
content(it) content(it)
} }
} }
/**
* Displays [content] whenever [value] changes and hides it after [hideAfterMillis]
* milliseconds without further updates.
*
* @param value The value whose changes should trigger visibility.
* @param hideAfterMillis Duration in milliseconds after which the content will be hidden
* if [value] has not changed again.
* @param content The composable to render while visible.
*/
@Composable
fun <T> ValueChangeTimedVisibility(
value: T,
hideAfterMillis: Long = 1_000,
content: @Composable (T) -> Unit,
) {
var displayedValue by remember { mutableStateOf(value) }
var isVisible by remember { mutableStateOf(false) }
var hasInitialValue by remember { mutableStateOf(false) }
LaunchedEffect(value) {
displayedValue = value
if (!hasInitialValue) {
hasInitialValue = true
return@LaunchedEffect
}
isVisible = true
delay(hideAfterMillis)
isVisible = false
}
AnimatedVisibility(
visible = isVisible,
enter = EnterTransition.None,
exit = ExitTransition.None
) {
content(displayedValue)
}
}