Skip to content

Commit 43f2a59

Browse files
authored
Merge pull request #1866 from EnsembleUI/radio-focus
Added focus and Scroll for Radio Group & Dropdown
2 parents 948fd86 + b62f2fb commit 43f2a59

File tree

2 files changed

+76
-4
lines changed

2 files changed

+76
-4
lines changed

modules/ensemble/lib/widget/input/dropdown.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,26 @@ class SelectOneState extends FormFieldWidgetState<SelectOne>
297297
});*/
298298
widget.controller.textEditingController =
299299
TextEditingController(text: widget.getValue());
300+
focusNode.addListener(_handleFocusChange);
300301

301302
super.initState();
302303
}
303304

305+
void _handleFocusChange() {
306+
// If gaining focus, scroll into view
307+
WidgetsBinding.instance.addPostFrameCallback((_) {
308+
final context = validatorKey.currentContext;
309+
if (context != null) {
310+
Scrollable.ensureVisible(
311+
context,
312+
duration: const Duration(milliseconds: 300),
313+
curve: Curves.easeInOut,
314+
alignment: 0.5,
315+
);
316+
}
317+
});
318+
}
319+
304320
@override
305321
void didChangeDependencies() {
306322
super.didChangeDependencies();

modules/ensemble/lib/widget/radio/radio_group.dart

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ class RadioGroup extends StatefulWidget
4141

4242
@override
4343
Map<String, Function> methods() {
44-
return {};
44+
return {
45+
'focus': () => _controller.radioGroupAction?.focusInputField(),
46+
'unfocus': () => _controller.radioGroupAction?.unfocusInputField(),
47+
};
4548
}
4649

4750
@override
@@ -73,7 +76,12 @@ class RadioGroup extends StatefulWidget
7376
}
7477
}
7578

79+
mixin RadioGroupAction on FormFieldWidgetState<RadioGroup> {
80+
void focusInputField();
81+
void unfocusInputField();
82+
}
7683
class RadioGroupController extends FormFieldController {
84+
RadioGroupAction? radioGroupAction;
7785
dynamic selectedValue;
7886

7987
// list of string for items
@@ -101,12 +109,43 @@ class RadioGroupController extends FormFieldController {
101109
}
102110

103111
class RadioGroupState extends FormFieldWidgetState<RadioGroup>
104-
with TemplatedWidgetState {
112+
with RadioGroupAction, TemplatedWidgetState {
105113
List? itemTemplateData;
114+
FocusNode focusNode = FocusNode();
115+
116+
@override
117+
void initState() {
118+
super.initState();
119+
focusNode.addListener(_handleFocusChange);
120+
}
121+
122+
@override
123+
void dispose() {
124+
focusNode.removeListener(_handleFocusChange);
125+
focusNode.dispose();
126+
super.dispose();
127+
}
128+
129+
void _handleFocusChange() {
130+
// If gaining focus, scroll into view
131+
WidgetsBinding.instance.addPostFrameCallback((_) {
132+
final context = validatorKey.currentContext;
133+
if (context != null) {
134+
Scrollable.ensureVisible(
135+
context,
136+
duration: const Duration(milliseconds: 300),
137+
curve: Curves.easeInOut,
138+
alignment: 0.5,
139+
);
140+
}
141+
});
142+
143+
}
106144

107145
@override
108146
void didChangeDependencies() {
109147
super.didChangeDependencies();
148+
widget.controller.radioGroupAction = this;
110149

111150
if (widget._controller.itemTemplate != null) {
112151
registerItemTemplate(context, widget._controller.itemTemplate!,
@@ -116,6 +155,20 @@ class RadioGroupState extends FormFieldWidgetState<RadioGroup>
116155
}
117156
}
118157

158+
@override
159+
void focusInputField() {
160+
if (!focusNode.hasFocus) {
161+
focusNode.requestFocus();
162+
}
163+
}
164+
165+
@override
166+
void unfocusInputField() {
167+
if (focusNode.hasFocus) {
168+
focusNode.unfocus();
169+
}
170+
}
171+
119172
@override
120173
Widget buildWidget(BuildContext context) {
121174
// build the children and gap if applicable
@@ -159,7 +212,9 @@ class RadioGroupState extends FormFieldWidgetState<RadioGroup>
159212
return null;
160213
},
161214
builder: (FormFieldState<String> field) {
162-
return InputDecorator(
215+
return Focus(
216+
focusNode: focusNode,
217+
child: InputDecorator(
163218
decoration: inputDecoration.copyWith(
164219
contentPadding: EdgeInsets.zero,
165220
filled: false,
@@ -169,7 +224,8 @@ class RadioGroupState extends FormFieldWidgetState<RadioGroup>
169224
focusedBorder: InputBorder.none,
170225
errorText: field.errorText,
171226
errorStyle: widget._controller.errorStyle ?? Theme.of(context).inputDecorationTheme.errorStyle),
172-
child: rtn);
227+
child: rtn),
228+
);
173229
},
174230
),
175231
);

0 commit comments

Comments
 (0)