From 1eb95620e9175c6199e354d268d7461c267f97db Mon Sep 17 00:00:00 2001 From: Harry Sild <46851868+Kypsis@users.noreply.github.com> Date: Wed, 22 Mar 2023 22:54:00 +0200 Subject: [PATCH] feat: [MDS-448] Create Modal widget (#87) --- example/lib/src/storybook/common/options.dart | 6 +- example/lib/src/storybook/stories/modal.dart | 115 +++++++++++ example/lib/src/storybook/storybook.dart | 4 +- lib/moon_design.dart | 2 + lib/src/theme/modal/modal_colors.dart | 58 ++++++ lib/src/theme/modal/modal_properties.dart | 62 ++++++ lib/src/theme/modal/modal_theme.dart | 59 ++++++ lib/src/theme/theme.dart | 11 + lib/src/widgets/modal/modal.dart | 191 ++++++++++++++++++ lib/src/widgets/tag/tag.dart | 2 +- 10 files changed, 506 insertions(+), 4 deletions(-) create mode 100644 example/lib/src/storybook/stories/modal.dart create mode 100644 lib/src/theme/modal/modal_colors.dart create mode 100644 lib/src/theme/modal/modal_properties.dart create mode 100644 lib/src/theme/modal/modal_theme.dart create mode 100644 lib/src/widgets/modal/modal.dart diff --git a/example/lib/src/storybook/common/options.dart b/example/lib/src/storybook/common/options.dart index b64ab0b3..cb0bb679 100644 --- a/example/lib/src/storybook/common/options.dart +++ b/example/lib/src/storybook/common/options.dart @@ -47,11 +47,12 @@ List> colorOptions = const [ Option(label: "whis100", value: 36), Option(label: "whis60", value: 37), Option(label: "whis10", value: 38), - Option(label: "none", value: 39), + Option(label: "transparent", value: 39), + Option(label: "null", value: 40), ]; /// LUT for the color options. -List colorTable(BuildContext context) => [ +List colorTable(BuildContext context) => [ context.moonColors!.piccolo, context.moonColors!.hit, context.moonColors!.beerus, @@ -92,4 +93,5 @@ List colorTable(BuildContext context) => [ context.moonColors!.whis60, context.moonColors!.whis10, Colors.transparent, + null, ]; diff --git a/example/lib/src/storybook/stories/modal.dart b/example/lib/src/storybook/stories/modal.dart new file mode 100644 index 00000000..00705bcc --- /dev/null +++ b/example/lib/src/storybook/stories/modal.dart @@ -0,0 +1,115 @@ +import 'package:example/src/storybook/common/options.dart'; +import 'package:flutter/material.dart'; +import 'package:moon_design/moon_design.dart'; +import 'package:storybook_flutter/storybook_flutter.dart'; + +class ModalStory extends Story { + ModalStory() + : super( + name: "Modal", + builder: (context) { + final backgroundColorsKnob = context.knobs.options( + label: "backgroundColor", + description: "MoonColors variants for Modal background.", + initial: 40, // null + options: colorOptions, + ); + + final backgroundColor = colorTable(context)[backgroundColorsKnob]; + + final barrierColorsKnob = context.knobs.options( + label: "barrierColor", + description: "MoonColors variants for Modal barrier.", + initial: 40, // null + options: colorOptions, + ); + + final barrierColor = colorTable(context)[barrierColorsKnob]; + + final borderRadiusKnob = context.knobs.sliderInt( + max: 20, + initial: 8, + label: "borderRadius", + description: "Border radius for Modal.", + ); + + final setRtlModeKnob = context.knobs.boolean( + label: "RTL mode", + description: "Switch between LTR and RTL modes.", + ); + + Future modalBuilder(BuildContext context) { + return showMoonModal( + context: context, + useRootNavigator: false, + barrierColor: barrierColor, + builder: (_) { + return MoonModal( + backgroundColor: backgroundColor, + borderRadius: BorderRadius.circular(borderRadiusKnob.toDouble()), + child: Directionality( + textDirection: Directionality.of(context), + child: SizedBox( + width: 300, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(24, 20, 24, 16), + child: Text( + "Modal title", + style: context.moonTypography!.heading.text18, + ), + ), + Container( + height: 1, + color: context.moonColors!.trunks, + ), + Padding( + padding: const EdgeInsets.fromLTRB(24, 16, 24, 16), + child: Text( + "Reopen the modal to see the new knob value changes.", + style: context.moonTypography!.body.text14, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(24, 16, 24, 24), + child: MoonPrimaryButton( + label: const Text("Okay"), + isFullWidth: true, + onTap: () => Navigator.of(context).pop(), + ), + ), + ], + ), + ), + ), + ); + }, + ); + } + + return Directionality( + textDirection: setRtlModeKnob ? TextDirection.rtl : TextDirection.ltr, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox(height: 64), + Builder( + builder: (context) { + return MoonPrimaryButton( + label: const Text("Open Modal"), + onTap: () => modalBuilder(context), + ); + }, + ), + const SizedBox(height: 64), + ], + ), + ), + ); + }, + ); +} diff --git a/example/lib/src/storybook/storybook.dart b/example/lib/src/storybook/storybook.dart index d5fe8ce6..d8c8f85b 100644 --- a/example/lib/src/storybook/storybook.dart +++ b/example/lib/src/storybook/storybook.dart @@ -9,6 +9,7 @@ import 'package:example/src/storybook/stories/circular_progress.dart'; import 'package:example/src/storybook/stories/icons.dart'; import 'package:example/src/storybook/stories/linear_loader.dart'; import 'package:example/src/storybook/stories/linear_progress.dart'; +import 'package:example/src/storybook/stories/modal.dart'; import 'package:example/src/storybook/stories/popover.dart'; import 'package:example/src/storybook/stories/radio.dart'; import 'package:example/src/storybook/stories/switch.dart'; @@ -36,7 +37,7 @@ class StorybookPage extends StatelessWidget { return Stack( children: [ Storybook( - initialStory: "Accordion", + initialStory: "Modal", plugins: _plugins, wrapperBuilder: (context, child) => MaterialApp( title: "Moon Design for Flutter", @@ -78,6 +79,7 @@ class StorybookPage extends StatelessWidget { IconsStory(), LinearLoaderStory(), LinearProgressStory(), + ModalStory(), PopoverStory(), RadioStory(), SwitchStory(), diff --git a/lib/moon_design.dart b/lib/moon_design.dart index ebbb678a..5a9989b8 100644 --- a/lib/moon_design.dart +++ b/lib/moon_design.dart @@ -10,6 +10,7 @@ export 'package:moon_design/src/theme/colors.dart'; export 'package:moon_design/src/theme/effects/effects.dart'; export 'package:moon_design/src/theme/loaders/circular_loader/circular_loader_theme.dart'; export 'package:moon_design/src/theme/loaders/linear_loader/linear_loader_theme.dart'; +export 'package:moon_design/src/theme/modal/modal_theme.dart'; export 'package:moon_design/src/theme/opacity.dart'; export 'package:moon_design/src/theme/popover/popover_theme.dart'; export 'package:moon_design/src/theme/progress/circular_progress/circular_progress_theme.dart'; @@ -47,6 +48,7 @@ export 'package:moon_design/src/widgets/common/progress_indicators/circular_prog export 'package:moon_design/src/widgets/common/progress_indicators/linear_progress_indicator.dart'; export 'package:moon_design/src/widgets/loaders/circular_loader.dart'; export 'package:moon_design/src/widgets/loaders/linear_loader.dart'; +export 'package:moon_design/src/widgets/modal/modal.dart'; export 'package:moon_design/src/widgets/popover/popover.dart'; export 'package:moon_design/src/widgets/progress/circular_progress.dart'; export 'package:moon_design/src/widgets/progress/linear_progress.dart'; diff --git a/lib/src/theme/modal/modal_colors.dart b/lib/src/theme/modal/modal_colors.dart new file mode 100644 index 00000000..55af8eed --- /dev/null +++ b/lib/src/theme/modal/modal_colors.dart @@ -0,0 +1,58 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:moon_design/src/theme/colors.dart'; + +@immutable +class MoonModalColors extends ThemeExtension with DiagnosticableTreeMixin { + static final light = MoonModalColors( + backgroundColor: MoonColors.light.gohan, + barrierColor: MoonColors.light.zeno, + ); + + static final dark = MoonModalColors( + backgroundColor: MoonColors.dark.gohan, + barrierColor: MoonColors.dark.zeno, + ); + + /// Modal background color. + final Color backgroundColor; + + /// Modal barrier color. + final Color barrierColor; + + const MoonModalColors({ + required this.backgroundColor, + required this.barrierColor, + }); + + @override + MoonModalColors copyWith({ + Color? backgroundColor, + Color? barrierColor, + }) { + return MoonModalColors( + backgroundColor: backgroundColor ?? this.backgroundColor, + barrierColor: barrierColor ?? this.barrierColor, + ); + } + + @override + MoonModalColors lerp(ThemeExtension? other, double t) { + if (other is! MoonModalColors) return this; + + return MoonModalColors( + backgroundColor: Color.lerp(backgroundColor, other.backgroundColor, t)!, + barrierColor: Color.lerp(barrierColor, other.barrierColor, t)!, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty("type", "MoonModalColors")) + ..add(ColorProperty("backgroundColor", backgroundColor)) + ..add(ColorProperty("barrierColor", barrierColor)); + } +} diff --git a/lib/src/theme/modal/modal_properties.dart b/lib/src/theme/modal/modal_properties.dart new file mode 100644 index 00000000..db2a6293 --- /dev/null +++ b/lib/src/theme/modal/modal_properties.dart @@ -0,0 +1,62 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:moon_design/src/theme/borders.dart'; + +@immutable +class MoonModalProperties extends ThemeExtension with DiagnosticableTreeMixin { + static final properties = MoonModalProperties( + borderRadius: MoonBorders.borders.surfaceSm, + transitionDuration: const Duration(milliseconds: 200), + transitionCurve: Curves.easeInOutCubic, + ); + + /// Modal border radius. + final BorderRadius borderRadius; + + /// Modal transition duration. + final Duration transitionDuration; + + /// Modal transition curve. + final Curve transitionCurve; + + const MoonModalProperties({ + required this.borderRadius, + required this.transitionDuration, + required this.transitionCurve, + }); + + @override + MoonModalProperties copyWith({ + BorderRadius? borderRadius, + Duration? transitionDuration, + Curve? transitionCurve, + }) { + return MoonModalProperties( + borderRadius: borderRadius ?? this.borderRadius, + transitionDuration: transitionDuration ?? this.transitionDuration, + transitionCurve: transitionCurve ?? this.transitionCurve, + ); + } + + @override + MoonModalProperties lerp(ThemeExtension? other, double t) { + if (other is! MoonModalProperties) return this; + + return MoonModalProperties( + borderRadius: BorderRadius.lerp(borderRadius, other.borderRadius, t)!, + transitionDuration: lerpDuration(transitionDuration, other.transitionDuration, t), + transitionCurve: other.transitionCurve, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DiagnosticsProperty("type", "MoonModalProperties")) + ..add(DiagnosticsProperty("borderRadius", borderRadius)) + ..add(DiagnosticsProperty("transitionDuration", transitionDuration)) + ..add(DiagnosticsProperty("transitionCurve", transitionCurve)); + } +} diff --git a/lib/src/theme/modal/modal_theme.dart b/lib/src/theme/modal/modal_theme.dart new file mode 100644 index 00000000..c1ebb781 --- /dev/null +++ b/lib/src/theme/modal/modal_theme.dart @@ -0,0 +1,59 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:moon_design/src/theme/modal/modal_colors.dart'; +import 'package:moon_design/src/theme/modal/modal_properties.dart'; + +@immutable +class MoonModalTheme extends ThemeExtension with DiagnosticableTreeMixin { + static final light = MoonModalTheme( + colors: MoonModalColors.light, + properties: MoonModalProperties.properties, + ); + + static final dark = MoonModalTheme( + colors: MoonModalColors.dark, + properties: MoonModalProperties.properties, + ); + + /// Checkbox colors. + final MoonModalColors colors; + + /// Checkbox properties. + final MoonModalProperties properties; + + const MoonModalTheme({ + required this.colors, + required this.properties, + }); + + @override + MoonModalTheme copyWith({ + MoonModalColors? colors, + MoonModalProperties? properties, + }) { + return MoonModalTheme( + colors: colors ?? this.colors, + properties: properties ?? this.properties, + ); + } + + @override + MoonModalTheme lerp(ThemeExtension? other, double t) { + if (other is! MoonModalTheme) return this; + + return MoonModalTheme( + colors: colors.lerp(other.colors, t), + properties: properties.lerp(other.properties, t), + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder diagnosticProperties) { + super.debugFillProperties(diagnosticProperties); + diagnosticProperties + ..add(DiagnosticsProperty("type", "MoonModalTheme")) + ..add(DiagnosticsProperty("colors", colors)) + ..add(DiagnosticsProperty("properties", properties)); + } +} diff --git a/lib/src/theme/theme.dart b/lib/src/theme/theme.dart index 04811531..5dff8fa2 100644 --- a/lib/src/theme/theme.dart +++ b/lib/src/theme/theme.dart @@ -11,6 +11,7 @@ import 'package:moon_design/src/theme/colors.dart'; import 'package:moon_design/src/theme/effects/effects.dart'; import 'package:moon_design/src/theme/loaders/circular_loader/circular_loader_theme.dart'; import 'package:moon_design/src/theme/loaders/linear_loader/linear_loader_theme.dart'; +import 'package:moon_design/src/theme/modal/modal_theme.dart'; import 'package:moon_design/src/theme/opacity.dart'; import 'package:moon_design/src/theme/popover/popover_theme.dart'; import 'package:moon_design/src/theme/progress/circular_progress/circular_progress_theme.dart'; @@ -38,6 +39,7 @@ class MoonTheme extends ThemeExtension with DiagnosticableTreeMixin { effects: MoonEffects.light, linearLoaderTheme: MoonLinearLoaderTheme.light, linearProgressTheme: MoonLinearProgressTheme.light, + modalTheme: MoonModalTheme.light, opacity: MoonOpacity.opacities, popoverTheme: MoonPopoverTheme.light, radioTheme: MoonRadioTheme.light, @@ -62,6 +64,7 @@ class MoonTheme extends ThemeExtension with DiagnosticableTreeMixin { effects: MoonEffects.dark, linearLoaderTheme: MoonLinearLoaderTheme.dark, linearProgressTheme: MoonLinearProgressTheme.dark, + modalTheme: MoonModalTheme.dark, opacity: MoonOpacity.opacities, popoverTheme: MoonPopoverTheme.dark, radioTheme: MoonRadioTheme.dark, @@ -109,6 +112,9 @@ class MoonTheme extends ThemeExtension with DiagnosticableTreeMixin { /// Moon Design System MoonLinearProgress widget theming. final MoonLinearProgressTheme linearProgressTheme; + /// Moon Design System MoonModal widget theming. + final MoonModalTheme modalTheme; + /// Moon Design System opacities. final MoonOpacity opacity; @@ -149,6 +155,7 @@ class MoonTheme extends ThemeExtension with DiagnosticableTreeMixin { required this.effects, required this.linearLoaderTheme, required this.linearProgressTheme, + required this.modalTheme, required this.opacity, required this.popoverTheme, required this.radioTheme, @@ -174,6 +181,7 @@ class MoonTheme extends ThemeExtension with DiagnosticableTreeMixin { MoonEffects? effects, MoonLinearLoaderTheme? linearLoaderTheme, MoonLinearProgressTheme? linearProgressTheme, + MoonModalTheme? modalTheme, MoonOpacity? opacity, MoonPopoverTheme? popoverTheme, MoonRadioTheme? radioTheme, @@ -197,6 +205,7 @@ class MoonTheme extends ThemeExtension with DiagnosticableTreeMixin { effects: effects ?? this.effects, linearLoaderTheme: linearLoaderTheme ?? this.linearLoaderTheme, linearProgressTheme: linearProgressTheme ?? this.linearProgressTheme, + modalTheme: modalTheme ?? this.modalTheme, opacity: opacity ?? this.opacity, popoverTheme: popoverTheme ?? this.popoverTheme, radioTheme: radioTheme ?? this.radioTheme, @@ -226,6 +235,7 @@ class MoonTheme extends ThemeExtension with DiagnosticableTreeMixin { effects: effects.lerp(other.effects, t), linearLoaderTheme: linearLoaderTheme.lerp(other.linearLoaderTheme, t), linearProgressTheme: linearProgressTheme.lerp(other.linearProgressTheme, t), + modalTheme: modalTheme.lerp(other.modalTheme, t), opacity: opacity.lerp(other.opacity, t), popoverTheme: popoverTheme.lerp(other.popoverTheme, t), radioTheme: radioTheme.lerp(other.radioTheme, t), @@ -255,6 +265,7 @@ class MoonTheme extends ThemeExtension with DiagnosticableTreeMixin { ..add(DiagnosticsProperty("MoonEffects", effects)) ..add(DiagnosticsProperty("MoonLinearLoaderTheme", linearLoaderTheme)) ..add(DiagnosticsProperty("MoonLinearProgressTheme", linearProgressTheme)) + ..add(DiagnosticsProperty("MoonModalTheme", modalTheme)) ..add(DiagnosticsProperty("MoonOpacity", opacity)) ..add(DiagnosticsProperty("MoonPopoverTheme", popoverTheme)) ..add(DiagnosticsProperty("MoonRadioTheme", radioTheme)) diff --git a/lib/src/widgets/modal/modal.dart b/lib/src/widgets/modal/modal.dart new file mode 100644 index 00000000..1a475aa0 --- /dev/null +++ b/lib/src/widgets/modal/modal.dart @@ -0,0 +1,191 @@ +import 'package:figma_squircle/figma_squircle.dart'; +import 'package:flutter/material.dart'; + +import 'package:moon_design/src/theme/borders.dart'; +import 'package:moon_design/src/theme/colors.dart'; +import 'package:moon_design/src/theme/theme.dart'; +import 'package:moon_design/src/utils/extensions.dart'; + +class MoonModal extends StatelessWidget { + final Color? backgroundColor; + final BorderRadius? borderRadius; + final Widget child; + + const MoonModal({ + super.key, + this.backgroundColor, + this.borderRadius, + required this.child, + }); + + Color _getTextColor(BuildContext context, {required bool isDarkMode, required Color effectiveBackgroundColor}) { + if (backgroundColor == null && context.moonTypography != null) { + return context.moonTypography!.colors.bodyPrimary; + } + + final backgroundLuminance = effectiveBackgroundColor.computeLuminance(); + if (backgroundLuminance > 0.5) { + return MoonColors.light.bulma; + } else { + return MoonColors.dark.bulma; + } + } + + @override + Widget build(BuildContext context) { + final Color effectiveBackgroundColor = + backgroundColor ?? context.moonTheme?.modalTheme.colors.backgroundColor ?? MoonColors.light.gohan; + + final Color effectiveTextColor = + _getTextColor(context, isDarkMode: context.isDarkMode, effectiveBackgroundColor: effectiveBackgroundColor); + + final BorderRadius effectiveBorderRadius = + borderRadius ?? context.moonTheme?.modalTheme.properties.borderRadius ?? MoonBorders.borders.surfaceSm; + + return IconTheme( + data: IconThemeData(color: effectiveTextColor), + child: DefaultTextStyle( + style: DefaultTextStyle.of(context).style.copyWith(color: effectiveTextColor), + child: Center( + child: Container( + decoration: ShapeDecoration( + color: effectiveBackgroundColor, + shape: SmoothRectangleBorder( + borderRadius: SmoothBorderRadius.only( + topLeft: SmoothRadius( + cornerRadius: effectiveBorderRadius.topLeft.x, + cornerSmoothing: 1, + ), + topRight: SmoothRadius( + cornerRadius: effectiveBorderRadius.topRight.x, + cornerSmoothing: 1, + ), + bottomLeft: SmoothRadius( + cornerRadius: effectiveBorderRadius.bottomLeft.x, + cornerSmoothing: 1, + ), + bottomRight: SmoothRadius( + cornerRadius: effectiveBorderRadius.bottomRight.x, + cornerSmoothing: 1, + ), + ), + ), + ), + child: child, + ), + ), + ), + ); + } +} + +/// Displays a modal above the current contents of the app, with entrance and exit animations, modal barrier color, +/// and modal barrier behavior (dialog is dismissible with a tap on the barrier). Used together with MoonModal. +Future showMoonModal({ + required BuildContext context, + required WidgetBuilder builder, + bool barrierDismissible = true, + String? barrierLabel = "Dismiss", + Color? barrierColor, + Duration? transitionDuration, + Curve? transitionCurve, + bool useSafeArea = true, + bool useRootNavigator = true, + RouteSettings? routeSettings, + Offset? anchorPoint, +}) { + assert(!barrierDismissible || barrierLabel != null); + assert(_debugIsActive(context)); + + final CapturedThemes themes = InheritedTheme.capture( + from: context, + to: Navigator.of( + context, + rootNavigator: useRootNavigator, + ).context, + ); + + final Color effectiveBarrierColor = + barrierColor ?? context.moonTheme?.modalTheme.colors.barrierColor ?? MoonColors.light.zeno; + + final Duration effectiveTransitionDuration = transitionDuration ?? + context.moonTheme?.modalTheme.properties.transitionDuration ?? + const Duration(milliseconds: 200); + + final Curve effectiveTransitionCurve = + transitionCurve ?? context.moonTheme?.modalTheme.properties.transitionCurve ?? Curves.easeInOutCubic; + + return Navigator.of(context, rootNavigator: useRootNavigator).push( + MoonModalRoute( + context: context, + builder: builder, + barrierDismissible: barrierDismissible, + barrierLabel: barrierLabel, + barrierColor: effectiveBarrierColor, + transitionDuration: effectiveTransitionDuration, + transitionCurve: effectiveTransitionCurve, + useSafeArea: useSafeArea, + settings: routeSettings, + anchorPoint: anchorPoint, + themes: themes, + ), + ); +} + +bool _debugIsActive(BuildContext context) { + if (context is Element && !context.debugIsActive) { + throw FlutterError.fromParts([ + ErrorSummary('This BuildContext is no longer valid.'), + ErrorDescription('The showMoonModal function context parameter is a BuildContext that is no longer valid.'), + ErrorHint( + 'This can commonly occur when the showMoonModal function is called after awaiting a Future. ' + 'In this situation the BuildContext might refer to a widget that has already been disposed during the await. ' + 'Consider using a parent context instead.', + ), + ]); + } + + return true; +} + +class MoonModalRoute extends RawDialogRoute { + /// A MDS modal route with entrance and exit animations, + /// modal barrier color, and modal barrier behavior (modal is dismissible + /// with a tap on the barrier). + MoonModalRoute({ + required BuildContext context, + required WidgetBuilder builder, + CapturedThemes? themes, + required super.barrierColor, + super.barrierDismissible, + required super.transitionDuration, + required Curve transitionCurve, + String? barrierLabel, + bool useSafeArea = true, + super.settings, + super.anchorPoint, + }) : super( + barrierLabel: barrierLabel ?? MaterialLocalizations.of(context).modalBarrierDismissLabel, + pageBuilder: (BuildContext buildContext, Animation animation, Animation secondaryAnimation) { + final Widget pageChild = Builder(builder: builder); + + Widget modal = themes?.wrap(pageChild) ?? pageChild; + + if (useSafeArea) { + modal = SafeArea(child: modal); + } + + return modal; + }, + transitionBuilder: + (BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { + return FadeTransition( + opacity: CurvedAnimation( + parent: animation, + curve: transitionCurve, + ), + child: child, + ); + }, + ); +} diff --git a/lib/src/widgets/tag/tag.dart b/lib/src/widgets/tag/tag.dart index bf5d17db..319349f0 100644 --- a/lib/src/widgets/tag/tag.dart +++ b/lib/src/widgets/tag/tag.dart @@ -1,8 +1,8 @@ import 'package:figma_squircle/figma_squircle.dart'; import 'package:flutter/material.dart'; + import 'package:moon_design/src/theme/colors.dart'; import 'package:moon_design/src/theme/tag/tag_size_properties.dart'; - import 'package:moon_design/src/theme/theme.dart'; import 'package:moon_design/src/utils/extensions.dart';