compose-animations
Use when writing or reviewing Jetpack Compose motion: visibility enter/exit, animating one property toward a target, color or size transitions, multiple properties from one state, switching composable content, or choosing between AnimatedVisibility, animate*AsState, rememberTransition, AnimatedContent, and Crossfade.
What this skill does
# Compose: animations
Official reference: [Quick guide to Animations in Compose](https://developer.android.com/develop/ui/compose/animation/quick-guide). See also [Choose an animation API](https://developer.android.com/develop/ui/compose/animation/choose-api), [Value-based animations](https://developer.android.com/develop/ui/compose/animation/value-based), [Animation modifiers and composables](https://developer.android.com/develop/ui/compose/animation/composables-modifiers).
## Core principle
Pick the **smallest API that matches the problem**: built-in visibility and layout transitions first, then a single animated value, then a shared transition object when several values must move together, then gesture-level or imperative APIs when the framework cannot express the motion.
## Pick the smallest animation API
| Need | API |
|---|---|
| Show or hide a subtree with enter/exit semantics; content is removed after exit completes | [`AnimatedVisibility`](https://developer.android.com/develop/ui/compose/animation/composables-modifiers#animatedvisibility) |
| Animate one property toward a target derived from state | [`animateFloatAsState`](https://developer.android.com/develop/ui/compose/animation/value-based#animate-as-state) / `animateDpAsState` / `animateColorAsState` / `animateOffsetAsState` / … |
| Several animated values keyed off one boolean, enum, or sealed state | `rememberTransition` + transition child animations (`animateFloat`, `animateDp`, `animateColor`, `animateValue`, …) |
| Smooth size when child layout height/width changes (e.g. text wraps) | `Modifier.animateContentSize()` |
| Swap between different composable trees for the same slot | `AnimatedContent` or `Crossfade` |
| User-driven motion (drag, fling, interruptible springs) | [`Animatable`](https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Animatable) and related coroutine APIs (see Advanced pointers) |
## Appear and disappear
**Prefer `AnimatedVisibility`** when the UI should leave or join the tree with enter/exit transitions.
```kotlin
AnimatedVisibility(visible = expanded) {
Text("Details…")
}
```
**`animateFloatAsState` on alpha** only fades; the composable **stays in composition** and continues to participate in layout unless you gate it yourself. Use that tradeoff when you intentionally keep children mounted (state, focus) but visually hidden. For true remove-from-tree behavior, use `AnimatedVisibility` (or conditional composition with `AnimatedVisibility` / `AnimatedContent` patterns from the [quick guide](https://developer.android.com/develop/ui/compose/animation/quick-guide)).
## Background color
Use `animateColorAsState` for smooth color targets.
For animated fills behind children, the [quick guide](https://developer.android.com/develop/ui/compose/animation/quick-guide) recommends drawing with **`Modifier.drawBehind`** rather than `Modifier.background()` so the animated color is applied in the draw phase appropriately for performance.
```kotlin
val background = animateColorAsState(
targetValue = if (selected) selectedColor else idleColor,
label = "background",
)
Box(
Modifier.drawBehind { drawRect(background.value) },
) { /* content */ }
```
## Size changes
`Modifier.animateContentSize()` animates layout size changes—common for expanding/collapsing text or dynamic chips—without hand-rolling width/height animations.
## Value-based animations (`animate*AsState`)
Compose provides `animate*AsState` for `Float`, `Dp`, `Color`, `Size`, `Offset`, `Rect`, `Int`, `IntOffset`, `IntSize`, and more. You supply the **target**; the API owns the animation state.
- Pass an [`AnimationSpec`](https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec) via `animationSpec` (e.g. `spring`, `tween`) when defaults are wrong for the UI.
- Set a distinct **`label`** for debugging and tooling when multiple animations exist in one composable.
- For completion or sequencing details, see [Value-based animations](https://developer.android.com/develop/ui/compose/animation/value-based).
```kotlin
val width by animateDpAsState(
targetValue = if (expanded) 200.dp else 56.dp,
animationSpec = spring(dampingRatio = 0.7f, stiffness = Spring.StiffnessMedium),
label = "fabWidth",
)
```
## Multiple properties: `rememberTransition`
When one piece of state (e.g. `enum class Phase { A, B, C }`) should drive **several** animated values in lockstep, use `rememberTransition` and define child animations on that transition:
```kotlin
val transition = rememberTransition(targetState = phase, label = "phase")
val alpha by transition.animateFloat(label = "alpha") { target ->
if (target == Phase.Visible) 1f else 0f
}
val offset by transition.animateDp(label = "offset") { target ->
if (target == Phase.Visible) 0.dp else 24.dp
}
```
Avoid multiple independent `animate*AsState` calls that should stay visually synchronized but can drift if specs or targets diverge. Older code may use `updateTransition`; prefer `rememberTransition` for new code.
## Choosing between content-level APIs
Use the official [Choose an animation API](https://developer.android.com/develop/ui/compose/animation/choose-api) tree when unsure. Compressed rules:
| Situation | Prefer |
|---|---|
| Same composable, different **target values** for layout properties | `animate*AsState` or `rememberTransition` |
| Different **composable content** for the same region (tabs, steps) | `AnimatedContent` (custom `transitionSpec`, `contentKey`) or simpler `Crossfade` |
| Pager-like **swipe between pages** | Horizontal pager APIs from the animation docs / Material—follow the choose-api guidance |
| Transitions **owned by Navigation Compose** | Use navigation’s built-in transitions rather than bolting `AnimatedContent` on top of the same destination swap |
**Art-based motion** (illustrations, Lottie, complex vector timelines) is outside this skill; use dedicated libraries and the “additional resources” links on [Animations](https://developer.android.com/develop/ui/compose/animation/resources).
## Decision flow (high level)
```mermaid
flowchart TD
start[Animation_need]
start --> showHide{Show_or_hide_subtree}
showHide -->|yes| av[AnimatedVisibility]
showHide -->|no| oneProp{Single_property_to_target}
oneProp -->|yes| asState["animate*AsState"]
oneProp -->|no| multiProp{Many_props_one_state}
multiProp -->|yes| rt[rememberTransition]
multiProp -->|no| swapTree{Different_composable_content}
swapTree -->|yes| ac[AnimatedContent_or_Crossfade]
swapTree -->|no| advanced[Animatable_or_lower_level]
```
## AnimatedContent keys for state holders
When `AnimatedContent` receives a state-holder wrapper such as `AsyncResult<T>`, `Result<T>`, or a sealed `UiState`, decide what should actually trigger the transition. Usually the animation should run when the **content shape** changes (loading → content → error), not when the payload inside the same shape changes.
Use `contentKey` to map rich state to the animation identity:
```kotlin
AnimatedContent(
targetState = result,
contentKey = { state ->
when (state) {
AsyncResult.Loading -> "loading"
is AsyncResult.Success -> "content"
is AsyncResult.Error -> "error"
}
},
label = "profile-content",
) { state ->
when (state) {
AsyncResult.Loading -> Loading()
is AsyncResult.Success -> Profile(state.value)
is AsyncResult.Error -> ErrorMessage(state.throwable)
}
}
```
Without `contentKey`, every unequal `Success(value)` can be treated as new content. That is useful if a payload change should animate, but noisy when fresh data updates the same screen shape.
Choose keys by visual shape:
| State change | Typical `contentKey` |
|---|---|
| Loading → Success → Error | Branch key: `"loading"`, `"content"`, `"error"` |
| Success item A → Success item B should crossfade | Stable item id |
| Success data refresh Related in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.