diff --git a/packages/mix/CHANGELOG.md b/packages/mix/CHANGELOG.md index 45c30ecd3..87300b0fa 100644 --- a/packages/mix/CHANGELOG.md +++ b/packages/mix/CHANGELOG.md @@ -1,3 +1,13 @@ +## Unreleased + +### Fixes + +- **Box / text shadow tokens through styler methods:** `BoxStyler.boxShadows`, `BoxStyler.shadows`, `FlexBoxStyler.shadows`, `StackBoxStyler.shadows`, and `TextStyler.shadows` now accept the `BoxShadowListMix` / `ShadowListMix` wrapper so design-token references (`BoxShadowToken('x').mix()`, `ShadowToken('y').mix()`) can be passed directly (#925). + +### Breaking changes + +- **Shadow styler methods now take a Mix wrapper instead of a raw list.** Update call sites that pass a literal list to wrap it: `BoxStyler().boxShadows([s1, s2])` → `BoxStyler().boxShadows(BoxShadowListMix([s1, s2]))`. The same applies to `.shadows(...)` on `BoxStyler` / `FlexBoxStyler` / `StackBoxStyler` and to `TextStyler.shadows(...)`. + ## 2.0.3 This release adds finer-grained control over scope inheritance and theming, and restores compatibility with newer Flutter SDKs. diff --git a/packages/mix/lib/src/specs/box/box_spec.g.dart b/packages/mix/lib/src/specs/box/box_spec.g.dart index 1b6c080de..3f5162d66 100644 --- a/packages/mix/lib/src/specs/box/box_spec.g.dart +++ b/packages/mix/lib/src/specs/box/box_spec.g.dart @@ -233,7 +233,7 @@ class BoxStyler extends MixStyler factory BoxStyler.elevation(ElevationShadow value) => BoxStyler().elevation(value); factory BoxStyler.shadow(BoxShadowMix value) => BoxStyler().shadow(value); - factory BoxStyler.shadows(List value) => + factory BoxStyler.shadows(BoxShadowListMix value) => BoxStyler().shadows(value); factory BoxStyler.width(double value) => BoxStyler().width(value); factory BoxStyler.height(double value) => BoxStyler().height(value); diff --git a/packages/mix/lib/src/specs/flexbox/flexbox_spec.g.dart b/packages/mix/lib/src/specs/flexbox/flexbox_spec.g.dart index a2ebedd9d..a30fa8499 100644 --- a/packages/mix/lib/src/specs/flexbox/flexbox_spec.g.dart +++ b/packages/mix/lib/src/specs/flexbox/flexbox_spec.g.dart @@ -170,7 +170,7 @@ class FlexBoxStyler extends MixStyler FlexBoxStyler().elevation(value); factory FlexBoxStyler.shadow(BoxShadowMix value) => FlexBoxStyler().shadow(value); - factory FlexBoxStyler.shadows(List value) => + factory FlexBoxStyler.shadows(BoxShadowListMix value) => FlexBoxStyler().shadows(value); factory FlexBoxStyler.width(double value) => FlexBoxStyler().width(value); factory FlexBoxStyler.height(double value) => FlexBoxStyler().height(value); diff --git a/packages/mix/lib/src/specs/stackbox/stackbox_spec.g.dart b/packages/mix/lib/src/specs/stackbox/stackbox_spec.g.dart index 5cb9f22b8..677d50a1b 100644 --- a/packages/mix/lib/src/specs/stackbox/stackbox_spec.g.dart +++ b/packages/mix/lib/src/specs/stackbox/stackbox_spec.g.dart @@ -162,7 +162,7 @@ class StackBoxStyler extends MixStyler StackBoxStyler().elevation(value); factory StackBoxStyler.shadow(BoxShadowMix value) => StackBoxStyler().shadow(value); - factory StackBoxStyler.shadows(List value) => + factory StackBoxStyler.shadows(BoxShadowListMix value) => StackBoxStyler().shadows(value); factory StackBoxStyler.width(double value) => StackBoxStyler().width(value); factory StackBoxStyler.height(double value) => StackBoxStyler().height(value); diff --git a/packages/mix/lib/src/specs/text/text_spec.g.dart b/packages/mix/lib/src/specs/text/text_spec.g.dart index a2d6293fd..43b0d7d57 100644 --- a/packages/mix/lib/src/specs/text/text_spec.g.dart +++ b/packages/mix/lib/src/specs/text/text_spec.g.dart @@ -309,7 +309,7 @@ class TextStyler extends MixStyler factory TextStyler.fontFamilyFallback(List value) => TextStyler().fontFamilyFallback(value); factory TextStyler.shadow(ShadowMix value) => TextStyler().shadow(value); - factory TextStyler.shadows(List value) => + factory TextStyler.shadows(ShadowListMix value) => TextStyler().shadows(value); factory TextStyler.fontFeatures(List value) => TextStyler().fontFeatures(value); diff --git a/packages/mix/lib/src/style/mixins/decoration_style_mixin.dart b/packages/mix/lib/src/style/mixins/decoration_style_mixin.dart index b362f7d5b..4569d0d5f 100644 --- a/packages/mix/lib/src/style/mixins/decoration_style_mixin.dart +++ b/packages/mix/lib/src/style/mixins/decoration_style_mixin.dart @@ -1,6 +1,7 @@ import 'package:flutter/widgets.dart'; import '../../core/mix_element.dart'; +import '../../core/prop.dart'; import '../../properties/painting/border_mix.dart'; import '../../properties/painting/border_radius_mix.dart'; import '../../properties/painting/decoration_image_mix.dart'; @@ -39,9 +40,13 @@ mixin DecorationStyleMixin> { return decoration(BoxDecorationMix.boxShadow([value])); } - /// Sets multiple shadows - T shadows(List value) { - return decoration(BoxDecorationMix.boxShadow(value)); + /// Sets multiple shadows. + /// + /// Accepts a [BoxShadowListMix] so that both literal lists + /// (`BoxShadowListMix([shadow1, shadow2])`) and design-token references + /// (`boxShadowToken.mix()`) can be passed. + T shadows(BoxShadowListMix value) { + return decoration(BoxDecorationMix.create(boxShadow: Prop.mix(value))); } /// Sets elevation shadow diff --git a/packages/mix/lib/src/style/mixins/shadow_style_mixin.dart b/packages/mix/lib/src/style/mixins/shadow_style_mixin.dart index 8d23f136e..73b9d8039 100644 --- a/packages/mix/lib/src/style/mixins/shadow_style_mixin.dart +++ b/packages/mix/lib/src/style/mixins/shadow_style_mixin.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import '../../core/mix_element.dart'; +import '../../core/prop.dart'; import '../../properties/painting/decoration_mix.dart'; import '../../properties/painting/shadow_mix.dart'; @@ -26,9 +27,13 @@ mixin ShadowStyleMixin> { return decoration(BoxDecorationMix.boxShadow([shadow])); } - /// Creates multiple box shadows from a list of BoxShadowMix - T boxShadows(List value) { - return decoration(BoxDecorationMix.boxShadow(value)); + /// Sets multiple box shadows. + /// + /// Accepts a [BoxShadowListMix] so that both literal lists + /// (`BoxShadowListMix([shadow1, shadow2])`) and design-token references + /// (`boxShadowToken.mix()`) can be passed. + T boxShadows(BoxShadowListMix value) { + return decoration(BoxDecorationMix.create(boxShadow: Prop.mix(value))); } /// Creates box shadows from Material Design elevation level diff --git a/packages/mix/lib/src/style/mixins/text_style_mixin.dart b/packages/mix/lib/src/style/mixins/text_style_mixin.dart index f10111ded..762029f7f 100644 --- a/packages/mix/lib/src/style/mixins/text_style_mixin.dart +++ b/packages/mix/lib/src/style/mixins/text_style_mixin.dart @@ -1,6 +1,7 @@ import 'package:flutter/widgets.dart'; import '../../core/mix_element.dart'; +import '../../core/prop.dart'; import '../../properties/painting/shadow_mix.dart'; import '../../properties/typography/text_style_mix.dart'; @@ -84,9 +85,13 @@ mixin TextStyleMixin> { return style(TextStyleMix.fontFamilyFallback(value)); } - /// Sets text shadows - T shadows(List value) { - return style(TextStyleMix.shadows(value)); + /// Sets text shadows. + /// + /// Accepts a [ShadowListMix] so that both literal lists + /// (`ShadowListMix([shadow1, shadow2])`) and design-token references + /// (`shadowToken.mix()`) can be passed. + T shadows(ShadowListMix value) { + return style(TextStyleMix.create(shadows: Prop.mix(value))); } /// Sets a single text shadow. diff --git a/packages/mix/test/src/specs/box/box_style_factory_test.dart b/packages/mix/test/src/specs/box/box_style_factory_test.dart index cb299f2f4..7b27448b9 100644 --- a/packages/mix/test/src/specs/box/box_style_factory_test.dart +++ b/packages/mix/test/src/specs/box/box_style_factory_test.dart @@ -120,10 +120,10 @@ void main() { }); test('shadows', () { - final s = [ + final s = BoxShadowListMix([ BoxShadowMix(color: Colors.black, blurRadius: 10), BoxShadowMix(color: Colors.grey, blurRadius: 5), - ]; + ]); expect(BoxStyler.shadows(s), equals(BoxStyler().shadows(s))); }); diff --git a/packages/mix/test/src/specs/box/box_style_test.dart b/packages/mix/test/src/specs/box/box_style_test.dart index 183a74667..a7107f243 100644 --- a/packages/mix/test/src/specs/box/box_style_test.dart +++ b/packages/mix/test/src/specs/box/box_style_test.dart @@ -251,10 +251,10 @@ void main() { }); test('shadows method sets multiple shadows', () { - final shadows = [ + final shadows = BoxShadowListMix([ BoxShadowMix(color: Colors.black, blurRadius: 5.0), BoxShadowMix(color: Colors.grey, blurRadius: 10.0), - ]; + ]); final boxMix = BoxStyler().shadows(shadows); expect(boxMix.$decoration, isNotNull); diff --git a/packages/mix/test/src/specs/flexbox/flexbox_style_factory_test.dart b/packages/mix/test/src/specs/flexbox/flexbox_style_factory_test.dart index f589b6d42..1124c1b67 100644 --- a/packages/mix/test/src/specs/flexbox/flexbox_style_factory_test.dart +++ b/packages/mix/test/src/specs/flexbox/flexbox_style_factory_test.dart @@ -168,10 +168,10 @@ void main() { }); test('shadows', () { - final s = [ + final s = BoxShadowListMix([ BoxShadowMix(color: Colors.black, blurRadius: 10), BoxShadowMix(color: Colors.grey, blurRadius: 5), - ]; + ]); expect(FlexBoxStyler.shadows(s), equals(FlexBoxStyler().shadows(s))); }); diff --git a/packages/mix/test/src/specs/stackbox/stackbox_style_factory_test.dart b/packages/mix/test/src/specs/stackbox/stackbox_style_factory_test.dart index e4c73bdab..88de2988f 100644 --- a/packages/mix/test/src/specs/stackbox/stackbox_style_factory_test.dart +++ b/packages/mix/test/src/specs/stackbox/stackbox_style_factory_test.dart @@ -144,10 +144,10 @@ void main() { }); test('shadows', () { - final s = [ + final s = BoxShadowListMix([ BoxShadowMix(color: Colors.black, blurRadius: 10), BoxShadowMix(color: Colors.grey, blurRadius: 5), - ]; + ]); expect(StackBoxStyler.shadows(s), equals(StackBoxStyler().shadows(s))); }); diff --git a/packages/mix/test/src/specs/text/text_style_factory_test.dart b/packages/mix/test/src/specs/text/text_style_factory_test.dart index a7dc48896..ea1ad72c7 100644 --- a/packages/mix/test/src/specs/text/text_style_factory_test.dart +++ b/packages/mix/test/src/specs/text/text_style_factory_test.dart @@ -200,7 +200,9 @@ void main() { }); test('shadows', () { - final s = [ShadowMix(color: Colors.black, blurRadius: 4)]; + final s = ShadowListMix([ + ShadowMix(color: Colors.black, blurRadius: 4), + ]); expect(TextStyler.shadows(s), equals(TextStyler().shadows(s))); }); diff --git a/packages/mix/test/src/specs/text/text_style_test.dart b/packages/mix/test/src/specs/text/text_style_test.dart index c7019303c..8ac5f2b01 100644 --- a/packages/mix/test/src/specs/text/text_style_test.dart +++ b/packages/mix/test/src/specs/text/text_style_test.dart @@ -525,9 +525,9 @@ void main() { }); test('shadows utility works correctly', () { - final attribute = TextStyler().shadows([ - ShadowMix(color: Colors.black, offset: Offset(2, 2)), - ]); + final attribute = TextStyler().shadows( + ShadowListMix([ShadowMix(color: Colors.black, offset: Offset(2, 2))]), + ); expect(attribute.$style, isNotNull); }); diff --git a/packages/mix/test/src/theme/tokens/shadow_list_token_integration_test.dart b/packages/mix/test/src/theme/tokens/shadow_list_token_integration_test.dart index 7d4283c46..1d0324f12 100644 --- a/packages/mix/test/src/theme/tokens/shadow_list_token_integration_test.dart +++ b/packages/mix/test/src/theme/tokens/shadow_list_token_integration_test.dart @@ -127,5 +127,92 @@ void main() { expect(boxShadowRef, isA>()); expect(boxShadowRef.runtimeType, equals(BoxShadowListRef)); }); + + test('BoxShadowToken.mix() returns BoxShadowListMixRef', () { + const boxShadowToken = BoxShadowToken('test.box.shadows.mix'); + final mixRef = boxShadowToken.mix(); + + expect(mixRef, isA()); + expect(mixRef, isA()); + expect(isAnyTokenRef(mixRef), isTrue); + }); + + test('BoxStyler.boxShadows accepts BoxShadowToken.mix()', () { + const boxShadowToken = BoxShadowToken('test.box.shadows.boxShadows'); + + // Compiles and produces a styler with the token-backed shadow prop. + final styler = BoxStyler().boxShadows(boxShadowToken.mix()); + + expect(styler.$decoration, isNotNull); + }); + + test('BoxStyler.shadows accepts BoxShadowToken.mix()', () { + const boxShadowToken = BoxShadowToken('test.box.shadows.shadows'); + + final styler = BoxStyler().shadows(boxShadowToken.mix()); + + expect(styler.$decoration, isNotNull); + }); + + test('BoxStyler.shadows accepts a BoxShadowListMix literal', () { + final styler = BoxStyler().shadows( + BoxShadowListMix([ + BoxShadowMix(color: Colors.black, blurRadius: 5), + BoxShadowMix(color: Colors.grey, blurRadius: 10), + ]), + ); + + expect(styler.$decoration, isNotNull); + }); + + testWidgets( + 'BoxStyler.boxShadows resolves BoxShadowToken.mix() through MixScope', + (tester) async { + const boxShadowToken = BoxShadowToken('box.shadows.token-mix.resolved'); + final testBoxShadows = [ + const BoxShadow(color: Colors.black, blurRadius: 4), + const BoxShadow(color: Colors.grey, blurRadius: 2), + ]; + + await tester.pumpWidget( + MixScope( + tokens: {boxShadowToken: testBoxShadows}, + child: Builder( + builder: (context) { + final styler = BoxStyler().boxShadows(boxShadowToken.mix()); + final styleSpec = styler.resolve(context); + final decoration = styleSpec.spec.decoration; + + expect(decoration, isA()); + expect( + (decoration as BoxDecoration).boxShadow, + equals(testBoxShadows), + ); + + return const SizedBox.shrink(); + }, + ), + ), + ); + }, + ); + + test('TextStyler.shadows accepts ShadowToken.mix()', () { + const shadowToken = ShadowToken('text.shadows.mix'); + + final styler = TextStyler().shadows(shadowToken.mix()); + + expect(styler.$style, isNotNull); + }); + + test('TextStyler.shadows accepts a ShadowListMix literal', () { + final styler = TextStyler().shadows( + ShadowListMix([ + ShadowMix(color: Colors.black, offset: const Offset(1, 1)), + ]), + ); + + expect(styler.$style, isNotNull); + }); }); } diff --git a/packages/mix_tailwinds/lib/src/tw_parser.dart b/packages/mix_tailwinds/lib/src/tw_parser.dart index 605be8cfe..ded4869f7 100644 --- a/packages/mix_tailwinds/lib/src/tw_parser.dart +++ b/packages/mix_tailwinds/lib/src/tw_parser.dart @@ -1063,7 +1063,8 @@ FlexBoxStyler _applyFlexShadow(FlexBoxStyler styler, TwValue value) { styler, value, applyElevation: (style, elevation) => style.elevation(elevation), - applyBoxShadows: (style, shadows) => style.boxShadows(shadows), + applyBoxShadows: (style, shadows) => + style.boxShadows(BoxShadowListMix(shadows)), ); } @@ -1211,7 +1212,8 @@ BoxStyler _applyBoxShadow(BoxStyler styler, TwValue value) { styler, value, applyElevation: (style, elevation) => style.elevation(elevation), - applyBoxShadows: (style, shadows) => style.boxShadows(shadows), + applyBoxShadows: (style, shadows) => + style.boxShadows(BoxShadowListMix(shadows)), ); } @@ -1363,7 +1365,7 @@ BoxStyler _applyBoxTextShadow(BoxStyler styler, TwValue value) { TextStyler _applyTextShadow(TextStyler styler, TwValue value) { final shadows = _resolveTextShadowMixes(value); if (shadows == null) return styler; - return styler.shadows(shadows); + return styler.shadows(ShadowListMix(shadows)); } TextStyler _applyPropertyToText(