Skip to content

Commit 037925f

Browse files
authored
[#375] Add. hook for ExpansionTileController (#386)
1 parent 34d0808 commit 037925f

File tree

4 files changed

+129
-17
lines changed

4 files changed

+129
-17
lines changed

README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -338,22 +338,23 @@ They will take care of creating/updating/disposing an object.
338338

339339
A series of hooks with no particular theme.
340340

341-
| Name | Description |
342-
| ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
343-
| [useReducer](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useReducer.html) | An alternative to `useState` for more complex states. |
344-
| [usePrevious](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/usePrevious.html) | Returns the previous argument called to [usePrevious]. |
345-
| [useTextEditingController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useTextEditingController-constant.html) | Creates a `TextEditingController`. |
346-
| [useFocusNode](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useFocusNode.html) | Creates a `FocusNode`. |
347-
| [useTabController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useTabController.html) | Creates and disposes a `TabController`. |
348-
| [useScrollController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useScrollController.html) | Creates and disposes a `ScrollController`. |
349-
| [usePageController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/usePageController.html) | Creates and disposes a `PageController`. |
350-
| [useAppLifecycleState](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useAppLifecycleState.html) | Returns the current `AppLifecycleState` and rebuilds the widget on change. |
351-
| [useOnAppLifecycleStateChange](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useOnAppLifecycleStateChange.html) | Listens to `AppLifecycleState` changes and triggers a callback on change. |
352-
| [useTransformationController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useTransformationController.html) | Creates and disposes a `TransformationController`. |
353-
| [useIsMounted](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useIsMounted.html) | An equivalent to `State.mounted` for hooks. |
354-
| [useAutomaticKeepAlive](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useAutomaticKeepAlive.html) | An equivalent to the `AutomaticKeepAlive` widget for hooks. |
355-
| [useOnPlatformBrightnessChange](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useOnPlatformBrightnessChange.html) | Listens to platform `Brightness` changes and triggers a callback on change.|
356-
| [useSearchController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useSearchController.html) | Creates and disposes a `SearchController`. |
341+
| Name | Description |
342+
|--------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|
343+
| [useReducer](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useReducer.html) | An alternative to `useState` for more complex states. |
344+
| [usePrevious](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/usePrevious.html) | Returns the previous argument called to [usePrevious]. |
345+
| [useTextEditingController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useTextEditingController-constant.html) | Creates a `TextEditingController`. |
346+
| [useFocusNode](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useFocusNode.html) | Creates a `FocusNode`. |
347+
| [useTabController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useTabController.html) | Creates and disposes a `TabController`. |
348+
| [useScrollController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useScrollController.html) | Creates and disposes a `ScrollController`. |
349+
| [usePageController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/usePageController.html) | Creates and disposes a `PageController`. |
350+
| [useAppLifecycleState](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useAppLifecycleState.html) | Returns the current `AppLifecycleState` and rebuilds the widget on change. |
351+
| [useOnAppLifecycleStateChange](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useOnAppLifecycleStateChange.html) | Listens to `AppLifecycleState` changes and triggers a callback on change. |
352+
| [useTransformationController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useTransformationController.html) | Creates and disposes a `TransformationController`. |
353+
| [useIsMounted](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useIsMounted.html) | An equivalent to `State.mounted` for hooks. |
354+
| [useAutomaticKeepAlive](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useAutomaticKeepAlive.html) | An equivalent to the `AutomaticKeepAlive` widget for hooks. |
355+
| [useOnPlatformBrightnessChange](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useOnPlatformBrightnessChange.html) | Listens to platform `Brightness` changes and triggers a callback on change. |
356+
| [useSearchController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useSearchController.html) | Creates and disposes a `SearchController`. |
357+
| [useExpansionTileController](https://api.flutter.dev/flutter/material/ExpansionTileController-class.html) | Creates a `ExpansionTileController`. |
357358

358359
## Contributions
359360

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
part of 'hooks.dart';
2+
3+
/// Creates a [ExpansionTileController] that will be disposed automatically.
4+
///
5+
/// See also:
6+
/// - [ExpansionTileController]
7+
ExpansionTileController useExpansionTileController({List<Object?>? keys}) {
8+
return use(_ExpansionTileControllerHook(keys: keys));
9+
}
10+
11+
class _ExpansionTileControllerHook extends Hook<ExpansionTileController> {
12+
const _ExpansionTileControllerHook({List<Object?>? keys}) : super(keys: keys);
13+
14+
@override
15+
HookState<ExpansionTileController, Hook<ExpansionTileController>>
16+
createState() => _ExpansionTileControllerHookState();
17+
}
18+
19+
class _ExpansionTileControllerHookState
20+
extends HookState<ExpansionTileController, _ExpansionTileControllerHook> {
21+
final controller = ExpansionTileController();
22+
23+
@override
24+
String get debugLabel => 'useExpansionTileController';
25+
26+
@override
27+
ExpansionTileController build(BuildContext context) => controller;
28+
}

packages/flutter_hooks/lib/src/hooks.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import 'dart:async';
22

33
import 'package:flutter/foundation.dart';
44
import 'package:flutter/material.dart'
5-
show Brightness, SearchController, TabController;
5+
show Brightness, ExpansionTileController, SearchController, TabController;
66
import 'package:flutter/scheduler.dart';
77
import 'package:flutter/widgets.dart';
88

99
import 'framework.dart';
1010

1111
part 'animation.dart';
1212
part 'async.dart';
13+
part 'expansion_tile_controller.dart';
1314
part 'focus_node.dart';
1415
part 'focus_scope_node.dart';
1516
part 'keep_alive.dart';
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import 'package:flutter/foundation.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:flutter_hooks/src/framework.dart';
4+
import 'package:flutter_hooks/src/hooks.dart';
5+
6+
import 'mock.dart';
7+
8+
void main() {
9+
testWidgets('debugFillProperties', (tester) async {
10+
await tester.pumpWidget(
11+
HookBuilder(builder: (context) {
12+
useExpansionTileController();
13+
return const SizedBox();
14+
}),
15+
);
16+
17+
await tester.pump();
18+
19+
final element = tester.element(find.byType(HookBuilder));
20+
21+
expect(
22+
element
23+
.toDiagnosticsNode(style: DiagnosticsTreeStyle.offstage)
24+
.toStringDeep(),
25+
equalsIgnoringHashCodes(
26+
'HookBuilder\n'
27+
" │ useExpansionTileController: Instance of 'ExpansionTileController'\n"
28+
' └SizedBox(renderObject: RenderConstrainedBox#00000)\n',
29+
),
30+
);
31+
});
32+
33+
group('useExpansionTileController', () {
34+
testWidgets('initial values matches with real constructor', (tester) async {
35+
late ExpansionTileController controller;
36+
final controller2 = ExpansionTileController();
37+
38+
await tester.pumpWidget(MaterialApp(
39+
home: Scaffold(
40+
body: HookBuilder(builder: (context) {
41+
controller = useExpansionTileController();
42+
return Column(
43+
children: [
44+
ExpansionTile(
45+
controller: controller,
46+
title: const Text('Expansion Tile'),
47+
),
48+
ExpansionTile(
49+
controller: controller2,
50+
title: const Text('Expansion Tile 2'),
51+
),
52+
],
53+
);
54+
}),
55+
),
56+
));
57+
expect(controller, isA<ExpansionTileController>());
58+
expect(controller.isExpanded, controller2.isExpanded);
59+
});
60+
61+
testWidgets('check expansion/collapse of tile', (tester) async {
62+
late ExpansionTileController controller;
63+
await tester.pumpWidget(MaterialApp(
64+
home: Scaffold(
65+
body: HookBuilder(builder: (context) {
66+
controller = useExpansionTileController();
67+
return ExpansionTile(
68+
controller: controller,
69+
title: const Text('Expansion Tile'),
70+
);
71+
}),
72+
),
73+
));
74+
75+
expect(controller.isExpanded, false);
76+
controller.expand();
77+
expect(controller.isExpanded, true);
78+
controller.collapse();
79+
expect(controller.isExpanded, false);
80+
});
81+
});
82+
}

0 commit comments

Comments
 (0)