fix: make text fields focusable in traversal

This commit is contained in:
edde746
2026-05-06 12:06:55 +02:00
parent c75c87f527
commit cf4fc74d68
2 changed files with 65 additions and 1 deletions
+4 -1
View File
@@ -171,7 +171,10 @@ abstract class _FocusableTextInputBase extends StatelessWidget {
Widget buildFocusableInput(BuildContext context, Widget Function(bool usesTvKeyboard) builder) {
final usesTvKeyboard = _hasTvKeyboard;
return Focus(
canRequestFocus: enabled,
// This wrapper only intercepts key events bubbling from the input; the
// real TextField/TextFormField must remain the traversable focus target.
canRequestFocus: false,
skipTraversal: true,
onKeyEvent: (node, event) => _handleKey(context, node, event),
child: builder(usesTvKeyboard),
);
@@ -0,0 +1,61 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:plezy/focus/focusable_text_field.dart';
void main() {
testWidgets('tab traversal focuses the text form field instead of its key handler wrapper', (tester) async {
final controller = TextEditingController();
final fieldFocusNode = FocusNode(debugLabel: 'server_url_field');
final buttonFocusNode = FocusNode(debugLabel: 'find_server_button');
addTearDown(controller.dispose);
addTearDown(fieldFocusNode.dispose);
addTearDown(buttonFocusNode.dispose);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Column(
children: [
FocusableTextFormField(
controller: controller,
focusNode: fieldFocusNode,
decoration: const InputDecoration(labelText: 'Server URL'),
),
FilledButton(focusNode: buttonFocusNode, onPressed: () {}, child: const Text('Find server')),
],
),
),
),
);
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.pump();
expect(fieldFocusNode.hasPrimaryFocus, isTrue);
expect(buttonFocusNode.hasFocus, isFalse);
});
testWidgets('focused text form field still receives wrapper select handling', (tester) async {
final controller = TextEditingController();
final fieldFocusNode = FocusNode(debugLabel: 'server_url_field');
var selects = 0;
addTearDown(controller.dispose);
addTearDown(fieldFocusNode.dispose);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: FocusableTextFormField(controller: controller, focusNode: fieldFocusNode, onSelect: () => selects++),
),
),
);
fieldFocusNode.requestFocus();
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.select);
await tester.pump();
expect(selects, 1);
});
}