From 339a822c83e687eb1dc1ec523aaaf5c5580ad01e Mon Sep 17 00:00:00 2001 From: Lucas Oliveira <62367544+tilucasoli@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:33:25 -0300 Subject: [PATCH 1/2] feat: Improve spring curve --- .../mix/lib/src/attributes/scalars/curves.dart | 18 +++++++++++++++++- .../src/attributes/scalars/scalar_util.dart | 13 ++++++++++--- .../components/accordion/accordion_theme.dart | 13 +++++++------ .../remix/lib/src/components/card/card.dart | 7 ++----- .../lib/src/components/card/card_widget.dart | 10 ++-------- .../lib/src/components/dialog/dialog.dart | 7 +++++-- .../src/components/select/select_theme.dart | 10 +++++----- .../src/components/switch/switch_style.dart | 11 +++++++++-- .../src/components/switch/switch_widget.dart | 11 +---------- .../lib/src/components/toast/toast_layer.dart | 2 +- 10 files changed, 59 insertions(+), 43 deletions(-) diff --git a/packages/mix/lib/src/attributes/scalars/curves.dart b/packages/mix/lib/src/attributes/scalars/curves.dart index 9a1ebb5af..16717af43 100644 --- a/packages/mix/lib/src/attributes/scalars/curves.dart +++ b/packages/mix/lib/src/attributes/scalars/curves.dart @@ -7,7 +7,7 @@ class SpringCurve extends Curve { late final SpringSimulation _sim; late final double _val; - SpringCurve({required Duration duration, double bounce = 0.0}) { + SpringCurve.durationBased({required Duration duration, double bounce = 0.0}) { assert( (bounce >= -1.0 && bounce <= 1.0), '"bounce" value must be between -1.0 and 1.0.', @@ -28,6 +28,22 @@ class SpringCurve extends Curve { _val = (1 - _sim.x(1.0)); } + SpringCurve({ + double stiffness = 3.5, + double dampingRatio = 1.0, + double mass = 1.0, + }) { + final SpringDescription desc = SpringDescription.withDampingRatio( + mass: mass, + stiffness: stiffness, + ratio: dampingRatio, + ); + + _sim = SpringSimulation(desc, 0.0, 1.0, 0.0); + + _val = (1 - _sim.x(1.0)); + } + @override double transform(double t) => _sim.x(t) + t * _val; } diff --git a/packages/mix/lib/src/attributes/scalars/scalar_util.dart b/packages/mix/lib/src/attributes/scalars/scalar_util.dart index ba59cb069..bc1dbba51 100644 --- a/packages/mix/lib/src/attributes/scalars/scalar_util.dart +++ b/packages/mix/lib/src/attributes/scalars/scalar_util.dart @@ -90,10 +90,17 @@ final class CurveUtility extends MixUtility T as(Curve curve) => builder(curve); T spring({ - Duration duration = const Duration(milliseconds: 500), - double bounce = 0.5, + double stiffness = 3.5, + double dampingRatio = 1.0, + double mass = 1.0, }) => - builder(SpringCurve(duration: duration, bounce: bounce)); + builder( + SpringCurve( + stiffness: stiffness, + dampingRatio: dampingRatio, + mass: mass, + ), + ); } @MixableClassUtility(generateCallMethod: false) diff --git a/packages/remix/lib/src/components/accordion/accordion_theme.dart b/packages/remix/lib/src/components/accordion/accordion_theme.dart index 038b1ddeb..51d474c20 100644 --- a/packages/remix/lib/src/components/accordion/accordion_theme.dart +++ b/packages/remix/lib/src/components/accordion/accordion_theme.dart @@ -28,12 +28,16 @@ class FortalezaAccordionStyle extends AccordionStyle { ..text.style.fontWeight.w400() ..text.style.color.$neutral(12) ..trailingIcon.color.$neutral(10) - ..container.color.$neutral(1), + ..container.color.$neutral(1) + ..container.animated.curve.easeInCubic() + ..container.animated.duration(const Duration(milliseconds: 100)), $.contentContainer.chain ..padding.all.$space(3) ..border.style.none() - ..border.top.color.$neutral(6), + ..border.top.color.$neutral(6) + ..animated.curve.spring(stiffness: 100) + ..animated.duration(const Duration(milliseconds: 250)), // Text Container $.textContent.chain @@ -48,9 +52,6 @@ class FortalezaAccordionStyle extends AccordionStyle { ), ); - return Style.create([baseStyle(), style()]).animate( - duration: const Duration(milliseconds: 100), - curve: Curves.easeInOut, - ); + return Style.create([baseStyle(), style()]); } } diff --git a/packages/remix/lib/src/components/card/card.dart b/packages/remix/lib/src/components/card/card.dart index eab016e73..b2641801a 100644 --- a/packages/remix/lib/src/components/card/card.dart +++ b/packages/remix/lib/src/components/card/card.dart @@ -21,11 +21,8 @@ base class CardSpec extends Spec with _$CardSpec, Diagnosticable { static const from = _$CardSpec.from; - const CardSpec({ - BoxSpec? container, - super.modifiers, - super.animated, - }) : container = container ?? const BoxSpec(); + const CardSpec({BoxSpec? container, super.modifiers, super.animated}) + : container = container ?? const BoxSpec(); Widget call({Key? key, required Widget child}) { return CardSpecWidget(key: key, spec: this, child: child); diff --git a/packages/remix/lib/src/components/card/card_widget.dart b/packages/remix/lib/src/components/card/card_widget.dart index e81458991..cab52786a 100644 --- a/packages/remix/lib/src/components/card/card_widget.dart +++ b/packages/remix/lib/src/components/card/card_widget.dart @@ -35,19 +35,13 @@ class Card extends StatelessWidget { } class CardSpecWidget extends StatelessWidget { - const CardSpecWidget({ - super.key, - required this.spec, - required this.child, - }); + const CardSpecWidget({super.key, required this.spec, required this.child}); final CardSpec? spec; final Widget child; @override Widget build(BuildContext context) { - return spec!.container( - child: child, - ); + return spec!.container(child: child); } } diff --git a/packages/remix/lib/src/components/dialog/dialog.dart b/packages/remix/lib/src/components/dialog/dialog.dart index fb99ec854..47a80ec92 100644 --- a/packages/remix/lib/src/components/dialog/dialog.dart +++ b/packages/remix/lib/src/components/dialog/dialog.dart @@ -29,13 +29,16 @@ Future showDialog({ transitionBuilder ??= (context, animation, secondaryAnimation, child) { final curvedAnimation = CurvedAnimation( parent: animation, - curve: Curves.easeInOut, + curve: SpringCurve.durationBased( + duration: transitionDuration, + bounce: 0.2, + ), ); return FadeTransition( opacity: curvedAnimation, child: ScaleTransition( - scale: curvedAnimation.drive(Tween(begin: 0.85, end: 1)), + scale: curvedAnimation.drive(Tween(begin: 0.7, end: 1)), child: child, ), ); diff --git a/packages/remix/lib/src/components/select/select_theme.dart b/packages/remix/lib/src/components/select/select_theme.dart index 0834ebb55..8f87b085b 100644 --- a/packages/remix/lib/src/components/select/select_theme.dart +++ b/packages/remix/lib/src/components/select/select_theme.dart @@ -16,17 +16,17 @@ class FortalezaSelectStyle extends SelectStyle { final baseThemeOverrides = Style( $.menu.autoWidth.off(), - $.item.container.padding.horizontal.$space(3), - $.button.icon.color.$accentAlpha(12), $.menu.container.chain ..color.$neutral(1) ..border.all.color.$neutral(5) ..wrap.intrinsicWidth() ..elevation.e2() ..padding.all.$space(2), - $.button.flex.chain - ..gap.$space(1) - ..mainAxisSize.min(), + $.button.chain + ..icon.color.$accentAlpha(12) + ..flex.gap.$space(1) + ..flex.mainAxisSize.min(), + $.item.container.padding.horizontal.$space(3), spec.on.disabled( $.button.chain ..container.color.$neutral(2) diff --git a/packages/remix/lib/src/components/switch/switch_style.dart b/packages/remix/lib/src/components/switch/switch_style.dart index 1f935a463..e0aa6e31e 100644 --- a/packages/remix/lib/src/components/switch/switch_style.dart +++ b/packages/remix/lib/src/components/switch/switch_style.dart @@ -14,7 +14,9 @@ class SwitchStyle extends SpecStyle { ..borderRadius(99) ..padding.all(2) ..alignment.centerLeft() - ..color.grey.shade300(), + ..color.grey.shade300() + ..animated.curve.spring(stiffness: 100, dampingRatio: 1) + ..animated.duration(const Duration(milliseconds: 300)), spec.on.selected( $.container.chain ..alignment.centerRight() @@ -25,13 +27,18 @@ class SwitchStyle extends SpecStyle { final indicatorStyle = [ $.indicator.chain + ..wrap.align(alignment: Alignment.centerLeft) ..color.white() ..shape.circle() ..width(20) ..shadow.color.black12() ..shadow.offset(0, 2) ..shadow.blurRadius(4) - ..shadow.spreadRadius(1), + ..shadow.spreadRadius(1) + ..animated.curve.spring(stiffness: 100, dampingRatio: 0.7) + ..animated.duration(const Duration(milliseconds: 300)), + spec.on + .selected($.indicator.wrap.align(alignment: Alignment.centerRight)), spec.on.disabled($.indicator.color.grey.shade100()), ]; diff --git a/packages/remix/lib/src/components/switch/switch_widget.dart b/packages/remix/lib/src/components/switch/switch_widget.dart index fa6b28c59..86de7ff22 100644 --- a/packages/remix/lib/src/components/switch/switch_widget.dart +++ b/packages/remix/lib/src/components/switch/switch_widget.dart @@ -63,16 +63,7 @@ class _SwitchState extends State { onPress: widget.disabled ? null : _handleOnPress, controller: _controller, child: SpecBuilder( - style: style - .makeStyle(configuration) - .applyVariants(widget.variants) - .animate( - duration: const Duration(milliseconds: 400), - curve: SpringCurve( - duration: const Duration(milliseconds: 400), - bounce: 0.4, - ), - ), + style: style.makeStyle(configuration).applyVariants(widget.variants), builder: (context) { final spec = SwitchSpec.of(context); diff --git a/packages/remix/lib/src/components/toast/toast_layer.dart b/packages/remix/lib/src/components/toast/toast_layer.dart index 5b2d858fe..ebe58804a 100644 --- a/packages/remix/lib/src/components/toast/toast_layer.dart +++ b/packages/remix/lib/src/components/toast/toast_layer.dart @@ -71,7 +71,7 @@ class ToastLayerState extends State implements ToastActions { reverseDuration: toast?.reverseAnimationDuration ?? const Duration(milliseconds: 200), switchInCurve: toast?.animationCurve ?? - SpringCurve( + SpringCurve.durationBased( duration: const Duration(milliseconds: 500), bounce: 0.2, ), From e263b4726bc48e50415afe734e176a224549af77 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira <62367544+tilucasoli@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:34:28 -0300 Subject: [PATCH 2/2] feat: Add Dark Theme --- .../demo/lib/components/select_use_case.dart | 35 +++++++++-------- .../components/accordion/accordion_style.dart | 8 ++-- .../lib/src/components/chip/chip_style.dart | 38 +++++++++++++++++-- .../lib/src/components/chip/chip_theme.dart | 2 +- .../src/components/dialog/dialog_style.dart | 21 ++++++++++ .../src/components/divider/divider_style.dart | 16 +++++++- .../lib/src/components/radio/radio_style.dart | 1 + packages/remix/lib/src/theme/remix_theme.dart | 3 ++ 8 files changed, 100 insertions(+), 24 deletions(-) diff --git a/packages/remix/demo/lib/components/select_use_case.dart b/packages/remix/demo/lib/components/select_use_case.dart index 94333ac40..428d29b45 100644 --- a/packages/remix/demo/lib/components/select_use_case.dart +++ b/packages/remix/demo/lib/components/select_use_case.dart @@ -37,22 +37,25 @@ class _SelectDemoState extends State { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Select( - disabled: - context.knobs.boolean(label: 'disabled', initialValue: false), - variants: [context.knobs.variant(FortalezaSelectStyle.variants)], - value: selectedValue, - onChanged: (value) => setState(() => selectedValue = value), - button: (spec) => spec( - text: selectedValue, - trailingIcon: m.Icons.keyboard_arrow_down_rounded, - ), - items: List.generate( - items.length, - (index) => SelectMenuItem( - value: items[index], - child: XSelectMenuItemWidget( - text: items[index], + SizedBox( + width: 200, + child: Select( + disabled: + context.knobs.boolean(label: 'disabled', initialValue: false), + variants: [context.knobs.variant(FortalezaSelectStyle.variants)], + value: selectedValue, + onChanged: (value) => setState(() => selectedValue = value), + button: (spec) => spec( + text: selectedValue, + trailingIcon: m.Icons.keyboard_arrow_down_rounded, + ), + items: List.generate( + items.length, + (index) => SelectMenuItem( + value: items[index], + child: XSelectMenuItemWidget( + text: items[index], + ), ), ), ), diff --git a/packages/remix/lib/src/components/accordion/accordion_style.dart b/packages/remix/lib/src/components/accordion/accordion_style.dart index 87362592c..a4f059581 100644 --- a/packages/remix/lib/src/components/accordion/accordion_style.dart +++ b/packages/remix/lib/src/components/accordion/accordion_style.dart @@ -12,8 +12,7 @@ class AccordionStyle extends SpecStyle { final containerStyle = [ $.container.chain ..clipBehavior.antiAlias() - ..border.bottom.color.black() - ..border.bottom.color.withOpacity(0.2), + ..border.bottom.color.grey.shade400(), ]; final contentStyle = [ @@ -70,7 +69,10 @@ class AccordionDarkStyle extends AccordionStyle { return Style.create([ super.makeStyle(spec).call(), - $.container.border.bottom.color.white(), + $.container.border.bottom.color.grey.shade700(), + $.header.text.style.color.white(), + $.header.trailingIcon.color.white(), + $.textContent.style.color.white(), ]); } } diff --git a/packages/remix/lib/src/components/chip/chip_style.dart b/packages/remix/lib/src/components/chip/chip_style.dart index 858a21bcd..2b33f4832 100644 --- a/packages/remix/lib/src/components/chip/chip_style.dart +++ b/packages/remix/lib/src/components/chip/chip_style.dart @@ -40,11 +40,14 @@ class ChipStyle extends SpecStyle { ..borderRadius(6) ..color.white() ..border.all.width(1) - ..border.color.grey.shade300() + ..border.color.grey.shade200() ..padding.vertical(8) ..padding.horizontal(12), - spec.on.disabled($.container.color.grey.shade400()), - spec.on.selected($.container.color.grey.shade100()), + spec.on.selected($.container.color.grey.shade200()), + spec.on.disabled( + $.label.style.color.grey.shade800(), + spec.on.selected($.container.color.grey.shade300()), + ), ]; return Style.create([ @@ -55,3 +58,32 @@ class ChipStyle extends SpecStyle { ]); } } + +class ChipDarkStyle extends ChipStyle { + const ChipDarkStyle(); + + @override + Style makeStyle(SpecConfiguration spec) { + final $ = spec.utilities; + + final containerStyle = [ + $.container.chain + ..border.all.color.grey.shade900() + ..color.black(), + spec.on.selected($.container.color.grey.shade900()), + spec.on.disabled( + $.label.style.color.grey.shade600(), + $.container.color.black(), + spec.on.selected($.container.color.grey.shade900()), + ), + ]; + + final labelStyle = $.label.chain..style.color.white(); + + return Style.create([ + super.makeStyle(spec).call(), + ...containerStyle, + labelStyle, + ]); + } +} diff --git a/packages/remix/lib/src/components/chip/chip_theme.dart b/packages/remix/lib/src/components/chip/chip_theme.dart index 460fd81d4..debd7c299 100644 --- a/packages/remix/lib/src/components/chip/chip_theme.dart +++ b/packages/remix/lib/src/components/chip/chip_theme.dart @@ -51,7 +51,7 @@ class FortalezaChipStyle extends ChipStyle { ..padding.horizontal(12), (spec.on.hover & spec.on.unselected)($.container.color.$accent(3)), spec.on.selected($.container.color.$accent(4)), - (spec.on.disabled)( + spec.on.disabled( $.container.color.$neutral(2), $.icon.color.$neutral(8), ), diff --git a/packages/remix/lib/src/components/dialog/dialog_style.dart b/packages/remix/lib/src/components/dialog/dialog_style.dart index b9a064224..4d93b6543 100644 --- a/packages/remix/lib/src/components/dialog/dialog_style.dart +++ b/packages/remix/lib/src/components/dialog/dialog_style.dart @@ -48,3 +48,24 @@ class DialogStyle extends SpecStyle { ); } } + +class DialogDarkStyle extends DialogStyle { + const DialogDarkStyle(); + + @override + Style makeStyle(SpecConfiguration spec) { + final $ = spec.utilities; + + return Style.create([ + super.makeStyle(spec).call(), + $.container.chain + ..color.black() + ..border.all.width(1) + ..border.color.grey.shade900(), + $.title.style.color.white(), + $.description.chain + ..style.color.white() + ..style.color.grey.shade400(), + ]); + } +} diff --git a/packages/remix/lib/src/components/divider/divider_style.dart b/packages/remix/lib/src/components/divider/divider_style.dart index e724f0e65..58b0c054f 100644 --- a/packages/remix/lib/src/components/divider/divider_style.dart +++ b/packages/remix/lib/src/components/divider/divider_style.dart @@ -12,7 +12,7 @@ class DividerStyle extends SpecStyle { final containerStyle = [ $.container.chain - ..color.black12() + ..color.grey.shade300() ..borderRadius(99), horizontal($.container.height(1)), vertical($.container.width(1)), @@ -21,3 +21,17 @@ class DividerStyle extends SpecStyle { return Style.create([...containerStyle]); } } + +class DividerDarkStyle extends DividerStyle { + const DividerDarkStyle(); + + @override + Style makeStyle(SpecConfiguration spec) { + final $ = spec.utilities; + + return Style.create([ + super.makeStyle(spec).call(), + $.container.color.grey.shade800(), + ]); + } +} diff --git a/packages/remix/lib/src/components/radio/radio_style.dart b/packages/remix/lib/src/components/radio/radio_style.dart index 1c256cdbe..5d9baeee1 100644 --- a/packages/remix/lib/src/components/radio/radio_style.dart +++ b/packages/remix/lib/src/components/radio/radio_style.dart @@ -63,6 +63,7 @@ class RadioDarkStyle extends RadioStyle { super.makeStyle(spec).call(), $.container.border.all.color.white(), $.indicator.color.white(), + $.text.style.color.white(), spec.on.disabled( $.container.border.all.color.white30(), $.indicator.color.white30(), diff --git a/packages/remix/lib/src/theme/remix_theme.dart b/packages/remix/lib/src/theme/remix_theme.dart index 65e2647c0..4d32663a8 100644 --- a/packages/remix/lib/src/theme/remix_theme.dart +++ b/packages/remix/lib/src/theme/remix_theme.dart @@ -99,6 +99,9 @@ class RemixComponentTheme { callout: const CalloutDarkStyle(), card: const CardDarkStyle(), checkbox: const CheckboxDarkStyle(), + dialog: const DialogDarkStyle(), + chip: const ChipDarkStyle(), + divider: const DividerDarkStyle(), iconButton: const IconButtonDarkStyle(), progress: const ProgressDarkStyle(), radio: const RadioDarkStyle(),