From 96c9ca096ec5b8cbe31bd8a05de09ea053b6f8ab Mon Sep 17 00:00:00 2001 From: mikecoomber Date: Mon, 29 Jul 2024 15:53:15 +0100 Subject: [PATCH] refactor: Searchbar uses ZetaFormField --- .../pages/components/search_bar_example.dart | 4 +- .../pages/components/text_input_example.dart | 3 + .../components/search_bar_widgetbook.dart | 7 +- lib/src/components/search_bar/search_bar.dart | 398 ++++++++---------- lib/src/interfaces/form_field.dart | 69 +-- .../search_bar/search_bar_test.dart | 42 +- 6 files changed, 234 insertions(+), 289 deletions(-) diff --git a/example/lib/pages/components/search_bar_example.dart b/example/lib/pages/components/search_bar_example.dart index 691bcaab..b44ee768 100644 --- a/example/lib/pages/components/search_bar_example.dart +++ b/example/lib/pages/components/search_bar_example.dart @@ -26,9 +26,9 @@ class _SearchBarExampleState extends State { Padding( padding: const EdgeInsets.all(20), child: ZetaSearchBar( - onChanged: (value) {}, + onChange: (value) {}, textInputAction: TextInputAction.search, - onSubmit: (text) { + onFieldSubmitted: (text) { print(text); }, ), diff --git a/example/lib/pages/components/text_input_example.dart b/example/lib/pages/components/text_input_example.dart index c953e128..c945e23f 100644 --- a/example/lib/pages/components/text_input_example.dart +++ b/example/lib/pages/components/text_input_example.dart @@ -9,6 +9,7 @@ class TextInputExample extends StatelessWidget { @override Widget build(BuildContext context) { + final controller = TextEditingController(text: 'Initial value'); final key = GlobalKey(); return ExampleScaffold( name: 'Text Input', @@ -24,6 +25,8 @@ class TextInputExample extends StatelessWidget { size: ZetaWidgetSize.large, placeholder: 'Placeholder', prefixText: '£', + controller: controller, + onChange: print, label: 'Label', requirementLevel: ZetaFormFieldRequirement.mandatory, errorText: 'Error text', diff --git a/example/widgetbook/pages/components/search_bar_widgetbook.dart b/example/widgetbook/pages/components/search_bar_widgetbook.dart index d9704d92..7932e2b1 100644 --- a/example/widgetbook/pages/components/search_bar_widgetbook.dart +++ b/example/widgetbook/pages/components/search_bar_widgetbook.dart @@ -35,10 +35,6 @@ Widget searchBarUseCase(BuildContext context) { options: ZetaWidgetBorder.values, labelBuilder: (shape) => shape.name, ); - final showLeadingIcon = context.knobs.boolean( - label: 'Show leading icon', - initialValue: true, - ); final showSpeechToText = context.knobs.boolean( label: 'Show Speech-To-Text button', initialValue: true, @@ -54,9 +50,8 @@ Widget searchBarUseCase(BuildContext context) { shape: shape, disabled: disabled, hint: hint, - showLeadingIcon: showLeadingIcon, showSpeechToText: showSpeechToText, - onChanged: (value) { + onChange: (value) { if (value == null) return; setState( () => items = _items diff --git a/lib/src/components/search_bar/search_bar.dart b/lib/src/components/search_bar/search_bar.dart index 2eaaf8df..d927c855 100644 --- a/lib/src/components/search_bar/search_bar.dart +++ b/lib/src/components/search_bar/search_bar.dart @@ -1,64 +1,195 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import '../../../zeta_flutter.dart'; +import '../../interfaces/form_field.dart'; +import '../buttons/input_icon_button.dart'; /// ZetaSearchBar provides input field for searching. /// {@category Components} -class ZetaSearchBar extends ZetaStatefulWidget { +class ZetaSearchBar extends ZetaTextFormField { /// Constructor for [ZetaSearchBar]. - const ZetaSearchBar({ - super.key, - this.size, - this.shape, + ZetaSearchBar({ + super.autovalidateMode, + super.validator, + super.onSaved, + super.onChange, + super.onFieldSubmitted, + super.requirementLevel, + super.controller, + super.disabled = false, + super.initialValue, + this.size = ZetaWidgetSize.medium, + this.shape = ZetaWidgetBorder.rounded, this.hint, - this.initialValue, - this.onChanged, - this.onSubmit, this.onSpeechToText, - this.disabled = false, - this.showLeadingIcon = true, this.showSpeechToText = true, @Deprecated('Use disabled instead. ' 'enabled is deprecated as of 0.11.0') bool enabled = true, this.focusNode, this.textInputAction, this.microphoneSemanticLabel, this.clearSemanticLabel, - }); + super.key, + @Deprecated('Show leading icon is deprecated as of 0.14.2') bool showLeadingIcon = true, + @Deprecated('Use onChange instead') ValueChanged? onChanged, + }) : super( + builder: (field) { + final zeta = Zeta.of(field.context); + + final _ZetaSearchBarState state = field as _ZetaSearchBarState; + + final BorderRadius borderRadius = switch (shape) { + ZetaWidgetBorder.rounded => ZetaRadius.minimal, + ZetaWidgetBorder.full => ZetaRadius.full, + _ => ZetaRadius.none, + }; + + final defaultInputBorder = OutlineInputBorder( + borderRadius: borderRadius, + borderSide: BorderSide(color: zeta.colors.cool.shade40), + ); + + final focusedBorder = defaultInputBorder.copyWith( + borderSide: BorderSide( + color: zeta.colors.blue.shade50, + width: ZetaSpacing.minimum, + ), + ); + + final disabledborder = defaultInputBorder.copyWith( + borderSide: BorderSide(color: zeta.colors.borderDisabled), + ); + + late final double iconSize; + late final double padding; + + switch (size) { + case ZetaWidgetSize.large: + iconSize = ZetaSpacing.xl_2; + padding = ZetaSpacing.medium; + case ZetaWidgetSize.medium: + iconSize = ZetaSpacing.xl_1; + padding = ZetaSpacing.small; + case ZetaWidgetSize.small: + iconSize = ZetaSpacing.large; + padding = ZetaSpacing.minimum; + } + + return ZetaRoundedScope( + rounded: shape != ZetaWidgetBorder.sharp, + child: Semantics( + excludeSemantics: disabled, + label: disabled ? hint ?? 'Search' : null, // TODO(UX-1003): Localize + enabled: disabled ? false : null, + child: TextFormField( + focusNode: focusNode, + enabled: !disabled, + controller: state.effectiveController, + keyboardType: TextInputType.text, + textInputAction: textInputAction, + onFieldSubmitted: onFieldSubmitted, + onChanged: state.onChange, + style: ZetaTextStyles.bodyMedium, + decoration: InputDecoration( + isDense: true, + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + vertical: padding, + ), + hintText: hint ?? 'Search', // TODO(UX-1003): Localize + hintStyle: ZetaTextStyles.bodyMedium.copyWith( + color: !disabled ? zeta.colors.textSubtle : zeta.colors.textDisabled, + ), + prefixIcon: Padding( + padding: const EdgeInsets.only(left: ZetaSpacingBase.x2_5, right: ZetaSpacing.small), + child: ZetaIcon( + ZetaIcons.search, + color: !disabled ? zeta.colors.cool.shade70 : zeta.colors.cool.shade50, + size: iconSize, + ), + ), + prefixIconConstraints: const BoxConstraints( + minHeight: ZetaSpacing.xl_2, + minWidth: ZetaSpacing.xl_2, + ), + suffixIcon: IntrinsicHeight( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (state.effectiveController.text.isNotEmpty && !disabled) ...[ + Semantics( + container: true, + button: true, + excludeSemantics: true, + label: clearSemanticLabel, + child: InputIconButton( + icon: ZetaIcons.cancel, + onTap: () => state.onChange(''), + disabled: disabled, + size: size, + color: zeta.colors.iconSubtle, + ), + ), + if (showSpeechToText) + SizedBox( + height: iconSize, + child: VerticalDivider( + color: zeta.colors.cool.shade40, + width: 5, + thickness: 1, + ), + ), + ], + if (showSpeechToText) + Semantics( + label: microphoneSemanticLabel, + container: true, + button: true, + excludeSemantics: true, + child: InputIconButton( + icon: ZetaIcons.microphone, + onTap: state.onSpeechToText, + disabled: disabled, + size: size, + color: zeta.colors.iconDefault, + ), + ), + ], + ), + ), + suffixIconConstraints: const BoxConstraints( + minHeight: ZetaSpacing.xl_2, + minWidth: ZetaSpacing.xl_2, + ), + filled: !disabled ? null : true, + fillColor: !disabled ? null : zeta.colors.cool.shade30, + enabledBorder: defaultInputBorder, + focusedBorder: focusedBorder, + disabledBorder: disabledborder, + ), + ), + ), + ); + }, + ); /// Determines the size of the input field. - /// Default is [ZetaWidgetSize.large] - final ZetaWidgetSize? size; + /// Default is [ZetaWidgetSize.medium] + final ZetaWidgetSize size; /// Determines the shape of the input field. /// Default is [ZetaWidgetBorder.rounded] - final ZetaWidgetBorder? shape; + final ZetaWidgetBorder shape; /// If provided, displays a hint inside the input field. /// Default is `Search`. final String? hint; - /// The initial value. - final String? initialValue; - - /// A callback, which provides the entered text. - final void Function(String? text)? onChanged; - - /// A callback, called when [textInputAction] is performed. - final void Function(String text)? onSubmit; - /// The type of action button to use for the keyboard. final TextInputAction? textInputAction; /// A callback, which is invoked when the microphone button is pressed. final Future Function()? onSpeechToText; - /// {@macro zeta-widget-disabled} - final bool disabled; - - /// Determines if there should be a leading icon. - /// Default is `true`. - final bool showLeadingIcon; - /// Determines if there should be a Speech-To-Text button. /// Default is `true`. final bool showSpeechToText; @@ -77,7 +208,7 @@ class ZetaSearchBar extends ZetaStatefulWidget { final String? clearSemanticLabel; @override - State createState() => _ZetaSearchBarState(); + FormFieldState createState() => _ZetaSearchBarState(); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { @@ -86,212 +217,27 @@ class ZetaSearchBar extends ZetaStatefulWidget { ..add(EnumProperty('size', size)) ..add(EnumProperty('shape', shape)) ..add(StringProperty('hint', hint)) - ..add(DiagnosticsProperty('enabled', disabled)) - ..add(ObjectFlagProperty.has('onChanged', onChanged)) ..add(StringProperty('initialValue', initialValue)) ..add(ObjectFlagProperty.has('onSpeechToText', onSpeechToText)) - ..add(DiagnosticsProperty('showLeadingIcon', showLeadingIcon)) ..add(DiagnosticsProperty('showSpeechToText', showSpeechToText)) ..add(DiagnosticsProperty('focusNode', focusNode)) - ..add(ObjectFlagProperty.has('onSubmit', onSubmit)) ..add(EnumProperty('textInputAction', textInputAction)) ..add(StringProperty('microphoneSemanticLabel', microphoneSemanticLabel)) ..add(StringProperty('clearSemanticLabel', clearSemanticLabel)); } } -class _ZetaSearchBarState extends State { - late final TextEditingController _controller; - late ZetaWidgetSize _size; - late ZetaWidgetBorder _shape; - +class _ZetaSearchBarState extends ZetaTextFormFieldState { @override - void initState() { - super.initState(); - _controller = TextEditingController(text: widget.initialValue ?? ''); - _size = widget.size ?? ZetaWidgetSize.large; - _shape = widget.shape ?? ZetaWidgetBorder.rounded; - } - - @override - void didUpdateWidget(ZetaSearchBar oldWidget) { - super.didUpdateWidget(oldWidget); - _size = widget.size ?? ZetaWidgetSize.large; - _shape = widget.shape ?? ZetaWidgetBorder.rounded; - if (oldWidget.initialValue != widget.initialValue) { - _controller.text = widget.initialValue ?? ''; + ZetaSearchBar get widget => super.widget as ZetaSearchBar; + + Future onSpeechToText() async { + if (widget.onSpeechToText != null) { + final text = await widget.onSpeechToText!(); + if (text != null) { + effectiveController.text = text; + super.onChange(value); + } } } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final zeta = Zeta.of(context); - final iconSize = _iconSize(_size); - - return ZetaRoundedScope( - rounded: widget.shape != ZetaWidgetBorder.sharp, - child: Semantics( - excludeSemantics: widget.disabled, - label: widget.disabled ? widget.hint ?? 'Search' : null, // TODO(UX-1003): Localize - enabled: widget.disabled ? false : null, - child: TextFormField( - focusNode: widget.focusNode, - enabled: !widget.disabled, - controller: _controller, - keyboardType: TextInputType.text, - textInputAction: widget.textInputAction, - onFieldSubmitted: widget.onSubmit, - onChanged: (value) => setState(() => widget.onChanged?.call(value)), - style: ZetaTextStyles.bodyMedium, - decoration: InputDecoration( - isDense: true, - contentPadding: EdgeInsets.symmetric( - horizontal: 10, - vertical: _inputVerticalPadding(_size), - ), - hintText: widget.hint ?? 'Search', // TODO(UX-1003): Localize - hintStyle: ZetaTextStyles.bodyMedium.copyWith( - color: !widget.disabled ? zeta.colors.textDefault : zeta.colors.cool.shade50, - ), - prefixIcon: widget.showLeadingIcon - ? Padding( - padding: const EdgeInsets.only(left: ZetaSpacingBase.x2_5, right: ZetaSpacing.small), - child: ZetaIcon( - ZetaIcons.search, - color: !widget.disabled ? zeta.colors.cool.shade70 : zeta.colors.cool.shade50, - size: iconSize, - ), - ) - : null, - prefixIconConstraints: const BoxConstraints( - minHeight: ZetaSpacing.xl_2, - minWidth: ZetaSpacing.xl_2, - ), - suffixIcon: IntrinsicHeight( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (_controller.text.isNotEmpty && !widget.disabled) ...[ - Semantics( - container: true, - button: true, - excludeSemantics: true, - label: widget.clearSemanticLabel, - child: IconButton( - key: const ValueKey('search-clear-btn'), - visualDensity: const VisualDensity( - horizontal: -4, - vertical: -4, - ), - onPressed: () { - setState(_controller.clear); - widget.onChanged?.call(''); - }, - icon: ZetaIcon( - ZetaIcons.cancel, - color: zeta.colors.cool.shade70, - size: iconSize, - ), - ), - ), - if (widget.showSpeechToText) - SizedBox( - height: iconSize, - child: VerticalDivider( - color: zeta.colors.cool.shade40, - width: 5, - thickness: 1, - ), - ), - ], - if (widget.showSpeechToText) - Padding( - padding: const EdgeInsets.only(right: ZetaSpacing.minimum), - child: Semantics( - container: true, - label: widget.microphoneSemanticLabel, - excludeSemantics: true, - button: true, - child: IconButton( - tooltip: widget.microphoneSemanticLabel, - key: const ValueKey('speech-to-text-btn'), - visualDensity: const VisualDensity( - horizontal: -4, - vertical: -4, - ), - onPressed: widget.onSpeechToText == null - ? null - : () async { - final text = await widget.onSpeechToText!.call(); - if (text != null) { - setState(() => _controller.text = text); - widget.onChanged?.call(text); - } - }, - icon: ZetaIcon( - ZetaIcons.microphone, - size: iconSize, - ), - ), - ), - ), - ], - ), - ), - suffixIconConstraints: const BoxConstraints( - minHeight: ZetaSpacing.xl_2, - minWidth: ZetaSpacing.xl_2, - ), - filled: !widget.disabled ? null : true, - fillColor: !widget.disabled ? null : zeta.colors.cool.shade30, - enabledBorder: _defaultInputBorder(zeta, shape: _shape), - focusedBorder: _focusedInputBorder(zeta, shape: _shape), - disabledBorder: _defaultInputBorder(zeta, shape: _shape), - ), - ), - ), - ); - } - - double _inputVerticalPadding(ZetaWidgetSize size) => switch (size) { - ZetaWidgetSize.large => ZetaSpacing.medium, - ZetaWidgetSize.medium => ZetaSpacing.small, - ZetaWidgetSize.small => ZetaSpacing.minimum, - }; - - double _iconSize(ZetaWidgetSize size) => switch (size) { - ZetaWidgetSize.large => ZetaSpacing.xl_2, - ZetaWidgetSize.medium => ZetaSpacing.xl_1, - ZetaWidgetSize.small => ZetaSpacing.large, - }; - - OutlineInputBorder _defaultInputBorder( - Zeta zeta, { - required ZetaWidgetBorder shape, - }) => - OutlineInputBorder( - borderRadius: _borderRadius(shape), - borderSide: BorderSide(color: zeta.colors.cool.shade40), - ); - - OutlineInputBorder _focusedInputBorder( - Zeta zeta, { - required ZetaWidgetBorder shape, - }) => - OutlineInputBorder( - borderRadius: _borderRadius(shape), - borderSide: BorderSide(color: zeta.colors.blue.shade50), - ); - - BorderRadius _borderRadius(ZetaWidgetBorder shape) => switch (shape) { - ZetaWidgetBorder.rounded => ZetaRadius.minimal, - ZetaWidgetBorder.full => ZetaRadius.full, - _ => ZetaRadius.none, - }; } diff --git a/lib/src/interfaces/form_field.dart b/lib/src/interfaces/form_field.dart index 57677b02..36178cb5 100644 --- a/lib/src/interfaces/form_field.dart +++ b/lib/src/interfaces/form_field.dart @@ -12,7 +12,9 @@ abstract class ZetaFormFieldStateOld { void reset(); } +/// An interface for all form fields used in Zeta abstract class ZetaFormField extends FormField { + /// Creates a new [ZetaFormField] const ZetaFormField({ required super.builder, required super.autovalidateMode, @@ -29,52 +31,31 @@ abstract class ZetaFormField extends FormField { enabled: !disabled, ); + /// Called whenever the form field changes. final ValueChanged? onChange; + /// Called whenever the form field is submitted. final ValueChanged? onFieldSubmitted; + /// The requirement level of the form field. final ZetaFormFieldRequirement? requirementLevel; -} - -/// A common interface shared with all Zeta form elements. -abstract class ZetaFormFieldOld extends ZetaStatefulWidget { - /// Creates a new [ZetaFormFieldOld] - const ZetaFormFieldOld({ - required this.disabled, - required this.initialValue, - required this.onChange, - required this.requirementLevel, - super.rounded, - super.key, - }); - - /// {@macro zeta-widget-disabled} - final bool disabled; - - /// The initial value of the form field. - final T? initialValue; - /// Called with the current value of the field whenever it is changed. - final ValueChanged? onChange; - - /// The requirement level of the form field, e.g. mandatory or optional. - final ZetaFormFieldRequirement requirementLevel; @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties - ..add(DiagnosticsProperty('disabled', disabled)) - ..add(DiagnosticsProperty('initialValue', initialValue)) ..add(ObjectFlagProperty?>.has('onChange', onChange)) - ..add(EnumProperty('requirementLevel', requirementLevel)); + ..add(ObjectFlagProperty?>.has('onFieldSubmitted', onFieldSubmitted)) + ..add(EnumProperty('requirementLevel', requirementLevel)); } } +/// A text form field used in Zeta abstract class ZetaTextFormField extends ZetaFormField { + /// Creates a new [ZetaTextFormField] ZetaTextFormField({ required super.builder, required super.autovalidateMode, - required super.initialValue, required super.validator, required super.onSaved, required super.onChange, @@ -82,16 +63,29 @@ abstract class ZetaTextFormField extends ZetaFormField { required super.disabled, required super.requirementLevel, required this.controller, + required String? initialValue, super.key, - }); + }) : super( + initialValue: controller != null ? controller.text : (initialValue ?? ''), + ); + /// The controller for the text form field. final TextEditingController? controller; + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty('controller', controller)); + } } +/// The state for a [ZetaTextFormField] class ZetaTextFormFieldState extends FormFieldState { @override ZetaTextFormField get widget => super.widget as ZetaTextFormField; + /// The effective controller for the form field. + /// This is either the controller passed in or a new controller. late final TextEditingController effectiveController; @override @@ -101,11 +95,12 @@ class ZetaTextFormFieldState extends FormFieldState { if (widget.initialValue != null) { effectiveController.text = widget.initialValue!; } + effectiveController.addListener(_handleControllerChange); super.initState(); } @override - void didUpdateWidget(covariant ZetaTextInput oldWidget) { + void didUpdateWidget(covariant ZetaTextFormField oldWidget) { if (oldWidget.initialValue != widget.initialValue && widget.initialValue != null) { effectiveController.text = widget.initialValue!; } @@ -119,13 +114,25 @@ class ZetaTextFormFieldState extends FormFieldState { widget.onChange?.call(effectiveController.text); } + /// Called whenever the form field changes. void onChange(String? value) { + didChange(value); + widget.onChange?.call(value); + } + + @override + void didChange(String? value) { super.didChange(value); if (effectiveController.text != value) { effectiveController.text = value ?? ''; } - widget.onChange?.call(value); + } + + void _handleControllerChange() { + if (effectiveController.text != value) { + didChange(effectiveController.text); + } } @override diff --git a/test/src/components/search_bar/search_bar_test.dart b/test/src/components/search_bar/search_bar_test.dart index 97ab79b0..f457a247 100644 --- a/test/src/components/search_bar/search_bar_test.dart +++ b/test/src/components/search_bar/search_bar_test.dart @@ -40,7 +40,7 @@ void main() { group('ZetaSearchBar', () { testWidgets('renders with default parameters', (WidgetTester tester) async { await tester.pumpWidget( - const TestApp( + TestApp( home: Scaffold( body: ZetaSearchBar(), ), @@ -53,7 +53,7 @@ void main() { testWidgets('golden: renders initializes correctly', (WidgetTester tester) async { await tester.pumpWidget( - const TestApp( + TestApp( home: ZetaSearchBar(), ), ); @@ -67,10 +67,8 @@ void main() { testWidgets('golden: renders size medium correctly', (WidgetTester tester) async { await tester.pumpWidget( - const TestApp( - home: ZetaSearchBar( - size: ZetaWidgetSize.medium, - ), + TestApp( + home: ZetaSearchBar(), ), ); expect(find.byType(ZetaSearchBar), findsOneWidget); @@ -83,7 +81,7 @@ void main() { testWidgets('golden: renders size small correctly', (WidgetTester tester) async { await tester.pumpWidget( - const TestApp( + TestApp( home: ZetaSearchBar( size: ZetaWidgetSize.small, ), @@ -99,7 +97,7 @@ void main() { testWidgets('golden: renders shape full correctly', (WidgetTester tester) async { await tester.pumpWidget( - const TestApp( + TestApp( home: ZetaSearchBar( shape: ZetaWidgetBorder.full, ), @@ -115,7 +113,7 @@ void main() { testWidgets('golden: renders shape sharp correctly', (WidgetTester tester) async { await tester.pumpWidget( - const TestApp( + TestApp( home: ZetaSearchBar( shape: ZetaWidgetBorder.sharp, ), @@ -133,7 +131,7 @@ void main() { const initialValue = 'Initial value'; await tester.pumpWidget( - const TestApp( + TestApp( home: Scaffold( body: ZetaSearchBar(initialValue: initialValue), ), @@ -149,7 +147,7 @@ void main() { const updatedValue = 'Updated value'; await tester.pumpWidget( - const TestApp( + TestApp( home: Scaffold( body: ZetaSearchBar(initialValue: initialValue), ), @@ -160,7 +158,7 @@ void main() { expect(find.text(initialValue), findsOneWidget); await tester.pumpWidget( - const TestApp( + TestApp( home: Scaffold( body: ZetaSearchBar(initialValue: updatedValue), ), @@ -175,7 +173,7 @@ void main() { await tester.pumpWidget( TestApp( home: Scaffold( - body: ZetaSearchBar(onChanged: callbacks.onChange), + body: ZetaSearchBar(onChange: callbacks.onChange), ), ), ); @@ -191,7 +189,7 @@ void main() { await tester.pumpWidget( TestApp( home: Scaffold( - body: ZetaSearchBar(onSubmit: callbacks.onSubmit), + body: ZetaSearchBar(onFieldSubmitted: callbacks.onSubmit), ), ), ); @@ -226,7 +224,7 @@ void main() { testWidgets('does not allow text input when disabled', (WidgetTester tester) async { await tester.pumpWidget( - const TestApp( + TestApp( home: Scaffold( body: ZetaSearchBar(disabled: true), ), @@ -240,12 +238,11 @@ void main() { expect(find.text('Disabled input'), findsNothing); }); - testWidgets('leading icon and speech-to-text button visibility', (WidgetTester tester) async { + testWidgets('speech-to-text button visibility', (WidgetTester tester) async { await tester.pumpWidget( - const TestApp( + TestApp( home: Scaffold( body: ZetaSearchBar( - showLeadingIcon: false, showSpeechToText: false, ), ), @@ -261,7 +258,7 @@ void main() { await tester.pumpWidget( TestApp( home: Scaffold( - body: ZetaSearchBar(onChanged: callbacks.onChange), + body: ZetaSearchBar(onChange: callbacks.onChange), ), ), ); @@ -289,15 +286,12 @@ void main() { const textInputAction = TextInputAction.search; final widget = ZetaSearchBar( - size: size, - shape: shape, hint: hint, initialValue: initialValue, - onChanged: callbacks.onChange, - onSubmit: callbacks.onSubmit, + onChange: callbacks.onChange, + onFieldSubmitted: callbacks.onSubmit, onSpeechToText: callbacks.onSpeech, disabled: disabled, - showLeadingIcon: showLeadingIcon, showSpeechToText: showSpeechToText, textInputAction: textInputAction, );