conceptadev / conceptadev/mix

keyframeAnimation styleBuilder loses parent style properties set before .box()

Open
#910 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
800
Forks
49
Avg merge
3h 39m
Merged PRs (30d)
22

Description

## Description

When using `keyframeAnimation` inside a `.box()` call, the animation's `styleBuilder` does not receive the properties declared earlier in the fluent chain (e.g., `color`, `padding`, `borderRadius`, `size`). The `styleBuilder` callback receives a bare `BoxStyler()` as its `style` parameter instead of one that carries the previously set properties.

The expectation is that the animation builds **on top of** the parent style — the animated properties should override specific values while the rest of the parent style is preserved.

## Steps to Reproduce

```dart
final style = IconBoxStyler()
.color(Color.purple). // expects this to carry into animation
.padding(.all(16)) // expects this to carry into animation
.borderRadius(.circular(16)) // expects this to carry into animation
.size(80, 80) // expects this to carry into animation
.box(
BoxStyler().keyframeAnimation(
timeline: [
.new('scale', [
.spring(3.0, 2000.ms),
.linear(1.0, 1000.ms),
], initial: 1.0),
],
styleBuilder: (values, style) => style.scale(values.get('scale'))),
),
)
.icon(.color(Colors.white).size(30));
```

## Expected Behavior

The `styleBuilder`'s `style` parameter should include the properties from the parent chain (`color`, `padding`, `borderRadius`, `size`). The animation should override only `scale` while preserving the rest of the parent style (padding, borderRadius, size).

## Actual Behavior

The `styleBuilder` receives a bare `BoxStyler()` with no parent properties. The animated frames lose `padding`, `borderRadius`, `size`, and any other properties set before `.box()`.

## Root Cause

In `keyframeAnimation()` (`animation_style_mixin.dart:12-25`), `initialStyle` is captured from `this`:

```dart
T keyframeAnimation({...}) {
return animate(
KeyframeAnimationConfig(
...
initialStyle: this, // captures current BoxStyler
),
);
}
```

Since the call is `BoxStyler().keyframeAnimation(...)`, `this` is an empty `BoxStyler()`. The parent properties (set via `IconBoxStyler.color()`, `.padding()`, etc.) live in a **separate** `BoxStyler` that gets merged into the `$box` prop via `Prop.mergeProp()`. But the animation's `initialStyle` never sees those accumulated parent properties.

When `_KeyframeAnimatable.transform()` runs (`style_animation_driver.dart:443-453`), it calls:
```dart
_config.styleBuilder(KeyframeAnimationResult(result), _config.initialStyle).resolve(_context)
```

The `initialStyle` is the bare `BoxStyler()`, so all parent properties are lost in the animated frames.

### Relevant code paths

- `AnimationStyleMixin.keyframeAnimation()` — `packages/mix/lib/src/style/mixins/animation_style_mixin.dart:12-25`
- `_KeyframeAnimatable.transform()` — `packages/mix/lib/src/animation/style_animation_driver.dart:443-453`
- `Prop.mergeProp()` — `packages/mix/lib/src/core/prop.dart`

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.