Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: callable specs and modifiers #332

Merged
merged 7 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/todo_list/lib/style/components/button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ class TodoButton extends StatelessWidget {
$text.style.ref($token.textStyle.heading3),
$text.style.bold(),
$with.scale(1),
$with.align(alignment: Alignment.center),
$on.press(
$with.scale(1.1),
),
$with.align(alignment: Alignment.center),
),
),
);
Expand Down
10 changes: 9 additions & 1 deletion packages/mix/lib/src/modifiers/padding_widget_modifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import 'package:flutter/widgets.dart';

import '../attributes/spacing/edge_insets_dto.dart';
import '../core/attribute.dart';
import '../core/factory/mix_data.dart';
import '../core/modifier.dart';
import '../core/utility.dart';

final class PaddingSpec extends WidgetModifierSpec<PaddingSpec> {
final EdgeInsetsGeometry padding;
Expand Down Expand Up @@ -38,7 +40,7 @@ final class PaddingModifierAttribute

@override
PaddingModifierAttribute merge(PaddingModifierAttribute? other) {
return PaddingModifierAttribute(other?.padding ?? padding);
return PaddingModifierAttribute(padding.merge(other?.padding));
}

@override
Expand All @@ -47,3 +49,9 @@ final class PaddingModifierAttribute
@override
get props => [padding];
}

final class PaddingModifierUtility<T extends Attribute>
extends MixUtility<T, PaddingModifierAttribute> {
const PaddingModifierUtility(super.builder);
T call(SpacingDto value) => builder(PaddingModifierAttribute(value));
}
46 changes: 23 additions & 23 deletions packages/mix/lib/src/modifiers/widget_modifiers_util.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import '../attributes/spacing/spacing_util.dart';
import '../core/attribute.dart';
import '../core/modifier.dart';
import '../core/utility.dart';
import 'align_widget_modifier.dart';
import 'aspect_ratio_widget_modifier.dart';
Expand All @@ -13,35 +15,33 @@ import 'sized_box_widget_modifier.dart';
import 'transform_widget_modifier.dart';
import 'visibility_widget_modifier.dart';

class WithModifierUtility {
late final intrinsicWidth =
const IntrinsicWidthWidgetUtility(MixUtility.selfBuilder);
late final intrinsicHeight =
const IntrinsicHeightWidgetUtility(MixUtility.selfBuilder);
late final rotate = const RotatedBoxWidgetUtility(MixUtility.selfBuilder);
late final opacity = const OpacityUtility(MixUtility.selfBuilder);
late final clipPath = const ClipPathUtility(MixUtility.selfBuilder);
late final clipRRect = const ClipRRectUtility(MixUtility.selfBuilder);
late final clipOval = const ClipOvalUtility(MixUtility.selfBuilder);
late final clipRect = const ClipRectUtility(MixUtility.selfBuilder);
late final clipTriangle = const ClipTriangleUtility(MixUtility.selfBuilder);
late final visibility = const VisibilityUtility(MixUtility.selfBuilder);
class WithModifierUtility<T extends Attribute>
extends MixUtility<T, WidgetModifierAttribute> {
late final intrinsicWidth = IntrinsicWidthWidgetUtility(builder);
late final intrinsicHeight = IntrinsicHeightWidgetUtility(builder);
late final rotate = RotatedBoxWidgetUtility(builder);
late final opacity = OpacityUtility(builder);
late final clipPath = ClipPathUtility(builder);
late final clipRRect = ClipRRectUtility(builder);
late final clipOval = ClipOvalUtility(builder);
late final clipRect = ClipRectUtility(builder);
late final clipTriangle = ClipTriangleUtility(builder);
late final visibility = VisibilityUtility(builder);
late final show = visibility.on;
late final hide = visibility.off;
late final aspectRatio = const AspectRatioUtility(MixUtility.selfBuilder);
late final flexible = _flexible;
late final aspectRatio = AspectRatioUtility(builder);
late final flexible = FlexibleModifierUtility(builder);
late final expanded = flexible.expanded;
late final transform = const TransformUtility(MixUtility.selfBuilder);
late final transform = TransformUtility(builder);

late final scale = transform.scale;
late final align = const AlignWidgetUtility(MixUtility.selfBuilder);
late final align = AlignWidgetUtility(builder);
late final fractionallySizedBox =
const FractionallySizedBoxModifierUtility(MixUtility.selfBuilder);
late final sizedBox = SizedBoxModifierUtility(MixUtility.selfBuilder);
late final padding = SpacingUtility(PaddingModifierAttribute.new);
FractionallySizedBoxModifierUtility(builder);
late final sizedBox = SizedBoxModifierUtility(builder);
late final padding = SpacingUtility(PaddingModifierUtility(builder).call);

static final self = WithModifierUtility._();
late final _flexible = const FlexibleModifierUtility(MixUtility.selfBuilder);
static final self = WithModifierUtility(MixUtility.selfBuilder);

WithModifierUtility._();
WithModifierUtility(super.builder);
}
10 changes: 8 additions & 2 deletions packages/mix/lib/src/specs/icon/icon_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,22 @@ final class IconSpec extends Spec<IconSpec> with _$IconSpec {
super.animated,
});

