Skip to content

Commit 7b1cbd3

Browse files
committed
refactor(widgets): name SheetHandle's container key explicitly
Replace the constructor that accepted `key` and forwarded it to the inner Container while passing null to super. Swallowing `key` made SheetHandle(key: k) silently unkeyed, which is surprising for a shared widget. An explicit `handleKey` keeps the three drag-handle test assertions matching a single Container and leaves `key` behaving normally. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017B31wKKL578bV18hcpXyE2
1 parent 229d0fc commit 7b1cbd3

3 files changed

Lines changed: 32 additions & 13 deletions

File tree

lib/widgets/festival_menu_sheets.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class FestivalSelectorSheet extends StatelessWidget {
9191
mainAxisSize: MainAxisSize.min,
9292
crossAxisAlignment: CrossAxisAlignment.start,
9393
children: [
94-
const SheetHandle(key: Key('festival_selector_drag_handle')),
94+
const SheetHandle(handleKey: Key('festival_selector_drag_handle')),
9595
const SizedBox(height: 16),
9696
Row(
9797
children: [
@@ -449,7 +449,7 @@ class SettingsSheet extends StatelessWidget {
449449
mainAxisSize: MainAxisSize.min,
450450
crossAxisAlignment: CrossAxisAlignment.start,
451451
children: [
452-
const SheetHandle(key: Key('settings_sheet_drag_handle')),
452+
const SheetHandle(handleKey: Key('settings_sheet_drag_handle')),
453453
const SizedBox(height: 16),
454454
Text('Settings', style: theme.textTheme.titleLarge),
455455
const SizedBox(height: 16),
@@ -500,7 +500,7 @@ class ThemeSelectorSheet extends StatelessWidget {
500500
mainAxisSize: MainAxisSize.min,
501501
crossAxisAlignment: CrossAxisAlignment.start,
502502
children: [
503-
const SheetHandle(key: Key('theme_selector_sheet_drag_handle')),
503+
const SheetHandle(handleKey: Key('theme_selector_sheet_drag_handle')),
504504
const SizedBox(height: 16),
505505
Text('Theme', style: theme.textTheme.titleLarge),
506506
const SizedBox(height: 16),

lib/widgets/sheet_handle.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@ import 'package:flutter/material.dart';
33
/// Drag handle shown at the top of every modal bottom sheet in this app
44
/// (filter sheets, festival selector, settings, theme selector).
55
///
6-
/// The key passed to this widget is applied to the inner [Container] rather
7-
/// than to [SheetHandle] itself, so callers that key the drag handle for
8-
/// tests (`SheetHandle(key: Key('some_drag_handle'))`) can keep finding a
9-
/// [Container] with that key — matching the pre-refactor widget tree where
10-
/// the key lived directly on the hand-rolled `Container`.
6+
/// [handleKey] is applied to the inner [Container] rather than to this widget,
7+
/// so callers that key the drag handle for tests keep finding a [Container]
8+
/// with that key — matching the pre-refactor widget tree, where the key lived
9+
/// directly on the hand-rolled `Container`. Keying the widget itself via [key]
10+
/// remains available and behaves normally.
1111
class SheetHandle extends StatelessWidget {
12-
const SheetHandle({Key? key}) : _handleKey = key, super(key: null);
12+
const SheetHandle({this.handleKey, super.key});
1313

14-
final Key? _handleKey;
14+
/// Key applied to the inner container, for tests locating the handle.
15+
final Key? handleKey;
1516

1617
@override
1718
Widget build(BuildContext context) {
1819
return Center(
1920
child: Container(
20-
key: _handleKey,
21+
key: handleKey,
2122
width: 32,
2223
height: 4,
2324
decoration: BoxDecoration(

test/widgets/sheet_handle_test.dart

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,17 @@ void main() {
3434
);
3535
});
3636

37-
testWidgets('honours a passed key on the inner container', (tester) async {
37+
testWidgets('applies handleKey to the inner container', (tester) async {
3838
await tester.pumpWidget(
3939
const MaterialApp(
40-
home: Scaffold(body: SheetHandle(key: Key('my_drag_handle'))),
40+
home: Scaffold(body: SheetHandle(handleKey: Key('my_drag_handle'))),
4141
),
4242
);
4343

44+
// Exactly one match: the key lands on the Container only, never on the
45+
// SheetHandle itself, so tester.widget<Container>() stays unambiguous.
46+
expect(find.byKey(const Key('my_drag_handle')), findsOneWidget);
47+
4448
final container = tester.widget<Container>(
4549
find.byKey(const Key('my_drag_handle')),
4650
);
@@ -50,6 +54,20 @@ void main() {
5054
);
5155
});
5256

57+
testWidgets('keys the widget itself normally via key', (tester) async {
58+
await tester.pumpWidget(
59+
const MaterialApp(
60+
home: Scaffold(body: SheetHandle(key: Key('handle_widget'))),
61+
),
62+
);
63+
64+
expect(find.byKey(const Key('handle_widget')), findsOneWidget);
65+
expect(
66+
tester.widget(find.byKey(const Key('handle_widget'))),
67+
isA<SheetHandle>(),
68+
);
69+
});
70+
5371
testWidgets('uses onSurfaceVariant from the current theme', (tester) async {
5472
final lightTheme = buildAppTheme(Brightness.light);
5573

0 commit comments

Comments
 (0)