-
Notifications
You must be signed in to change notification settings - Fork 28.9k
Description
Use case
I have a use-case where if descendants of a FocusScope
are not focusable, then it should not be possible to focus the scope itself. Otherwise this introduce a bug where you have to press TAB twice (see video & sample code).
Current problem
- run the sample code
- Press TAB twice
EXPECTED
Since focus scope doesn't have any focusable descendant, then Enabled Button 2
should be focused
CURRENT
You have to press TAB trice to focus Enabled Button 2
NO WORKAROUNDS...
I can't simply set skipTraversal: true
dynamically as my parent component doesn't know wether descendants are focusable or not.
Video
preview.mp4
Sample code
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SemanticsBinding.instance.ensureSemantics();
final node = FocusScopeNode();
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('FocusScope.onFocusChange Bug')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
MaterialButton(
onPressed: () {}, // disabled
child: Text('Enabled Button 1'),
),
FocusScope(
descendantsAreFocusable: true,
descendantsAreTraversable: true,
onFocusChange: (focused) {
debugPrint('FocusScope: $focused - focusable descendants: ${node.traversalDescendants.length}');
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: const [
MaterialButton(
onPressed: null, // disabled
child: Text('Disabled Button 1'),
),
SizedBox(height: 16),
MaterialButton(
onPressed: null, // disabled
child: Text('Disabled Button 2'),
),
],
),
),
MaterialButton(
onPressed: () {}, // disabled
child: Text('Enabled Button 2'),
),
],
),
),
),
),
);
}
Proposal
Provide a boolean param so we can control this behaviour, e.g. "skipScopeFocusIfNoTraversalDescendants". When true (regardless of the value from skipTraversal
), whenever the Scope is about to gain focus but no descendants are traversable, then "do not" focus the scope itself.