diff --git a/CHANGELOG.md b/CHANGELOG.md index ef7c536..4c34253 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 3.1.0 - 30.06.2023 +* Enhancement: Add `snackBarPosition` parameter by [fox-avokadik](https://github.com/fox-avokadik) +* Correct errors in the example +* Update README.md + ## 3.0.0+1 - 27.12.2022 * Update README.md diff --git a/README.md b/README.md index fb1f270..3872085 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ but we have a CustomSnackBar for example. ```dart showTopSnackBar( - context, + Overlay.of(context), CustomSnackBar.success( message: "Good job, your release is successful. Have a nice day", @@ -27,7 +27,7 @@ showTopSnackBar( ```dart showTopSnackBar( - context, + Overlay.of(context), CustomSnackBar.info( message: "There is some information. You need to do something with that", @@ -37,7 +37,7 @@ showTopSnackBar( ```dart showTopSnackBar( - context, + Overlay.of(context), CustomSnackBar.error( message: "Something went wrong. Please check your credentials and try again", @@ -52,7 +52,7 @@ AnimationController localAnimationController; TapBounceContainer( onTap: () { showTopSnackBar( - context, + Overlay.of(context), CustomSnackBar.info( message: "Persistent SnackBar", ), diff --git a/example/assets/top-snackbar-example.gif b/example/assets/top-snackbar-example.gif index 3482550..bce241f 100644 Binary files a/example/assets/top-snackbar-example.gif and b/example/assets/top-snackbar-example.gif differ diff --git a/example/lib/main.dart b/example/lib/main.dart index 6440a4b..ea0a5ea 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -8,14 +8,14 @@ void main() { } class MyApp extends StatefulWidget { - const MyApp({Key key}) : super(key: key); + const MyApp({Key? key}) : super(key: key); @override MyAppState createState() => MyAppState(); } class MyAppState extends State { - AnimationController localAnimationController; + late AnimationController localAnimationController; @override Widget build(BuildContext context) { diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 5f5a12d..52be3e0 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -19,7 +19,7 @@ void main() { expect( find.byWidgetPredicate( (Widget widget) => - widget is Text && widget.data.startsWith('Running on:'), + widget is Text && (widget.data?.startsWith('Running on:') ?? false), ), findsOneWidget, ); diff --git a/lib/custom_snack_bar.dart b/lib/custom_snack_bar.dart index 747efe2..1babda7 100644 --- a/lib/custom_snack_bar.dart +++ b/lib/custom_snack_bar.dart @@ -128,7 +128,7 @@ class CustomSnackBarState extends State { padding: widget.messagePadding, child: Text( widget.message, - style: theme.textTheme.bodyText2?.merge(widget.textStyle), + style: theme.textTheme.bodyMedium?.merge(widget.textStyle), textAlign: widget.textAlign, overflow: TextOverflow.ellipsis, maxLines: widget.maxLines, diff --git a/lib/safe_area_values.dart b/lib/safe_area_values.dart index 48e78d1..43a5862 100644 --- a/lib/safe_area_values.dart +++ b/lib/safe_area_values.dart @@ -1,5 +1,6 @@ import 'package:flutter/widgets.dart'; +/// A data class that is used to pass safe area values for snackbar class SafeAreaValues { const SafeAreaValues({ this.left = true, diff --git a/lib/tap_bounce_container.dart b/lib/tap_bounce_container.dart index 2eed271..e2d8c88 100644 --- a/lib/tap_bounce_container.dart +++ b/lib/tap_bounce_container.dart @@ -17,6 +17,7 @@ class TapBounceContainer extends StatefulWidget { TapBounceContainerState createState() => TapBounceContainerState(); } +/// State for a [TapBounceContainer]. class TapBounceContainerState extends State with SingleTickerProviderStateMixin { late double _scale; diff --git a/lib/top_snack_bar.dart b/lib/top_snack_bar.dart index d9f93f2..941ba8e 100644 --- a/lib/top_snack_bar.dart +++ b/lib/top_snack_bar.dart @@ -6,8 +6,12 @@ import 'package:top_snackbar_flutter/tap_bounce_container.dart'; typedef ControllerCallback = void Function(AnimationController); +/// Represents possible triggers to dismiss the snackbar. enum DismissType { onTap, onSwipe, none } +/// Represents possible vertical position of snackbar. +enum SnackBarPosition { top, bottom } + OverlayEntry? _previousEntry; /// The [overlayState] argument is used to add specific overlay state. @@ -42,10 +46,13 @@ OverlayEntry? _previousEntry; /// The [safeAreaValues] argument is used to specify the arguments of the /// [SafeArea] widget that wrap the snackbar. /// -/// The [dismissType] argument specify which action to trigger to +/// The [dismissType] argument specifies which action to trigger to /// dismiss the snackbar. Defaults to `TopSnackBarDismissType.onTap` /// -/// The [dismissDirection] argument specify in which direction the snackbar +/// The [snackBarPosition] argument specifies the vertical position of the snackbar. +/// Defaults to [SnackBarPosition.top] +/// +/// The [dismissDirection] argument specifies in which direction the snackbar /// can be dismissed. This argument is only used when [dismissType] is equal /// to `DismissType.onSwipe`. Defaults to `[DismissDirection.up]` void showTopSnackBar( @@ -62,6 +69,7 @@ void showTopSnackBar( Curve reverseCurve = Curves.linearToEaseOut, SafeAreaValues safeAreaValues = const SafeAreaValues(), DismissType dismissType = DismissType.onTap, + SnackBarPosition snackBarPosition = SnackBarPosition.top, List dismissDirection = const [DismissDirection.up], }) { late OverlayEntry _overlayEntry; @@ -83,6 +91,7 @@ void showTopSnackBar( reverseCurve: reverseCurve, safeAreaValues: safeAreaValues, dismissType: dismissType, + snackBarPosition: snackBarPosition, dismissDirections: dismissDirection, child: child, ); @@ -111,6 +120,7 @@ class _TopSnackBar extends StatefulWidget { required this.reverseCurve, required this.safeAreaValues, required this.dismissDirections, + required this.snackBarPosition, this.onTap, this.persistent = false, this.onAnimationControllerInit, @@ -131,19 +141,19 @@ class _TopSnackBar extends StatefulWidget { final SafeAreaValues safeAreaValues; final DismissType dismissType; final List dismissDirections; + final SnackBarPosition snackBarPosition; @override _TopSnackBarState createState() => _TopSnackBarState(); } -class _TopSnackBarState extends State<_TopSnackBar> - with SingleTickerProviderStateMixin { +class _TopSnackBarState extends State<_TopSnackBar> with SingleTickerProviderStateMixin { late final Animation _offsetAnimation; late final AnimationController _animationController; Timer? _timer; - final _offsetTween = Tween(begin: const Offset(0, -1), end: Offset.zero); + late final Tween _offsetTween; @override void initState() { @@ -170,6 +180,15 @@ class _TopSnackBarState extends State<_TopSnackBar> widget.onAnimationControllerInit?.call(_animationController); + switch(widget.snackBarPosition) { + case SnackBarPosition.top: + _offsetTween = Tween(begin: const Offset(0, -1), end: Offset.zero); + break; + case SnackBarPosition.bottom: + _offsetTween = Tween(begin: const Offset(0, 1), end: Offset.zero); + break; + } + _offsetAnimation = _offsetTween.animate( CurvedAnimation( parent: _animationController, @@ -193,7 +212,8 @@ class _TopSnackBarState extends State<_TopSnackBar> @override Widget build(BuildContext context) { return Positioned( - top: widget.padding.top, + top: widget.snackBarPosition == SnackBarPosition.top ? widget.padding.top : null, + bottom: widget.snackBarPosition == SnackBarPosition.bottom ? widget.padding.bottom : null, left: widget.padding.left, right: widget.padding.right, child: SlideTransition( @@ -204,8 +224,7 @@ class _TopSnackBarState extends State<_TopSnackBar> left: widget.safeAreaValues.left, right: widget.safeAreaValues.right, minimum: widget.safeAreaValues.minimum, - maintainBottomViewPadding: - widget.safeAreaValues.maintainBottomViewPadding, + maintainBottomViewPadding: widget.safeAreaValues.maintainBottomViewPadding, child: _buildDismissibleChild(), ), ), diff --git a/pubspec.yaml b/pubspec.yaml index 0da2740..19c084c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,10 @@ name: top_snackbar_flutter description: Top snack bar package was created for nice and convenient way to inform users about what happened. -version: 3.0.0+1 +version: 3.1.0 homepage: https://github.com/LanarsInc/top-snackbar-flutter environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.15.0 <4.0.0' dependencies: flutter: diff --git a/test/top_snackbar_flutter_test.dart b/test/top_snackbar_flutter_test.dart index 64f6e72..d503db5 100644 --- a/test/top_snackbar_flutter_test.dart +++ b/test/top_snackbar_flutter_test.dart @@ -7,12 +7,14 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); setUp(() { - channel.setMockMethodCallHandler((MethodCall methodCall) async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (message) async { return '42'; }); }); tearDown(() { - channel.setMockMethodCallHandler(null); + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, null); }); }