Skip to content

Commit 30aa93e

Browse files
feat: update FormBuilderRadioGroup with new RadioGroup widget
1 parent 7694bfc commit 30aa93e

File tree

3 files changed

+84
-35
lines changed

3 files changed

+84
-35
lines changed

lib/src/fields/form_builder_radio_group.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import 'package:flutter/material.dart';
2-
3-
import 'package:flutter_form_builder/flutter_form_builder.dart';
2+
import 'package:flutter_form_builder/src/form_builder_field.dart';
3+
import 'package:flutter_form_builder/src/form_builder_field_decoration.dart';
4+
import 'package:flutter_form_builder/src/form_builder_field_option.dart';
5+
import 'package:flutter_form_builder/src/widgets/grouped_radio.dart';
46

57
/// Field to select one value from a list of Radio Widgets
68
class FormBuilderRadioGroup<T> extends FormBuilderFieldDecoration<T> {

lib/src/widgets/grouped_radio.dart

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -217,36 +217,42 @@ class _GroupedRadioState<T> extends State<GroupedRadio<T?>> {
217217
widgetList.add(buildItem(i));
218218
}
219219

220-
return switch (widget.orientation) {
221-
OptionsOrientation.auto => OverflowBar(
222-
alignment: MainAxisAlignment.spaceEvenly,
223-
children: widgetList,
224-
),
225-
OptionsOrientation.vertical => SingleChildScrollView(
226-
scrollDirection: Axis.vertical,
227-
child: Column(
228-
crossAxisAlignment: CrossAxisAlignment.start,
220+
return RadioGroup<T?>(
221+
onChanged: (value) {
222+
widget.onChanged(value);
223+
},
224+
groupValue: widget.value,
225+
child: switch (widget.orientation) {
226+
OptionsOrientation.auto => OverflowBar(
227+
alignment: MainAxisAlignment.spaceEvenly,
229228
children: widgetList,
230229
),
231-
),
232-
OptionsOrientation.horizontal => SingleChildScrollView(
233-
scrollDirection: Axis.horizontal,
234-
child: Row(children: widgetList),
235-
),
236-
OptionsOrientation.wrap => SingleChildScrollView(
237-
child: Wrap(
238-
spacing: widget.wrapSpacing,
239-
runSpacing: widget.wrapRunSpacing,
240-
textDirection: widget.wrapTextDirection,
241-
crossAxisAlignment: widget.wrapCrossAxisAlignment,
242-
verticalDirection: widget.wrapVerticalDirection,
243-
alignment: widget.wrapAlignment,
244-
direction: Axis.horizontal,
245-
runAlignment: widget.wrapRunAlignment,
246-
children: widgetList,
230+
OptionsOrientation.vertical => SingleChildScrollView(
231+
scrollDirection: Axis.vertical,
232+
child: Column(
233+
crossAxisAlignment: CrossAxisAlignment.start,
234+
children: widgetList,
235+
),
236+
),
237+
OptionsOrientation.horizontal => SingleChildScrollView(
238+
scrollDirection: Axis.horizontal,
239+
child: Row(children: widgetList),
240+
),
241+
OptionsOrientation.wrap => SingleChildScrollView(
242+
child: Wrap(
243+
spacing: widget.wrapSpacing,
244+
runSpacing: widget.wrapRunSpacing,
245+
textDirection: widget.wrapTextDirection,
246+
crossAxisAlignment: widget.wrapCrossAxisAlignment,
247+
verticalDirection: widget.wrapVerticalDirection,
248+
alignment: widget.wrapAlignment,
249+
direction: Axis.horizontal,
250+
runAlignment: widget.wrapRunAlignment,
251+
children: widgetList,
252+
),
247253
),
248-
),
249-
};
254+
},
255+
);
250256
}
251257

252258
/// the composite of all the components for the option at index
@@ -255,17 +261,12 @@ class _GroupedRadioState<T> extends State<GroupedRadio<T?>> {
255261
final optionValue = option.value;
256262
final isOptionDisabled = true == widget.disabled?.contains(optionValue);
257263
final control = Radio<T?>(
258-
groupValue: widget.value,
259264
activeColor: widget.activeColor,
260265
focusColor: widget.focusColor,
261266
hoverColor: widget.hoverColor,
262267
materialTapTargetSize: widget.materialTapTargetSize,
263268
value: optionValue,
264-
onChanged: isOptionDisabled
265-
? null
266-
: (T? selected) {
267-
widget.onChanged(selected);
268-
},
269+
enabled: !isOptionDisabled,
269270
);
270271

271272
final label = GestureDetector(

test/src/fields/form_builder_radio_group_test.dart

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,51 @@ void main() {
172172
expect(Focus.of(tester.element(widgetFinder)).hasFocus, true);
173173
expect(focusNode?.hasFocus, true);
174174
});
175+
testWidgets(
176+
'when change value, onChange will be called with value changed',
177+
(WidgetTester tester) async {
178+
const widgetName = 'key';
179+
int? changedValue;
180+
final testWidget = FormBuilderRadioGroup<int>(
181+
name: widgetName,
182+
onChanged: (value) {
183+
changedValue = value;
184+
},
185+
options: const [
186+
FormBuilderFieldOption(key: ValueKey('1'), value: 1),
187+
FormBuilderFieldOption(key: ValueKey('2'), value: 2),
188+
FormBuilderFieldOption(key: ValueKey('3'), value: 3),
189+
],
190+
);
191+
await tester.pumpWidget(buildTestableFieldWidget(testWidget));
192+
193+
expect(formValue(widgetName), isNull);
194+
await tester.tap(find.byKey(const ValueKey('2')));
195+
await tester.pumpAndSettle();
196+
expect(changedValue, equals(2));
197+
},
198+
);
199+
testWidgets('when is disable then can not change value', (
200+
WidgetTester tester,
201+
) async {
202+
const widgetName = 'key';
203+
int? changedValue;
204+
final testWidget = FormBuilderRadioGroup<int>(
205+
name: widgetName,
206+
onChanged: (value) {
207+
changedValue = value;
208+
},
209+
enabled: false,
210+
options: const [
211+
FormBuilderFieldOption(key: ValueKey('1'), value: 1),
212+
FormBuilderFieldOption(key: ValueKey('2'), value: 2),
213+
FormBuilderFieldOption(key: ValueKey('3'), value: 3),
214+
],
215+
);
216+
await tester.pumpWidget(buildTestableFieldWidget(testWidget));
217+
await tester.tap(find.byKey(const ValueKey('2')));
218+
await tester.pumpAndSettle();
219+
expect(changedValue, equals(null));
220+
});
175221
});
176222
}

0 commit comments

Comments
 (0)