@@ -109,6 +109,8 @@ class _AutoSuggestBoxState<T> extends State<AutoSuggestBox> {
109109
110110 late TextEditingController controller;
111111
112+ final FocusScopeNode overlayNode = FocusScopeNode ();
113+
112114 @override
113115 void initState () {
114116 super .initState ();
@@ -153,6 +155,7 @@ class _AutoSuggestBoxState<T> extends State<AutoSuggestBox> {
153155 child: SizedBox (
154156 width: box.size.width,
155157 child: _AutoSuggestBoxOverlay (
158+ node: overlayNode,
156159 controller: controller,
157160 items: widget.items,
158161 onSelected: (String item) {
@@ -162,6 +165,11 @@ class _AutoSuggestBoxState<T> extends State<AutoSuggestBox> {
162165 offset: item.length,
163166 );
164167 widget.onChanged? .call (item, TextChangedReason .userInput);
168+
169+ // After selected, the overlay is dismissed and the text box is
170+ // unfocused
171+ _dismissOverlay ();
172+ focusNode.unfocus ();
165173 },
166174 ),
167175 ),
@@ -195,59 +203,77 @@ class _AutoSuggestBoxState<T> extends State<AutoSuggestBox> {
195203
196204 return CompositedTransformTarget (
197205 link: _layerLink,
198- child: TextBox (
199- key: _textBoxKey,
200- controller: controller,
201- focusNode: focusNode,
202- placeholder: widget.placeholder,
203- placeholderStyle: widget.placeholderStyle,
204- clipBehavior: _entry != null ? Clip .none : Clip .antiAliasWithSaveLayer,
205- suffix: Row (children: [
206- if (widget.trailingIcon != null ) widget.trailingIcon! ,
207- if (widget.clearButtonEnabled && controller.text.isNotEmpty)
208- Padding (
209- padding: const EdgeInsets .only (left: 2.0 ),
210- child: IconButton (
211- icon: const Icon (FluentIcons .chrome_close),
212- onPressed: () {
213- controller.clear ();
214- focusNode.unfocus ();
215- },
216- ),
217- ),
218- ]),
219- suffixMode: OverlayVisibilityMode .always,
220- onChanged: (text) {
221- widget.onChanged? .call (text, TextChangedReason .userInput);
222- _showOverlay ();
206+ child: Actions (
207+ actions: {
208+ DirectionalFocusIntent : _DirectionalFocusAction (),
223209 },
210+ child: TextBox (
211+ key: _textBoxKey,
212+ controller: controller,
213+ focusNode: focusNode,
214+ placeholder: widget.placeholder,
215+ placeholderStyle: widget.placeholderStyle,
216+ clipBehavior:
217+ _entry != null ? Clip .none : Clip .antiAliasWithSaveLayer,
218+ suffix: Row (children: [
219+ if (widget.trailingIcon != null ) widget.trailingIcon! ,
220+ if (widget.clearButtonEnabled &&
221+ controller.text.isNotEmpty &&
222+ focusNode.hasFocus)
223+ Padding (
224+ padding: const EdgeInsets .only (left: 2.0 ),
225+ child: IconButton (
226+ icon: const Icon (FluentIcons .chrome_close),
227+ onPressed: () {
228+ controller.clear ();
229+ focusNode.unfocus ();
230+ },
231+ ),
232+ ),
233+ ]),
234+ suffixMode: OverlayVisibilityMode .always,
235+ onChanged: (text) {
236+ widget.onChanged? .call (text, TextChangedReason .userInput);
237+ _showOverlay ();
238+ },
239+ ),
224240 ),
225241 );
226242 }
227243}
228244
245+ class _DirectionalFocusAction extends DirectionalFocusAction {
246+ @override
247+ void invoke (covariant DirectionalFocusIntent intent) {
248+ // if (!intent.ignoreTextFields || !_isForTextField) {
249+ // primaryFocus!.focusInDirection(intent.direction);
250+ // }
251+ debugPrint (intent.direction.toString ());
252+ }
253+ }
254+
229255class _AutoSuggestBoxOverlay extends StatelessWidget {
230256 const _AutoSuggestBoxOverlay ({
231257 Key ? key,
232258 required this .items,
233259 required this .controller,
234260 required this .onSelected,
261+ required this .node,
235262 }) : super (key: key);
236263
237264 final List items;
238265 final TextEditingController controller;
239266 final ValueChanged <String > onSelected;
267+ final FocusScopeNode node;
240268
241269 @override
242270 Widget build (BuildContext context) {
243271 final theme = FluentTheme .of (context);
244272 final localizations = FluentLocalizations .of (context);
245273 return FocusScope (
246- autofocus : true ,
274+ node : node ,
247275 child: Container (
248- constraints: const BoxConstraints (
249- maxHeight: 385 ,
250- ),
276+ constraints: const BoxConstraints (maxHeight: 380 ),
251277 decoration: ShapeDecoration (
252278 shape: RoundedRectangleBorder (
253279 borderRadius: const BorderRadius .vertical (
@@ -281,9 +307,7 @@ class _AutoSuggestBoxOverlay extends StatelessWidget {
281307 final item = items[index];
282308 return _AutoSuggestBoxOverlayTile (
283309 text: '$item ' ,
284- onSelected: () {
285- onSelected (item);
286- },
310+ onSelected: () => onSelected (item),
287311 );
288312 }),
289313 );
@@ -314,6 +338,7 @@ class _AutoSuggestBoxOverlayTile extends StatefulWidget {
314338class __AutoSuggestBoxOverlayTileState extends State <_AutoSuggestBoxOverlayTile >
315339 with SingleTickerProviderStateMixin {
316340 late AnimationController controller;
341+ final node = FocusNode ();
317342
318343 @override
319344 void initState () {
@@ -328,19 +353,21 @@ class __AutoSuggestBoxOverlayTileState extends State<_AutoSuggestBoxOverlayTile>
328353 @override
329354 void dispose () {
330355 controller.dispose ();
356+ node.dispose ();
331357 super .dispose ();
332358 }
333359
334360 @override
335361 Widget build (BuildContext context) {
336362 final theme = FluentTheme .of (context);
337363 return HoverButton (
364+ focusNode: node,
338365 onPressed: widget.onSelected,
339366 margin: const EdgeInsets .only (top: 4.0 , left: 4.0 , right: 4.0 ),
340367 builder: (context, states) => Stack (
341368 children: [
342369 Container (
343- height: 40 .0 ,
370+ height: 36 .0 ,
344371 padding: const EdgeInsets .symmetric (horizontal: 10.0 ),
345372 decoration: BoxDecoration (
346373 borderRadius: BorderRadius .circular (6.0 ),
0 commit comments