From 77c544e7c18dbf58a9c71658ed676a40e9d26e64 Mon Sep 17 00:00:00 2001 From: Job Guldemeester Date: Mon, 28 Sep 2026 12:23:58 +0200 Subject: [PATCH] :recycle: Migration to material_ui/cupertino_ui package --- .fvmrc | 4 + .github/workflows/flutter.yml | 4 +- CHANGELOG.md | 5 + analysis_options.yaml | 3 +- example/analysis_options.yaml | 5 + example/lib/main.dart | 100 ++--- example/lib/profile/data/model/user.dart | 2 +- example/lib/profile/data/user_repository.dart | 6 +- .../presentation/cubit/user_cubit.dart | 7 +- .../lib/profile/presentation/user_page.dart | 17 +- example/pubspec.lock | 363 +++++++++--------- example/pubspec.yaml | 14 +- lib/chopper/json_converter_exception.dart | 12 +- lib/chopper/json_serializable_converter.dart | 10 +- lib/common/dimensions.dart | 2 +- lib/common/extensions/build_context.dart | 2 +- lib/common/extensions/text_style.dart | 2 +- lib/common/extensions/text_theme.dart | 2 +- lib/common/result/result.dart | 20 +- lib/debouncer/debouncer.dart | 6 +- lib/logger/charges/file_charge.dart | 22 +- lib/logger/charges/memory_charge.dart | 9 +- lib/logger/ui/bolt_logger_view.dart | 2 +- lib/logger/zap_event.dart | 16 +- lib/pagination/paginated_scroll_view.dart | 56 ++- lib/pagination/pagination_state.dart | 33 +- lib/pagination/pagination_state_view.dart | 51 ++- lib/style/interface/boekwerk_interface.dart | 2 +- lib/style/kleurplaat/color_group.dart | 24 +- lib/style/kleurplaat/katjas_kleurplaat.dart | 88 +---- lib/style/kleurplaat/surface_group.dart | 81 +--- lib/style/text_style/boekwerk_decorator.dart | 89 ++--- lib/style/text_style/handschrift.dart | 79 ++-- .../text_style/handschrift_color_group.dart | 17 +- .../text_style/handschrift_decorator.dart | 8 +- .../text_style/handschrift_surface_group.dart | 69 +--- lib/style/text_style/katjas_boekwerk.dart | 85 ++-- lib/test_util/devices_sizes.dart | 2 +- lib/ui/annotated_text/annotated_text.dart | 28 +- lib/ui/blocful_widget.dart | 33 +- lib/ui/native_dialog.dart | 86 ++--- pubspec.lock | 85 ++-- pubspec.yaml | 8 +- .../dcc-toolkit-create-blocful-page/SKILL.md | 78 ++-- .../SKILL.md | 66 ++-- skills/dcc-toolkit-setup-bolt-logger/SKILL.md | 21 +- .../SKILL.md | 28 +- test/common/extensions/color_test.dart | 2 +- test/ui/annotated_text_test.dart | 2 +- 49 files changed, 775 insertions(+), 981 deletions(-) create mode 100644 .fvmrc diff --git a/.fvmrc b/.fvmrc new file mode 100644 index 0000000..4a08e3a --- /dev/null +++ b/.fvmrc @@ -0,0 +1,4 @@ +{ + "flutter": "3.47.5", + "flavors": {} +} \ No newline at end of file diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 2b1d421..e337a42 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -19,6 +19,8 @@ jobs: - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 - uses: subosito/flutter-action@v2 + with: + flutter-version-file: .fvmrc - name: Install dependencies run: flutter pub get @@ -26,7 +28,7 @@ jobs: run: dart format . -o none --set-exit-if-changed - name: Run code generation - run: cd example && flutter pub get && flutter pub run build_runner build && cd .. + run: cd example && flutter pub get && dart run build_runner build && cd .. - name: Analyze project source run: flutter analyze --fatal-infos diff --git a/CHANGELOG.md b/CHANGELOG.md index aa5bbc9..d1ba661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.1.0 +* **Breaking:** Requires Flutter `>=3.47.0` and Dart `^3.13.0` +* **Breaking:** Migrated from `package:flutter/material.dart` / `package:flutter/cupertino.dart` to the `material_ui` and `cupertino_ui` packages. Apps must migrate as well, see [doc/migrate_to_material_ui.md](doc/migrate_to_material_ui.md) +* Migrated classes to primary constructors; the public API is unchanged + ## 0.0.22 * Added `BoltLogger.surge` and the `surge` extension method for logging at `Level.WARNING`, completing the `zap` (info) / `surge` (warning) / `shock` (severe) trio * `DebugConsoleCharge` now prints warning level logs in yellow; severe logs and logs carrying an error or stack trace remain red diff --git a/analysis_options.yaml b/analysis_options.yaml index bdcf72c..1864412 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -13,4 +13,5 @@ analyzer: missing_required_param: error exclude: - "**/*.g.dart" - - "**/*.freezed.dart" \ No newline at end of file + - "**/*.freezed.dart" + - build/** diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 0d29021..0d87f43 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -7,6 +7,11 @@ # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. +analyzer: + exclude: + - build/** + - android/** + - ios/** include: package:flutter_lints/flutter.yaml linter: diff --git a/example/lib/main.dart b/example/lib/main.dart index be00332..eea042f 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -3,16 +3,14 @@ import 'package:dcc_toolkit/ui/native_dialog.dart'; import 'package:example/core/injectable/injectable.dart'; import 'package:example/profile/presentation/cubit/user_cubit.dart'; import 'package:example/profile/presentation/user_page.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; Future main() async { await configureDependencies(); runApp(const MyApp()); } -class MyApp extends StatelessWidget { - const MyApp({super.key}); - +class const MyApp({super.key}) extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( @@ -26,9 +24,7 @@ class MyApp extends StatelessWidget { } } -class MyHomePage extends StatelessWidget { - const MyHomePage({super.key}); - +class const MyHomePage({super.key}) extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( @@ -38,75 +34,59 @@ class MyHomePage extends StatelessWidget { Padding( padding: const EdgeInsets.all(16), child: AnnotatedText( - text: - '[Flutter](onFlutterTap) example of using a Rich Text with annotations with multiple [tap](onTap) actions.\nThis tap [action](action) does nothing. And [action] without () does nothing as well', + text: '[Flutter](onFlutterTap) example of using a Rich Text with annotations with multiple [tap](onTap) actions.\nThis tap [action](action) does nothing. And [action] without () does nothing as well', defaultStyle: const TextStyle(color: Colors.black), annotationStyle: const TextStyle(color: Colors.blue), actions: { - 'onFlutterTap': - () => - ScaffoldMessenger.of(context) - ..hideCurrentSnackBar() - ..showSnackBar( - const SnackBar(content: Text('Flutter')), - ), - 'onTap': - () => - ScaffoldMessenger.of(context) - ..hideCurrentSnackBar() - ..showSnackBar( - const SnackBar(content: Text('Tap')), - ), + 'onFlutterTap': () => ScaffoldMessenger.of(context) + ..hideCurrentSnackBar() + ..showSnackBar(const SnackBar(content: Text('Flutter'))), + 'onTap': () => ScaffoldMessenger.of(context) + ..hideCurrentSnackBar() + ..showSnackBar(const SnackBar(content: Text('Tap'))), }, ), ), ElevatedButton( - onPressed: - () => Navigator.of(context).push( - MaterialPageRoute( - builder: - (context) => UserPage( - onCreateCubit: - (context) => - getIt()..getRandomUser(), - ), - ), + onPressed: () => Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => UserPage( + onCreateCubit: (context) => + getIt()..getRandomUser(), ), + ), + ), child: const Text('Get user succesfully'), ), ElevatedButton( - onPressed: - () => Navigator.of(context).push( - MaterialPageRoute( - builder: - (context) => UserPage( - onCreateCubit: - (context) => - getIt()..getRandomUserFails(), - ), - ), + onPressed: () => Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => UserPage( + onCreateCubit: (context) => + getIt()..getRandomUserFails(), ), + ), + ), child: const Text('Get user fails'), ), ElevatedButton( - onPressed: - () => showNativeDialog( - context, - title: 'Title', - content: 'Content', - actions: [ - DialogAction( - text: 'Action', - onTap: () {}, - textStyle: const TextStyle(color: Colors.green), - ), - DialogAction( - text: 'Action', - onTap: () {}, - textStyle: const TextStyle(color: Colors.red), - ), - ], + onPressed: () => showNativeDialog( + context, + title: 'Title', + content: 'Content', + actions: [ + DialogAction( + text: 'Action', + onTap: () {}, + textStyle: const TextStyle(color: Colors.green), + ), + DialogAction( + text: 'Action', + onTap: () {}, + textStyle: const TextStyle(color: Colors.red), ), + ], + ), child: const Text('Show native dialog'), ), ], diff --git a/example/lib/profile/data/model/user.dart b/example/lib/profile/data/model/user.dart index 520c2b3..707424e 100644 --- a/example/lib/profile/data/model/user.dart +++ b/example/lib/profile/data/model/user.dart @@ -1,7 +1,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; -import 'name.dart'; import 'location.dart'; +import 'name.dart'; import 'picture.dart'; part 'user.freezed.dart'; diff --git a/example/lib/profile/data/user_repository.dart b/example/lib/profile/data/user_repository.dart index 4b430b1..5676a68 100644 --- a/example/lib/profile/data/user_repository.dart +++ b/example/lib/profile/data/user_repository.dart @@ -5,11 +5,7 @@ import 'model/api_user_response.dart'; import 'user_service.dart'; @lazySingleton -class UserRepository { - const UserRepository(this._userService); - - final UserService _userService; - +class const UserRepository(final UserService _userService) { Future> getRandomUser() async { return tryCall(() => _userService.getRandomUser()); } diff --git a/example/lib/profile/presentation/cubit/user_cubit.dart b/example/lib/profile/presentation/cubit/user_cubit.dart index 3e94735..6a71c9e 100644 --- a/example/lib/profile/presentation/cubit/user_cubit.dart +++ b/example/lib/profile/presentation/cubit/user_cubit.dart @@ -10,11 +10,10 @@ part 'user_cubit.freezed.dart'; part 'user_state.dart'; @injectable -class UserCubit extends Cubit +class UserCubit(final UserRepository _userRepo) + extends Cubit with BlocPresentationMixin { - UserCubit(this._userRepo) : super(const UserState(user: null)); - - final UserRepository _userRepo; + this : super(const UserState(user: null)); Future getRandomUser() async { final result = await _userRepo.getRandomUser(); diff --git a/example/lib/profile/presentation/user_page.dart b/example/lib/profile/presentation/user_page.dart index 45bd215..1ea232d 100644 --- a/example/lib/profile/presentation/user_page.dart +++ b/example/lib/profile/presentation/user_page.dart @@ -1,19 +1,18 @@ import 'package:dcc_toolkit/ui/blocful_widget.dart'; import 'package:example/profile/presentation/cubit/user_cubit.dart'; import 'package:example/profile/presentation/cubit/user_event.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; -class UserPage extends BlocfulWidget { - const UserPage({required this.onCreateCubit, super.key}) - : super(onCreateBloc: onCreateCubit); - - final UserCubit Function(BuildContext)? onCreateCubit; +class const UserPage({ + required final UserCubit Function(BuildContext)? onCreateCubit, + super.key, +}) extends BlocfulWidget { + this : super(onCreateBloc: onCreateCubit); @override void onPresentationEvent(BuildContext context, UserEvent event) { - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text(event.reason))); + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text(event.reason))); } @override diff --git a/example/pubspec.lock b/example/pubspec.lock index 5fdc674..e5e6acc 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,50 +5,66 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f + sha256: "1b0e6a07425a3e460666e88bf1c949ccc7bb0116ad562ce94a1eca60fe820725" url: "https://pub.dev" source: hosted - version: "85.0.0" + version: "103.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "974859dc0ff5f37bc4313244b3218c791810d03ab3470a579580279ba971a48d" + sha256: "61c04d0c1bfed555c681ea079519933f071a5a026578ff73c4ff0df2d3462e5e" url: "https://pub.dev" source: hosted - version: "7.7.1" + version: "13.3.0" + analyzer_buffer: + dependency: transitive + description: + name: analyzer_buffer + sha256: f890a2e708e38fbf4238ad2f9fd3d506538acdddb0cd8eb2c3e8c7bd17784b57 + url: "https://pub.dev" + source: hosted + version: "0.3.4" + ansicolor: + dependency: transitive + description: + name: ansicolor + sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f" + url: "https://pub.dev" + source: hosted + version: "2.0.3" args: dependency: transitive description: name: args - sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" async: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.13.1" bloc: dependency: transitive description: name: bloc - sha256: "52c10575f4445c61dd9e0cafcc6356fdd827c4c64dd7945ef3c4105f6b6ac189" + sha256: e03b235924e4f509c27b5d6b2f949200e0a91149a9818b4f65eeb56662b75413 url: "https://pub.dev" source: hosted - version: "9.0.0" + version: "9.2.1" bloc_presentation: dependency: "direct main" description: name: bloc_presentation - sha256: "03ea22745a23274a7fa4425ac16e120838471d3073fa37a3332c18641cb2d8a2" + sha256: b8f5c72e0c6a356767719cd7f56b37f6aec9747598c77cbc986d85244674061a url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2+3" boolean_selector: dependency: transitive description: @@ -61,50 +77,34 @@ packages: dependency: transitive description: name: build - sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0 + sha256: "8a5c5761af8e31748bba3c82f68925ace40f3225c3eea25be9beb57eca7cd7a8" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "4.0.11" build_config: dependency: transitive description: name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + sha256: d466ed2dc9c6cd1d169948879b84ee061eb5e22c64a7c6089879c6296d272a8d url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.3.3" build_daemon: dependency: transitive description: name: build_daemon - sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0 + sha256: e1d40ef3f7934986d5da2271b1ba07794921ce263e44d622fb6c406d76589e33 url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "4.1.6" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99" - url: "https://pub.dev" - source: hosted - version: "2.4.15" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021" + sha256: "894c243f6bc32015fec466ce30a6925bd537a77a426ee5bf481120477eb3de67" url: "https://pub.dev" source: hosted - version: "8.0.0" + version: "2.16.1" built_collection: dependency: transitive description: @@ -117,58 +117,58 @@ packages: dependency: transitive description: name: built_value - sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb + sha256: f87ea98192116f7093cb214551ce1929caae0681fdba282b3d8b4462adee7bb7 url: "https://pub.dev" source: hosted - version: "8.9.2" + version: "8.13.0" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" checked_yaml: dependency: transitive description: name: checked_yaml - sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "2.0.4" chopper: dependency: "direct main" description: name: chopper - sha256: "18928a74069cf1c257e657809c1b84b0304d8e32a6fc446dd2bbb28657e0358a" + sha256: da972c2444b73f64b9f22e5e3e7442f8fdd3ad16d6a8d084d0acf9da70a4a82a url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "8.7.0" chopper_generator: dependency: "direct dev" description: name: chopper_generator - sha256: "2cb23febc9ac9bbc9288b4703e60f3edc8e301a2ef5057d0c22369eab7313c6d" + sha256: "2235c4866ecb2e86262cbde29c5a450fe7bd6891c67a1ca780cade6a647db42a" url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "8.7.0" clock: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: e51d50bca3217c9a9fa2b41a30e4a38971133f5f9ec7a3d57bae095007f1d28e url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.3" code_builder: dependency: transitive description: name: code_builder - sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + sha256: aa5932e94c6c39c2f9ec4e5e06dfdd11a9430a61f6c41b6ba75b28ce0c481baf url: "https://pub.dev" source: hosted - version: "4.10.1" + version: "4.12.0" collection: dependency: "direct main" description: @@ -189,33 +189,41 @@ packages: dependency: transitive description: name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" + cupertino_ui: + dependency: transitive + description: + name: cupertino_ui + sha256: c23816577a1280cff409e989541767887011f8f1d8c1863a794ed308af46f2a9 + url: "https://pub.dev" + source: hosted + version: "1.1.1" dart_style: dependency: transitive description: name: dart_style - sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac" + sha256: "82ade9fc4273f29ed673e33166944465225b4f7fc5d4aaef48605cc751c18fc1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.13" dcc_toolkit: dependency: "direct main" description: path: ".." relative: true source: path - version: "0.0.21" + version: "0.1.0" equatable: dependency: transitive description: name: equatable - sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + sha256: "3bce007a596ff8b3119c45d68aaef631272537c03d30e5d4534dd24bf4c5eaa2" url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "2.1.0" fake_async: dependency: transitive description: @@ -249,18 +257,23 @@ packages: dependency: "direct main" description: name: flutter_bloc - sha256: "1046d719fbdf230330d3443187cc33cc11963d15c9089f6cc56faa42a4c5f0cc" + sha256: cf51747952201a455a1c840f8171d273be009b932c75093020f9af64f2123e38 url: "https://pub.dev" source: hosted - version: "9.1.0" + version: "9.1.1" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "6.0.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -270,18 +283,18 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "7ed2ddaa47524976d5f2aa91432a79da36a76969edd84170777ac5bea82d797c" + sha256: "541a82723c84298f3ca46a6c2186935aa21ad529ad1f1423d67af18040494f51" url: "https://pub.dev" source: hosted - version: "3.0.4" + version: "4.0.1" freezed_annotation: dependency: "direct main" description: name: freezed_annotation - sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b + sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.1.0" frontend_server_client: dependency: transitive description: @@ -294,18 +307,18 @@ packages: dependency: "direct main" description: name: get_it - sha256: f126a3e286b7f5b578bf436d5592968706c4c1de28a228b870ce375d9f743103 + sha256: "2b5c6b077aad30bba9782178baff6076a2044141f1d5f2f15b43bca3fbe74874" url: "https://pub.dev" source: hosted - version: "8.0.3" + version: "9.3.0" glob: dependency: transitive description: name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + sha256: "218aeb56050c714f62a3182775320dfa04602b55074873e24e31bbd39bda96fb" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.2.0" graphs: dependency: transitive description: @@ -314,86 +327,86 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" + hotreloader: + dependency: transitive + description: + name: hotreloader + sha256: "66871df468fc24eee81f1a0a7cb98acc104716f9b7376d355437b48d633c4ebf" + url: "https://pub.dev" + source: hosted + version: "4.4.0" http: dependency: transitive description: name: http - sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.6.0" http_multi_server: dependency: transitive description: name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" http_parser: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.2" injectable: dependency: "direct main" description: name: injectable - sha256: "5e1556ea1d374fe44cbe846414d9bab346285d3d8a1da5877c01ad0774006068" + sha256: "1da6399509e44ddb0d8a4a35291d7122c4efb5c625a9d733bf5e48d4a72e379e" url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "3.0.0" injectable_generator: dependency: "direct dev" description: name: injectable_generator - sha256: b04673a4c88b3a848c0c77bf58b8309f9b9e064d9fe1df5450c8ee1675eaea1a + sha256: "24d525c60ed9abf345c8749c3291ca1b3f1d21fd53344c0c644da820a92049df" url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "3.1.3" intl: dependency: transitive description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + sha256: "1ca20c894b1717686a2319b8548763d812bc0aabdac580420a44c5178c57a867" url: "https://pub.dev" source: hosted - version: "0.20.2" + version: "0.20.3" io: dependency: transitive description: name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - js: - dependency: transitive - description: - name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + sha256: "2635216ca6a737e60de577ffa1a48a0bec76ca8a62917cfc1bb88c14c570646f" url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "1.1.0" json_annotation: dependency: "direct main" description: name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + sha256: "2a743920d81b7910627f68ee2c9ac1fc0bfee32b9fc3403587d7c6791ca12f80" url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.12.0" json_serializable: dependency: "direct dev" description: name: json_serializable - sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c + sha256: e45aefa0324f08c683caafbb94b72837aa6193c61822799c916e45f4a263113d url: "https://pub.dev" source: hosted - version: "6.9.5" + version: "6.14.1" leak_tracker: dependency: transitive description: @@ -418,14 +431,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + lean_builder: + dependency: transitive + description: + name: lean_builder + sha256: "5acef0857ec7163da8e6e5c86a9d7df87ce2487c8e866eb24c60508b82e67917" + url: "https://pub.dev" + source: hosted + version: "1.2.2" lints: dependency: transitive description: name: lints - sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "6.1.0" logging: dependency: transitive description: @@ -438,34 +459,42 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.20" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + url: "https://pub.dev" + source: hosted + version: "0.13.0" + material_ui: + dependency: "direct main" + description: + name: material_ui + sha256: "134ab2f0843545c4e661e4ba2753fe1bcf0753cb690d5a9ee4870638a40411e9" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "1.4.0" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.19.0" mime: dependency: transitive description: name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + sha256: bd47de35f07e27267e69c8c8b22edf9473bfee170a60d60fcc93730c5144b7f6 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" nested: dependency: transitive description: @@ -478,10 +507,10 @@ packages: dependency: transitive description: name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + sha256: ffcf4cf3d6c0b74ac43708d9f56625506e8a68aa935abe9d267a7330f320eb5d url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "3.0.0" path: dependency: transitive description: @@ -494,42 +523,42 @@ packages: dependency: transitive description: name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + sha256: "4177f68c237ea2128d1bee66ac17b2ce05ba3dbaafcbdd54c5d40a39d0b6b11c" url: "https://pub.dev" source: hosted - version: "1.5.1" + version: "1.5.3" provider: dependency: transitive description: name: provider - sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "6.1.5+1" pub_semver: dependency: transitive description: name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + sha256: "261236774e8b1d69cfc6b9eabbc96c40f25e7a2d6b171f3385d4f65d5734fb24" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.1" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + sha256: c38b81cbf34450b67e0265d73433569d12e34782e30ed769c9cc99c9d5f2e796 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.6.0" qs_dart: dependency: transitive description: name: qs_dart - sha256: c775dbe663cd59365050220b3499dee259b72ad6b352a3e087a15bd77e161b74 + sha256: be8d08e7f8bf5e175e0897ff4823265a0fcc6fccc65ae44bb439d1956b106074 url: "https://pub.dev" source: hosted - version: "1.3.3+1" + version: "1.8.2" recase: dependency: transitive description: @@ -538,30 +567,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.0" - recursive_regex: - dependency: transitive - description: - name: recursive_regex - sha256: f7252e3d3dfd1665e594d9fe035eca6bc54139b1f2fee38256fa427ea41adc60 - url: "https://pub.dev" - source: hosted - version: "1.0.0" shelf: dependency: transitive description: name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.0.0" sky_engine: dependency: transitive description: flutter @@ -571,34 +592,34 @@ packages: dependency: transitive description: name: source_gen - sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b" + sha256: a603f1fb984a7391ae5978d1b92bfaaa08b350dca5c825256f925818f7943bf5 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "4.2.4" source_helper: dependency: transitive description: name: source_helper - sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c" + sha256: "5e6f216fdf6376c9f3852381ae037499797a3385377d388b011dac98d303c67c" url: "https://pub.dev" source: hosted - version: "1.3.5" + version: "1.3.13" source_span: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.2" stack_trace: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "277654b3034d17ac6f9f1cb5595db011b1d5d41e8806866db28e0abaa101c490" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.12.2" stream_channel: dependency: transitive description: @@ -611,10 +632,10 @@ packages: dependency: transitive description: name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + sha256: a00e5f18bffc764f923e7dec1038527f7fe7a1791361a7117f0358193f13d53a url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -635,90 +656,82 @@ packages: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 - url: "https://pub.dev" - source: hosted - version: "0.7.7" - timing: - dependency: transitive - description: - name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "0.7.12" typed_data: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" vector_math: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "92b9910f66ed1057fd4da7b040ae7c74cafacf885bdc81be496928d5049b032d" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.3" vm_service: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: "5f37239c4851efcef929cea7824e76df7f2f0970aef85d66bbc430afa40e72f0" url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "15.3.0" watcher: dependency: transitive description: name: watcher - sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - weak_map: - dependency: transitive - description: - name: weak_map - sha256: "5f8e5d5ce57dc624db5fae814dd689ccae1f17f92b426e52f0a7cbe7f6f4ab97" + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "1.2.1" web: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" web_socket: dependency: transitive description: name: web_socket - sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" url: "https://pub.dev" source: hosted - version: "0.1.6" + version: "1.0.1" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + xxh3: + dependency: transitive + description: + name: xxh3 + sha256: "399a0438f5d426785723c99da6b16e136f4953fb1e9db0bf270bd41dd4619916" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "1.2.0" yaml: dependency: transitive description: name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + sha256: f67cdd8e07d3c6329146aaef1ba043542b3134c12489f553ca9a7435d1068aea url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" sdks: - dart: ">=3.8.0-0 <4.0.0" - flutter: ">=3.29.0" + dart: ">=3.13.0 <4.0.0" + flutter: ">=3.47.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 162d1c6..c54ecea 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -5,7 +5,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ^3.7.0 + sdk: ^3.13.0 + flutter: ">=3.47.0" dependencies: bloc_presentation: ^1.1.0 @@ -17,18 +18,19 @@ dependencies: sdk: flutter flutter_bloc: ^9.1.0 freezed_annotation: ^3.0.0 - get_it: ^8.0.3 - injectable: ^2.5.0 + get_it: ^9.3.0 + injectable: ^3.0.0 json_annotation: ^4.9.0 + material_ui: ^1.4.0 dev_dependencies: build_runner: ^2.4.15 chopper_generator: ^8.1.0 flutter_test: sdk: flutter - flutter_lints: ^5.0.0 - freezed: ^3.0.4 - injectable_generator: ^2.7.0 + flutter_lints: ^6.0.0 + freezed: ^4.0.1 + injectable_generator: ^3.1.3 json_serializable: ^6.9.5 flutter: diff --git a/lib/chopper/json_converter_exception.dart b/lib/chopper/json_converter_exception.dart index f0c3d3c..2490a53 100644 --- a/lib/chopper/json_converter_exception.dart +++ b/lib/chopper/json_converter_exception.dart @@ -1,13 +1,13 @@ /// Thrown when a json response cannot be converted to the expected type. -class JsonConverterException implements Exception { - /// Creates a new [JsonConverterException]. - const JsonConverterException(this.type, {required this.message}); - +class const JsonConverterException( /// The type that could not be converted. - final Type type; + final Type type, { /// A description of what went wrong. - final String message; + required final String message, +}) implements Exception { + /// Creates a new [JsonConverterException]. + this; @override String toString() => 'JsonConverterException: $message'; diff --git a/lib/chopper/json_serializable_converter.dart b/lib/chopper/json_serializable_converter.dart index 686fd33..b16cf11 100644 --- a/lib/chopper/json_serializable_converter.dart +++ b/lib/chopper/json_serializable_converter.dart @@ -11,10 +11,7 @@ typedef JsonFactory = T Function(Map json); /// JsonSeriablizableConverter /// Converter for chopper to convert json response to a dart object using json_serializable. /// Based of: https://hadrien-lejard.gitbook.io/chopper/faq#write-a-custom-jsonconverter -class JsonSerializableConverter extends JsonConverter { - /// Creates a new JsonSerializableConverter - const JsonSerializableConverter(this.factories); - +class const JsonSerializableConverter( /// The factories to use for decoding the json responses. /// For example: /// ```dart @@ -22,7 +19,10 @@ class JsonSerializableConverter extends JsonConverter { /// User: User.fromJson, /// }); /// ``` - final Map> factories; + final Map> factories, +) extends JsonConverter { + /// Creates a new JsonSerializableConverter + this; Never _logAndThrow(String message) { final exception = JsonConverterException(T, message: message); diff --git a/lib/common/dimensions.dart b/lib/common/dimensions.dart index ecb723f..273b0b4 100644 --- a/lib/common/dimensions.dart +++ b/lib/common/dimensions.dart @@ -1,6 +1,6 @@ // const naming is clear enough by itself. //ignore_for_file: public_member_api_docs -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; // Sizes class Sizes { diff --git a/lib/common/extensions/build_context.dart b/lib/common/extensions/build_context.dart index a7ed4b2..6443728 100644 --- a/lib/common/extensions/build_context.dart +++ b/lib/common/extensions/build_context.dart @@ -1,6 +1,6 @@ import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:dcc_toolkit/style/text_style/katjas_boekwerk.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// Extension for [BuildContext] to get theme related data. extension ThemingExtensions on BuildContext { diff --git a/lib/common/extensions/text_style.dart b/lib/common/extensions/text_style.dart index 5e14cc2..8fadf4e 100644 --- a/lib/common/extensions/text_style.dart +++ b/lib/common/extensions/text_style.dart @@ -1,5 +1,5 @@ import 'package:dcc_toolkit/style/text_style/handschrift.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// Extensions for [TextStyle]. extension TextStyleX on TextStyle { diff --git a/lib/common/extensions/text_theme.dart b/lib/common/extensions/text_theme.dart index dced47b..2ef1728 100644 --- a/lib/common/extensions/text_theme.dart +++ b/lib/common/extensions/text_theme.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// LinkStyle extension for [TextTheme]. extension LinkStyle on TextTheme { diff --git a/lib/common/result/result.dart b/lib/common/result/result.dart index be10538..792ae1d 100644 --- a/lib/common/result/result.dart +++ b/lib/common/result/result.dart @@ -80,12 +80,12 @@ Future> tryCall(FutureOr Function() fn, {Future> Funct /// Class representing a successful result. @immutable -final class Success extends Result { - /// Creates a [Success] with the given [value]. - const Success(this.value); - +final class const Success( /// The value of the [Result]. - final T value; + final T value, +) extends Result { + /// Creates a [Success] with the given [value]. + this; @override bool operator ==(Object other) { @@ -98,12 +98,12 @@ final class Success extends Result { /// Class representing a failed result. @immutable -final class Failure extends Result { - /// Creates a [Failure] with the given [error]. - const Failure(this.error); - +final class const Failure( /// The exception of the [Result]. - final Object? error; + final Object? error, +) extends Result { + /// Creates a [Failure] with the given [error]. + this; @override bool operator ==(Object other) { diff --git a/lib/debouncer/debouncer.dart b/lib/debouncer/debouncer.dart index 97fcd71..a648fba 100644 --- a/lib/debouncer/debouncer.dart +++ b/lib/debouncer/debouncer.dart @@ -27,15 +27,15 @@ const _debounceTime = Duration(milliseconds: 400); /// } // } /// ``` -class Debouncer { +class Debouncer({Duration? delay}) { /// Creates a new [Debouncer] with the given delay. /// If no delay is provided, the default delay of 400 milliseconds is used. - Debouncer({Duration? delay}) : delay = delay ?? _debounceTime; + this; Timer? _timer; /// The delay for the debouncer. - final Duration delay; + final Duration delay = delay ?? _debounceTime; /// Runs the given action after the delay. void run(VoidCallback action) { diff --git a/lib/logger/charges/file_charge.dart b/lib/logger/charges/file_charge.dart index c14d890..3e32222 100644 --- a/lib/logger/charges/file_charge.dart +++ b/lib/logger/charges/file_charge.dart @@ -12,22 +12,24 @@ import 'package:intl/intl.dart'; /// Logs are written to the file in batches, this is done when it reaches the [bufferSize] or every [writeDelay]. /// /// {@endtemplate} -class FileCharge implements BoltCharge { +class FileCharge( + /// The path to the directory where the log files will be written. + final String path, { + + /// The size of the buffer (in lines) before writing to the file. + final int bufferSize = 1000, + + /// The delay between writing to the file. + final Duration writeDelay = const Duration(seconds: 5), +}) implements BoltCharge { /// {@macro file_charge} - FileCharge(this.path, {this.bufferSize = 1000, this.writeDelay = const Duration(seconds: 5)}) { + this { _timer = Timer.periodic(writeDelay, (_) => _flush()); } + @override String get name => 'FileCharge'; - /// The size of the buffer (in lines) before writing to the file. - final int bufferSize; - - /// The path to the directory where the log files will be written. - final String path; - - /// The delay between writing to the file. - final Duration writeDelay; final List _buffer = []; IOSink? _sink; String? _sinkFileName; diff --git a/lib/logger/charges/memory_charge.dart b/lib/logger/charges/memory_charge.dart index 50b0485..8e8bf52 100644 --- a/lib/logger/charges/memory_charge.dart +++ b/lib/logger/charges/memory_charge.dart @@ -11,9 +11,12 @@ import 'package:dcc_toolkit/logger/zap_event.dart'; /// By default, the [maxItems] is set to 1000. This is the amount of logs that will be stored in memory. /// /// {@endtemplate} -class MemoryCharge implements BoltCharge { +class MemoryCharge({ + /// The maximum amount of logs to store in memory. + final int maxItems = 1000, +}) implements BoltCharge { /// {@macro memory_charge} - MemoryCharge({this.maxItems = 1000}); + this; /// The name used to register and look up this charge. static const chargeName = 'MemoryCharge'; @@ -21,8 +24,6 @@ class MemoryCharge implements BoltCharge { @override String get name => chargeName; - /// The maximum amount of logs to store in memory. - final int maxItems; final List _items = []; StreamController _controller = StreamController.broadcast(); diff --git a/lib/logger/ui/bolt_logger_view.dart b/lib/logger/ui/bolt_logger_view.dart index 8299953..f1db043 100644 --- a/lib/logger/ui/bolt_logger_view.dart +++ b/lib/logger/ui/bolt_logger_view.dart @@ -1,5 +1,5 @@ import 'package:dcc_toolkit/logger/bolt_logger.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// {@template bolt_logger_view} /// A widget that displays the logs stored in the [MemoryCharge]. diff --git a/lib/logger/zap_event.dart b/lib/logger/zap_event.dart index 83d4e11..93e8e76 100644 --- a/lib/logger/zap_event.dart +++ b/lib/logger/zap_event.dart @@ -4,19 +4,19 @@ import 'package:logging/logging.dart'; /// {@template zap_event} /// A zap event that contains the [lines] of a log record and the [origin] [LogRecord]. /// {@endtemplate} -class ZapEvent { +class const ZapEvent._( + /// Formatted lines of the [LogRecord]. + final List lines, + + /// The original [LogRecord] that was zapped. + final LogRecord origin, +) { /// {@macro zap_event} - const ZapEvent._(this.lines, this.origin); + this; /// Create a [ZapEvent] from a [LogRecord]. factory ZapEvent.fromRecord(LogRecord record) { final lines = const LogRecordFormatter().format(record); return ZapEvent._(lines, record); } - - /// The original [LogRecord] that was zapped. - final LogRecord origin; - - /// Formatted lines of the [LogRecord]. - final List lines; } diff --git a/lib/pagination/paginated_scroll_view.dart b/lib/pagination/paginated_scroll_view.dart index 50aab4c..54588ae 100644 --- a/lib/pagination/paginated_scroll_view.dart +++ b/lib/pagination/paginated_scroll_view.dart @@ -1,36 +1,30 @@ import 'package:dcc_toolkit/dcc_toolkit.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// A widget that displays a list of items with pagination. /// /// This widget is a [CustomScrollView] that displays a paginated list of items. /// It uses a [PaginationState] to manage the behavior of the widget. /// It also uses a [NotificationListener] to listen for scroll events and load more items when the user scrolls to the bottom of the list. -class PaginatedScrollView extends StatelessWidget { - /// Creates a new [PaginatedScrollView]. - const PaginatedScrollView({ - required this.state, - required this.itemBuilder, - this.onLoadMore, - this.topWidget, - this.bottomWidget, - super.key, - }); - +class const PaginatedScrollView({ /// The state of the pagination. - final PaginationState state; + required final PaginationState state, /// The builder for the items. - final Widget Function(BuildContext, T) itemBuilder; + required final Widget Function(BuildContext, T) itemBuilder, /// The function to call when the user scrolls to the bottom of the list, to load more items. - final void Function()? onLoadMore; + final void Function()? onLoadMore, /// Optional widget to display at the top of the list. - final Widget? topWidget; + final Widget? topWidget, /// Optional widget to display at the bottom of the list. - final Widget? bottomWidget; + final Widget? bottomWidget, + super.key, +}) extends StatelessWidget { + /// Creates a new [PaginatedScrollView]. + this; int get _itemCount => state.items.length; @@ -41,20 +35,19 @@ class PaginatedScrollView extends StatelessWidget { @override Widget build(BuildContext context) { return NotificationListener( - onNotification: - onLoadMore != null - ? (notification) { - final metrics = notification.metrics; - if (metrics.extentAfter == metrics.minScrollExtent) { - // We don't trigger loading if no next page is available or while we are already fetching more - if (state.hasNextPage && !state.isLoading) { - onLoadMore?.call(); - return true; - } + onNotification: onLoadMore != null + ? (notification) { + final metrics = notification.metrics; + if (metrics.extentAfter == metrics.minScrollExtent) { + // We don't trigger loading if no next page is available or while we are already fetching more + if (state.hasNextPage && !state.isLoading) { + onLoadMore?.call(); + return true; } - return false; } - : null, + return false; + } + : null, child: CustomScrollView( physics: const AlwaysScrollableScrollPhysics(), slivers: [ @@ -65,7 +58,10 @@ class PaginatedScrollView extends StatelessWidget { ), if (state.hasNextPage) const SliverToBoxAdapter( - child: Padding(padding: EdgeInsets.all(Sizes.px16), child: Center(child: CircularProgressIndicator())), + child: Padding( + padding: EdgeInsets.all(Sizes.px16), + child: Center(child: CircularProgressIndicator()), + ), ), if (bottomWidget != null) SliverToBoxAdapter(child: bottomWidget), //Bottom insets to be able to scroll the entire content above the FloatingActionButton diff --git a/lib/pagination/pagination_state.dart b/lib/pagination/pagination_state.dart index 684d54b..ea79a61 100644 --- a/lib/pagination/pagination_state.dart +++ b/lib/pagination/pagination_state.dart @@ -2,42 +2,33 @@ import 'package:flutter/foundation.dart'; /// State for pagination. @immutable -class PaginationState { - /// Creates a new [PaginationState] with the given values. - const PaginationState({ - this.items = const [], - this.currentPage = 1, - this.lastPage = 1, - this.isLoading = false, - this.loadingInitialPage = true, - this.hasError = false, - this.total = 0, - this.searchQuery, - }); - +class const PaginationState({ /// All items fetched so far for the loaded pages. - final List items; + final List items = const [], /// The current page in the pagination process. - final int currentPage; + final int currentPage = 1, /// The last page in the pagination process. - final int lastPage; + final int lastPage = 1, /// Whether the current page is being loaded. - final bool isLoading; + final bool isLoading = false, /// Whether the initial page is being loaded. - final bool loadingInitialPage; + final bool loadingInitialPage = true, /// Whether there is an error loading the current page. - final bool hasError; + final bool hasError = false, /// The total number of items. - final int total; + final int total = 0, /// The search query to filter the items. - final String? searchQuery; + final String? searchQuery, +}) { + /// Creates a new [PaginationState] with the given values. + this; /// Checks if there is a next page to load for the current [PaginationState]. bool get hasNextPage => currentPage < lastPage; diff --git a/lib/pagination/pagination_state_view.dart b/lib/pagination/pagination_state_view.dart index 6810cbc..e6ef15d 100644 --- a/lib/pagination/pagination_state_view.dart +++ b/lib/pagination/pagination_state_view.dart @@ -1,5 +1,5 @@ import 'package:dcc_toolkit/dcc_toolkit.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// A widget that displays a different widget based on the state of the pagination /// @@ -9,54 +9,47 @@ import 'package:flutter/material.dart'; /// [errorWidget] is the widget to display when [state] is [PaginationState.hasError] /// [builder] is the builder for the actual success view (usually [PaginatedScrollView]) /// [onRefresh] is the refresh callback for [RefreshIndicator] -class PaginationStateView extends StatelessWidget { - /// Constructor - const PaginationStateView({ - required this.state, - required this.loadingWidget, - required this.emptyWidget, - required this.errorWidget, - required this.builder, - this.onRefresh, - super.key, - }); - +class const PaginationStateView({ /// The state of the pagination - final PaginationState state; + required final PaginationState state, /// Custom widget for [PaginationState.isLoading] - final Widget loadingWidget; + required final Widget loadingWidget, /// Custom widget for [PaginationState.items] is empty - final Widget emptyWidget; + required final Widget emptyWidget, /// Custom widget for [PaginationState.hasError] - final Widget errorWidget; + required final Widget errorWidget, /// Builder for the actual success view (usually [PaginatedScrollView]) - final WidgetBuilder builder; + required final WidgetBuilder builder, /// Optional: refresh callback for [RefreshIndicator] - final RefreshCallback? onRefresh; + final RefreshCallback? onRefresh, + super.key, +}) extends StatelessWidget { + /// Constructor + this; @override Widget build(BuildContext context) { // If there is a refresh callback and the state is not loading, enable the refresh indicator return onRefresh != null && !state.isLoading ? RefreshIndicator( - onRefresh: onRefresh!, - child: switch (state) { + onRefresh: onRefresh!, + child: switch (state) { + PaginationState(isLoading: true) => loadingWidget, + PaginationState(hasError: true) => errorWidget, + PaginationState(items: const []) => emptyWidget, + PaginationState() => builder(context), + }, + ) + : switch (state) { PaginationState(isLoading: true) => loadingWidget, PaginationState(hasError: true) => errorWidget, PaginationState(items: const []) => emptyWidget, PaginationState() => builder(context), - }, - ) - : switch (state) { - PaginationState(isLoading: true) => loadingWidget, - PaginationState(hasError: true) => errorWidget, - PaginationState(items: const []) => emptyWidget, - PaginationState() => builder(context), - }; + }; } } diff --git a/lib/style/interface/boekwerk_interface.dart b/lib/style/interface/boekwerk_interface.dart index 3d06689..1bcb93e 100644 --- a/lib/style/interface/boekwerk_interface.dart +++ b/lib/style/interface/boekwerk_interface.dart @@ -1,5 +1,5 @@ import 'package:dcc_toolkit/style/text_style/handschrift.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// An abstract interface that defines a typography scale contract. /// diff --git a/lib/style/kleurplaat/color_group.dart b/lib/style/kleurplaat/color_group.dart index a1e7ea3..ec92652 100644 --- a/lib/style/kleurplaat/color_group.dart +++ b/lib/style/kleurplaat/color_group.dart @@ -3,18 +3,13 @@ import 'dart:ui'; import 'package:dcc_toolkit/style/interface/color_group_interface.dart'; /// {@macro color_group} -class ColorGroup implements ColorGroupInterface { +class const ColorGroup({ + @override required final Color color, + @override required final Color onColorContrast, + @override final Color? onColorSubtle, +}) implements ColorGroupInterface { /// {@macro color_group} - const ColorGroup({required this.color, required this.onColorContrast, this.onColorSubtle}); - - @override - final Color color; - - @override - final Color onColorContrast; - - @override - final Color? onColorSubtle; + this; @override ColorGroup lerp(ColorGroup? other, double t) { @@ -25,10 +20,9 @@ class ColorGroup implements ColorGroupInterface { return ColorGroup( color: Color.lerp(color, other.color, t) ?? color, onColorContrast: Color.lerp(onColorContrast, other.onColorContrast, t) ?? onColorContrast, - onColorSubtle: - onColorSubtle == null || other.onColorSubtle == null - ? null - : Color.lerp(onColorSubtle, other.onColorSubtle, t), + onColorSubtle: onColorSubtle == null || other.onColorSubtle == null + ? null + : Color.lerp(onColorSubtle, other.onColorSubtle, t), ); } } diff --git a/lib/style/kleurplaat/katjas_kleurplaat.dart b/lib/style/kleurplaat/katjas_kleurplaat.dart index 7c7c96f..dff5aee 100644 --- a/lib/style/kleurplaat/katjas_kleurplaat.dart +++ b/lib/style/kleurplaat/katjas_kleurplaat.dart @@ -1,77 +1,29 @@ import 'package:dcc_toolkit/style/interface/kleurplaat_interface.dart'; import 'package:dcc_toolkit/style/kleurplaat/color_group.dart'; import 'package:dcc_toolkit/style/kleurplaat/surface_group.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// {@macro kleurplaat} -class KatjasKleurplaat extends ThemeExtension implements KleurplaatInterface { +class const KatjasKleurplaat({ + @override required final ColorGroup primary, + @override required final ColorGroup primaryFill, + @override required final ColorGroup content, + @override required final ColorGroup contentFill, + @override required final ColorGroup error, + @override required final ColorGroup errorFill, + @override required final ColorGroup success, + @override required final ColorGroup successFill, + @override required final SurfaceGroup surface, + @override required final SurfaceGroup? surfaceInverse, + @override final ColorGroup? secondary, + @override final ColorGroup? secondaryFill, + @override final ColorGroup? tertiary, + @override final ColorGroup? tertiaryFill, + @override final ColorGroup? accent, + @override final ColorGroup? accentFill, +}) extends ThemeExtension implements KleurplaatInterface { /// {@macro kleurplaat} - const KatjasKleurplaat({ - required this.primary, - required this.primaryFill, - required this.content, - required this.contentFill, - required this.error, - required this.errorFill, - required this.success, - required this.successFill, - required this.surface, - required this.surfaceInverse, - this.secondary, - this.secondaryFill, - this.tertiary, - this.tertiaryFill, - this.accent, - this.accentFill, - }); - - @override - final ColorGroup primary; - - @override - final ColorGroup primaryFill; - - @override - final ColorGroup? secondary; - - @override - final ColorGroup? secondaryFill; - - @override - final ColorGroup? tertiary; - - @override - final ColorGroup? tertiaryFill; - - @override - final ColorGroup? accent; - - @override - final ColorGroup? accentFill; - - @override - final ColorGroup content; - - @override - final ColorGroup contentFill; - - @override - final ColorGroup error; - - @override - final ColorGroup errorFill; - - @override - final ColorGroup success; - - @override - final ColorGroup successFill; - - @override - final SurfaceGroup surface; - - @override - final SurfaceGroup? surfaceInverse; + this; @override ThemeExtension copyWith({ diff --git a/lib/style/kleurplaat/surface_group.dart b/lib/style/kleurplaat/surface_group.dart index 5db8d45..6219155 100644 --- a/lib/style/kleurplaat/surface_group.dart +++ b/lib/style/kleurplaat/surface_group.dart @@ -3,70 +3,25 @@ import 'dart:ui'; import 'package:dcc_toolkit/style/interface/surface_group_interface.dart'; /// {@macro surface_group} -class SurfaceGroup implements SurfaceGroupInterface { +class const SurfaceGroup({ + @override required final Color color, + @override required final Color onColorContrast, + @override required final Color onColorContrastDim, + @override required final Color onColorSubtle, + @override required final Color onColorSubtleDim, + @override required final Color containerLowest, + @override required final Color containerLow, + @override required final Color container, + @override required final Color containerHigh, + @override required final Color containerHighest, + @override required final Color link, + @override final Color? onColorError, + @override final Color? onColorSuccess, + @override final Color? onColorPrimary, + @override final Color? onColorPrimaryVariant, +}) implements SurfaceGroupInterface { /// {@macro surface_group} - const SurfaceGroup({ - required this.color, - required this.onColorContrast, - required this.onColorContrastDim, - required this.onColorSubtle, - required this.onColorSubtleDim, - required this.containerLowest, - required this.containerLow, - required this.container, - required this.containerHigh, - required this.containerHighest, - required this.link, - this.onColorError, - this.onColorSuccess, - this.onColorPrimary, - this.onColorPrimaryVariant, - }); - - @override - final Color color; - - @override - final Color onColorContrast; - - @override - final Color onColorContrastDim; - - @override - final Color onColorSubtle; - - @override - final Color onColorSubtleDim; - - @override - final Color containerLowest; - - @override - final Color containerLow; - - @override - final Color container; - - @override - final Color containerHigh; - - @override - final Color containerHighest; - - @override - final Color link; - - @override - final Color? onColorError; - - @override - final Color? onColorSuccess; - - @override - final Color? onColorPrimary; - - @override - final Color? onColorPrimaryVariant; + this; @override SurfaceGroup lerp(SurfaceGroup? other, double t) { diff --git a/lib/style/text_style/boekwerk_decorator.dart b/lib/style/text_style/boekwerk_decorator.dart index cb78d46..f314e92 100644 --- a/lib/style/text_style/boekwerk_decorator.dart +++ b/lib/style/text_style/boekwerk_decorator.dart @@ -15,79 +15,69 @@ import 'package:dcc_toolkit/style/text_style/katjas_boekwerk.dart'; /// [Handschrift] from the underlying [KatjasBoekwerk], or `null` if the /// source style is not defined. /// {@endtemplate} -class BoekwerkDecorator implements BoekwerkInterface { - /// {@macro boekwerk_decorator} - const BoekwerkDecorator(this._katjasBoekwerk, this._katjasKleurplaat); - +class const BoekwerkDecorator( /// The underlying typography scale to decorate. - final KatjasBoekwerk _katjasBoekwerk; + final KatjasBoekwerk _katjasBoekwerk, /// The color palette to apply to the typography. - final KatjasKleurplaat _katjasKleurplaat; + final KatjasKleurplaat _katjasKleurplaat, +) implements BoekwerkInterface { + /// {@macro boekwerk_decorator} + this; @override - HandschriftDecorator? get displayLarge => - _katjasBoekwerk.displayLarge != null - ? HandschriftDecorator(_katjasBoekwerk.displayLarge!, _katjasKleurplaat) - : null; + HandschriftDecorator? get displayLarge => _katjasBoekwerk.displayLarge != null + ? HandschriftDecorator(_katjasBoekwerk.displayLarge!, _katjasKleurplaat) + : null; @override - HandschriftDecorator? get displayMedium => - _katjasBoekwerk.displayMedium != null - ? HandschriftDecorator(_katjasBoekwerk.displayMedium!, _katjasKleurplaat) - : null; + HandschriftDecorator? get displayMedium => _katjasBoekwerk.displayMedium != null + ? HandschriftDecorator(_katjasBoekwerk.displayMedium!, _katjasKleurplaat) + : null; @override - HandschriftDecorator? get displaySmall => - _katjasBoekwerk.displaySmall != null - ? HandschriftDecorator(_katjasBoekwerk.displaySmall!, _katjasKleurplaat) - : null; + HandschriftDecorator? get displaySmall => _katjasBoekwerk.displaySmall != null + ? HandschriftDecorator(_katjasBoekwerk.displaySmall!, _katjasKleurplaat) + : null; @override - HandschriftDecorator? get subtitleLarge => - _katjasBoekwerk.subtitleLarge != null - ? HandschriftDecorator(_katjasBoekwerk.subtitleLarge!, _katjasKleurplaat) - : null; + HandschriftDecorator? get subtitleLarge => _katjasBoekwerk.subtitleLarge != null + ? HandschriftDecorator(_katjasBoekwerk.subtitleLarge!, _katjasKleurplaat) + : null; @override - HandschriftDecorator? get subtitleMedium => - _katjasBoekwerk.subtitleMedium != null - ? HandschriftDecorator(_katjasBoekwerk.subtitleMedium!, _katjasKleurplaat) - : null; + HandschriftDecorator? get subtitleMedium => _katjasBoekwerk.subtitleMedium != null + ? HandschriftDecorator(_katjasBoekwerk.subtitleMedium!, _katjasKleurplaat) + : null; @override - HandschriftDecorator? get subtitleSmall => - _katjasBoekwerk.subtitleSmall != null - ? HandschriftDecorator(_katjasBoekwerk.subtitleSmall!, _katjasKleurplaat) - : null; + HandschriftDecorator? get subtitleSmall => _katjasBoekwerk.subtitleSmall != null + ? HandschriftDecorator(_katjasBoekwerk.subtitleSmall!, _katjasKleurplaat) + : null; @override - HandschriftDecorator? get headlineLarge => - _katjasBoekwerk.headlineLarge != null - ? HandschriftDecorator(_katjasBoekwerk.headlineLarge!, _katjasKleurplaat) - : null; + HandschriftDecorator? get headlineLarge => _katjasBoekwerk.headlineLarge != null + ? HandschriftDecorator(_katjasBoekwerk.headlineLarge!, _katjasKleurplaat) + : null; @override - HandschriftDecorator? get headlineMedium => - _katjasBoekwerk.headlineMedium != null - ? HandschriftDecorator(_katjasBoekwerk.headlineMedium!, _katjasKleurplaat) - : null; + HandschriftDecorator? get headlineMedium => _katjasBoekwerk.headlineMedium != null + ? HandschriftDecorator(_katjasBoekwerk.headlineMedium!, _katjasKleurplaat) + : null; @override - HandschriftDecorator? get headlineSmall => - _katjasBoekwerk.headlineSmall != null - ? HandschriftDecorator(_katjasBoekwerk.headlineSmall!, _katjasKleurplaat) - : null; + HandschriftDecorator? get headlineSmall => _katjasBoekwerk.headlineSmall != null + ? HandschriftDecorator(_katjasBoekwerk.headlineSmall!, _katjasKleurplaat) + : null; @override HandschriftDecorator? get titleLarge => _katjasBoekwerk.titleLarge != null ? HandschriftDecorator(_katjasBoekwerk.titleLarge!, _katjasKleurplaat) : null; @override - HandschriftDecorator? get titleMedium => - _katjasBoekwerk.titleMedium != null - ? HandschriftDecorator(_katjasBoekwerk.titleMedium!, _katjasKleurplaat) - : null; + HandschriftDecorator? get titleMedium => _katjasBoekwerk.titleMedium != null + ? HandschriftDecorator(_katjasBoekwerk.titleMedium!, _katjasKleurplaat) + : null; @override HandschriftDecorator? get titleSmall => @@ -110,10 +100,9 @@ class BoekwerkDecorator implements BoekwerkInterface { _katjasBoekwerk.labelLarge != null ? HandschriftDecorator(_katjasBoekwerk.labelLarge!, _katjasKleurplaat) : null; @override - HandschriftDecorator? get labelMedium => - _katjasBoekwerk.labelMedium != null - ? HandschriftDecorator(_katjasBoekwerk.labelMedium!, _katjasKleurplaat) - : null; + HandschriftDecorator? get labelMedium => _katjasBoekwerk.labelMedium != null + ? HandschriftDecorator(_katjasBoekwerk.labelMedium!, _katjasKleurplaat) + : null; @override HandschriftDecorator? get labelSmall => diff --git a/lib/style/text_style/handschrift.dart b/lib/style/text_style/handschrift.dart index 7680505..7bd337e 100644 --- a/lib/style/text_style/handschrift.dart +++ b/lib/style/text_style/handschrift.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// An extended [TextStyle] that supports additional style variants for bold and link text. /// @@ -44,43 +44,46 @@ import 'package:flutter/material.dart'; /// /// [Handschrift] supports smooth interpolation via the [lerp] method, /// which interpolates all properties including the bold and link variants. -class Handschrift extends TextStyle { +class const Handschrift({ + super.inherit, + super.color, + super.backgroundColor, + super.fontSize, + super.fontWeight, + super.fontStyle, + super.letterSpacing, + super.wordSpacing, + super.textBaseline, + super.height, + super.leadingDistribution, + super.locale, + super.foreground, + super.background, + super.shadows, + super.fontFeatures, + super.fontVariations, + super.decoration, + super.decorationColor, + super.decorationStyle, + super.decorationThickness, + super.debugLabel, + super.fontFamily, + super.fontFamilyFallback, + super.package, + super.overflow, + + /// The style to merge when [bold] is accessed. + final TextStyle? _boldStyle, + + /// The style to merge when [link] is accessed. + final TextStyle? _linkStyle, +}) extends TextStyle { /// Creates a [Handschrift] with the given properties. /// /// All parameters from [TextStyle] are supported, plus: - /// - [boldStyle]: Optional style to merge when accessing [bold] - /// - [linkStyle]: Optional style to merge when accessing [link] - const Handschrift({ - super.inherit, - super.color, - super.backgroundColor, - super.fontSize, - super.fontWeight, - super.fontStyle, - super.letterSpacing, - super.wordSpacing, - super.textBaseline, - super.height, - super.leadingDistribution, - super.locale, - super.foreground, - super.background, - super.shadows, - super.fontFeatures, - super.fontVariations, - super.decoration, - super.decorationColor, - super.decorationStyle, - super.decorationThickness, - super.debugLabel, - super.fontFamily, - super.fontFamilyFallback, - super.package, - super.overflow, - TextStyle? boldStyle, - TextStyle? linkStyle, - }) : _boldStyle = boldStyle, - _linkStyle = linkStyle; + /// - `boldStyle`: Optional style to merge when accessing [bold] + /// - `linkStyle`: Optional style to merge when accessing [link] + this; /// Creates a [Handschrift] from an existing [TextStyle]. /// @@ -120,12 +123,6 @@ class Handschrift extends TextStyle { linkStyle: linkStyle, ); - /// The style to merge when [bold] is accessed. - final TextStyle? _boldStyle; - - /// The style to merge when [link] is accessed. - final TextStyle? _linkStyle; - /// Returns this style merged with [_boldStyle]. /// /// Use this getter to apply bold styling to text while preserving diff --git a/lib/style/text_style/handschrift_color_group.dart b/lib/style/text_style/handschrift_color_group.dart index c5d6ae7..2e9d9fa 100644 --- a/lib/style/text_style/handschrift_color_group.dart +++ b/lib/style/text_style/handschrift_color_group.dart @@ -2,18 +2,13 @@ import 'package:dcc_toolkit/style/interface/color_group_interface.dart'; import 'package:dcc_toolkit/style/text_style/handschrift.dart'; /// {@macro color_group} -class HandschriftColorGroup implements ColorGroupInterface { +class const HandschriftColorGroup({ + @override required final Handschrift color, + @override required final Handschrift onColorContrast, + @override final Handschrift? onColorSubtle, +}) implements ColorGroupInterface { /// {@macro color_group} - const HandschriftColorGroup({required this.color, required this.onColorContrast, this.onColorSubtle}); - - @override - final Handschrift color; - - @override - final Handschrift onColorContrast; - - @override - final Handschrift? onColorSubtle; + this; @override HandschriftColorGroup lerp(HandschriftColorGroup? other, double t) => this; diff --git a/lib/style/text_style/handschrift_decorator.dart b/lib/style/text_style/handschrift_decorator.dart index cefd7fd..557ba02 100644 --- a/lib/style/text_style/handschrift_decorator.dart +++ b/lib/style/text_style/handschrift_decorator.dart @@ -9,12 +9,10 @@ import 'package:dcc_toolkit/style/text_style/handschrift_surface_group.dart'; /// {@template text_style_decorator} /// Decorates a [Handschrift] with [KatjasKleurplaat] colors. /// {@endtemplate} -class HandschriftDecorator implements KleurplaatInterface { +class const HandschriftDecorator(final Handschrift _textStyle, final KatjasKleurplaat _kleurplaat) + implements KleurplaatInterface { /// {@macro text_style_decorator} - const HandschriftDecorator(this._textStyle, this._kleurplaat); - - final Handschrift _textStyle; - final KatjasKleurplaat _kleurplaat; + this; @override ColorGroupInterface get content => HandschriftColorGroup( diff --git a/lib/style/text_style/handschrift_surface_group.dart b/lib/style/text_style/handschrift_surface_group.dart index d318a1d..cd0e8f3 100644 --- a/lib/style/text_style/handschrift_surface_group.dart +++ b/lib/style/text_style/handschrift_surface_group.dart @@ -2,58 +2,25 @@ import 'package:dcc_toolkit/style/interface/surface_group_interface.dart'; import 'package:dcc_toolkit/style/text_style/handschrift.dart'; /// {@macro surface_group} -class HandschriftSurfaceGroup implements SurfaceGroupInterface { +class const HandschriftSurfaceGroup({ + @override required final Handschrift color, + @override required final Handschrift onColorContrast, + @override required final Handschrift onColorContrastDim, + @override required final Handschrift onColorSubtle, + @override required final Handschrift onColorSubtleDim, + @override required final Handschrift containerLowest, + @override required final Handschrift containerLow, + @override required final Handschrift container, + @override required final Handschrift containerHigh, + @override required final Handschrift containerHighest, + @override required final Handschrift link, + @override final Handschrift? onColorError, + @override final Handschrift? onColorSuccess, + @override final Handschrift? onColorPrimary, + @override final Handschrift? onColorPrimaryVariant, +}) implements SurfaceGroupInterface { /// {@macro surface_group} - const HandschriftSurfaceGroup({ - required this.color, - required this.onColorContrast, - required this.onColorContrastDim, - required this.onColorSubtle, - required this.onColorSubtleDim, - required this.containerLowest, - required this.containerLow, - required this.container, - required this.containerHigh, - required this.containerHighest, - required this.link, - this.onColorError, - this.onColorSuccess, - this.onColorPrimary, - this.onColorPrimaryVariant, - }); - - @override - final Handschrift color; - @override - final Handschrift onColorContrast; - @override - final Handschrift onColorContrastDim; - @override - final Handschrift onColorSubtle; - @override - final Handschrift onColorSubtleDim; - - @override - final Handschrift containerLowest; - @override - final Handschrift containerLow; - @override - final Handschrift container; - @override - final Handschrift containerHigh; - @override - final Handschrift containerHighest; - @override - final Handschrift link; - - @override - final Handschrift? onColorError; - @override - final Handschrift? onColorSuccess; - @override - final Handschrift? onColorPrimary; - @override - final Handschrift? onColorPrimaryVariant; + this; @override HandschriftSurfaceGroup lerp(HandschriftSurfaceGroup? other, double t) => this; diff --git a/lib/style/text_style/katjas_boekwerk.dart b/lib/style/text_style/katjas_boekwerk.dart index 45ae2b0..b2f653e 100644 --- a/lib/style/text_style/katjas_boekwerk.dart +++ b/lib/style/text_style/katjas_boekwerk.dart @@ -1,6 +1,6 @@ import 'package:dcc_toolkit/style/interface/boekwerk_interface.dart'; import 'package:dcc_toolkit/style/text_style/handschrift.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// {@template katjas_boekwerk} /// A [ThemeExtension] that provides a complete typography scale using [Handschrift] styles. @@ -26,68 +26,29 @@ import 'package:flutter/material.dart'; /// final boekwerk = Theme.of(context).extension(); /// ``` /// {@endtemplate} -class KatjasBoekwerk extends ThemeExtension implements BoekwerkInterface { +class KatjasBoekwerk({ + @override final Handschrift? displayLarge, + @override final Handschrift? displayMedium, + @override final Handschrift? displaySmall, + @override final Handschrift? subtitleLarge, + @override final Handschrift? subtitleMedium, + @override final Handschrift? subtitleSmall, + @override final Handschrift? headlineLarge, + @override final Handschrift? headlineMedium, + @override final Handschrift? headlineSmall, + @override final Handschrift? titleLarge, + @override final Handschrift? titleMedium, + @override final Handschrift? titleSmall, + @override final Handschrift? bodyLarge, + @override final Handschrift? bodyMedium, + @override final Handschrift? bodySmall, + @override final Handschrift? labelLarge, + @override final Handschrift? labelMedium, + @override final Handschrift? labelSmall, + @override final Handschrift? navbar, +}) extends ThemeExtension implements BoekwerkInterface { /// {@macro katjas_boekwerk} - KatjasBoekwerk({ - this.displayLarge, - this.displayMedium, - this.displaySmall, - this.subtitleLarge, - this.subtitleMedium, - this.subtitleSmall, - this.headlineLarge, - this.headlineMedium, - this.headlineSmall, - this.titleLarge, - this.titleMedium, - this.titleSmall, - this.bodyLarge, - this.bodyMedium, - this.bodySmall, - this.labelLarge, - this.labelMedium, - this.labelSmall, - this.navbar, - }); - - @override - final Handschrift? displayLarge; - @override - final Handschrift? displayMedium; - @override - final Handschrift? displaySmall; - @override - final Handschrift? subtitleLarge; - @override - final Handschrift? subtitleMedium; - @override - final Handschrift? subtitleSmall; - @override - final Handschrift? headlineLarge; - @override - final Handschrift? headlineMedium; - @override - final Handschrift? headlineSmall; - @override - final Handschrift? titleLarge; - @override - final Handschrift? titleMedium; - @override - final Handschrift? titleSmall; - @override - final Handschrift? bodyLarge; - @override - final Handschrift? bodyMedium; - @override - final Handschrift? bodySmall; - @override - final Handschrift? labelLarge; - @override - final Handschrift? labelMedium; - @override - final Handschrift? labelSmall; - @override - final Handschrift? navbar; + this; /// Converts this typography scale to a Flutter [TextTheme]. /// diff --git a/lib/test_util/devices_sizes.dart b/lib/test_util/devices_sizes.dart index 8f4d9e7..278ff47 100644 --- a/lib/test_util/devices_sizes.dart +++ b/lib/test_util/devices_sizes.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// Device sizes for testing. class DeviceSizes { diff --git a/lib/ui/annotated_text/annotated_text.dart b/lib/ui/annotated_text/annotated_text.dart index 54506bf..10baeb1 100644 --- a/lib/ui/annotated_text/annotated_text.dart +++ b/lib/ui/annotated_text/annotated_text.dart @@ -1,5 +1,5 @@ import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// A widget that displays a text with inline actions. /// Supported formats: [text](action) or [text] @@ -25,31 +25,25 @@ import 'package:flutter/material.dart'; /// annotationStyle: TextStyle(color: Colors.blue), /// ) /// ``` -class AnnotatedText extends StatelessWidget { - /// Creates a widget that displays a text with annotations. - const AnnotatedText({ - required this.text, - required this.actions, - required this.defaultStyle, - required this.annotationStyle, - this.textAlign = TextAlign.start, - super.key, - }); - +class const AnnotatedText({ /// The complete text to display. - final String text; + required final String text, /// A map {actionName: action} of actions to perform when the text is tapped. - final Map? actions; + required final Map? actions, /// The style of the default text. - final TextStyle defaultStyle; + required final TextStyle defaultStyle, /// The style of the annotated text. - final TextStyle annotationStyle; + required final TextStyle annotationStyle, /// The alignment of the text. - final TextAlign textAlign; + final TextAlign textAlign = TextAlign.start, + super.key, +}) extends StatelessWidget { + /// Creates a widget that displays a text with annotations. + this; @override Widget build(BuildContext context) { diff --git a/lib/ui/blocful_widget.dart b/lib/ui/blocful_widget.dart index 1282e37..724345d 100644 --- a/lib/ui/blocful_widget.dart +++ b/lib/ui/blocful_widget.dart @@ -21,33 +21,34 @@ import 'package:flutter_bloc/flutter_bloc.dart'; /// } /// } /// ``` -abstract class BlocfulWidget, STATE, EVENT> extends StatelessWidget { - /// Creates a [BlocfulWidget] - const BlocfulWidget({this.onCreateBloc, super.key}); - +abstract class const BlocfulWidget, STATE, EVENT>({ /// Wraps the widget with a [BlocProvider] with the given [BLOC] when this is not null - final BLOC Function(BuildContext)? onCreateBloc; + final BLOC Function(BuildContext)? onCreateBloc, + super.key, +}) extends StatelessWidget { + /// Creates a [BlocfulWidget] + this; @override Widget build(BuildContext context) { return onCreateBloc != null ? BlocProvider( - create: onCreateBloc!, - child: BlocPresentationListener( + create: onCreateBloc!, + child: BlocPresentationListener( + listener: onPresentationEvent, + child: BlocConsumer( + listener: (context, state) => listener(context, context.read(), state), + builder: (context, state) => builder(context, context.read(), state), + ), + ), + ) + : BlocPresentationListener( listener: onPresentationEvent, child: BlocConsumer( listener: (context, state) => listener(context, context.read(), state), builder: (context, state) => builder(context, context.read(), state), ), - ), - ) - : BlocPresentationListener( - listener: onPresentationEvent, - child: BlocConsumer( - listener: (context, state) => listener(context, context.read(), state), - builder: (context, state) => builder(context, context.read(), state), - ), - ); + ); } /// A function that defines what UI behaviour should be triggered when an [EVENT] has taken place diff --git a/lib/ui/native_dialog.dart b/lib/ui/native_dialog.dart index 8796183..f7a8ce8 100644 --- a/lib/ui/native_dialog.dart +++ b/lib/ui/native_dialog.dart @@ -1,8 +1,8 @@ import 'dart:async'; -import 'package:flutter/cupertino.dart'; +import 'package:cupertino_ui/cupertino_ui.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; /// A native dialog which shows a [CupertinoAlertDialog] on iOS and a [AlertDialog] on Android. /// @@ -26,63 +26,59 @@ Future showNativeDialog( if (defaultTargetPlatform == TargetPlatform.iOS) { return showCupertinoDialog( context: context, - builder: - (dialogContext) => CupertinoAlertDialog( - title: Text(title), - content: Text(content), - actions: - actions - .map( - (action) => CupertinoDialogAction( - onPressed: () async { - final result = await action.onTap(); - if (dialogContext.mounted) Navigator.of(dialogContext).pop(result); - }, - isDestructiveAction: action.isDestructiveAction, - child: Text(action.text, style: action.textStyle), - ), - ) - .toList(), - ), + builder: (dialogContext) => CupertinoAlertDialog( + title: Text(title), + content: Text(content), + actions: actions + .map( + (action) => CupertinoDialogAction( + onPressed: () async { + final result = await action.onTap(); + if (dialogContext.mounted) Navigator.of(dialogContext).pop(result); + }, + isDestructiveAction: action.isDestructiveAction, + child: Text(action.text, style: action.textStyle), + ), + ) + .toList(), + ), ); } else { return showDialog( context: context, - builder: - (dialogContext) => AlertDialog( - title: Text(title), - content: Text(content), - actions: - actions - .map( - (action) => TextButton( - onPressed: () async { - final result = await action.onTap(); - if (dialogContext.mounted) Navigator.of(dialogContext).pop(result); - }, - child: Text(action.text, style: action.textStyle), - ), - ) - .toList(), - ), + builder: (dialogContext) => AlertDialog( + title: Text(title), + content: Text(content), + actions: actions + .map( + (action) => TextButton( + onPressed: () async { + final result = await action.onTap(); + if (dialogContext.mounted) Navigator.of(dialogContext).pop(result); + }, + child: Text(action.text, style: action.textStyle), + ), + ) + .toList(), + ), ); } } /// A dialog action which is used to show the actions of a native dialog. Tapping a action will also close the dialog. -class DialogAction { - /// Creates a [DialogAction]. - const DialogAction({required this.text, required this.onTap, this.isDestructiveAction = false, this.textStyle}); - +class const DialogAction({ /// The text of the action. - final String text; + required final String text, /// The callback that is called when the action is tapped. - final FutureOr Function() onTap; + required final FutureOr Function() onTap, /// Whether the action is a destructive action. This is only used on iOS. - final bool isDestructiveAction; + final bool isDestructiveAction = false, /// The style of the action text. - final TextStyle? textStyle; + final TextStyle? textStyle, +}) { + /// Creates a [DialogAction]. + this; } diff --git a/pubspec.lock b/pubspec.lock index 0feb4c3..1a052e5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -61,10 +61,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" chopper: dependency: "direct main" description: @@ -73,6 +73,14 @@ packages: url: "https://pub.dev" source: hosted version: "8.1.0" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" clock: dependency: transitive description: @@ -101,10 +109,10 @@ packages: dependency: transitive description: name: coverage - sha256: c1fb2dce3c0085f39dc72668e85f8e0210ec7de05345821ff58530567df345a5 + sha256: "956a3de0725ca232ad353565a8290d3357592bf4250f6f298a185e2d949c5d3d" url: "https://pub.dev" source: hosted - version: "1.9.2" + version: "1.15.1" crypto: dependency: transitive description: @@ -113,6 +121,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.5" + cupertino_ui: + dependency: "direct main" + description: + name: cupertino_ui + sha256: c23816577a1280cff409e989541767887011f8f1d8c1863a794ed308af46f2a9 + url: "https://pub.dev" + source: hosted + version: "1.1.1" equatable: dependency: transitive description: @@ -150,6 +166,11 @@ packages: url: "https://pub.dev" source: hosted version: "9.1.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -199,10 +220,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + sha256: "1ca20c894b1717686a2319b8548763d812bc0aabdac580420a44c5178c57a867" url: "https://pub.dev" source: hosted - version: "0.20.2" + version: "0.20.3" io: dependency: transitive description: @@ -211,14 +232,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" - js: - dependency: transitive - description: - name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf - url: "https://pub.dev" - source: hosted - version: "0.7.1" json_annotation: dependency: "direct main" description: @@ -263,26 +276,34 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.20" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" + material_ui: + dependency: "direct main" + description: + name: material_ui + sha256: "134ab2f0843545c4e661e4ba2753fe1bcf0753cb690d5a9ee4870638a40411e9" + url: "https://pub.dev" + source: hosted + version: "1.4.0" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.19.0" mime: dependency: transitive description: @@ -476,26 +497,26 @@ packages: dependency: transitive description: name: test - sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7" + sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f url: "https://pub.dev" source: hosted - version: "1.26.3" + version: "1.31.1" test_api: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.12" test_core: dependency: transitive description: name: test_core - sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0" + sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5 url: "https://pub.dev" source: hosted - version: "0.6.12" + version: "0.6.18" typed_data: dependency: transitive description: @@ -508,10 +529,10 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "92b9910f66ed1057fd4da7b040ae7c74cafacf885bdc81be496928d5049b032d" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.3" very_good_analysis: dependency: "direct dev" description: @@ -580,10 +601,10 @@ packages: dependency: transitive description: name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + sha256: f67cdd8e07d3c6329146aaef1ba043542b3134c12489f553ca9a7435d1068aea url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" sdks: - dart: ">=3.9.0 <4.0.0" - flutter: ">=3.29.0" + dart: ">=3.13.0 <4.0.0" + flutter: ">=3.47.0" diff --git a/pubspec.yaml b/pubspec.yaml index b9220fc..c776406 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,17 +1,18 @@ name: dcc_toolkit description: "Internal toolkit package used by the DCC team." -version: 0.0.22 +version: 0.1.0 homepage: https://dutchcodingcompany.com repository: https://github.com/DutchCodingCompany/dcc_toolkit environment: - sdk: ">=3.7.0 <4.0.0" - flutter: ">=3.29.0" + sdk: ^3.13.0 + flutter: ">=3.47.0" dependencies: bloc_presentation: ^1.1.0 chopper: ^8.1.0 collection: ^1.19.1 + cupertino_ui: ^1.0.0 flutter: sdk: flutter flutter_bloc: ^9.1.0 @@ -19,6 +20,7 @@ dependencies: intl: ^0.20.2 json_annotation: ^4.9.0 logging: ^1.3.0 + material_ui: ^1.4.0 dev_dependencies: flutter_test: diff --git a/skills/dcc-toolkit-create-blocful-page/SKILL.md b/skills/dcc-toolkit-create-blocful-page/SKILL.md index 509514e..2a89afb 100644 --- a/skills/dcc-toolkit-create-blocful-page/SKILL.md +++ b/skills/dcc-toolkit-create-blocful-page/SKILL.md @@ -2,7 +2,7 @@ name: dcc-toolkit-create-blocful-page description: Create a full page using BlocfulWidget with BlocPresentationMixin for one-shot events, Cubit state management, and native dialogs. Use when creating a new screen with BLoC, adding presentation events, wiring up a Cubit to a page, or showing platform-adaptive dialogs. metadata: - last_modified: "2025-06-18" + last_modified: "2026-09-28" --- # Create a BlocfulWidget Page @@ -35,7 +35,12 @@ Additionally, the toolkit provides `showNativeDialog()` for platform-adaptive di import 'package:dcc_toolkit/dcc_toolkit.dart'; // BlocfulWidget, showNativeDialog, DialogAction ``` +Requirements: +- Flutter >=3.47.0 +- Dart ^3.13.0 + Dependencies required in the consuming project: +- `material_ui: ^1.4.0` (Material widgets moved out of the Flutter SDK) - `flutter_bloc` (for `Cubit`, `BlocPresentationMixin`) - `bloc_presentation` (for `BlocPresentationMixin`, `emitPresentation()`) - `dcc_toolkit` @@ -103,20 +108,12 @@ class UserLoaded implements UserEvent { String get message => 'User loaded successfully'; } -class UserSaveFailed implements UserEvent { - const UserSaveFailed(this.reason); - - final String reason; - +class const UserSaveFailed(final String reason) implements UserEvent { @override String get message => 'Save failed: $reason'; } -class NavigateToProfile implements UserEvent { - const NavigateToProfile(this.userId); - - final String userId; - +class const NavigateToProfile(final String userId) implements UserEvent { @override String get message => ''; } @@ -146,13 +143,11 @@ Or manually: import 'package:flutter/foundation.dart'; @immutable -class UserState { - const UserState({this.user, this.isLoading = false, this.hasError = false}); - - final User? user; - final bool isLoading; - final bool hasError; - +class const UserState({ + final User? user, + final bool isLoading = false, + final bool hasError = false, +}) { UserState copyWith({User? user, bool? isLoading, bool? hasError}) => UserState( user: user ?? this.user, isLoading: isLoading ?? this.isLoading, @@ -183,11 +178,9 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'user_cubit.freezed.dart'; part 'user_state.dart'; -class UserCubit extends Cubit +class UserCubit(final UserRepository _repository) extends Cubit with BlocPresentationMixin { - UserCubit(this._repository) : super(const UserState()); - - final UserRepository _repository; + this : super(const UserState()); Future loadUser(String id) async { emit(state.copyWith(isLoading: true)); @@ -220,13 +213,13 @@ class UserCubit extends Cubit ```dart // user_page.dart import 'package:dcc_toolkit/ui/blocful_widget.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; -class UserPage extends BlocfulWidget { - const UserPage({required this.onCreateCubit, super.key}) - : super(onCreateBloc: onCreateCubit); - - final UserCubit Function(BuildContext)? onCreateCubit; +class const UserPage({ + required final UserCubit Function(BuildContext)? onCreateCubit, + super.key, +}) extends BlocfulWidget { + this : super(onCreateBloc: onCreateCubit); @override void onPresentationEvent(BuildContext context, UserEvent event) { @@ -313,8 +306,9 @@ Or if the Cubit is already provided higher in the tree: ```dart // No onCreateBloc needed -- Cubit already exists in widget tree -class UserDetailPage extends BlocfulWidget { - const UserDetailPage({super.key}) : super(onCreateBloc: null); +class const UserDetailPage({super.key}) + extends BlocfulWidget { + this : super(onCreateBloc: null); @override Widget builder(BuildContext context, UserCubit bloc, UserState state) { @@ -345,9 +339,7 @@ class ProfileUpdateSuccess implements ProfileEvent { String get message => 'Profile updated successfully'; } -class ProfileError implements ProfileEvent { - const ProfileError(this.error); - final String error; +class const ProfileError(final String error) implements ProfileEvent { @override String get message => error; } @@ -362,11 +354,10 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'profile_cubit.freezed.dart'; part 'profile_state.dart'; -class ProfileCubit extends Cubit +class ProfileCubit(final ProfileRepository _repository) + extends Cubit with BlocPresentationMixin { - ProfileCubit(this._repository) : super(const ProfileState()); - - final ProfileRepository _repository; + this : super(const ProfileState()); Future loadProfile() async { emit(state.copyWith(isLoading: true)); @@ -414,12 +405,12 @@ sealed class ProfileState with _$ProfileState { import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:dcc_toolkit/ui/blocful_widget.dart'; import 'package:dcc_toolkit/ui/native_dialog.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:material_ui/material_ui.dart'; -class ProfilePage extends BlocfulWidget { - const ProfilePage({super.key}) - : super(onCreateBloc: _createCubit); +class const ProfilePage({super.key}) + extends BlocfulWidget { + this : super(onCreateBloc: _createCubit); static ProfileCubit _createCubit(BuildContext context) => context.read()..loadProfile(); @@ -555,8 +546,9 @@ class OrderPage extends StatelessWidget { } } -class _OrderContent extends BlocfulWidget { - const _OrderContent() : super(onCreateBloc: _create); +class const _OrderContent() + extends BlocfulWidget { + this : super(onCreateBloc: _create); static OrderCubit _create(BuildContext context) => getIt()..load(); diff --git a/skills/dcc-toolkit-create-paginated-cubit/SKILL.md b/skills/dcc-toolkit-create-paginated-cubit/SKILL.md index d64bf07..feb4f34 100644 --- a/skills/dcc-toolkit-create-paginated-cubit/SKILL.md +++ b/skills/dcc-toolkit-create-paginated-cubit/SKILL.md @@ -2,7 +2,7 @@ name: dcc-toolkit-create-paginated-cubit description: Scaffold a paginated Cubit using PaginationMixin and PaginationState with PaginatedScrollView and PaginationStateView widgets. Use when adding pagination, implementing infinite scroll, loading more items on scroll, or creating a paginated list. metadata: - last_modified: "2025-06-18" + last_modified: "2026-09-28" --- # Create a Paginated Cubit @@ -39,7 +39,12 @@ import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:dcc_toolkit/pagination/pagination_state_view.dart'; ``` +Requirements: +- Flutter >=3.47.0 +- Dart ^3.13.0 + Dependencies required in the consuming project: +- `material_ui: ^1.4.0` (Material widgets moved out of the Flutter SDK) - `flutter_bloc` (for `Cubit`) - `dcc_toolkit` @@ -96,14 +101,9 @@ import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:flutter/foundation.dart'; @immutable -class ProductListState implements PaginationInterface { - const ProductListState({ - this.paginationState = const PaginationState(), - }); - - @override - final PaginationState paginationState; - +class const ProductListState({ + @override final PaginationState paginationState = const PaginationState(), +}) implements PaginationInterface { ProductListState copyWith({ PaginationState? paginationState, }) { @@ -128,11 +128,10 @@ class ProductListState implements PaginationInterface { import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class ProductListCubit extends Cubit +class ProductListCubit(final ProductRepository _repository) + extends Cubit with PaginationMixin { - ProductListCubit(this._repository) : super(const ProductListState()); - - final ProductRepository _repository; + this : super(const ProductListState()); @override Future?> fetchPageItems({ @@ -194,12 +193,10 @@ class ProductListCubit extends Cubit ```dart import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:dcc_toolkit/pagination/pagination_state_view.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:material_ui/material_ui.dart'; -class ProductListPage extends StatelessWidget { - const ProductListPage({super.key}); - +class const ProductListPage({super.key}) extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( @@ -210,9 +207,7 @@ class ProductListPage extends StatelessWidget { } } -class _ProductListView extends StatelessWidget { - const _ProductListView(); - +class const _ProductListView() extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( @@ -262,14 +257,9 @@ import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:flutter/foundation.dart'; @immutable -class ProductListState implements PaginationInterface { - const ProductListState({ - this.paginationState = const PaginationState(), - }); - - @override - final PaginationState paginationState; - +class const ProductListState({ + @override final PaginationState paginationState = const PaginationState(), +}) implements PaginationInterface { ProductListState copyWith({PaginationState? paginationState}) => ProductListState(paginationState: paginationState ?? this.paginationState); @@ -288,11 +278,10 @@ class ProductListState implements PaginationInterface { import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class ProductListCubit extends Cubit +class ProductListCubit(final ProductRepository _repository) + extends Cubit with PaginationMixin { - ProductListCubit(this._repository) : super(const ProductListState()); - - final ProductRepository _repository; + this : super(const ProductListState()); @override Future?> fetchPageItems({ @@ -339,12 +328,10 @@ class ProductListCubit extends Cubit // product_list_page.dart import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:dcc_toolkit/pagination/pagination_state_view.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:material_ui/material_ui.dart'; -class ProductListPage extends StatelessWidget { - const ProductListPage({super.key}); - +class const ProductListPage({super.key}) extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( @@ -395,11 +382,10 @@ Debounce search input using the toolkit's `Debouncer`: ```dart import 'package:dcc_toolkit/debouncer/debouncer.dart'; -class ProductListCubit extends Cubit +class ProductListCubit(final ProductRepository _repository) + extends Cubit with PaginationMixin { - ProductListCubit(this._repository) : super(const ProductListState()); - - final ProductRepository _repository; + this : super(const ProductListState()); final _debouncer = Debouncer(); // 400ms default void onSearchChanged(String query) { diff --git a/skills/dcc-toolkit-setup-bolt-logger/SKILL.md b/skills/dcc-toolkit-setup-bolt-logger/SKILL.md index 775bc0e..4d02d59 100644 --- a/skills/dcc-toolkit-setup-bolt-logger/SKILL.md +++ b/skills/dcc-toolkit-setup-bolt-logger/SKILL.md @@ -2,7 +2,7 @@ name: dcc-toolkit-setup-bolt-logger description: Set up and configure BoltLogger for structured logging with charges (DebugConsole, File, Memory). Use when adding logging, setting up error tracking, adding an in-app log viewer, or bootstrapping a Flutter app with error handling. metadata: - last_modified: "2025-06-18" + last_modified: "2026-09-28" --- # Set Up BoltLogger @@ -29,6 +29,11 @@ BoltLogger is the DCC toolkit's structured logging system built on top of the `l ## Prerequisites +Requirements: +- Flutter >=3.47.0 +- Dart ^3.13.0 +- `material_ui: ^1.4.0` in the app's `pubspec.yaml` (Material widgets moved out of the Flutter SDK) + The project must depend on `dcc_toolkit`. BoltLogger is exported from the main barrel file: ```dart @@ -86,7 +91,7 @@ Replace your `main()` function to use `runAppBootstrap()`. This wraps the app in ```dart import 'package:dcc_toolkit/common/run_app_bootstrap.dart'; import 'package:dcc_toolkit/dcc_toolkit.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; Future main() async { await runAppBootstrap(() async { @@ -186,9 +191,7 @@ class UserRepository { Create a debug page that shows logs in-app: ```dart -class DebugLogPage extends StatelessWidget { - const DebugLogPage({super.key}); - +class const DebugLogPage({super.key}) extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( @@ -215,7 +218,7 @@ BoltLogger.discharge(); // Cancels subscription, flushes FileCharge, closes Memo // main.dart import 'package:dcc_toolkit/common/run_app_bootstrap.dart'; import 'package:dcc_toolkit/dcc_toolkit.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; import 'package:path_provider/path_provider.dart'; Future main() async { @@ -240,10 +243,8 @@ Future main() async { import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -class SomeCubit extends Cubit { - SomeCubit(this._repository) : super(const SomeState.initial()); - - final SomeRepository _repository; +class SomeCubit(final SomeRepository _repository) extends Cubit { + this : super(const SomeState.initial()); Future loadData() async { zap('Loading data...'); // Uses ZapExtension, tag = 'SomeCubit' diff --git a/skills/dcc-toolkit-setup-kleurplaat-boekwerk/SKILL.md b/skills/dcc-toolkit-setup-kleurplaat-boekwerk/SKILL.md index f51f96d..ef6ee7d 100644 --- a/skills/dcc-toolkit-setup-kleurplaat-boekwerk/SKILL.md +++ b/skills/dcc-toolkit-setup-kleurplaat-boekwerk/SKILL.md @@ -2,7 +2,7 @@ name: dcc-toolkit-setup-kleurplaat-boekwerk description: Create and configure a custom design system using KatjasKleurplaat (colors) and KatjasBoekwerk (typography) theme extensions. Use when setting up theming, adding a color palette, configuring typography, or integrating the DCC design system into a Flutter app. metadata: - last_modified: "2025-06-18" + last_modified: "2026-09-28" --- # Set Up Kleurplaat & Boekwerk Design System @@ -29,6 +29,11 @@ Both are registered as Flutter `ThemeExtension`s and accessed via `BuildContext` ## Prerequisites +Requirements: +- Flutter >=3.47.0 +- Dart ^3.13.0 +- `material_ui: ^1.4.0` in the app's `pubspec.yaml` (Material widgets moved out of the Flutter SDK) + ```dart import 'package:dcc_toolkit/dcc_toolkit.dart'; ``` @@ -36,8 +41,8 @@ import 'package:dcc_toolkit/dcc_toolkit.dart'; For `KatjasBoekwerk` and `Handschrift` (not in barrel file), import directly: ```dart -import 'package:dcc_toolkit/style/text_style/katjas_boekwerk.dart'; import 'package:dcc_toolkit/style/text_style/handschrift.dart'; +import 'package:dcc_toolkit/style/text_style/katjas_boekwerk.dart'; ``` ## Core Concepts @@ -104,7 +109,7 @@ Create a file (e.g., `lib/core/theme/app_kleurplaat.dart`): ```dart import 'package:dcc_toolkit/dcc_toolkit.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; final appKleurplaatLight = KatjasKleurplaat( primary: const ColorGroup( @@ -180,7 +185,7 @@ Create a file (e.g., `lib/core/theme/app_boekwerk.dart`): ```dart import 'package:dcc_toolkit/style/text_style/handschrift.dart'; import 'package:dcc_toolkit/style/text_style/katjas_boekwerk.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; final appBoekwerk = KatjasBoekwerk( displayLarge: const Handschrift( @@ -311,7 +316,7 @@ final appBoekwerk = KatjasBoekwerk( In your app's theme configuration: ```dart -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; ThemeData buildAppTheme() { final kleurplaat = appKleurplaatLight; @@ -390,7 +395,7 @@ Widget build(BuildContext context) { import 'package:dcc_toolkit/dcc_toolkit.dart'; import 'package:dcc_toolkit/style/text_style/handschrift.dart'; import 'package:dcc_toolkit/style/text_style/katjas_boekwerk.dart'; -import 'package:flutter/material.dart'; +import 'package:material_ui/material_ui.dart'; class AppTheme { static ThemeData get light { @@ -449,12 +454,11 @@ class AppTheme { ```dart // Usage in a widget -class ProfileCard extends StatelessWidget { - const ProfileCard({required this.name, required this.email, super.key}); - - final String name; - final String email; - +class const ProfileCard({ + required final String name, + required final String email, + super.key, +}) extends StatelessWidget { @override Widget build(BuildContext context) { final kleurplaat = context.katjasKleurPlaat; diff --git a/test/common/extensions/color_test.dart b/test/common/extensions/color_test.dart index 0d54154..2f33acf 100644 --- a/test/common/extensions/color_test.dart +++ b/test/common/extensions/color_test.dart @@ -1,6 +1,6 @@ import 'package:dcc_toolkit/common/extensions/color.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:material_ui/material_ui.dart'; void main() { test('Color extension test', () { diff --git a/test/ui/annotated_text_test.dart b/test/ui/annotated_text_test.dart index 16baab6..e456320 100644 --- a/test/ui/annotated_text_test.dart +++ b/test/ui/annotated_text_test.dart @@ -1,7 +1,7 @@ import 'package:dcc_toolkit/ui/annotated_text/annotated_text.dart'; import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:material_ui/material_ui.dart'; void main() { testWidgets('renders annotated text without action', (WidgetTester tester) async {