Skip to content

Commit b36a2fa

Browse files
committed
library: fix tooltip twitch when dismissed during enter animation
1 parent 8bbd898 commit b36a2fa

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

  • miuix-ui/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic

miuix-ui/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Tooltip.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
package top.yukonga.miuix.kmp.basic
55

66
import androidx.compose.animation.AnimatedVisibility
7+
import androidx.compose.animation.core.FiniteAnimationSpec
78
import androidx.compose.animation.core.MutableTransitionState
9+
import androidx.compose.animation.core.Spring
10+
import androidx.compose.animation.core.spring
811
import androidx.compose.animation.fadeIn
912
import androidx.compose.animation.fadeOut
1013
import androidx.compose.animation.scaleIn
@@ -169,7 +172,11 @@ private class TooltipStateImpl(
169172
MutableTransitionState(initialIsVisible)
170173

171174
override val isVisible: Boolean
172-
get() = transition.currentState || transition.targetState
175+
// Keep the popup composed while shown or still animating. Gating on currentState would
176+
// hard-cut the exit when a dismiss interrupts an unfinished enter, since currentState only
177+
// flips to true once the enter has settled; !isIdle keeps it through the reversal so the
178+
// exit can animate out.
179+
get() = transition.targetState || !transition.isIdle
173180

174181
/** continuation used to clean up */
175182
private var job: (CancellableContinuation<Unit>)? = null
@@ -237,6 +244,14 @@ fun rememberTooltipState(
237244
TooltipStateImpl(initialIsVisible, isPersistent, mutatorMutex)
238245
}
239246

247+
/**
248+
* Spring driving the tooltip's exit scale. A spring (not a tween) honors the inbound velocity left
249+
* by the enter spring when a dismiss interrupts an unsettled enter, so the reversal stays smooth; a
250+
* tween would discard that velocity and produce a stall-and-reverse hitch.
251+
*/
252+
private val TooltipExitScaleSpec: FiniteAnimationSpec<Float> =
253+
spring(dampingRatio = Spring.DampingRatioNoBouncy, stiffness = Spring.StiffnessMedium, visibilityThreshold = 0.0001f)
254+
240255
/**
241256
* A tooltip box that anchors a [tooltip] (a [PlainTooltip] or [RichTooltip]) to its [content].
242257
*
@@ -276,7 +291,7 @@ fun TooltipBox(
276291
enter = fadeIn(ListPopupDefaults.AlphaEnterAnimationSpec) +
277292
scaleIn(initialScale = 0.9f, animationSpec = ListPopupDefaults.FractionAnimationSpec),
278293
exit = fadeOut(ListPopupDefaults.AlphaExitAnimationSpec) +
279-
scaleOut(targetScale = 0.9f, animationSpec = ListPopupDefaults.AlphaExitAnimationSpec),
294+
scaleOut(targetScale = 0.9f, animationSpec = TooltipExitScaleSpec),
280295
) {
281296
scope.tooltip()
282297
}

0 commit comments

Comments
 (0)