Widget call([IconData? icon]) {
Widget call(IconData? icon, {String? semanticLabel}) {
return isAnimated
? AnimatedIconSpecWidget(
icon,
spec: this,
semanticLabel: semanticLabel,
textDirection: textDirection,
curve: animated!.curve,
duration: animated!.duration,
)
: IconSpecWidget(icon, spec: this, textDirection: textDirection);
: IconSpecWidget(
icon,
spec: this,
semanticLabel: semanticLabel,
textDirection: textDirection,
);
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/mix/lib/src/specs/icon/icon_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class StyledIcon extends StyledWidget {

final IconData? icon;
final String? semanticLabel;
// TODO: Should textDirection be a contructor argument or a style attribute?
final TextDirection? textDirection;

@override
Expand Down
36 changes: 34 additions & 2 deletions packages/mix/lib/src/specs/image/image_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,46 @@ final class ImageSpec extends Spec<ImageSpec> with _$ImageSpec {
super.animated,
});

Widget call({required ImageProvider<Object> image}) {
Widget call({
required ImageProvider<Object> image,
ImageFrameBuilder? frameBuilder,
ImageLoadingBuilder? loadingBuilder,
ImageErrorWidgetBuilder? errorBuilder,
String? semanticLabel,
bool excludeFromSemantics = false,
bool gaplessPlayback = false,
bool isAntiAlias = false,
bool matchTextDirection = false,
Animation<double>? opacity,
}) {
return isAnimated
? AnimatedImageSpecWidget(
spec: this,
image: image,
frameBuilder: frameBuilder,
loadingBuilder: loadingBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
duration: animated!.duration,
curve: animated!.curve,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
matchTextDirection: matchTextDirection,
opacity: opacity,
)
: ImageSpecWidget(spec: this, image: image);
: ImageSpecWidget(
spec: this,
image: image,
frameBuilder: frameBuilder,
loadingBuilder: loadingBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
opacity: opacity,
matchTextDirection: matchTextDirection,
);
}
}
11 changes: 9 additions & 2 deletions packages/mix/lib/src/specs/text/text_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,21 @@ final class TextSpec extends Spec<TextSpec> with _$TextSpec {
super.animated,
});

Widget call(String text) {
Widget call(String text, {String? semanticLabel, Locale? locale}) {
return isAnimated
? AnimatedTextSpecWidget(
text,
spec: this,
semanticsLabel: semanticLabel,
locale: locale,
duration: animated!.duration,
curve: animated!.curve,
)
: TextSpecWidget(text, spec: this);
: TextSpecWidget(
text,
spec: this,
semanticsLabel: semanticLabel,
locale: locale,
);
}
}
16 changes: 16 additions & 0 deletions packages/mix/test/src/modifiers/padding_widget_modifier_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@ void main() {
expect(result.padding, equals(padding2));
});

test('deep merge returns correct PaddingModifierAttribute', () {
const padding1 = EdgeInsetsDto(top: 1, bottom: 2, left: 3, right: 4);
const padding2 = EdgeInsetsDto(top: 4, bottom: 3);
const attribute1 = PaddingModifierAttribute(padding1);
const attribute2 = PaddingModifierAttribute(padding2);

final result = attribute1.merge(attribute2);

expect(
result.padding,
equals(
const EdgeInsetsDto(top: 4, bottom: 3, left: 3, right: 4),
),
);
});

test('merge returns original PaddingModifierAttribute when other is null',
() {
const padding = EdgeInsetsDto.all(10.0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void main() {
MockMixData(
Style(modifier),
),
);
) as TransformModifierSpec;

expect(spec.transform, Matrix4.diagonal3Values(scale, scale, 1));
});
Expand Down
Loading