From 4b74a14cbff996d3d668b935c1cf2fe6cbb98b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Orzech?= Date: Thu, 19 Mar 2026 14:06:59 +0100 Subject: [PATCH] feat: add AnimatedDialog reusable component --- .../microblog/ui/components/AnimatedDialog.kt | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 app/src/main/java/com/swoosh/microblog/ui/components/AnimatedDialog.kt diff --git a/app/src/main/java/com/swoosh/microblog/ui/components/AnimatedDialog.kt b/app/src/main/java/com/swoosh/microblog/ui/components/AnimatedDialog.kt new file mode 100644 index 0000000..e56b4f4 --- /dev/null +++ b/app/src/main/java/com/swoosh/microblog/ui/components/AnimatedDialog.kt @@ -0,0 +1,72 @@ +package com.swoosh.microblog.ui.components + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.MutableTransitionState +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.scaleIn +import androidx.compose.animation.scaleOut +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.swoosh.microblog.ui.animation.SwooshMotion + +@Composable +fun AnimatedDialog( + onDismissRequest: () -> Unit, + content: @Composable () -> Unit +) { + val transitionState = remember { + MutableTransitionState(false).apply { targetState = true } + } + + Dialog( + onDismissRequest = onDismissRequest, + properties = DialogProperties(usePlatformDefaultWidth = false) + ) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + // Backdrop + AnimatedVisibility( + visibleState = transitionState, + enter = fadeIn(animationSpec = SwooshMotion.quick()), + exit = fadeOut(animationSpec = SwooshMotion.quick()) + ) { + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.Black.copy(alpha = 0.4f)) + .clickable( + indication = null, + interactionSource = remember { MutableInteractionSource() } + ) { onDismissRequest() } + ) + } + // Content + AnimatedVisibility( + visibleState = transitionState, + enter = scaleIn( + initialScale = 0.8f, + animationSpec = SwooshMotion.snappy() + ) + fadeIn(animationSpec = SwooshMotion.quick()), + exit = scaleOut( + targetScale = 0.8f, + animationSpec = SwooshMotion.quick() + ) + fadeOut(animationSpec = SwooshMotion.quick()) + ) { + content() + } + } + } +}