From 5d37debd460080836b4cef5fa356460d1a33f0ac Mon Sep 17 00:00:00 2001 From: Eren Gun Date: Tue, 17 Jun 2025 09:43:46 +0300 Subject: [PATCH 1/6] Add useCupertinoTabController hook for automatic disposal of CupertinoTabController --- .../lib/src/cupertino_tab_controller.dart | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 packages/flutter_hooks/lib/src/cupertino_tab_controller.dart diff --git a/packages/flutter_hooks/lib/src/cupertino_tab_controller.dart b/packages/flutter_hooks/lib/src/cupertino_tab_controller.dart new file mode 100644 index 0000000..eac6af5 --- /dev/null +++ b/packages/flutter_hooks/lib/src/cupertino_tab_controller.dart @@ -0,0 +1,47 @@ +part of 'hooks.dart'; + + +/// Creates a [CupertinoTabController] that will be disposed automatically. +/// +/// See also: +/// - [CupertinoTabController] +CupertinoTabController useCupertinoTabController({ + int initialIndex = 0, + List? keys, +}) { + return use( + _CupertinoTabControllerHook( + initialIndex: initialIndex, + keys: keys, + ), + ); +} + +class _CupertinoTabControllerHook extends Hook { + const _CupertinoTabControllerHook({ + required this.initialIndex, + super.keys, + }); + + final int initialIndex; + + @override + HookState> createState() => + _CupertinoTabControllerHookState(); +} + +class _CupertinoTabControllerHookState + extends HookState { + late final controller = CupertinoTabController( + initialIndex: hook.initialIndex, + ); + + @override + CupertinoTabController build(BuildContext context) => controller; + + @override + void dispose() => controller.dispose(); + + @override + String get debugLabel => 'useCupertinoTabController'; +} \ No newline at end of file From 01cf58af23c243a3047e1751cd3bdb5a6505df4e Mon Sep 17 00:00:00 2001 From: Eren Gun Date: Tue, 17 Jun 2025 09:43:51 +0300 Subject: [PATCH 2/6] Add import for CupertinoTabController and include it in part directives --- packages/flutter_hooks/lib/src/hooks.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/flutter_hooks/lib/src/hooks.dart b/packages/flutter_hooks/lib/src/hooks.dart index 7fb94cd..9c8ffa3 100644 --- a/packages/flutter_hooks/lib/src/hooks.dart +++ b/packages/flutter_hooks/lib/src/hooks.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'package:flutter/cupertino.dart' + show CupertinoTabController; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart' show @@ -21,6 +23,7 @@ import 'framework.dart'; part 'animation.dart'; part 'async.dart'; part 'carousel_controller.dart'; +part 'cupertino_tab_controller.dart'; part 'debounced.dart'; part 'draggable_scrollable_controller.dart'; part 'expansion_tile_controller.dart'; From 97a3bef416cb503931ee657be15b148518fa8016 Mon Sep 17 00:00:00 2001 From: Eren Gun Date: Tue, 17 Jun 2025 09:43:58 +0300 Subject: [PATCH 3/6] Add tests for useCupertinoTabController functionality --- .../use_cupertino_tab_controller_test.dart | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 packages/flutter_hooks/test/use_cupertino_tab_controller_test.dart diff --git a/packages/flutter_hooks/test/use_cupertino_tab_controller_test.dart b/packages/flutter_hooks/test/use_cupertino_tab_controller_test.dart new file mode 100644 index 0000000..727956f --- /dev/null +++ b/packages/flutter_hooks/test/use_cupertino_tab_controller_test.dart @@ -0,0 +1,89 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.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) { + useCupertinoTabController(); + return const SizedBox(); + }), + ); + + await tester.pump(); + + final element = tester.element(find.byType(HookBuilder)); + + expect( + element + .toDiagnosticsNode(style: DiagnosticsTreeStyle.offstage) + .toStringDeep(), + equalsIgnoringHashCodes( + 'HookBuilder\n' + " │ useCupertinoTabController: Instance of 'CupertinoTabController'\n" + ' └SizedBox(renderObject: RenderConstrainedBox#00000)\n', + ), + ); + }); + + group('useCupertinoCupertinoCupertinoTabController', () { + testWidgets('initial values matches with real constructor', (tester) async { + late CupertinoTabController controller; + late CupertinoTabController controller2; + + await tester.pumpWidget( + HookBuilder(builder: (context) { + controller2 = CupertinoTabController(); + controller = useCupertinoTabController(); + return Container(); + }), + ); + + expect(controller.index, controller2.index); + }); + testWidgets("returns a CupertinoTabController that doesn't change", + (tester) async { + late CupertinoTabController controller; + late CupertinoTabController controller2; + + await tester.pumpWidget( + HookBuilder(builder: (context) { + controller = useCupertinoTabController(initialIndex: 1); + return Container(); + }), + ); + + expect(controller, isA()); + + await tester.pumpWidget( + HookBuilder(builder: (context) { + controller2 = useCupertinoTabController(initialIndex: 1); + return Container(); + }), + ); + + expect(identical(controller, controller2), isTrue); + }); + + testWidgets('passes hook parameters to the CupertinoTabController', + (tester) async { + late CupertinoTabController controller; + + await tester.pumpWidget( + HookBuilder( + builder: (context) { + controller = useCupertinoTabController(initialIndex: 2); + + return Container(); + }, + ), + ); + + expect(controller.index, 2); + }); + }); +} From 470968fd8e15652ee6d7ff47f6a66ad46f9d57d6 Mon Sep 17 00:00:00 2001 From: Eren Gun Date: Tue, 17 Jun 2025 10:48:19 +0300 Subject: [PATCH 4/6] Fix typo in test group name for useCupertinoTabController --- .../flutter_hooks/test/use_cupertino_tab_controller_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutter_hooks/test/use_cupertino_tab_controller_test.dart b/packages/flutter_hooks/test/use_cupertino_tab_controller_test.dart index 727956f..a57748a 100644 --- a/packages/flutter_hooks/test/use_cupertino_tab_controller_test.dart +++ b/packages/flutter_hooks/test/use_cupertino_tab_controller_test.dart @@ -30,7 +30,7 @@ void main() { ); }); - group('useCupertinoCupertinoCupertinoTabController', () { + group('useCupertinoTabController', () { testWidgets('initial values matches with real constructor', (tester) async { late CupertinoTabController controller; late CupertinoTabController controller2; From 2f444749a455b17b3757be582f8f9c587abec7df Mon Sep 17 00:00:00 2001 From: Remi Rousselet Date: Tue, 12 Aug 2025 18:32:09 +0200 Subject: [PATCH 5/6] Doc --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4f014f8..a50587e 100644 --- a/README.md +++ b/README.md @@ -360,8 +360,9 @@ A series of hooks with no particular theme. | [useDraggableScrollableController](https://api.flutter.dev/flutter/widgets/DraggableScrollableController-class.html) | Creates a `DraggableScrollableController`. | | [useCarouselController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useCarouselController.html) | Creates and disposes a **`CarouselController`**. | | [useTreeSliverController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useTreeSliverController.html) | Creates a `TreeSliverController`. | -| [useOverlayPortalController](https://api.flutter.dev/flutter/widgets/OverlayPortalController-class.html) | Creates and manages an `OverlayPortalController` for controlling the visibility of overlay content. The controller will be automatically disposed when no longer needed. | -| [useSnapshotController](https://api.flutter.dev/flutter/widgets/SnapshotController-class.html) | Creates and manages a `SnapshotController` | +| [useOverlayPortalController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useOverlayPortalController.html) | Creates and manages an `OverlayPortalController` for controlling the visibility of overlay content. The controller will be automatically disposed when no longer needed. | +| [useSnapshotController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useSnapshotController.html) | Creates and manages a `SnapshotController` | +| [useCupertinoController](https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useCupertinoController.html) | Creates and manages a `CupertinoController` | ## Contributions From c221c829bb01ffb09ea5f5a0ac3ffc4d979b8562 Mon Sep 17 00:00:00 2001 From: Remi Rousselet Date: Tue, 12 Aug 2025 18:47:08 +0200 Subject: [PATCH 6/6] Format --- .../flutter_hooks/lib/src/cupertino_tab_controller.dart | 7 +++---- packages/flutter_hooks/lib/src/hooks.dart | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/flutter_hooks/lib/src/cupertino_tab_controller.dart b/packages/flutter_hooks/lib/src/cupertino_tab_controller.dart index eac6af5..53e7114 100644 --- a/packages/flutter_hooks/lib/src/cupertino_tab_controller.dart +++ b/packages/flutter_hooks/lib/src/cupertino_tab_controller.dart @@ -1,6 +1,5 @@ part of 'hooks.dart'; - /// Creates a [CupertinoTabController] that will be disposed automatically. /// /// See also: @@ -26,8 +25,8 @@ class _CupertinoTabControllerHook extends Hook { final int initialIndex; @override - HookState> createState() => - _CupertinoTabControllerHookState(); + HookState> + createState() => _CupertinoTabControllerHookState(); } class _CupertinoTabControllerHookState @@ -44,4 +43,4 @@ class _CupertinoTabControllerHookState @override String get debugLabel => 'useCupertinoTabController'; -} \ No newline at end of file +} diff --git a/packages/flutter_hooks/lib/src/hooks.dart b/packages/flutter_hooks/lib/src/hooks.dart index e149f42..f9b04a9 100644 --- a/packages/flutter_hooks/lib/src/hooks.dart +++ b/packages/flutter_hooks/lib/src/hooks.dart @@ -1,7 +1,6 @@ import 'dart:async'; -import 'package:flutter/cupertino.dart' - show CupertinoTabController; +import 'package:flutter/cupertino.dart' show CupertinoTabController; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart' show