diff --git a/demo/ios/Runner.xcodeproj/project.pbxproj b/demo/ios/Runner.xcodeproj/project.pbxproj index 9567c3d..0a73ba1 100644 --- a/demo/ios/Runner.xcodeproj/project.pbxproj +++ b/demo/ios/Runner.xcodeproj/project.pbxproj @@ -169,7 +169,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 331C8080294A63A400263BE5 = { diff --git a/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 87131a0..8e3ca5d 100644 --- a/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/demo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ const StyledIcon(Icons.person), @@ -33,8 +33,8 @@ Widget buildCheckboxUseCase(BuildContext context) { RemixAvatar( style: RemixAvatarStyle.base().copyWith( container: Style( - box.height(50), - box.width(50), + $box.height(50), + $box.width(50), ), ), imageBuilder: (style) => @@ -47,8 +47,8 @@ Widget buildCheckboxUseCase(BuildContext context) { ), style: RemixAvatarStyle.base().copyWith( container: Style( - box.height(40), - box.width(40), + $box.height(40), + $box.width(40), ), ), ), diff --git a/demo/lib/components/badge.dart b/demo/lib/components/badge.dart index f2e09ec..debfaa7 100644 --- a/demo/lib/components/badge.dart +++ b/demo/lib/components/badge.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:mix/mix.dart'; import 'package:remix_ui/remix_ui.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; @@ -13,6 +12,7 @@ Widget buildCheckboxUseCase(BuildContext context) { child: RemixBadge( label: context.knobs.string( label: "Label", + description: 'The text displayed in the badge', initialValue: "Label", ), ), diff --git a/demo/lib/components/card.dart b/demo/lib/components/card.dart index 1d0fb93..662a608 100644 --- a/demo/lib/components/card.dart +++ b/demo/lib/components/card.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:mix/mix.dart'; import 'package:remix_ui/remix_ui.dart'; import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; diff --git a/demo/lib/components/checkbox.dart b/demo/lib/components/checkbox.dart index 0208627..6039a70 100644 --- a/demo/lib/components/checkbox.dart +++ b/demo/lib/components/checkbox.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; import 'package:remix_ui/remix_ui.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; @@ -9,20 +10,32 @@ import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; ) Widget buildCheckboxUseCase(BuildContext context) { return Center( - child: RemixCheckbox( - label: context.knobs.stringOrNull( - label: 'Title', - initialValue: 'Title', - ), - onChanged: (value) {}, - checked: context.knobs.boolean( - label: 'Checked', - initialValue: false, - ), - disabled: context.knobs.boolean( - label: 'Disabled', - initialValue: false, - ), + child: Row( + children: [ + Box( + style: Style( + $box.color.grey(), + $box.height(20), + $box.width(20), + $box.borderRadius(4), + ), + ), + RemixCheckbox( + label: context.knobs.stringOrNull( + label: 'Title', + initialValue: 'Title', + ), + onChanged: (value) {}, + value: context.knobs.boolean( + label: 'Checked', + initialValue: false, + ), + disabled: context.knobs.boolean( + label: 'Disabled', + initialValue: false, + ), + ), + ], ), ); } diff --git a/demo/lib/components/list_tile.dart b/demo/lib/components/list_tile.dart index b4389a2..3dc8b1f 100644 --- a/demo/lib/components/list_tile.dart +++ b/demo/lib/components/list_tile.dart @@ -14,10 +14,10 @@ Widget buildCheckboxUseCase(BuildContext context) { leading: RemixAvatar( style: RemixAvatarStyle.base().copyWith( container: Style( - height(60), - width(60), - borderRadius(6), - box.color( + $box.height(60), + $box.width(60), + $box.borderRadius(6), + $box.color( Colors.black26, ), ), diff --git a/demo/pubspec.yaml b/demo/pubspec.yaml index fda8f17..dda2105 100644 --- a/demo/pubspec.yaml +++ b/demo/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: remix_ui: path: ../ - mix: 1.0.0-beta.8 + mix: ^0.9.0 dev_dependencies: flutter_test: diff --git a/ios/Flutter/Generated.xcconfig b/ios/Flutter/Generated.xcconfig index 0e87386..2f21fc4 100644 --- a/ios/Flutter/Generated.xcconfig +++ b/ios/Flutter/Generated.xcconfig @@ -1,6 +1,6 @@ // This is a generated file; do not edit or check into version control. -FLUTTER_ROOT=/Users/leofarias/flutter -FLUTTER_APPLICATION_PATH=/Users/leofarias/Concepta/remix_ui +FLUTTER_ROOT=/Users/lucasoliveira/fvm/versions/stable +FLUTTER_APPLICATION_PATH=/Users/lucasoliveira/Developer/Concepta/Concepta/remix_ui COCOAPODS_PARALLEL_CODE_SIGN=true FLUTTER_TARGET=lib/main.dart FLUTTER_BUILD_DIR=build diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh index fc3dfd9..158ab73 100755 --- a/ios/Flutter/flutter_export_environment.sh +++ b/ios/Flutter/flutter_export_environment.sh @@ -1,7 +1,7 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=/Users/leofarias/flutter" -export "FLUTTER_APPLICATION_PATH=/Users/leofarias/Concepta/remix_ui" +export "FLUTTER_ROOT=/Users/lucasoliveira/fvm/versions/stable" +export "FLUTTER_APPLICATION_PATH=/Users/lucasoliveira/Developer/Concepta/Concepta/remix_ui" export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" diff --git a/lib/components/alert/alert.style.dart b/lib/components/alert/alert.style.dart index 75b7bed..ff29d5e 100644 --- a/lib/components/alert/alert.style.dart +++ b/lib/components/alert/alert.style.dart @@ -68,37 +68,37 @@ class RemixAlertStyle extends StyleRecipe { } Style _outerRowContainer() => Style( - flex.gap(8), - box.padding(16), - box.borderRadius(8), - box.border.width(1), - box.border.color.redAccent(), - flex.mainAxisSize.min(), - flex.mainAxisAlignment.start(), - flex.crossAxisAlignment.start(), + $flex.gap(8), + $box.padding(16), + $box.borderRadius(8), + $box.border.width(1), + $box.border.color.redAccent(), + $flex.mainAxisSize.min(), + $flex.mainAxisAlignment.start(), + $flex.crossAxisAlignment.start(), ); Style _innerColumnContainer() => Style( - flex.gap(2), - flex.mainAxisSize.min(), - flex.mainAxisAlignment.start(), - flex.crossAxisAlignment.start(), + $flex.gap(2), + $flex.mainAxisSize.min(), + $flex.mainAxisAlignment.start(), + $flex.crossAxisAlignment.start(), flexible.expanded(), ); Style _title() => Style( - text.style.fontSize(14), - text.style.fontWeight.w600(), - text.style.color.redAccent(), + $text.style.fontSize(14), + $text.style.fontWeight.w600(), + $text.style.color.redAccent(), ); Style _subtitle() => Style( - text.style.fontSize(14), - text.style.fontWeight.normal(), - text.style.color.redAccent(), + $text.style.fontSize(14), + $text.style.fontWeight.normal(), + $text.style.color.redAccent(), ); Style _icon() => Style( - icon.size(20), - icon.color.redAccent(), + $icon.size(20), + $icon.color.redAccent(), ); diff --git a/lib/components/avatar/avatar.style.dart b/lib/components/avatar/avatar.style.dart index 37200c5..ab1de0b 100644 --- a/lib/components/avatar/avatar.style.dart +++ b/lib/components/avatar/avatar.style.dart @@ -52,21 +52,21 @@ class RemixAvatarStyle extends StyleRecipe { } Style _container() => Style( - box.color.grey.shade100(), - box.borderRadius(50), - box.alignment.center(), - box.width(40), - box.height(40), - box.clipBehavior.antiAlias(), - clip.oval(), + $box.color.grey.shade100(), + $box.borderRadius(50), + $box.alignment.center(), + $box.width(40), + $box.height(40), + $box.clipBehavior.antiAlias(), + $with.clipOval(), ); -Style _label() => Style.text( - text.style.fontSize(16), - text.style.color.black54(), - text.style.fontWeight.bold(), +Style _label() => Style( + $text.style.fontSize(16), + $text.style.color.black54(), + $text.style.fontWeight.bold(), ); -Style _image() => Style.image( - image.fit.cover(), +Style _image() => Style( + $image.fit.cover(), ); diff --git a/lib/components/badge/badge.style.dart b/lib/components/badge/badge.style.dart index 113ccef..de8259e 100644 --- a/lib/components/badge/badge.style.dart +++ b/lib/components/badge/badge.style.dart @@ -46,21 +46,18 @@ class RemixBadgeStyle extends StyleRecipe { } Style _container() => Style( - flex.mainAxisAlignment.center(), - flex.mainAxisSize.min(), - flex.crossAxisAlignment.center(), - flex.gap(4), - box.padding.horizontal(10), - box.padding.vertical(2), - box.borderRadius(20), - box.color.black(), - onHover( - box.color(Colors.black.withOpacity(0.8)), - ), + $flex.mainAxisAlignment.center(), + $flex.mainAxisSize.min(), + $flex.crossAxisAlignment.center(), + $flex.gap(4), + $box.padding.horizontal(10), + $box.padding.vertical(2), + $box.borderRadius(20), + $box.color.black(), ); -Style _label() => Style.text( - text.style.fontSize(12), - text.style.fontWeight.w600(), - text.style.color.white(), +Style _label() => Style( + $text.style.fontSize(12), + $text.style.fontWeight.w600(), + $text.style.color.white(), ); diff --git a/lib/components/button/button.dart b/lib/components/button/button.dart index dcab1d2..6b573f5 100644 --- a/lib/components/button/button.dart +++ b/lib/components/button/button.dart @@ -54,7 +54,7 @@ class RemixButton extends StatelessWidget RemixButtonStyle buttonStyle, ) => [ - _buildLoadingIndicator(MixData.create(context, buttonStyle.icon)), + _buildLoadingIndicator(context), if (loadingLabel != null) StyledText( loadingLabel!, @@ -62,8 +62,8 @@ class RemixButton extends StatelessWidget ), ]; - Widget _buildLoadingIndicator(MixData mix) { - final icon = IconSpec.of(mix); + Widget _buildLoadingIndicator(BuildContext context) { + final icon = IconSpec.of(context); const indicatorWidth = 2.5; return SizedBox( @@ -87,7 +87,7 @@ class RemixButton extends StatelessWidget final style = buildStyle([size, type, ...variants]); return PressableBox( - onPressed: disabled || loading ? null : onPressed, + onPress: disabled || loading ? null : onPressed, child: HBox( style: style.container, children: _buildChildren(context, style), diff --git a/lib/components/button/button.style.dart b/lib/components/button/button.style.dart index 4863845..058292c 100644 --- a/lib/components/button/button.style.dart +++ b/lib/components/button/button.style.dart @@ -65,119 +65,119 @@ class RemixButtonStyle extends StyleRecipe { } Style _container() => Style( - flex.gap(6), - flex.mainAxisAlignment.center(), - flex.crossAxisAlignment.center(), - flex.mainAxisSize.min(), + $flex.gap(6), + $flex.mainAxisAlignment.center(), + $flex.crossAxisAlignment.center(), + $flex.mainAxisSize.min(), ButtonSize.xsmall( - box.padding.horizontal(8), - box.padding.vertical(4), + $box.padding.horizontal(8), + $box.padding.vertical(4), ), ButtonSize.small( - box.padding.horizontal(12), - box.padding.vertical(6), + $box.padding.horizontal(12), + $box.padding.vertical(6), ), ButtonSize.medium( - box.padding.horizontal(16), - box.padding.vertical(8), + $box.padding.horizontal(16), + $box.padding.vertical(8), ), ButtonSize.large( - box.padding.horizontal(20), - box.padding.vertical(10), + $box.padding.horizontal(20), + $box.padding.vertical(10), ), ButtonType.primary( - box.color.black(), - onHover( - box.color.black87(), + $box.color.black(), + $on.hover( + $box.color.black87(), ), ), ButtonType.secondary( - box.color.grey.shade200(), - onHover( - box.color.grey.shade100(), + $box.color.grey.shade200(), + $on.hover( + $box.color.grey.shade100(), ), ), ButtonType.destructive( - box.color.redAccent(), - onHover( - box.color.redAccent.shade200(), + $box.color.redAccent(), + $on.hover( + $box.color.redAccent.shade200(), ), ), ButtonType.outline( - box.color.white(), - box.border.width(1.5), - box.border.color.black12(), - box.shadow.color(Colors.black12.withOpacity(0.1)), - box.shadow.blurRadius(1), + $box.color.white(), + $box.border.width(1.5), + $box.border.color.black12(), + $box.shadow.color(Colors.black12.withOpacity(0.1)), + $box.shadow.blurRadius(1), ), ButtonType.ghost( - box.color.transparent(), - onHover( - box.color.black12(), + $box.color.transparent(), + $on.hover( + $box.color.black12(), ), ), ButtonType.link( - box.color.transparent(), + $box.color.transparent(), ), - box.borderRadius(6), + $box.borderRadius(6), ); Style _icon() => Style( ButtonSize.xsmall( - icon.size(12), + $icon.size(12), ), ButtonSize.small( - icon.size(14), + $icon.size(14), ), ButtonSize.medium( - icon.size(16), + $icon.size(16), ), ButtonSize.large( - icon.size(18), + $icon.size(18), ), (ButtonType.primary | ButtonType.destructive)( - icon.color(Colors.white), + $icon.color(Colors.white), ), (ButtonType.link | ButtonType.secondary | ButtonType.outline)( - icon.color(Colors.black), + $icon.color(Colors.black), ), ); Style _label() => Style( - text.style.height(1.1), - text.style.letterSpacing(0.5), - text.style.fontWeight(FontWeight.w600), + $text.style.height(1.1), + $text.style.letterSpacing(0.5), + $text.style.fontWeight(FontWeight.w600), ButtonSize.xsmall( - text.style.fontSize(12), + $text.style.fontSize(12), ), ButtonSize.small( - text.style.fontSize(14), + $text.style.fontSize(14), ), ButtonSize.medium( - text.style.fontSize(16), + $text.style.fontSize(16), ), ButtonSize.large( - text.style.fontSize(18), + $text.style.fontSize(18), ), ButtonType.primary( - text.style.color.white(), + $text.style.color.white(), ), ButtonType.secondary( - text.style.color.black87(), + $text.style.color.black87(), ), ButtonType.destructive( - text.style.color.white(), + $text.style.color.white(), ), ButtonType.outline( - text.style.color.black(), + $text.style.color.black(), ), ButtonType.ghost( - text.style.color.black(), + $text.style.color.black(), ), ButtonType.link( - text.style.color.black(), - onHover( - text.style.decoration(TextDecoration.underline), + $text.style.color.black(), + $on.hover( + $text.style.decoration(TextDecoration.underline), ), ), ); diff --git a/lib/components/card/card.style.dart b/lib/components/card/card.style.dart index 4d3ee05..91c1e9c 100644 --- a/lib/components/card/card.style.dart +++ b/lib/components/card/card.style.dart @@ -39,8 +39,8 @@ class RemixCardStyle extends StyleRecipe { } Style _container() => Style( - box.padding(16), - box.elevation(1), - box.borderRadius(8), - box.color.white(), + $box.padding(16), + $box.elevation(1), + $box.borderRadius(8), + $box.color.white(), ); diff --git a/lib/components/checkbox/checkbox.dart b/lib/components/checkbox/checkbox.dart index f3a89b7..7312ebb 100644 --- a/lib/components/checkbox/checkbox.dart +++ b/lib/components/checkbox/checkbox.dart @@ -1,71 +1,123 @@ import 'package:flutter/material.dart'; import 'package:mix/mix.dart'; -import 'package:remix_ui/components/checkbox/checkbox.style.dart'; + import 'package:remix_ui/components/checkbox/checkbox.variants.dart'; +import 'package:remix_ui/components/checkbox/tokens/checkbox_attr.dart'; + +import 'tokens/checkbox_spec.dart'; +import 'tokens/checkbox_util.dart'; + +const kNoAnimation = + AnimatedData(duration: Duration.zero, curve: Curves.linear); + +AnimatedStyle $defaultCheckboxStyle() { + final checkbox = CheckboxSpecUtility((value) => CheckboxSpecAttribute( + flexContainer: value.flexContainer, + innerContainer: value.innerContainer, + icon: value.icon, + label: value.label, + )); -import '../../utils/component_recipe.dart'; + return Style( + // Flex Container + checkbox.flexContainer.mainAxisAlignment.center(), + checkbox.flexContainer.crossAxisAlignment.center(), + checkbox.flexContainer.mainAxisSize.min(), + checkbox.flexContainer.gap(6), + // Inner Container + checkbox.innerContainer.borderRadius.all(7), + checkbox.innerContainer.width(20), + checkbox.innerContainer.height(20), + checkbox.innerContainer.border( + color: const Color.fromARGB(115, 3, 3, 3), + width: 1.5, + ), + // Label + checkbox.label.style.fontSize(16), + checkbox.label.style.color.black87(), + checkbox.icon.color.white(), -class RemixCheckbox extends StatelessWidget - implements RemixComponentRecipe { - const RemixCheckbox({ + // Checked + CheckboxState.checked( + // Inner Container + checkbox.innerContainer.color.black87(), + // Icon + checkbox.icon.color.white(), + checkbox.icon.size(15), + // Label + checkbox.label.style.fontSize(16), + checkbox.label.style.bold(), + checkbox.label.style.color.black87(), + ), + ).animate( + curve: Curves.easeInOut, + duration: const Duration(milliseconds: 200), + ); +} + +class RemixCheckbox extends StatelessWidget { + RemixCheckbox({ super.key, this.label, this.disabled = false, - this.checked = false, + this.value = false, this.onChanged, this.iconChecked = Icons.check_rounded, this.iconUnchecked, - this.style, + Style? style, this.variants = const [], - }); + }) : style = style ?? $defaultCheckboxStyle(); final String? label; final bool disabled; - final bool checked; + final bool value; final IconData iconChecked; final IconData? iconUnchecked; final ValueChanged? onChanged; - @override - final RemixCheckboxStyle? style; + final Style style; - @override final List variants; - RemixCheckboxStyle buildStyle(List variants) { - final result = style == null ? RemixCheckboxStyle.base() : style!; - - return result.applyVariants(variants); - } - @override Widget build(BuildContext context) { - var internalVariants = - checked ? CheckboxState.checked : CheckboxState.unchecked; - - final style = buildStyle([internalVariants, ...variants]); + return SpecBuilder( + style: style.applyVariant( + value ? CheckboxState.checked : CheckboxState.unchecked, + ), + builder: (context) { + final spec = CheckboxSpec.of(context); + final mix = MixProvider.of(context); + final animationData = mix.animation ?? kNoAnimation; - return Pressable( - onPressed: - onChanged == null || disabled ? null : () => onChanged!(!checked), - child: HBox( - style: style.flexContainer, - children: [ - AnimatedBox( - style: style.innerContainer, - duration: const Duration(milliseconds: 150), - child: StyledIcon( - checked ? iconChecked : iconUnchecked, - style: style.icon, - ), + return Pressable( + onPress: + onChanged == null || disabled ? null : () => onChanged!(!value), + child: FlexSpecWidget( + spec: spec.flexContainer, + direction: Axis.horizontal, + children: [ + AnimatedBoxSpecWidget( + spec: spec.innerContainer, + duration: animationData.duration, + child: AnimatedIconSpecWidget( + icon: value ? iconChecked : iconUnchecked, + spec: spec.icon, + duration: animationData.duration, + curve: animationData.curve, + ), + ), + if (label != null) + AnimatedTextSpecWidget( + label!, + spec: spec.label, + duration: animationData.duration, + curve: animationData.curve, + ), + ], ), - if (label != null) - StyledText( - label!, - style: style.label, - ), - ], - ), + ); + }, ); } } diff --git a/lib/components/checkbox/checkbox.style.dart b/lib/components/checkbox/checkbox.style.dart deleted file mode 100644 index ec356a7..0000000 --- a/lib/components/checkbox/checkbox.style.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:mix/mix.dart'; -import 'package:remix_ui/components/checkbox/checkbox.variants.dart'; - -class RemixCheckboxStyle extends StyleRecipe { - const RemixCheckboxStyle({ - required this.flexContainer, - required this.innerContainer, - required this.icon, - required this.label, - }); - - final Style flexContainer; - final Style innerContainer; - final Style icon; - final Style label; - - factory RemixCheckboxStyle.base() { - return RemixCheckboxStyle( - flexContainer: _flexContainerStyle(), - innerContainer: _innerContainerStyle(), - icon: _iconStyle(), - label: _labelStyle(), - ); - } - - @override - RemixCheckboxStyle applyVariants(List variants) { - return RemixCheckboxStyle( - flexContainer: flexContainer.applyVariants(variants), - innerContainer: innerContainer.applyVariants(variants), - icon: icon.applyVariants(variants), - label: label.applyVariants(variants), - ); - } - - @override - RemixCheckboxStyle copyWith({ - Style? flexContainer, - Style? innerContainer, - Style? icon, - Style? label, - }) { - return RemixCheckboxStyle( - innerContainer: this.innerContainer.merge(innerContainer), - icon: this.icon.merge(icon), - label: this.label.merge(label), - flexContainer: this.flexContainer.merge(flexContainer), - ); - } - - @override - RemixCheckboxStyle merge(RemixCheckboxStyle? other) { - return copyWith( - flexContainer: other?.flexContainer, - innerContainer: other?.innerContainer, - icon: other?.icon, - label: other?.label, - ); - } -} - -Style _flexContainerStyle() => Style( - flex.mainAxisAlignment.center(), - flex.crossAxisAlignment.center(), - flex.mainAxisSize.min(), - flex.gap(6), - ); - -Style _innerContainerStyle() => Style( - box.borderRadius.all(7), - width(20), - height(20), - border(color: const Color.fromARGB(115, 3, 3, 3), width: 1.5), - CheckboxState.checked( - backgroundColor(Colors.black87), - ), - ); - -Style _iconStyle() => Style( - CheckboxState.checked( - icon.color.white(), - icon.size(15), - ), - ); - -Style _labelStyle() => Style( - text.style.fontSize(16), - text.style.bold(), - text.style.color.black87(), - ); diff --git a/lib/components/checkbox/tokens/checkbox_attr.dart b/lib/components/checkbox/tokens/checkbox_attr.dart new file mode 100644 index 0000000..7874855 --- /dev/null +++ b/lib/components/checkbox/tokens/checkbox_attr.dart @@ -0,0 +1,44 @@ +import 'package:mix/mix.dart'; +import 'package:remix_ui/components/checkbox/tokens/checkbox_spec.dart'; + +class CheckboxSpecAttribute extends SpecAttribute { + const CheckboxSpecAttribute({ + this.flexContainer = const FlexSpecAttribute(), + this.innerContainer = const BoxSpecAttribute(), + this.icon = const IconSpecAttribute(), + this.label = const TextSpecAttribute(), + }); + + final FlexSpecAttribute flexContainer; + final BoxSpecAttribute innerContainer; + final IconSpecAttribute icon; + final TextSpecAttribute label; + + @override + CheckboxSpecAttribute merge(covariant CheckboxSpecAttribute? other) { + return CheckboxSpecAttribute( + flexContainer: flexContainer.merge(other?.flexContainer), + innerContainer: innerContainer.merge(other?.innerContainer), + icon: icon.merge(other?.icon), + label: label.merge(other?.label), + ); + } + + @override + List get props => [ + flexContainer, + innerContainer, + icon, + label, + ]; + + @override + CheckboxSpec resolve(MixData mix) { + return CheckboxSpec( + flexContainer: flexContainer.resolve(mix), + innerContainer: innerContainer.resolve(mix), + icon: icon.resolve(mix), + label: label.resolve(mix), + ); + } +} diff --git a/lib/components/checkbox/tokens/checkbox_spec.dart b/lib/components/checkbox/tokens/checkbox_spec.dart new file mode 100644 index 0000000..915443d --- /dev/null +++ b/lib/components/checkbox/tokens/checkbox_spec.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:mix/mix.dart'; +import 'package:remix_ui/components/checkbox/tokens/checkbox_attr.dart'; + +class CheckboxSpec extends Spec { + final FlexSpec flexContainer; + final BoxSpec innerContainer; + final IconSpec icon; + final TextSpec label; + + const CheckboxSpec({ + required this.flexContainer, + required this.innerContainer, + required this.icon, + required this.label, + }); + + const CheckboxSpec.empty() + : flexContainer = const FlexSpec.empty(), + innerContainer = const BoxSpec.empty(), + icon = const IconSpec.empty(), + label = const TextSpec.empty(); + + @override + CheckboxSpec copyWith({ + FlexSpec? flexContainer, + BoxSpec? innerContainer, + IconSpec? icon, + TextSpec? label, + }) { + return CheckboxSpec( + flexContainer: flexContainer ?? this.flexContainer, + innerContainer: innerContainer ?? this.innerContainer, + icon: icon ?? this.icon, + label: label ?? this.label, + ); + } + + static CheckboxSpec of(BuildContext context) { + final mix = MixProvider.of(context); + + return mix.attributeOf()?.resolve(mix) ?? + const CheckboxSpec.empty(); + } + + @override + CheckboxSpec lerp(CheckboxSpec other, double t) { + return CheckboxSpec( + flexContainer: flexContainer.lerp(other.flexContainer, t), + innerContainer: innerContainer.lerp(other.innerContainer, t), + icon: icon.lerp(other.icon, t), + label: label.lerp(other.label, t), + ); + } + + @override + List get props => [ + flexContainer, + innerContainer, + icon, + label, + ]; +} diff --git a/lib/components/checkbox/tokens/checkbox_util.dart b/lib/components/checkbox/tokens/checkbox_util.dart new file mode 100644 index 0000000..714d856 --- /dev/null +++ b/lib/components/checkbox/tokens/checkbox_util.dart @@ -0,0 +1,41 @@ +import 'package:mix/mix.dart'; + +import 'checkbox_attr.dart'; + +class CheckboxSpecUtility + extends SpecUtility { + CheckboxSpecUtility(super.builder); + + BoxSpecUtility get innerContainer => BoxSpecUtility( + (innerContainer) => only(innerContainer: innerContainer), + ); + + FlexSpecUtility get flexContainer => FlexSpecUtility( + (flexContainer) => only(flexContainer: flexContainer), + ); + + IconSpecUtility get icon => IconSpecUtility( + (icon) => only(icon: icon), + ); + + TextSpecUtility get label => TextSpecUtility( + (label) => only(label: label), + ); + + @override + T only({ + FlexSpecAttribute flexContainer = const FlexSpecAttribute(), + BoxSpecAttribute innerContainer = const BoxSpecAttribute(), + IconSpecAttribute icon = const IconSpecAttribute(), + TextSpecAttribute label = const TextSpecAttribute(), + }) { + return builder( + CheckboxSpecAttribute( + flexContainer: flexContainer, + innerContainer: innerContainer, + icon: icon, + label: label, + ), + ); + } +} diff --git a/lib/components/divider/divider.style.dart b/lib/components/divider/divider.style.dart index 33c04cb..dd07fe1 100644 --- a/lib/components/divider/divider.style.dart +++ b/lib/components/divider/divider.style.dart @@ -38,8 +38,8 @@ class RemixDividerStyle extends StyleRecipe { } Style _container() => Style( - box.margin.vertical(15), - box.height(2), - box.borderRadius(1), - box.color.grey.shade200(), + $box.margin.vertical(15), + $box.height(2), + $box.borderRadius(1), + $box.color.grey.shade200(), ); diff --git a/lib/components/list_tile/list_tile.style.dart b/lib/components/list_tile/list_tile.style.dart index 430e841..a5d1a24 100644 --- a/lib/components/list_tile/list_tile.style.dart +++ b/lib/components/list_tile/list_tile.style.dart @@ -60,25 +60,25 @@ class RemixListTileStyle extends StyleRecipe { } Style _outerRowContainer() => Style( - flex.gap(16), + $flex.gap(16), ); Style _innerColumnContainer() => Style( - flex.mainAxisAlignment.center(), - flex.mainAxisSize.min(), - flex.crossAxisAlignment.start(), - flex.gap(4), + $flex.mainAxisAlignment.center(), + $flex.mainAxisSize.min(), + $flex.crossAxisAlignment.start(), + $flex.gap(4), ); -Style _title() => Style.text( - text.style.fontSize(14), - text.style.fontWeight.w600(), - text.style.color.black(), +Style _title() => Style( + $text.style.fontSize(14), + $text.style.fontWeight.w600(), + $text.style.color.black(), ); -Style _subtitle() => Style.text( - text.style.fontSize(14), - text.style.fontWeight.normal(), - text.style.color.grey(), - text.maxLines(2), +Style _subtitle() => Style( + $text.style.fontSize(14), + $text.style.fontWeight.normal(), + $text.style.color.grey(), + $text.maxLines(2), ); diff --git a/lib/components/radio/radio.dart b/lib/components/radio/radio.dart index 0ebc191..fd40794 100644 --- a/lib/components/radio/radio.dart +++ b/lib/components/radio/radio.dart @@ -50,10 +50,8 @@ class RemixRadio extends StatelessWidget children: [ Box( style: style.outerContainer, - child: AnimatedBox( + child: Box( style: style.innerContainer, - duration: const Duration(milliseconds: 150), - curve: Curves.bounceInOut, ), ), if (label != null) diff --git a/lib/components/radio/radio.style.dart b/lib/components/radio/radio.style.dart index cdbfa4c..a8f2e5a 100644 --- a/lib/components/radio/radio.style.dart +++ b/lib/components/radio/radio.style.dart @@ -62,36 +62,36 @@ class RemixRadioStyle extends StyleRecipe { } Style _outerContainerStyle() => Style( - box.width(16), - box.height(16), - box.alignment.center(), - box.borderRadius.all(10), - box.color.transparent(), - box.border.all(width: 1.5, color: Colors.black87), + $box.width(16), + $box.height(16), + $box.alignment.center(), + $box.borderRadius.all(10), + $box.color.transparent(), + $box.border.all(width: 1.5, color: Colors.black87), ); Style _innerContainerStyle() => Style( - box.borderRadius.all(10), - box.color.black87(), + $box.borderRadius.all(10), + $box.color.black87(), RadioState.active( - box.width(8.5), - box.height(8.5), + $box.width(8.5), + $box.height(8.5), ), RadioState.inactive( - box.width(0), - box.height(0), + $box.width(0), + $box.height(0), ), ); Style _labelStyle() => Style( - text.style.fontSize(16), - text.style.bold(), - text.style.color.black87(), + $text.style.fontSize(16), + $text.style.bold(), + $text.style.color.black87(), ); Style _hboxStyle() => Style( - flex.mainAxisAlignment.center(), - flex.crossAxisAlignment.center(), - flex.mainAxisSize.min(), - flex.gap(6), + $flex.mainAxisAlignment.center(), + $flex.crossAxisAlignment.center(), + $flex.mainAxisSize.min(), + $flex.gap(6), ); diff --git a/lib/components/switch/switch.style.dart b/lib/components/switch/switch.style.dart index 92d6ff9..bdb1db3 100644 --- a/lib/components/switch/switch.style.dart +++ b/lib/components/switch/switch.style.dart @@ -48,26 +48,26 @@ class RemixSwitchStyle extends StyleRecipe { } Style _outerFlexContainerStyle() => Style( - box.width(32), - box.height(16), + $box.width(32), + $box.height(16), border.width(2), border.strokeAlign(BorderSide.strokeAlignOutside), - box.borderRadius(20), + $box.borderRadius(20), SwitchState.active( - box.color.black(), + $box.color.black(), border.color.black(), - box.alignment.centerRight(), + $box.alignment.centerRight(), ), SwitchState.inactive( - box.alignment.centerLeft(), - box.color.grey.shade300(), + $box.alignment.centerLeft(), + $box.color.grey.shade300(), border.color.grey.shade300(), ), ); Style _innerContainerStyle() => Style( - box.borderRadius(10), + $box.borderRadius(10), width(16), height(16), - box.color.white(), + $box.color.white(), ); diff --git a/lib/remix_ui.dart b/lib/remix_ui.dart index e12baf5..4386a29 100644 --- a/lib/remix_ui.dart +++ b/lib/remix_ui.dart @@ -6,7 +6,6 @@ export 'components/button/button.dart'; export 'components/button/button.style.dart'; export 'components/button/button.variants.dart'; export 'components/checkbox/checkbox.dart'; -export 'components/checkbox/checkbox.style.dart'; export 'components/checkbox/checkbox.variants.dart'; export 'components/radio/radio.dart'; export 'components/radio/radio.style.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index a1520d5..2b1ceb3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ environment: dependencies: flutter: sdk: flutter - mix: 1.0.0-beta.8 + mix: ^0.9.0 cupertino_icons: ^1.0.2 flutter_hooks: ^0.18.4 diff --git a/test/components/checkbox_test.dart b/test/components/checkbox_test.dart index c2fa04f..0cad07c 100644 --- a/test/components/checkbox_test.dart +++ b/test/components/checkbox_test.dart @@ -12,7 +12,7 @@ void main() { await tester.pumpWidget( MaterialApp( home: RemixCheckbox( - checked: isChecked, + value: isChecked, label: 'Checkbox', onChanged: (value) { expect(value, !isChecked); @@ -32,7 +32,7 @@ void main() { await tester.pumpWidget(MaterialApp( home: Scaffold( body: RemixCheckbox( - checked: false, + value: false, disabled: true, onChanged: (value) { didCallOnChanged = true; @@ -52,7 +52,7 @@ void main() { for (var isChecked in [true, false]) { await tester.pumpWidget(MaterialApp( home: RemixCheckbox( - checked: isChecked, + value: isChecked, label: 'Checkbox', onChanged: (value) {}, ), @@ -60,7 +60,7 @@ void main() { expect( find.byWidgetPredicate( - (widget) => widget is RemixCheckbox && widget.checked == isChecked, + (widget) => widget is RemixCheckbox && widget.value == isChecked, ), findsOneWidget, ); @@ -72,7 +72,7 @@ void main() { await tester.pumpWidget(MaterialApp( home: RemixCheckbox( - checked: false, + value: false, label: label, onChanged: (value) {}, ), @@ -94,7 +94,7 @@ void main() { for (var isChecked in [true, false]) { await tester.pumpWidget(MaterialApp( home: RemixCheckbox( - checked: isChecked, + value: isChecked, iconChecked: iconChecked, iconUnchecked: iconUnchecked, label: 'Checkbox',