From 4110b0d53e5ab749fbf26b823a46b1c5905b0257 Mon Sep 17 00:00:00 2001 From: Xuan Nguyen <24372782+xuanswe@users.noreply.github.com> Date: Fri, 5 Sep 2025 12:07:55 +0200 Subject: [PATCH 1/4] Focus text field after clicking `SelectAll` icon button In the example, when user click `SelectAll` icon button, the `controller.selection` is updated, but the focus is moved to the `SelectAll` icon button. Visually, user doesn't see the selection. If we give the focus back to the text field, user will see the selection visually. --- .../ui/interactivity/actions-and-shortcuts.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/content/ui/interactivity/actions-and-shortcuts.md b/src/content/ui/interactivity/actions-and-shortcuts.md index e31fea3549b..921bc77a733 100644 --- a/src/content/ui/interactivity/actions-and-shortcuts.md +++ b/src/content/ui/interactivity/actions-and-shortcuts.md @@ -446,10 +446,12 @@ class CopyableTextField extends StatefulWidget { class _CopyableTextFieldState extends State { late final TextEditingController controller = TextEditingController(); + late final FocusNode focusNode = FocusNode(); @override void dispose() { controller.dispose(); + focusNode.dispose(); super.dispose(); } @@ -460,7 +462,7 @@ class _CopyableTextFieldState extends State { actions: >{ ClearIntent: ClearAction(controller), CopyIntent: CopyAction(controller), - SelectAllIntent: SelectAllAction(controller), + SelectAllIntent: SelectAllAction(controller, focusNode), }, child: Builder( builder: (context) { @@ -469,7 +471,12 @@ class _CopyableTextFieldState extends State { child: Row( children: [ const Spacer(), - Expanded(child: TextField(controller: controller)), + Expanded( + child: TextField( + controller: controller, + focusNode: focusNode, + ) + ), IconButton( icon: const Icon(Icons.copy), onPressed: Actions.handler( @@ -577,9 +584,10 @@ class SelectAllIntent extends Intent { /// An action that is bound to SelectAllAction that selects all text in its /// TextEditingController. class SelectAllAction extends Action { - SelectAllAction(this.controller); + SelectAllAction(this.controller, this.focusNode); final TextEditingController controller; + final FocusNode focusNode; @override Object? invoke(covariant SelectAllIntent intent) { @@ -589,6 +597,8 @@ class SelectAllAction extends Action { affinity: controller.selection.affinity, ); + focusNode.requestFocus(); + return null; } } From 7421ba3af27813ceb83605fae20efd9814864dd2 Mon Sep 17 00:00:00 2001 From: Xuan Nguyen <24372782+xuanswe@users.noreply.github.com> Date: Fri, 5 Sep 2025 19:57:14 +0200 Subject: [PATCH 2/4] Sync copyable_text.dart and actions-and-shortcuts.md --- .../actions_and_shortcuts/lib/copyable_text.dart | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/examples/ui/actions_and_shortcuts/lib/copyable_text.dart b/examples/ui/actions_and_shortcuts/lib/copyable_text.dart index 73a05a7ac7c..4cc0d9500c0 100644 --- a/examples/ui/actions_and_shortcuts/lib/copyable_text.dart +++ b/examples/ui/actions_and_shortcuts/lib/copyable_text.dart @@ -14,10 +14,12 @@ class CopyableTextField extends StatefulWidget { class _CopyableTextFieldState extends State { late final TextEditingController controller = TextEditingController(); + late final FocusNode focusNode = FocusNode(); @override void dispose() { controller.dispose(); + focusNode.dispose(); super.dispose(); } @@ -28,7 +30,7 @@ class _CopyableTextFieldState extends State { actions: >{ ClearIntent: ClearAction(controller), CopyIntent: CopyAction(controller), - SelectAllIntent: SelectAllAction(controller), + SelectAllIntent: SelectAllAction(controller, focusNode), }, child: Builder( builder: (context) { @@ -37,7 +39,12 @@ class _CopyableTextFieldState extends State { child: Row( children: [ const Spacer(), - Expanded(child: TextField(controller: controller)), + Expanded( + child: TextField( + controller: controller, + focusNode: focusNode, + ) + ), IconButton( icon: const Icon(Icons.copy), onPressed: Actions.handler( @@ -145,9 +152,10 @@ class SelectAllIntent extends Intent { /// An action that is bound to SelectAllAction that selects all text in its /// TextEditingController. class SelectAllAction extends Action { - SelectAllAction(this.controller); + SelectAllAction(this.controller, this.focusNode); final TextEditingController controller; + final FocusNode focusNode; @override Object? invoke(covariant SelectAllIntent intent) { @@ -157,6 +165,8 @@ class SelectAllAction extends Action { affinity: controller.selection.affinity, ); + focusNode.requestFocus(); + return null; } } From 5d63cc32346644aacc1aee82decc147fbdb762d5 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Mon, 8 Sep 2025 16:58:44 -0500 Subject: [PATCH 3/4] Run formatter --- examples/ui/actions_and_shortcuts/lib/copyable_text.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ui/actions_and_shortcuts/lib/copyable_text.dart b/examples/ui/actions_and_shortcuts/lib/copyable_text.dart index 4cc0d9500c0..b43613a2559 100644 --- a/examples/ui/actions_and_shortcuts/lib/copyable_text.dart +++ b/examples/ui/actions_and_shortcuts/lib/copyable_text.dart @@ -43,7 +43,7 @@ class _CopyableTextFieldState extends State { child: TextField( controller: controller, focusNode: focusNode, - ) + ), ), IconButton( icon: const Icon(Icons.copy), From 79d21fc73c5c379c3bd9b1f67d3e6887183eef53 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Mon, 8 Sep 2025 17:01:53 -0500 Subject: [PATCH 4/4] Update excerpt as well --- src/content/ui/interactivity/actions-and-shortcuts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/ui/interactivity/actions-and-shortcuts.md b/src/content/ui/interactivity/actions-and-shortcuts.md index 921bc77a733..66e7e93f32a 100644 --- a/src/content/ui/interactivity/actions-and-shortcuts.md +++ b/src/content/ui/interactivity/actions-and-shortcuts.md @@ -475,7 +475,7 @@ class _CopyableTextFieldState extends State { child: TextField( controller: controller, focusNode: focusNode, - ) + ), ), IconButton( icon: const Icon(Icons.copy),