Skip to content

Commit

Permalink
add modifiers in specs
Browse files Browse the repository at this point in the history
  • Loading branch information
tilucasoli committed Jun 28, 2024
1 parent 18f7343 commit 2e2aeab
Show file tree
Hide file tree
Showing 36 changed files with 421 additions and 200 deletions.
2 changes: 1 addition & 1 deletion examples/todo_list/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:mix/mix.dart';
import 'package:todo_list/pages/todo_list_page.dart';

import 'pages/todo_list_page.dart';
import 'style/design_tokens.dart';

void main() {
Expand Down
26 changes: 9 additions & 17 deletions examples/todo_list/lib/style/components/checkbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,15 @@ class TodoCheckbox extends StatelessWidget {
$box.borderRadius(3),
scaleEffect(),
outlinePattern(),
$icon.size(16),
$icon.color.ref($token.color.surface),
$icon.modifiers.opacity(0),
$icon.modifiers.padding.top(5),
$icon.modifiers.scale(0.5),
_CheckboxVariant.checked(
$icon.modifiers.padding.top(0),
$icon.modifiers.scale(2),
$icon.modifiers.opacity(1),
$box.color.ref($token.color.primary),
$box.border.color.ref($token.color.primary),
),
Expand All @@ -41,24 +49,8 @@ class TodoCheckbox extends StatelessWidget {
.animate(
duration: const Duration(milliseconds: 150),
),
child: StyledIcon(
child: const StyledIcon(
Icons.check,
style: Style(
$icon.weight(16),
$icon.color.ref($token.color.surface),
$with.opacity(0),
$with.padding.top(5),
_CheckboxVariant.checked(
$with.padding.top(0),
$with.opacity(1),
),
)
.applyVariant(
value ? _CheckboxVariant.checked : _CheckboxVariant.unchecked,
)
.animate(
duration: const Duration(milliseconds: 300),
),
),
);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/mix/lib/src/attributes/attributes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ export 'enum/enum_util.dart';
export 'gap/gap_util.dart';
export 'gap/spacing_side_dto.dart';
export 'gradient/gradient_dto.dart';
export 'modifiers/widget_modifiers_data.dart';
export 'modifiers/widget_modifiers_data_dto.dart';
export 'modifiers/widget_modifiers_util.dart';
export 'nested_style/nested_style_attribute.dart';
export 'nested_style/nested_style_util.dart';
export 'scalars/scalar_util.dart';
Expand Down
29 changes: 0 additions & 29 deletions packages/mix/lib/src/attributes/modifiers/modifiers_data_dto.dart

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '../../core/modifier.dart';

class ModifiersData {
class WidgetModifiersData {
// ignore: avoid-dynamic
final List<WidgetModifierSpec<dynamic>> value;
const ModifiersData(this.value);
const WidgetModifiersData(this.value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import '../../core/core.dart';
import 'widget_modifiers_data.dart';

class WidgetModifiersDataDto extends Dto<WidgetModifiersData> {
final List<WidgetModifierAttribute> value;

const WidgetModifiersDataDto(this.value);

@override
WidgetModifiersDataDto merge(WidgetModifiersDataDto? other) {
if (other == null) return this;
final thisMap = AttributeMap(value);
final otherMap = AttributeMap(other.value);
final mergedMap = thisMap.merge(otherMap).values;

return WidgetModifiersDataDto(mergedMap);
}

@override
WidgetModifiersData resolve(MixData mix) {
return WidgetModifiersData(value.map((e) => e.resolve(mix)).toList());
}

@override
WidgetModifiersData get defaultValue => const WidgetModifiersData([]);

@override
List<Object?> get props => [value];
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import '../../core/core.dart';
import '../../modifiers/modifiers.dart';
import '../spacing/spacing_util.dart';
import 'modifiers_data_dto.dart';
import 'widget_modifiers_data_dto.dart';

final class ModifiersDataUtility<T extends Attribute>
extends MixUtility<T, ModifiersDataDto> {
late final add = WithModifierUtility((v) => builder(ModifiersDataDto([v])));
final class ModifierUtility<T extends Attribute>
extends MixUtility<T, WidgetModifiersDataDto> {
late final add =
WithModifierUtility((v) => builder(WidgetModifiersDataDto([v])));

late final intrinsicWidth = IntrinsicWidthWidgetUtility(only);
late final intrinsicHeight = IntrinsicHeightWidgetUtility(only);
Expand All @@ -30,9 +31,9 @@ final class ModifiersDataUtility<T extends Attribute>
late final sizedBox = SizedBoxModifierUtility(only);
late final padding = SpacingUtility(PaddingModifierUtility(only));

ModifiersDataUtility(super.builder);
ModifierUtility(super.builder);

T only(WidgetModifierAttribute attribute) {
return builder(ModifiersDataDto([attribute]));
return builder(WidgetModifiersDataDto([attribute]));
}
}
8 changes: 4 additions & 4 deletions packages/mix/lib/src/core/spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'package:flutter/foundation.dart';

import '../attributes/animated/animated_data.dart';
import '../attributes/animated/animated_data_dto.dart';
import '../attributes/modifiers/modifiers_data.dart';
import '../attributes/modifiers/modifiers_data_dto.dart';
import '../attributes/modifiers/widget_modifiers_data.dart';
import '../attributes/modifiers/widget_modifiers_data_dto.dart';
import '../internal/compare_mixin.dart';
import 'attribute.dart';
import 'factory/mix_data.dart';
Expand All @@ -12,7 +12,7 @@ import 'utility.dart';
@immutable
abstract class Spec<T extends Spec<T>> with EqualityMixin {
final AnimatedData? animated;
final ModifiersData? modifiers;
final WidgetModifiersData? modifiers;

const Spec({this.animated, this.modifiers});

Expand All @@ -34,7 +34,7 @@ abstract class Spec<T extends Spec<T>> with EqualityMixin {
/// The [Self] type represents the concrete implementation of the attribute, while the [Value] type represents the resolvable value.
abstract base class SpecAttribute<Value> extends StyledAttribute {
final AnimatedDataDto? animated;
final ModifiersDataDto? modifiers;
final WidgetModifiersDataDto? modifiers;

const SpecAttribute({this.animated, this.modifiers});

Expand Down
54 changes: 50 additions & 4 deletions packages/mix/lib/src/modifiers/render_widget_modifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@ const _defaultOrder = [
OpacityModifierAttribute,
];

const _defaultOrderSpecs = [
VisibilityModifierSpec,
SizedBoxModifierSpec,
FractionallySizedBoxModifierSpec,
AlignModifierSpec,
IntrinsicHeightModifierSpec,
IntrinsicWidthModifierSpec,
AspectRatioModifierSpec,
TransformModifierSpec,
ClipOvalModifierSpec,
ClipRRectModifierSpec,
ClipPathModifierSpec,
ClipTriangleModifierSpec,
ClipRectModifierSpec,
OpacityModifierSpec,
];

class RenderModifiers extends StatelessWidget {
const RenderModifiers({
required this.child,
Expand Down Expand Up @@ -152,6 +169,31 @@ Set<WidgetModifierSpec> resolveModifierSpecs(
return orderModifierSpecs(orderOfModifiers, mix, modifiers);
}

Set<WidgetModifierSpec<dynamic>> orderSpecs(
List<Type> orderOfModifiers, [
Set<WidgetModifierSpec<dynamic>> modifiers = const {},
]) {
final listOfModifiers = ({
// Prioritize the order of modifiers provided by the user.
...orderOfModifiers,
// Add the default order of modifiers.
..._defaultOrderSpecs,
// Add any remaining modifiers that were not included in the order.
...modifiers.map((e) => e.type),
}).toList();

final specs = <WidgetModifierSpec<dynamic>>{};

for (final modifierType in listOfModifiers) {
// Resolve the modifier and add it to the list of specs.
final modifier = modifiers.where((e) => e.type == modifierType).firstOrNull;
if (modifier == null) continue;
specs.add(modifier as WidgetModifierSpec<WidgetModifierSpec<dynamic>>);
}

return specs;
}

Set<WidgetModifierSpec> orderModifierSpecs(
List<Type> orderOfModifiers,
MixData mix,
Expand Down Expand Up @@ -182,14 +224,12 @@ Set<WidgetModifierSpec> orderModifierSpecs(

class RenderInlineModifiers extends StatelessWidget {
const RenderInlineModifiers({
required this.mix,
required this.orderOfModifiers,
required this.child,
required this.spec,
super.key,
});

final MixData mix;
final Widget child;
final List<Type> orderOfModifiers;
final Spec spec;
Expand All @@ -198,13 +238,19 @@ class RenderInlineModifiers extends StatelessWidget {
Widget build(BuildContext context) {
return spec.isAnimated
? RenderAnimatedModifiers(
modifiers: spec.modifiers?.value.toSet() ?? {},
modifiers: orderSpecs(
orderOfModifiers,
spec.modifiers?.value.toSet() ?? {},
),
duration: spec.animated!.duration,
curve: spec.animated!.curve,
child: child,
)
: RenderModifiers(
modifiers: spec.modifiers?.value.toSet() ?? {},
modifiers: orderSpecs(
orderOfModifiers,
spec.modifiers?.value.toSet() ?? {},
),
child: child,
);
}
Expand Down
12 changes: 6 additions & 6 deletions packages/mix/lib/src/specs/box/box_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import 'package:flutter/widgets.dart';
import 'package:mix/mix.dart';
import 'package:mix_annotations/mix_annotations.dart';

import '../../attributes/modifiers/modifiers_data.dart';
import '../../attributes/modifiers/modifiers_data_dto.dart';
import '../../attributes/modifiers/modifiers_util.dart';

part 'box_spec.g.dart';

const _constraints = MixableUtility(
Expand Down Expand Up @@ -104,14 +100,18 @@ final class BoxSpec extends Spec<BoxSpec> with _$BoxSpec {
super.animated,
});

Widget call({Widget? child}) {
Widget call({Widget? child, List<Type> orderOfModifiers = const []}) {
return isAnimated
? AnimatedBoxSpecWidget(
spec: this,
duration: animated!.duration,
curve: animated!.curve,
child: child,
)
: BoxSpecWidget(spec: this, child: child);
: BoxSpecWidget(
spec: this,
orderOfModifiers: orderOfModifiers,
child: child,
);
}
}
6 changes: 3 additions & 3 deletions packages/mix/lib/src/specs/box/box_spec.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2e2aeab

Please sign in to comment.