Skip to content

Commit

Permalink
[rrousselGit#375] Add. hook for ExpansionTileController
Browse files Browse the repository at this point in the history
  • Loading branch information
droidbg committed Oct 7, 2023
1 parent 92bd0e2 commit aaf28c1
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 17 deletions.
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,22 +338,23 @@ They will take care of creating/updating/disposing an object.

A series of hooks with no particular theme.

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

## Contributions

Expand Down
28 changes: 28 additions & 0 deletions packages/flutter_hooks/lib/src/expansion_tile_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
part of 'hooks.dart';

/// Creates a [ExpansionTileController] that will be disposed automatically.
///
/// See also:
/// - [ExpansionTileController]
ExpansionTileController useExpansionTileController({List<Object?>? keys}) {
return use(_ExpansionTileControllerHook(keys: keys));
}

class _ExpansionTileControllerHook extends Hook<ExpansionTileController> {
const _ExpansionTileControllerHook({List<Object?>? keys}) : super(keys: keys);

@override
HookState<ExpansionTileController, Hook<ExpansionTileController>>
createState() => _ExpansionTileControllerHookState();
}

class _ExpansionTileControllerHookState
extends HookState<ExpansionTileController, _ExpansionTileControllerHook> {
final controller = ExpansionTileController();

@override
String get debugLabel => 'useExpansionTileController';

@override
ExpansionTileController build(BuildContext context) => controller;
}
3 changes: 2 additions & 1 deletion packages/flutter_hooks/lib/src/hooks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'
show Brightness, SearchController, TabController;
show Brightness, ExpansionTileController, SearchController, TabController;
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';

import 'framework.dart';

part 'animation.dart';
part 'async.dart';
part 'expansion_tile_controller.dart';
part 'focus_node.dart';
part 'focus_scope_node.dart';
part 'keep_alive.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/src/framework.dart';
import 'package:flutter_hooks/src/hooks.dart';

import 'mock.dart';

void main() {
testWidgets('debugFillProperties', (tester) async {
await tester.pumpWidget(
HookBuilder(builder: (context) {
useExpansionTileController();
return const SizedBox();
}),
);

await tester.pump();

final element = tester.element(find.byType(HookBuilder));

expect(
element
.toDiagnosticsNode(style: DiagnosticsTreeStyle.offstage)
.toStringDeep(),
equalsIgnoringHashCodes(
'HookBuilder\n'
" │ useExpansionTileController: Instance of 'ExpansionTileController'\n"
' └SizedBox(renderObject: RenderConstrainedBox#00000)\n',
),
);
});

group('useExpansionTileController', () {
testWidgets('initial values matches with real constructor', (tester) async {
late ExpansionTileController controller;
final controller2 = ExpansionTileController();

await tester.pumpWidget(MaterialApp(
home: Scaffold(
body: HookBuilder(builder: (context) {
controller = useExpansionTileController();
return Column(
children: [
ExpansionTile(
controller: controller,
title: const Text('Expansion Tile'),
),
ExpansionTile(
controller: controller2,
title: const Text('Expansion Tile 2'),
),
],
);
}),
),
));
expect(controller, isA<ExpansionTileController>());
expect(controller.isExpanded, controller2.isExpanded);
});

testWidgets('check expansion/collapse of tile', (tester) async {
late ExpansionTileController controller;
await tester.pumpWidget(MaterialApp(
home: Scaffold(
body: HookBuilder(builder: (context) {
controller = useExpansionTileController();
return ExpansionTile(
controller: controller,
title: const Text('Expansion Tile'),
);
}),
),
));

expect(controller.isExpanded, false);
controller.expand();
expect(controller.isExpanded, true);
controller.collapse();
expect(controller.isExpanded, false);
});
});
}

0 comments on commit aaf28c1

Please sign in to comment.