Description
When chaining multiple transform methods on BoxStyler (e.g., scale() then translate()), the last transform completely replaces the previous one instead of composing them.
Steps to Reproduce
final style = BoxStyler()
.scale(1)
.translate(0, 10);
Box(style: style, child: child);
Expected Behavior
Both transforms should be applied: the box should be scaled and translated. The resulting Matrix4 should be the composition (multiplication) of both transform matrices.
Actual Behavior
Only the last transform (translate) is applied. The scale is silently discarded.
Root Cause
Each transform method (defined in TransformStyleMixin) calls transform(matrix) which creates a new BoxStyler with that single Matrix4 and merges it. During merge, Prop.mergeProp() correctly accumulates both Matrix4 sources. However, during resolution in Prop.resolveProp(), because Matrix4 is not a Mix type, it falls into the replacement strategy (resolvedValue = values.last) instead of composing (multiplying) the matrices.
Key code path:
TransformStyleMixin.scale() / .translate() → transform(Matrix4) → creates new styler and merges
Prop.mergeProp() accumulates sources: [scaleMatrix, translateMatrix]
Prop.resolveProp() resolves with values.last → only translateMatrix is returned
Affected Methods
All transform helpers in TransformStyleMixin are affected when chained together:
scale()
translate()
rotate()
skew()
Any combination of two or more of these will result in only the last one being applied.
Possible Solution
Stop using Container's transform property for these operations. Instead, each transform method (scale, translate, rotate, skew) should use wrap() behind the scenes to apply the respective ModifierMix. This way, each chained call adds its own independent Modifierwidget in the widget tree, so they naturally compose without needing Matrix4 multiplication logic in theProp` resolution system.
Description
When chaining multiple transform methods on
BoxStyler(e.g.,scale()thentranslate()), the last transform completely replaces the previous one instead of composing them.Steps to Reproduce
Expected Behavior
Both transforms should be applied: the box should be scaled and translated. The resulting
Matrix4should be the composition (multiplication) of both transform matrices.Actual Behavior
Only the last transform (
translate) is applied. Thescaleis silently discarded.Root Cause
Each transform method (defined in
TransformStyleMixin) callstransform(matrix)which creates a newBoxStylerwith that singleMatrix4and merges it. During merge,Prop.mergeProp()correctly accumulates both Matrix4 sources. However, during resolution inProp.resolveProp(), becauseMatrix4is not aMixtype, it falls into the replacement strategy (resolvedValue = values.last) instead of composing (multiplying) the matrices.Key code path:
TransformStyleMixin.scale()/.translate()→transform(Matrix4)→ creates new styler and mergesProp.mergeProp()accumulates sources:[scaleMatrix, translateMatrix]Prop.resolveProp()resolves withvalues.last→ onlytranslateMatrixis returnedAffected Methods
All transform helpers in
TransformStyleMixinare affected when chained together:scale()translate()rotate()skew()Any combination of two or more of these will result in only the last one being applied.
Possible Solution
Stop using
Container'stransformproperty for these operations. Instead, each transform method (scale,translate,rotate,skew) should usewrap()behind the scenes to apply the respectiveModifierMix. This way, each chained call adds its own independentModifierwidget in the widget tree, so they naturally compose without needing Matrix4 multiplication logic in theProp` resolution system.