diff --git a/analysis_options.yaml b/analysis_options.yaml index 09aefd5..3a7e8a1 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,10 @@ include: package:lints/recommended.yaml +analyzer: + exclude: [ + "**/*.g.dart", + "**/*.freezed.dart", + "example/**", + ] linter: rules: avoid_print: true diff --git a/example/lib/main.dart b/example/lib/main.dart index cb3bfee..3fcc858 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -207,8 +207,16 @@ class ExampleApp extends StatelessWidget { onChange: (item) { print('== Selected Country: ${item.name}, ID: ${item.id}'); }, - buttonAlignment: MainAxisAlignment.start, - displaySubmitButton: false, + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () { + instance.dismiss(); + print('Submit button pressed'); + }, + child: Text('Submit'), + style: ElevatedButton.styleFrom(minimumSize: Size(100, 40)), + ); + }, dismissable: true, filterPredicate: (item, value) { if (int.tryParse(value) != null) { @@ -483,6 +491,7 @@ class ExampleApp extends StatelessWidget { print(firstDate); print(secondDate); }, + closeOnSubmit: true, onRangePickerDismissed: (p0, p1) { print(p0); print(p1); diff --git a/lib/bottom_picker.dart b/lib/bottom_picker.dart index ac91afc..4669839 100644 --- a/lib/bottom_picker.dart +++ b/lib/bottom_picker.dart @@ -41,24 +41,23 @@ class BottomPicker extends StatefulWidget { this.itemBuilder, this.dismissable = false, this.onChange, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) this.onSubmit, this.onDismiss, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, this.selectedItemIndex = 0, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.pickerThemeData, this.itemExtent = 35.0, this.layoutOrientation = TextDirection.ltr, - this.buttonAlignment = MainAxisAlignment.center, this.height, - this.displaySubmitButton = true, this.selectionOverlay, - this.buttonContent, - this.buttonStyle, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) this.closeOnSubmit = true, this.headerBuilder, this.diameterRatio = 1.1, @@ -66,6 +65,15 @@ class BottomPicker extends StatefulWidget { this.filterPredicate, this.textInputAction, this.searchFieldDecoration, + this.buttonBuilder, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { dateOrder = null; onRangeDateSubmitPressed = null; @@ -81,31 +89,39 @@ class BottomPicker extends StatefulWidget { super.key, this.dismissable = false, this.onChange, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) this.onSubmit, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.closeOnSubmit = true, this.onDismiss, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, this.initialDateTime, this.minDateTime, this.maxDateTime, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.dateOrder = DatePickerDateOrder.ymd, this.pickerThemeData, this.layoutOrientation = TextDirection.ltr, - this.buttonAlignment = MainAxisAlignment.center, this.height, - this.displaySubmitButton = true, - this.buttonContent, - this.buttonStyle, this.itemExtent = 35.0, - this.closeOnSubmit = true, this.headerBuilder, this.calendarDays = CupertinoDatePickerWidget.fullWeek, this.diameterRatio = 1.1, this.useSafeArea = false, + this.buttonBuilder, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { datePickerMode = CupertinoDatePickerMode.date; bottomPickerType = BottomPickerType.dateTime; @@ -119,27 +135,36 @@ class BottomPicker extends StatefulWidget { super.key, this.dismissable = false, this.onChange, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) this.onSubmit, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.closeOnSubmit = true, this.onDismiss, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, this.initialDateTime, this.minDateTime, this.maxDateTime, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.pickerThemeData, - this.buttonAlignment = MainAxisAlignment.center, this.height, - this.displaySubmitButton = true, - this.buttonContent, - this.buttonStyle, this.itemExtent = 35.0, this.diameterRatio = 1.1, this.headerBuilder, this.useSafeArea = false, + this.buttonBuilder, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { datePickerMode = CupertinoDatePickerMode.date; bottomPickerType = BottomPickerType.year; @@ -153,30 +178,38 @@ class BottomPicker extends StatefulWidget { super.key, this.dismissable = false, this.onChange, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) this.onSubmit, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.closeOnSubmit = true, this.onDismiss, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, this.initialDateTime, this.minDateTime, this.maxDateTime, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.pickerThemeData, this.layoutOrientation = TextDirection.ltr, - this.buttonAlignment = MainAxisAlignment.center, this.height, - this.displaySubmitButton = true, - this.buttonContent, - this.buttonStyle, this.itemExtent = 35.0, - this.closeOnSubmit = true, this.headerBuilder, this.calendarDays = CupertinoDatePickerWidget.fullWeek, this.diameterRatio = 1.1, this.useSafeArea = false, + this.buttonBuilder, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { datePickerMode = CupertinoDatePickerMode.monthYear; bottomPickerType = BottomPickerType.dateTime; @@ -190,7 +223,14 @@ class BottomPicker extends StatefulWidget { super.key, this.dismissable = false, this.onChange, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) this.onSubmit, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.closeOnSubmit = true, this.onDismiss, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, @@ -199,26 +239,27 @@ class BottomPicker extends StatefulWidget { this.minDateTime, this.maxDateTime, this.use24hFormat = false, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.dateOrder = DatePickerDateOrder.ymd, this.pickerThemeData, this.layoutOrientation = TextDirection.ltr, - this.buttonAlignment = MainAxisAlignment.center, this.height, - this.displaySubmitButton = true, - this.buttonContent, - this.buttonStyle, this.itemExtent = 30, this.showTimeSeparator = false, - this.closeOnSubmit = true, this.headerBuilder, this.calendarDays = CupertinoDatePickerWidget.fullWeek, this.diameterRatio = 1.1, this.hourPredicate, this.useSafeArea = false, + this.buttonBuilder, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { datePickerMode = CupertinoDatePickerMode.dateAndTime; bottomPickerType = BottomPickerType.dateTime; @@ -233,30 +274,38 @@ class BottomPicker extends StatefulWidget { this.minTime, this.dismissable = false, this.onChange, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) this.onSubmit, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.closeOnSubmit = true, this.onDismiss, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, this.minuteInterval = 1, this.use24hFormat = false, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.pickerThemeData, this.layoutOrientation = TextDirection.ltr, - this.buttonAlignment = MainAxisAlignment.center, this.height, - this.displaySubmitButton = true, - this.buttonContent, - this.buttonStyle, this.showTimeSeparator = false, this.itemExtent = 30, - this.closeOnSubmit = true, this.headerBuilder, this.calendarDays = CupertinoDatePickerWidget.fullWeek, this.diameterRatio = 1.1, this.useSafeArea = false, + this.buttonBuilder, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { datePickerMode = CupertinoDatePickerMode.time; bottomPickerType = BottomPickerType.time; @@ -273,28 +322,36 @@ class BottomPicker extends StatefulWidget { this.initialTimerDuration, this.dismissable = false, this.onChange, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) this.onSubmit, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.closeOnSubmit = true, this.onDismiss, this.itemExtent = 30, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, this.minuteInterval = 1, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.pickerThemeData, this.layoutOrientation = TextDirection.ltr, - this.buttonAlignment = MainAxisAlignment.center, this.height, - this.displaySubmitButton = true, - this.buttonContent, - this.buttonStyle, - this.closeOnSubmit = true, this.headerBuilder, this.calendarDays = CupertinoDatePickerWidget.fullWeek, this.diameterRatio = 1.1, + this.buttonBuilder, this.useSafeArea = false, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { dateOrder = null; onRangeDateSubmitPressed = null; @@ -306,18 +363,21 @@ class BottomPicker extends StatefulWidget { BottomPicker.range({ super.key, - required this.onRangeDateSubmitPressed, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.closeOnSubmit = true, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.onRangeDateSubmitPressed, this.onRangePickerDismissed, this.dismissable = false, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.pickerThemeData, this.layoutOrientation = TextDirection.ltr, - this.buttonAlignment = MainAxisAlignment.center, this.height, this.initialSecondDate, this.initialFirstDate, @@ -326,14 +386,20 @@ class BottomPicker extends StatefulWidget { this.maxFirstDate, this.maxSecondDate, this.dateOrder = DatePickerDateOrder.ymd, - this.buttonContent, - this.buttonStyle, this.itemExtent = 30, - this.closeOnSubmit = true, this.headerBuilder, this.calendarDays = CupertinoDatePickerWidget.fullWeek, this.diameterRatio = 1.1, this.useSafeArea = false, + this.buttonBuilder, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { datePickerMode = CupertinoDatePickerMode.date; bottomPickerType = BottomPickerType.rangeDate; @@ -359,19 +425,22 @@ class BottomPicker extends StatefulWidget { BottomPicker.rangeTime({ super.key, - required this.onRangeTimeSubmitPressed, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.closeOnSubmit = true, + @Deprecated( + 'Use buttonBuilder with a callback widget to handle the onSubmit action instead', + ) + this.onRangeTimeSubmitPressed, this.onRangePickerDismissed, this.use24hFormat = true, this.dismissable = false, this.bottomPickerTheme = BottomPickerTheme.blue, this.gradientColors, - this.buttonPadding, - this.buttonWidth, - this.buttonSingleColor, this.backgroundColor = Colors.white, this.pickerThemeData, this.layoutOrientation = TextDirection.ltr, - this.buttonAlignment = MainAxisAlignment.center, this.height, this.initialSecondTime, this.initialFirstTime, @@ -379,16 +448,22 @@ class BottomPicker extends StatefulWidget { this.minSecondTime, this.maxFirstTime, this.maxSecondTime, - this.buttonContent, - this.buttonStyle, this.minuteInterval = 1, this.showTimeSeparator = false, this.itemExtent = 30, - this.closeOnSubmit = true, this.headerBuilder, this.calendarDays = CupertinoDatePickerWidget.fullWeek, this.diameterRatio = 1.1, this.useSafeArea = false, + this.buttonBuilder, + @Deprecated('Use buttonBuilder instead') this.displaySubmitButton = true, + @Deprecated('Use buttonBuilder instead') this.buttonContent, + @Deprecated('Use buttonBuilder instead') this.buttonStyle, + @Deprecated('Use buttonBuilder instead') + this.buttonAlignment = MainAxisAlignment.center, + @Deprecated('Use buttonBuilder instead') this.buttonSingleColor, + @Deprecated('Use buttonBuilder instead') this.buttonPadding, + @Deprecated('Use buttonBuilder instead') this.buttonWidth, }) { datePickerMode = CupertinoDatePickerMode.time; bottomPickerType = BottomPickerType.rangeTime; @@ -538,10 +613,12 @@ class BottomPicker extends StatefulWidget { ///the padding that will be applied to the button ///if the padding is null the button will be rendered null + @Deprecated('Use buttonBuilder instead') final double? buttonPadding; ///the width that will be applied to the button ///if the buttonWidth is null the button will be rendered with null + @Deprecated('Use buttonBuilder instead') final double? buttonWidth; ///the bottom picker background color, @@ -592,6 +669,7 @@ class BottomPicker extends StatefulWidget { ///THe alignment of the bottom picker button ///by default it's `MainAxisAlignment.center` + @Deprecated('Use buttonBuilder instead') final MainAxisAlignment buttonAlignment; ///bottom picker main widget height @@ -635,15 +713,17 @@ class BottomPicker extends StatefulWidget { ///The button's widget that will be displayed ///if null the button will have a simple 'Select' text in the center + @Deprecated('Use buttonBuilder instead') final Widget? buttonContent; ///indicates if the submit button will be displayed or not ///by default the submit button is shown + @Deprecated('Use buttonBuilder instead') late bool displaySubmitButton; ///a single color will be applied to the button instead of the gradient ///themes - /// + @Deprecated('Use buttonBuilder instead') final Color? buttonSingleColor; ///to set a custom button theme color use this list @@ -652,8 +732,16 @@ class BottomPicker extends StatefulWidget { final List? gradientColors; /// The style that will be applied on the button's widget + @Deprecated('Use buttonBuilder instead') final BoxDecoration? buttonStyle; + /// The button builder callback that will be used to build the button widget. + /// If this is provided, it will override the default button widget and any other button-related properties + /// The callback takes a [BuildContext] and returns a [Widget] that will be used as the button. + /// If it's null, the default button widget will be used (will be removed in the future). + final Widget Function(BottomPicker instance, BuildContext context)? + buttonBuilder; + /// Invoked when pressing on the submit button when using range picker /// it return two dates (first time, end time) /// required when using [BottomPicker.rangeTime] @@ -707,9 +795,13 @@ class BottomPicker extends StatefulWidget { /// Indicates whether to use SafeArea to avoid content overflow. final bool useSafeArea; + BuildContext? _context; + bool disposed = false; + ///display the bottom picker popup ///[context] the app context to display the popup void show(BuildContext context) { + _context = context; showModalBottomSheet( useSafeArea: useSafeArea, context: context, @@ -732,6 +824,17 @@ class BottomPicker extends StatefulWidget { ); } + /// Dismiss the bottom picker popup + void dismiss() { + if (_context != null && + _context!.mounted && + Navigator.of(_context!).canPop() && + !disposed) { + Navigator.of(_context!).pop(); + disposed = true; + } + } + @override BottomPickerState createState() => BottomPickerState(); } @@ -747,8 +850,6 @@ class BottomPickerState extends State> { late DateTime selectedSecondDateTime = widget.initialSecondDate ?? DateTime.now(); - bool disposed = false; - late final List? originalItemList = widget.items; late List? displayedItemList = originalItemList; @@ -775,6 +876,7 @@ class BottomPickerState extends State> { @override void dispose() { + widget.disposed = true; if (kIsWeb || (!Platform.isIOS && !Platform.isAndroid)) { try { View.of(context).platformDispatcher.onKeyData = null; @@ -1024,7 +1126,9 @@ class BottomPickerState extends State> { widget.pickerThemeData, ), ), - if (widget.displaySubmitButton) + if (widget.buttonBuilder != null) + widget.buttonBuilder!(widget, context) + else if (widget.displaySubmitButton) Padding( padding: const EdgeInsets.symmetric( vertical: 20, @@ -1082,11 +1186,11 @@ class BottomPickerState extends State> { /// Handle the key press event bool _onKeyPressed(KeyData keyData) { if (keyData.logical == LogicalKeyboardKey.escape.keyId && - !disposed && + !widget.disposed && widget.dismissable) { - disposed = true; + widget.disposed = true; Navigator.pop(context); - return disposed; + return widget.disposed; } return false; } diff --git a/lib/widgets/bottom_picker_button.dart b/lib/widgets/bottom_picker_button.dart index 943b3ce..acfa25b 100644 --- a/lib/widgets/bottom_picker_button.dart +++ b/lib/widgets/bottom_picker_button.dart @@ -2,6 +2,9 @@ import 'package:bottom_picker/resources/arrays.dart'; import 'package:flutter/material.dart'; /// A button widget that can be used to open the bottom picker. +@Deprecated( + 'Will be replaced with button builder callback in the future. check [BottomPicker].', +) class BottomPickerButton extends StatelessWidget { /// The callback function that is called when the button is pressed. final Function onClick; diff --git a/test/button_builder_test.dart b/test/button_builder_test.dart new file mode 100644 index 0000000..8b8bfe8 --- /dev/null +++ b/test/button_builder_test.dart @@ -0,0 +1,117 @@ +import 'package:bottom_picker/bottom_picker.dart'; +import 'package:bottom_picker/widgets/bottom_picker_button.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('Button builder tests...', () { + late List items = List.generate( + 10, + (index) => index, + ); + + testWidgets( + 'Use case: no button builder provided, displaySubmitButton = false', + (tester) async { + var bottomPicker = BottomPicker( + headerBuilder: (context) { + return Text('Item picker'); + }, + items: items, + displaySubmitButton: false, + ); + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: bottomPicker, + ), + ), + ); + + expect(find.byType(BottomPickerButton), findsNothing); + expect(bottomPicker.buttonBuilder, isNull); + }); + + testWidgets( + 'Use case: buttonBuilder provided, displaySubmitButton = false, buttonBuilder should be used', + (tester) async { + var bottomPicker = BottomPicker( + headerBuilder: (context) { + return Text('Item picker'); + }, + items: items, + displaySubmitButton: false, + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () {}, + child: Text('Custom Button'), + ); + }, + ); + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: bottomPicker, + ), + ), + ); + + expect(find.byType(BottomPickerButton), findsNothing); + expect(bottomPicker.buttonBuilder, isNotNull); + expect(find.text('Custom Button'), findsOneWidget); + }); + + testWidgets( + 'Use case: buttonBuilder is not provided but displaySubmitButton = true, default button should be used', + (tester) async { + var bottomPicker = BottomPicker( + headerBuilder: (context) { + return Text('Item picker'); + }, + items: items, + buttonContent: Text('Submit'), + buttonBuilder: null, + ); + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: bottomPicker, + ), + ), + ); + + expect(find.byType(BottomPickerButton), findsOneWidget); + expect(find.text('Submit'), findsOneWidget); + expect(bottomPicker.buttonBuilder, isNull); + }); + + testWidgets( + 'Use case: buttonBuilder is provided and displaySubmitButton = true, buttonBuilder should be used', + (tester) async { + var bottomPicker = BottomPicker( + headerBuilder: (context) { + return Text('Item picker'); + }, + items: items, + buttonContent: Text('Submit'), + buttonBuilder: (instance, context) { + return ElevatedButton( + onPressed: () {}, + child: Text('Custom Button'), + ); + }, + ); + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: bottomPicker, + ), + ), + ); + + expect(find.byType(BottomPickerButton), findsNothing); + expect(find.text('Custom Button'), findsOneWidget); + expect(bottomPicker.buttonBuilder, isNotNull); + }); + }); +}