Transition
Transition is a lightweight animation helper for one common visual property on one child.
Use it when a state change should ease visually instead of snapping immediately. Typical cases are fading content in, sliding a panel slightly, scaling a pressed card, or rotating a small affordance. It is deliberately smaller than a full animation system. You give it a stable id, a target value, a property, and timing information. The runtime then animates from the current visible value to the new one.
This fits Fission's architecture well because the animation target still comes from explicit state. Your reducer decides that show_banner is now true. component conversion then describes the banner with a new opacity or translation value. Transition requests the runtime animation, but it does not invent hidden product state of its own.
Example
use fission::prelude::*;
let banner = Transition {
id: WidgetId::explicit("save_banner"),
property: AnimationPropertyId::Opacity,
value: if view.state().show_saved_banner { 1.0 } else { 0.0 },
duration: 250,
delay: 0,
child: saved_banner.into(),
}
.into();
Field table
| | | |
|---|
| | Stable animation target identity. | Required. Reuse the same id across reconversions so the runtime can animate from the current visual state. |
| | Target value for the chosen property. | Defaults to 0.0. Interpret it according to property. |
| | Which visual property to animate. | |
| | Animation duration in milliseconds. | |
| | Delay before the animation starts, in milliseconds. | |
| | Content that should visually transition. | Required. The widget wraps it in a repaint boundary for the built-in properties. |
When to use it and when not to
Transition is the right tool when you want one straightforward, state-driven animation on a subtree. It is not the right tool for choreographed multi-element sequences, physics-driven motion, or route-to-route shared element behavior. Those cases usually want a more intentional animation structure such as Hero, nested transitions, or a custom runtime animation strategy.
Specific advice
Keep the id stable and meaningful. If you generate a new id every reconvert, the runtime has no previous visual state to animate from.
Also know the current limits of this helper. The built-in widget applies compositor-friendly wrappers for Opacity, TranslateX, TranslateY, Scale, and Rotation. If you pass AnimationPropertyId::Custom(_), the current implementation leaves the child visually unchanged, so use a lower-level path for truly custom animated properties.
Production checklist
For Transition, review the fields that change behavior before treating the widget as finished: id, value, property, duration, delay, child. The goal is to make the product rule visible in state and actions, not hidden inside ad-hoc construction code.
If this widget appears inside an interactive flow, keep the surrounding action binding in the parent component and test that the flow still has one clear reducer path.
When child widgets are generated from data, give reordered or filtered rows an explicit WidgetId so retained local state and scroll behavior do not drift between items.
Set id only when identity must be stable across filtering, reordering, diagnostics, or tests; otherwise let Fission derive identity from structure.
Check the semantics tree for the user-facing label or role that makes this widget understandable without relying only on pixels.
Add at least one component or harness test that confirms the visible text, semantic role, action dispatch, and layout constraint that matter for this widget in context.
If a screen starts repeating the same Transition setup, extract a named component around this widget. That keeps the reference API small while making product code easier to read and safer for generated code to copy.
Hero, Composite, and Rendering pipeline.