From a0e68250ade579281e8cd45e6ce105ce183dda4e Mon Sep 17 00:00:00 2001 From: dario-piotrowicz Date: Tue, 7 Dec 2021 22:48:33 +0000 Subject: [PATCH] docs(animations): improve animation transition api docs (#44396) improve the transition api docs by removing unnecessary examplanations and examples also provide helpful information regarding entering and leaving elements (as part of #44253) PR Close #44396 --- packages/animations/src/animation_metadata.ts | 244 ++++++++---------- 1 file changed, 111 insertions(+), 133 deletions(-) diff --git a/packages/animations/src/animation_metadata.ts b/packages/animations/src/animation_metadata.ts index 45141068fc1..90b9cac4436 100644 --- a/packages/animations/src/animation_metadata.ts +++ b/packages/animations/src/animation_metadata.ts @@ -871,170 +871,148 @@ export function keyframes(steps: AnimationStyleMetadata[]): AnimationKeyframesSe } /** - * Declares an animation transition as a sequence of animation steps to run when a given - * condition is satisfied. The condition is a Boolean expression or function that compares - * the previous and current animation states, and returns true if this transition should occur. - * When the state criteria of a defined transition are met, the associated animation is - * triggered. + * Declares an animation transition which is played when a certain specified condition is met. * - * @param stateChangeExpr A Boolean expression or function that compares the previous and current - * animation states, and returns true if this transition should occur. Note that "true" and "false" - * match 1 and 0, respectively. An expression is evaluated each time a state change occurs in the - * animation trigger element. - * The animation steps run when the expression evaluates to true. + * @param stateChangeExpr A string with a specific format or a function that specifies when the + * animation transition should occur (see [State Change Expression](#state-change-expression)). * - * - A state-change string takes the form "state1 => state2", where each side is a defined animation - * state, or an asterisk (*) to refer to a dynamic start or end state. - * - The expression string can contain multiple comma-separated statements; - * for example "state1 => state2, state3 => state4". - * - Special values `:enter` and `:leave` initiate a transition on the entry and exit states, - * equivalent to "void => *" and "* => void". - * - Special values `:increment` and `:decrement` initiate a transition when a numeric value has - * increased or decreased in value. - * - A function is executed each time a state change occurs in the animation trigger element. - * The animation steps run when the function returns true. + * @param steps One or more animation objects that represent the animation's instructions. + * + * @param options An options object that can be used to specify a delay for the animation or provide + * custom parameters for it. * - * @param steps One or more animation objects, as returned by the `animate()` or - * `sequence()` function, that form a transformation from one state to another. - * A sequence is used by default when you pass an array. - * @param options An options object that can contain a delay value for the start of the animation, - * and additional developer-defined parameters. Provided values for additional parameters are used - * as defaults, and override values can be passed to the caller on invocation. * @returns An object that encapsulates the transition data. * * @usageNotes - * The template associated with a component binds an animation trigger to an element. * - * ```HTML - * - *
...
- * ``` + * ### State Change Expression * - * All transitions are defined within an animation trigger, - * along with named states that the transitions change to and from. + * The State Change Expression instructs Angular when to run the transition's animations, it can + *either be + * - a string with a specific syntax + * - or a function that compares the previous and current state (value of the expression bound to + * the element's trigger) and returns `true` if the transition should occur or `false` otherwise * - * ```typescript - * trigger("myAnimationTrigger", [ - * // define states - * state("on", style({ background: "green" })), - * state("off", style({ background: "grey" })), - * ...] - * ``` + * The string format can be: + * - `fromState => toState`, which indicates that the transition's animations should occur then the + * expression bound to the trigger's element goes from `fromState` to `toState` * - * Note that when you call the `sequence()` function within a `{@link animations/group group()}` - * or a `transition()` call, execution does not continue to the next instruction - * until each of the inner animation steps have completed. + * _Example:_ + * ```typescript + * transition('open => closed', animate('.5s ease-out', style({ height: 0 }) )) + * ``` * - * ### Syntax examples + * - `fromState <=> toState`, which indicates that the transition's animations should occur then + * the expression bound to the trigger's element goes from `fromState` to `toState` or vice versa * - * The following examples define transitions between the two defined states (and default states), - * using various options: + * _Example:_ + * ```typescript + * transition('enabled <=> disabled', animate('1s cubic-bezier(0.8,0.3,0,1)')) + * ``` * - * ```typescript - * // Transition occurs when the state value - * // bound to "myAnimationTrigger" changes from "on" to "off" - * transition("on => off", animate(500)) - * // Run the same animation for both directions - * transition("on <=> off", animate(500)) - * // Define multiple state-change pairs separated by commas - * transition("on => off, off => void", animate(500)) - * ``` + * - `:enter`/`:leave`, which indicates that the transition's animations should occur when the + * element enters or exists the DOM * - * ### Special values for state-change expressions + * _Example:_ + * ```typescript + * transition(':enter', [ + * style({ opacity: 0 }), + * animate('500ms', style({ opacity: 1 })) + * ]) + * ``` * - * - Catch-all state change for when an element is inserted into the page and the - * destination state is unknown: + * - `:increment`/`:decrement`, which indicates that the transition's animations should occur when + * the numerical expression bound to the trigger's element has increased in value or decreased * - * ```typescript - * transition("void => *", [ - * style({ opacity: 0 }), - * animate(500) - * ]) - * ``` + * _Example:_ + * ```typescript + * transition(':increment', query('@counter', animateChild())) + * ``` * - * - Capture a state change between any states: + * - a sequence of any of the above divided by commas, which indicates that transition's animations + * should occur whenever one of the state change expressions matches * - * `transition("* => *", animate("1s 0s"))` + * _Example:_ + * ```typescript + * transition(':increment, * => enabled, :enter', animate('1s ease', keyframes([ + * style({ transform: 'scale(1)', offset: 0}), + * style({ transform: 'scale(1.1)', offset: 0.7}), + * style({ transform: 'scale(1)', offset: 1}) + * ]))), + * ``` * - * - Entry and exit transitions: + * Also note that in such context: + * - `void` can be used to indicate the absence of the element + * - asterisks can be used as wildcards that match any state + * - (as a consequence of the above, `void => *` is equivalent to `:enter` and `* => void` is + * equivalent to `:leave`) + * - `true` and `false` also match expression values of `1` and `0` respectively (but do not match + * _truthy_ and _falsy_ values) * - * ```typescript - * transition(":enter", [ - * style({ opacity: 0 }), - * animate(500, style({ opacity: 1 })) - * ]), - * transition(":leave", [ - * animate(500, style({ opacity: 0 })) - * ]) - * ``` + *
* - * - Use `:increment` and `:decrement` to initiate transitions: + * Be careful about entering end leaving elements as their transitions present a common + * pitfall for developers. * - * ```typescript - * transition(":increment", group([ - * query(':enter', [ - * style({ left: '100%' }), - * animate('0.5s ease-out', style('*')) - * ]), - * query(':leave', [ - * animate('0.5s ease-out', style({ left: '-100%' })) - * ]) - * ])) + * Note that when an element with a trigger enters the DOM its `:enter` transition always + * gets executed, but its `:leave` transition will not be executed if the element is removed + * alongside its parent (as it will be removed "without warning" before its transition has + * a chance to be executed, the only way that such transition can occur is if the element + * is exiting the DOM on its own). * - * transition(":decrement", group([ - * query(':enter', [ - * style({ left: '100%' }), - * animate('0.5s ease-out', style('*')) - * ]), - * query(':leave', [ - * animate('0.5s ease-out', style({ left: '-100%' })) - * ]) - * ])) - * ``` * - * ### State-change functions + *
* - * Here is an example of a `fromState` specified as a state-change function that invokes an - * animation when true: - * - * ```typescript - * transition((fromState, toState) => - * { - * return fromState == "off" && toState == "on"; - * }, - * animate("1s 0s")) - * ``` - * - * ### Animating to the final state + * ### Animating to a Final State * * If the final step in a transition is a call to `animate()` that uses a timing value - * with no style data, that step is automatically considered the final animation arc, - * for the element to reach the final state. Angular automatically adds or removes + * with no `style` data, that step is automatically considered the final animation arc, + * for the element to reach the final state, in such case Angular automatically adds or removes * CSS styles to ensure that the element is in the correct final state. * - * The following example defines a transition that starts by hiding the element, - * then makes sure that it animates properly to whatever state is currently active for trigger: * - * ```typescript - * transition("void => *", [ - * style({ opacity: 0 }), - * animate(500) - * ]) - * ``` - * ### Boolean value matching - * If a trigger binding value is a Boolean, it can be matched using a transition expression - * that compares true and false or 1 and 0. For example: + * ### Usage Examples * - * ``` - * // in the template - *
...
- * // in the component metadata - * trigger('openClose', [ - * state('true', style({ height: '*' })), - * state('false', style({ height: '0px' })), - * transition('false <=> true', animate(500)) - * ]) - * ``` + * - Transition animations applied based on + * the trigger's expression value + * + * ```HTML + *
+ * ... + *
+ * ``` + * + * ```typescript + * trigger("myAnimationTrigger", [ + * ..., // states + * transition("on => off, open => closed", animate(500)), + * transition("* <=> error", query('.indicator', animateChild())) + * ]) + * ``` + * + * - Transition animations applied based on custom logic dependent + * on the trigger's expression value and provided parameters + * + * ```HTML + *
+ * ... + *
+ * ``` + * + * ```typescript + * trigger("myAnimationTrigger", [ + * ..., // states + * transition( + * (fromState, toState, _element, params) => + * ['firststep', 'laststep'].includes(fromState.toLowerCase()) + * && toState === params?.['target'], + * animate('1s') + * ) + * ]) + * ``` * * @publicApi **/