[client] Search focus

This commit is contained in:
Abhishek Shroff
2025-04-22 23:01:15 +05:30
parent e5d9690f94
commit e30d58c3ba
4 changed files with 60 additions and 19 deletions
+4 -1
View File
@@ -9,7 +9,9 @@ import 'package:provider/provider.dart';
class AppActions extends StatelessWidget {
final Widget child;
const AppActions({super.key, required this.child});
final FocusNode searchFocusNode;
const AppActions({super.key, required this.child, required this.searchFocusNode});
@override
Widget build(BuildContext context) {
@@ -65,6 +67,7 @@ class AppActions extends StatelessWidget {
NavForwardIntent: CallbackAction<NavForwardIntent>(
onInvoke: (i) => context.read<PhylumRouterDelegate>().goForward(),
),
FocusSearchIntent: CallbackAction<FocusSearchIntent>(onInvoke: (i) => searchFocusNode.requestFocus()),
},
child: child,
);
+30 -5
View File
@@ -13,7 +13,7 @@ import 'package:phylum/ui/menu/bottom_sheet.dart';
import 'package:phylum/ui/menu/option_groups.dart';
import 'package:provider/provider.dart';
class AppLayout extends StatelessWidget {
class AppLayout extends StatefulWidget {
const AppLayout._();
static Widget create() {
@@ -24,10 +24,28 @@ class AppLayout extends StatelessWidget {
);
}
@override
State<AppLayout> createState() => _AppLayoutState();
}
class _AppLayoutState extends State<AppLayout> {
final _searchFocusNode = FocusNode();
@override
void dispose() {
_searchFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.sizeOf(context);
final layout = size.width <= 600 ? CollapsedAppLayout() : ExpandedAppLayout(large: size.width > 1200);
final layout = size.width <= 600
? CollapsedAppLayout()
: ExpandedAppLayout(
large: size.width > 1200,
searchFocusNode: _searchFocusNode,
);
return ExternalDropRegion(
buildItem: (context, dropTargetActive) {
final child = (dropTargetActive)
@@ -48,7 +66,10 @@ class AppLayout extends StatelessWidget {
],
)
: layout;
return AppActions(child: child);
return AppActions(
searchFocusNode: _searchFocusNode,
child: child,
);
},
);
}
@@ -121,8 +142,10 @@ class CollapsedAppLayout extends StatelessWidget {
}
class ExpandedAppLayout extends StatelessWidget {
final FocusNode searchFocusNode;
final bool large;
const ExpandedAppLayout({super.key, required this.large});
const ExpandedAppLayout({super.key, required this.large, required this.searchFocusNode});
@override
Widget build(BuildContext context) {
@@ -156,7 +179,9 @@ class ExpandedAppLayout extends StatelessWidget {
child: Icon(Icons.search),
),
Expanded(
child: SearchField(),
child: SearchField(
focusNode: searchFocusNode,
),
),
],
),
+5
View File
@@ -96,6 +96,10 @@ class NavIntent extends Intent {
const NavIntent({required this.target});
}
class FocusSearchIntent extends Intent {
const FocusSearchIntent();
}
Map<ShortcutActivator, Intent> get appShortcuts => const {
// General
SingleActivator(LogicalKeyboardKey.tab): NextFocusIntent(),
@@ -142,6 +146,7 @@ Map<ShortcutActivator, Intent> get appShortcuts => const {
// Top-level Navigation
SingleActivator(LogicalKeyboardKey.arrowUp, alt: true): NavUpIntent(),
SingleActivator(LogicalKeyboardKey.keyH, alt: true): NavIntent(target: ExplorerPageHome()),
SingleActivator(LogicalKeyboardKey.keyS, alt: true): FocusSearchIntent(),
if (!kIsWeb) SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true): NavBackIntent(),
if (!kIsWeb) SingleActivator(LogicalKeyboardKey.arrowRight, alt: true): NavForwardIntent(),
};
+21 -13
View File
@@ -5,7 +5,9 @@ import 'package:phylum/ui/explorer/page.dart';
import 'package:provider/provider.dart';
class SearchField extends StatefulWidget {
const SearchField({super.key});
final FocusNode focusNode;
const SearchField({super.key, required this.focusNode});
@override
State<SearchField> createState() => _SearchFieldState();
@@ -35,19 +37,25 @@ class _SearchFieldState extends State<SearchField> {
@override
Widget build(BuildContext context) {
return TextField(
decoration: InputDecoration.collapsed(
hintText: 'Search Files...',
hintStyle: TextStyle(fontSize: 18),
),
controller: _controller,
style: TextStyle(fontSize: 18),
onSubmitted: (text) {
final query = text.trim();
if (query.isNotEmpty) {
context.read<PhylumRouterDelegate>().go(ExplorerPageSearch(query: query));
}
return Actions(
actions: {
DismissIntent: CallbackAction<DismissIntent>(onInvoke: (i) => widget.focusNode.nextFocus()),
},
child: TextField(
decoration: InputDecoration.collapsed(
hintText: 'Search Files...',
hintStyle: TextStyle(fontSize: 18),
),
focusNode: widget.focusNode,
controller: _controller,
style: TextStyle(fontSize: 18),
onSubmitted: (text) {
final query = text.trim();
if (query.isNotEmpty) {
context.read<PhylumRouterDelegate>().go(ExplorerPageSearch(query: query));
}
},
),
);
}
}