### Flutter ThemeData Example Source: https://engineering.verygood.ventures/theming/theming Demonstrates using ThemeData to automatically inherit widget styles, manage light/dark themes, and reference design tokens for consistency. This approach centralizes styling updates. ```dart return MaterialApp( theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), textTheme: AppTextStyles.textTheme, ), home: const MyHomePage(), ); ``` -------------------------------- ### GoRouter Configuration Example Source: https://engineering.verygood.ventures/navigation/navigation Illustrates a basic GoRouter configuration with a root route and a sub-route for 'details'. This example shows how to define routes, including path parameters, and how to navigate to them. ```Dart GoRoute( path: '/flutter/news', builder: (BuildContext context, GoRouterState state) { return const NewsListPage(); }, routes: [ GoRoute( path: 'details', builder: (BuildContext context, GoRouterState state) { return const NewsDetailsPage(); }, ), ], ) ``` -------------------------------- ### Flutter Component Theming Example Source: https://engineering.verygood.ventures/theming/theming Shows how to customize specific Material component themes within ThemeData, such as setting the minimum width for FilledButton widgets. This centralizes widget-specific styling. ```dart MaterialApp( theme: ThemeData( filledButtonTheme: FilledButtonThemeData( style: ButtonStyle(minimumSize: MaterialStateProperty.all(const Size(72, 40))), ), ), home: const MyHomePage(), ); ``` -------------------------------- ### CSS Spacing Class Example Source: https://engineering.verygood.ventures/theming/theming This CSS code defines a class for managing spacing units, promoting consistency in UI design. It uses a base unit to simplify layout creation and avoid hardcoded values. ```css .spacing { /* Define spacing properties here */ margin: 1rem; padding: 0.5rem; } ``` -------------------------------- ### Keep Test Setup Inside a Group Source: https://engineering.verygood.ventures/testing/testing To prevent side effects and ensure test stability, especially when using optimized test execution, setup methods like 'setUp' and 'setUpAll' should be placed within test groups. ```dart group('My Group', () { setUp(() { // Setup logic here }); test('My Test', () { // Test logic here }); }); ``` -------------------------------- ### Dart Project Structure Example Source: https://engineering.verygood.ventures/architecture/backend Illustrates a typical directory structure for a backend project using Dart, separating concerns like routes, data models, and data sources into distinct packages and directories. This promotes modularity and testability. ```Dart Directoryapi/ Directoryroutes/ Directoryapi/ Directoryv1/ Directorytodos/ ... Directorytest/ Directoryroutes/ Directoryapi/ Directoryv1/ Directorytodos/ ... Directorypackages/ Directorymodels/ Directorylib/ Directorysrc/ Directoryendpoint_models/ ... Directoryshared_models/ ... Directorytest/ Directorysrc/ Directoryendpoint_models/ ... Directoryshared_models/ ... Directorydata_source/ Directorylib/ Directorysrc/ ... Directorytest/ Directorysrc/ ... ``` -------------------------------- ### Organize Test Files by Directory Structure Source: https://engineering.verygood.ventures/testing/testing Test files should mirror the project's file structure to maintain organization. This example shows how a 'lib' directory with 'models' and 'widgets' subdirectories should have a corresponding 'test' directory structure. ```dart Directorytest/ Directorymodels/ model_a_test.dart model_b_test.dart Directorywidgets/ widget_1_test.dart widget_2_test.dart ``` -------------------------------- ### GoRouter StatefulShellRoute Navigation Source: https://engineering.verygood.ventures/examples/airplane_entertainment_system Demonstrates how to set up navigation using GoRouter's StatefulShellRoute for managing different branches of the application. It includes examples of defining route data classes and overriding the build method to return widgets. ```Dart class HomeScreenRouteData extends GoRouteData { @override Widget build() { return const AirplaneEntertainmentSystemScreen(); } } class OverviewPageBranchData extends GoRouteData { @override Widget build() { return const OverviewScreen(); } } class MusicPlayerPageRouteData extends GoRouteData { @override Widget build() { return const MusicPlayerScreen(); } } ``` -------------------------------- ### HTML Structure for Spacing Source: https://engineering.verygood.ventures/theming/theming This HTML snippet shows how to apply the spacing class to a div element, ensuring consistent spacing is applied to the content within it. ```html

This content will have spacing applied.

``` -------------------------------- ### Flutter Custom Colors with ColorScheme Source: https://engineering.verygood.ventures/theming/theming Demonstrates creating a custom color class and updating Flutter's ColorScheme with these custom colors. This ensures consistent color usage across widgets by referencing tokens from the ColorScheme. ```dart class AppColors { static const Color primary = Color(0xFF6200EE); static const Color secondary = Color(0xFF03DAC6); } // Usage in ThemeData: MaterialApp( theme: ThemeData( colorScheme: ColorScheme( brightness: Brightness.light, primary: AppColors.primary, secondary: AppColors.secondary, // ... other color properties ), ), ); ``` -------------------------------- ### Setup Internationalization in pubspec.yaml Source: https://engineering.verygood.ventures/internationalization/localization This snippet shows how to enable internationalization by adding the `flutter_localizations` and `intl` packages and setting the `generate` flag in the `pubspec.yaml` file. ```yaml dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter intl: dev_dependencies: flutter_test: sdk: flutter flutter: generate: true ``` -------------------------------- ### Flutter Layout Constraints Example Source: https://engineering.verygood.ventures/widgets/layouts Shows examples of how parent constraints affect child widget sizing in Flutter layouts, demonstrating scenarios with and without explicit constraints. ```Dart // Without explicit constraints (child determines size) Widget childWidget = Container(width: 50, height: 50, color: Colors.blue); // With constraints (parent enforces size) Widget constrainedWidget = Container( constraints: BoxConstraints.tightFor(width: 100, height: 100), child: Container(color: Colors.red), // This child will be 100x100 ); ``` -------------------------------- ### Flutter Typography with TextTheme Source: https://engineering.verygood.ventures/theming/theming Shows how to define custom text styles and integrate them into Flutter's TextTheme. This allows widgets to reference text styles through ThemeData, ensuring consistent typography across the application. ```dart class AppTextStyles { static const TextStyle _titleLarge = TextStyle( fontSize: 32, fontWeight: FontWeight.bold, ); static TextTheme textTheme = TextTheme( titleLarge: _titleLarge, bodyMedium: const TextStyle(fontSize: 14.0), ); } // Usage: // Theme.of(context).textTheme.titleLarge ``` -------------------------------- ### Generate Flutter App with VGV CLI Source: https://engineering.verygood.ventures/index Use the Very Good CLI to generate a new Flutter application. This command-line tool simplifies project setup with scalable templates and built-in best practices. ```Shell dart pub global activate very_good_cli very_good create my_app --template=flutter_app ``` -------------------------------- ### Importing Fonts in Flutter Source: https://engineering.verygood.ventures/theming/theming Illustrates how to import custom fonts into a Flutter project by placing them in the assets folder and declaring them in the pubspec.yaml file. It also mentions using flutter_gen for type safety. ```yaml flutter: fonts: - family: Inter fonts: - asset: assets/fonts/Inter-Regular.ttf - asset: assets/fonts/Inter-Bold.ttf weight: 700 ``` -------------------------------- ### Dart Record Type Naming - Good Example Source: https://engineering.verygood.ventures/code_style/code_style This snippet illustrates the recommended way to use Dart record types by assigning meaningful names to positional values. This practice significantly enhances code clarity and maintainability, making it easier for developers to understand the data being accessed. ```Dart ({required String name, required String email}) getUserNameAndEmail() { return (name: 'Alice', email: 'alice@example.com'); } void main() { final userData = getUserNameAndEmail(); print(userData.name); // Prints 'Alice' print(userData.email); // Prints 'alice@example.com' } ``` -------------------------------- ### Assert Test Results with expect or verify Source: https://engineering.verygood.ventures/testing/testing Tests should conclude with assertions using 'expect' or 'verify' to validate outcomes. This example demonstrates a more valuable test that explicitly checks the 'onTap' property of a widget, ensuring its behavior is tested. ```dart expect(someTappableWidget.onTap, isNotNull); ``` -------------------------------- ### Feature Bloc as Barrel File (Dart) Source: https://engineering.verygood.ventures/architecture/barrel_files In this Dart example, the main bloc file acts as a barrel file for its associated events and states using 'part of' directives. This convention avoids the need for an additional barrel file for the bloc module. ```Dart // feature_bloc.dart part of 'feature_event.dart'; part of 'feature_state.dart'; ``` -------------------------------- ### Dart Record Type Naming - Bad Example Source: https://engineering.verygood.ventures/code_style/code_style This snippet demonstrates a poor use of Dart record types where positional values are accessed using generic names like '$1'. This makes the code less readable and harder to understand, especially in larger codebases. ```Dart ({required String name, required String email}) getUserNameAndEmail() { return ('Alice', 'alice@example.com'); } void main() { final userData = getUserNameAndEmail(); print(userData.$1); // Prints 'Alice' print(userData.$2); // Prints 'alice@example.com' } ``` -------------------------------- ### Documenting External Tools with Commands Source: https://engineering.verygood.ventures/documentation/documentation When using external tools like build_runner, custom_lint, or flutter gen-l10n, document their purpose, usage, and provide actionable CLI commands. This includes specifying when and why to use the tool, where its configuration resides, and any common pitfalls. ```bash # Example for flutter gen-l10n flutter gen-l10n # Example for build_runner flutter pub run build_runner build --delete-conflicting-outputs # Example for custom_lint flutter pub run custom_lint ``` -------------------------------- ### Automating Flutter/Dart CI/CD with GitHub Actions Workflows Source: https://engineering.verygood.ventures/automation/ci_cd This snippet outlines the common CI/CD workflows used for Flutter and Dart applications via GitHub Actions. It includes running tests, ensuring code coverage, performing semantic pull request checks, and spell checks for every pull request. ```YAML # Example GitHub Actions workflow for Flutter/Dart CI/CD name: CI/CD Pipeline on: pull_request: branches: [ main ] push: branches: [ main ] jobs: build_and_test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Flutter uses: subosito/flutter-action@v2 with: flutter-version: '3.x.x' - name: Install Dependencies run: flutter pub get - name: Run Tests and Check Coverage run: flutter test --coverage - name: Upload Coverage Report uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Semantic Pull Request Check uses: actions/semantic-pullrequest-action@v1.0.0 - name: Spell Check run: | # Add spell check command here, e.g., using a linter or dedicated tool ``` -------------------------------- ### GoRouter Extension Methods Source: https://engineering.verygood.ventures/navigation/navigation Highlights the use of GoRouter's extension methods on BuildContext for simplified navigation. Using these methods is recommended for consistency and cleaner code. ```Dart // Instead of: // GoRouter.of(context).go('/home'); // Use the extension method: context.go('/home'); ``` -------------------------------- ### Flavor Cubit for Theming Source: https://engineering.verygood.ventures/examples/financial_dashboard Demonstrates a simple Cubit that emits the selected flavor when a button is tapped, rebuilding the appropriate page with a BlocBuilder. This manages theme changes in the application. ```Dart class FlavorCubit extends Cubit { FlavorCubit() : super(FlavorState.green); void selectFlavor(FlavorState state) => emit(state); } ``` -------------------------------- ### Navigate to Article Details with Path Parameter Source: https://engineering.verygood.ventures/navigation/navigation Shows how to define a route with a path parameter for an article ID and how to navigate to that route, passing the article ID as a parameter. ```Dart GoRoute( path: '/article/:id', builder: (BuildContext context, GoRouterState state) { // Access the id parameter final String id = state.params['id']!; return ArticleDetailsPage(articleId: id); }, ) ``` ```Dart FlutterArticlePageRoute(id: '123').go(context) ``` -------------------------------- ### Flutter EdgeInsetsDirectional for Direction-Aware Padding Source: https://engineering.verygood.ventures/internationalization/text_directionality Illustrates using EdgeInsetsDirectional to apply padding that respects text directionality. 'Start' padding is applied before the text, adapting automatically to LTR or RTL layouts. ```Dart Padding( padding: EdgeInsetsDirectional.only(start: 16.0), child: Text('Some text'), ) ``` -------------------------------- ### Widget Testing with Mocked Dependencies Source: https://engineering.verygood.ventures/widgets Demonstrates how to test a LoginView by mocking its associated Bloc (LoginBloc) and providing it directly to the view. This approach enhances testability by isolating the view's logic. ```dart We can easily write tests for the `LoginView` by mocking the `LoginBloc` and providing it directly to the view. ``` -------------------------------- ### Enforcing Lint Rules with very_good_analysis Source: https://engineering.verygood.ventures/documentation/documentation Automate the enforcement of coding standards and naming conventions using linting tools. The `very_good_analysis` package is recommended for Flutter projects to ensure consistency and reduce surprises. ```yaml dev_dependencies: flutter_test: sdk: flutter very_good_analysis: version: "3.1.0" flutter: uses-material-design: true linter: rules: - prefer_const_constructors - prefer_const_declarations - prefer_const_literals_to_create_objects - prefer_final_fields - prefer_final_locals - prefer_interpolation_to_compose_strings - prefer_null_aware_operators - prefer_single_widget_per_file - prefer_typing_uninitialized_variables - sort_child_properties_last - sort_pub_dependencies - type_annotate_public_configurable_api - unawaited_futures - unnecessary_await_in_return - unnecessary_null_checks - use_full_hex_colors - use_key_in_widget_constructors - use_named_routes - use_package_imports - use_platform_type_for_local_variable - use_super_parameters - void_checks - curly_braces_in_flow_control_structures - cascade_invocations - avoid_redundant_argument_values - avoid_returning_null - avoid_returning_this - avoid_setters_without_getters - avoid_shadowing_type_parameters - avoid_types_on_closure_parameters - avoid_unused_constructor_parameters - avoid_weak_references - await_only_futures - camel_case_extensions - camel_case_types - close_sinks - comment_references - constant_identifier_names - control_flow_in_loops - diagnostic_describe_all_properties - empty_statements - exhaustive_cases - file_names - flutter_style_todos - implementation_imports - import_of_legacy_library_into_null_safe - invalid_assignment - iterable_contains_unrelated_type - library_annotations - library_init - library_private_types_in_public_api - literal_only_boolean_expressions - missing_whitespace_between_attributes - missing_whitespace_after_comma - missing_whitespace_before_first_element - missing_whitespace_before_parameter_separator - missing_whitespace_between_arguments - no_leading_underscores_for_library_prefixes - no_leading_underscores_for_local_identifiers - no_logic_in_literal - no_self_assignment - no_leading_underscores_for_method_parameters - non_constant_identifier_names - null_aware_method_call - null_aware_operators - omit_local_variable_types - one_member_abstract_classes - only_throw_error - ordered_imports - package_api_docs - package_names - parameter_assignments - prefer_adjacent_string_literals - prefer_asserts_in_initializer_list - prefer_assert_with_message - prefer_bool_in_operator_chains - prefer_constructors_over_static_methods - prefer_equal_for_default_values - prefer_expression_function_bodies - prefer_final_in_for_each - prefer_generic_function_type_syntax - prefer_if_elements_to_conditional_expressions - prefer_inconsistent_parameter_locations - prefer_interpolation_to_compose_strings - prefer_literal_enum_values - prefer_mixin - prefer_null_aware_method_calls - prefer_null_aware_operators - prefer_numeric_literals - prefer_relative_imports - prefer_single_widget_per_file - prefer_spread_collections - prefer_typing_uninitialized_variables - prefer_void_to_null - provide_single_widget_per_file - recursive_getters - require_trailing_commas - sized_box_for_whitespace - sort_assignments - sort_constructors_first - sort_enum_members - sort_imports_first - sort_key_properties_first - sort_null_unsafe_operators - sort_public_member_api_docs - sort_sibling_tag_attributes - sort_unnamed_types_first - specific_imports - strict_raw_type - syntactic_sugar_enabled - test_types - throw_in_catch_block - tighten_type_of_initial_values - type_annotate_public_configurable_api - type_init_formals - unawaited_futures - unnecessary_await_in_return - unnecessary_brace_in_string_interps - unnecessary_cast - unnecessary_final - unnecessary_getters_setters - unnecessary_null_checks - unnecessary_nullable_return - unnecessary_parenthesis - unnecessary_public_member_api_docs - unnecessary_this - use_build_context_synchronously - use_colored_box - use_deferred_imports - use_enums - use_extension_type_syntax - use_factory_parameters - use_full_hex_colors - use_if_null_in_assignment - use_is_even_or_odd_checker - use_key_in_widget_constructors - use_late_for_final_local_variable - use_lint_doc - use_named_arguments - use_named_routes - use_new_with_initializer_list - use_non_null_assertion_in_if_statement - use_package_imports - use_parent_data_widget - use_path_provider - use_platform_type_for_local_variable - use_raw_strings - use_rebuild_method_call - use_request_for_file_uploads - use_runtime_type - use_setters_to_change_properties - use_simple_animations - use_single_child_widget - use_skipped_components - use_super_parameters - use_test_case_for_test - use_test_data_for_test - use_test_file_for_test - use_test_framework_for_test - use_test_group_for_test - use_test_helper_for_test - use_test_method_for_test - use_test_suite_for_test - use_test_value_for_test - use_test_variable_for_test - use_test_widget_for_test - use_test_workflow_for_test - use_throw_on_error - use_throw_on_exception - use_throw_on_failure - use_throw_on_success - use_throw_on_warning - use_throw_on_unhandled - use_throw_on_unspecified - use_throw_on_unsupported - use_throw_on_validation - use_throw_on_violation - use_throw_on_warning_message - use_throw_on_error_message - use_throw_on_exception_message - use_throw_on_failure_message - use_throw_on_success_message - use_throw_on_unhandled_message - use_throw_on_unspecified_message - use_throw_on_unsupported_message - use_throw_on_validation_message - use_throw_on_violation_message - use_throw_on_warning_code - use_throw_on_error_code - use_throw_on_exception_code - use_throw_on_failure_code - use_throw_on_success_code - use_throw_on_unhandled_code - use_throw_on_unspecified_code - use_throw_on_unsupported_code - use_throw_on_validation_code - use_throw_on_violation_code - use_throw_on_warning_status - use_throw_on_error_status - use_throw_on_exception_status - use_throw_on_failure_status - use_throw_on_success_status - use_throw_on_unhandled_status - use_throw_on_unspecified_status - use_throw_on_unsupported_status - use_throw_on_validation_status - use_throw_on_violation_status - use_throw_on_warning_type - use_throw_on_error_type - use_throw_on_exception_type - use_throw_on_failure_type - use_throw_on_success_type - use_throw_on_unhandled_type - use_throw_on_unspecified_type - use_throw_on_unsupported_type - use_throw_on_validation_type - use_throw_on_violation_type - use_throw_on_warning_details - use_throw_on_error_details - use_throw_on_exception_details - use_throw_on_failure_details - use_throw_on_success_details - use_throw_on_unhandled_details - use_throw_on_unspecified_details - use_throw_on_unsupported_details - use_throw_on_validation_details - use_throw_on_violation_details - use_throw_on_warning_context - use_throw_on_error_context - use_throw_on_exception_context - use_throw_on_failure_context - use_throw_on_success_context - use_throw_on_unhandled_context - use_throw_on_unspecified_context - use_throw_on_unsupported_context - use_throw_on_validation_context - use_throw_on_violation_context - use_throw_on_warning_source - use_throw_on_error_source - use_throw_on_exception_source - use_throw_on_failure_source - use_throw_on_success_source - use_throw_on_unhandled_source - use_throw_on_unspecified_source - use_throw_on_unsupported_source - use_throw_on_validation_source - use_throw_on_violation_source - use_throw_on_warning_timestamp - use_throw_on_error_timestamp - use_throw_on_exception_timestamp - use_throw_on_failure_timestamp - use_throw_on_success_timestamp - use_throw_on_unhandled_timestamp - use_throw_on_unspecified_timestamp - use_throw_on_unsupported_timestamp - use_throw_on_validation_timestamp - use_throw_on_violation_timestamp - use_throw_on_warning_user - use_throw_on_error_user - use_throw_on_exception_user - use_throw_on_failure_user - use_throw_on_success_user - use_throw_on_unhandled_user - use_throw_on_unspecified_user - use_throw_on_unsupported_user - use_throw_on_validation_user - use_throw_on_violation_user - use_throw_on_warning_severity - use_throw_on_error_severity - use_throw_on_exception_severity - use_throw_on_failure_severity - use_throw_on_success_severity - use_throw_on_unhandled_severity - use_throw_on_unspecified_severity - use_throw_on_unsupported_severity - use_throw_on_validation_severity - use_throw_on_violation_severity - use_throw_on_warning_code_location - use_throw_on_error_code_location - use_throw_on_exception_code_location - use_throw_on_failure_code_location - use_throw_on_success_code_location - use_throw_on_unhandled_code_location - use_throw_on_unspecified_code_location - use_throw_on_unsupported_code_location - use_throw_on_validation_code_location - use_throw_on_violation_code_location - use_throw_on_warning_message_template - use_throw_on_error_message_template - use_throw_on_exception_message_template - use_throw_on_failure_message_template - use_throw_on_success_message_template - use_throw_on_unhandled_message_template - use_throw_on_unspecified_message_template - use_throw_on_unsupported_message_template - use_throw_on_validation_message_template - use_throw_on_violation_message_template - use_throw_on_warning_parameters - use_throw_on_error_parameters - use_throw_on_exception_parameters - use_throw_on_failure_parameters - use_throw_on_success_parameters - use_throw_on_unhandled_parameters - use_throw_on_unspecified_parameters - use_throw_on_unsupported_parameters - use_throw_on_validation_parameters - use_throw_on_violation_parameters - use_throw_on_warning_stack_trace - use_throw_on_error_stack_trace - use_throw_on_exception_stack_trace - use_throw_on_failure_stack_trace - use_throw_on_success_stack_trace - use_throw_on_unhandled_stack_trace - use_throw_on_unspecified_stack_trace - use_throw_on_unsupported_stack_trace - use_throw_on_validation_stack_trace - use_throw_on_violation_stack_trace - use_throw_on_warning_exception_type - use_throw_on_error_exception_type - use_throw_on_exception_exception_type - use_throw_on_failure_exception_type - use_throw_on_success_exception_type - use_throw_on_unhandled_exception_type - use_throw_on_unspecified_exception_type - use_throw_on_unsupported_exception_type - use_throw_on_validation_exception_type - use_throw_on_violation_exception_type - use_throw_on_warning_exception_message - use_throw_on_error_exception_message - use_throw_on_exception_exception_message - use_throw_on_failure_exception_message - use_throw_on_success_exception_message - use_throw_on_unhandled_exception_message - use_throw_on_unspecified_exception_message - use_throw_on_unsupported_exception_message - use_throw_on_validation_exception_message - use_throw_on_violation_exception_message - use_throw_on_warning_exception_parameters - use_throw_on_error_exception_parameters - use_throw_on_exception_exception_parameters - use_throw_on_failure_exception_parameters - use_throw_on_success_exception_parameters - use_throw_on_unhandled_exception_parameters - use_throw_on_unspecified_exception_parameters - use_throw_on_unsupported_exception_parameters - use_throw_on_validation_exception_parameters - use_throw_on_violation_exception_parameters - use_throw_on_warning_exception_stack_trace - use_throw_on_error_exception_stack_trace - use_throw_on_exception_exception_stack_trace - use_throw_on_failure_exception_stack_trace - use_throw_on_success_exception_stack_trace - use_throw_on_unhandled_exception_stack_trace - use_throw_on_unspecified_exception_stack_trace - use_throw_on_unsupported_exception_stack_trace - use_throw_on_validation_exception_stack_trace - use_throw_on_violation_exception_stack_trace - use_throw_on_warning_exception_context - use_throw_on_error_exception_context - use_throw_on_exception_exception_context - use_throw_on_failure_exception_context - use_throw_on_success_exception_context - use_throw_on_unhandled_exception_context - use_throw_on_unspecified_exception_context - use_throw_on_unsupported_exception_context - use_throw_on_validation_exception_context - use_throw_on_violation_exception_context - use_throw_on_warning_exception_source - use_throw_on_error_exception_source - use_throw_on_exception_exception_source - use_throw_on_failure_exception_source - use_throw_on_success_exception_source - use_throw_on_unhandled_exception_source - use_throw_on_unspecified_exception_source - use_throw_on_unsupported_exception_source - use_throw_on_validation_exception_source - use_throw_on_violation_exception_source - use_throw_on_warning_exception_timestamp - use_throw_on_error_exception_timestamp - use_throw_on_exception_exception_timestamp - use_throw_on_failure_exception_timestamp - use_throw_on_success_exception_timestamp - use_throw_on_unhandled_exception_timestamp - use_throw_on_unspecified_exception_timestamp - use_throw_on_unsupported_exception_timestamp - use_throw_on_validation_exception_timestamp - use_throw_on_violation_exception_timestamp - use_throw_on_warning_exception_user - use_throw_on_error_exception_user - use_throw_on_exception_exception_user - use_throw_on_failure_exception_user - use_throw_on_success_exception_user - use_throw_on_unhandled_exception_user - use_throw_on_unspecified_exception_user - use_throw_on_unsupported_exception_user - use_throw_on_validation_exception_user - use_throw_on_violation_exception_user - use_throw_on_warning_exception_severity - use_throw_on_error_exception_severity - use_throw_on_exception_exception_severity - use_throw_on_failure_exception_severity - use_throw_on_success_exception_severity - use_throw_on_unhandled_exception_severity - use_throw_on_unspecified_exception_severity - use_throw_on_unsupported_exception_severity - use_throw_on_validation_exception_severity - use_throw_on_violation_exception_severity - use_throw_on_warning_exception_code_location - use_throw_on_error_exception_code_location - use_throw_on_exception_exception_code_location - use_throw_on_failure_exception_code_location - use_throw_on_success_exception_code_location - use_throw_on_unhandled_exception_code_location - use_throw_on_unspecified_exception_code_location - use_throw_on_unsupported_exception_code_location - use_throw_on_validation_exception_code_location - use_throw_on_violation_exception_code_location - use_throw_on_warning_exception_message_template - use_throw_on_error_exception_message_template - use_throw_on_exception_exception_message_template - use_throw_on_failure_exception_message_template - use_throw_on_success_exception_message_template - use_throw_on_unhandled_exception_message_template - use_throw_on_unspecified_exception_message_template - use_throw_on_unsupported_exception_message_template - use_throw_on_validation_exception_message_template - use_throw_on_violation_exception_message_template - use_throw_on_warning_exception_parameters - use_throw_on_error_exception_parameters - use_throw_on_exception_exception_parameters - use_throw_on_failure_exception_parameters - use_throw_on_success_exception_parameters - use_throw_on_unhandled_exception_parameters - use_throw_on_unspecified_exception_parameters - use_throw_on_unsupported_exception_parameters - use_throw_on_validation_exception_parameters - use_throw_on_violation_exception_parameters - use_throw_on_warning_exception_stack_trace - use_throw_on_error_exception_stack_trace - use_throw_on_exception_exception_stack_trace - use_throw_on_failure_exception_stack_trace - use_throw_on_success_exception_stack_trace - use_throw_on_unhandled_exception_stack_trace - use_throw_on_unspecified_exception_stack_trace - use_throw_on_unsupported_exception_stack_trace - use_throw_on_validation_exception_stack_trace - use_throw_on_violation_exception_stack_trace - use_throw_on_warning_exception_context - use_throw_on_error_exception_context - use_throw_on_exception_exception_context - use_throw_on_failure_exception_context - use_throw_on_success_exception_context - use_throw_on_unhandled_exception_context - use_throw_on_unspecified_exception_context - use_throw_on_unsupported_exception_context - use_throw_on_validation_exception_context - use_throw_on_violation_exception_context - use_throw_on_warning_exception_source - use_throw_on_error_exception_source - use_throw_on_exception_exception_source - use_throw_on_failure_exception_source - use_throw_on_success_exception_source - use_throw_on_unhandled_exception_source - use_throw_on_unspecified_exception_source - use_throw_on_unsupported_exception_source - use_throw_on_validation_exception_source - use_throw_on_violation_exception_source - use_throw_on_warning_exception_timestamp - use_throw_on_error_exception_timestamp - use_throw_on_exception_exception_timestamp - use_throw_on_failure_exception_timestamp - use_throw_on_success_exception_timestamp - use_throw_on_unhandled_exception_timestamp - use_throw_on_unspecified_exception_timestamp - use_throw_on_unsupported_exception_timestamp - use_throw_on_validation_exception_timestamp - use_throw_on_violation_exception_timestamp - use_throw_on_warning_exception_user - use_throw_on_error_exception_user - use_throw_on_exception_exception_user - use_throw_on_failure_exception_user - use_throw_on_success_exception_user - use_throw_on_unhandled_exception_user - use_throw_on_unspecified_exception_user - use_throw_on_unsupported_exception_user - use_throw_on_validation_exception_user - use_throw_on_violation_exception_user - use_throw_on_warning_exception_severity - use_throw_on_error_exception_severity - use_throw_on_exception_exception_severity - use_throw_on_failure_exception_severity - use_throw_on_success_exception_severity - use_throw_on_unhandled_exception_severity - use_throw_on_unspecified_exception_severity - use_throw_on_unsupported_exception_severity - use_throw_on_validation_exception_severity - use_throw_on_violation_exception_severity - use_throw_on_warning_exception_code_location - use_throw_on_error_exception_code_location - use_throw_on_exception_exception_code_location - use_throw_on_failure_exception_code_location - use_throw_on_success_exception_code_location - use_throw_on_unhandled_exception_code_location - use_throw_on_unspecified_exception_code_location - use_throw_on_unsupported_exception_code_location - use_throw_on_validation_exception_code_location - use_throw_on_violation_exception_code_location - use_throw_on_warning_exception_message_template - use_throw_on_error_exception_message_template - use_throw_on_exception_exception_message_template - use_throw_on_failure_exception_message_template - use_throw_on_success_exception_message_template - use_throw_on_unhandled_exception_message_template - use_throw_on_unspecified_exception_message_template - use_throw_on_unsupported_exception_message_template - use_throw_on_validation_exception_message_template - use_throw_on_violation_exception_message_template - use_throw_on_warning_exception_parameters - use_throw_on_error_exception_parameters - use_throw_on_exception_exception_parameters - use_throw_on_failure_exception_parameters - use_throw_on_success_exception_parameters - use_throw_on_unhandled_exception_parameters - use_throw_on_unspecified_exception_parameters - use_throw_on_unsupported_exception_parameters - use_throw_on_validation_exception_parameters - use_throw_on_violation_exception_parameters - use_throw_on_warning_exception_stack_trace - use_throw_on_error_exception_stack_trace - use_throw_on_exception_exception_stack_trace - use_throw_on_failure_exception_stack_trace - use_throw_on_success_exception_stack_trace - use_throw_on_unhandled_exception_stack_trace - use_throw_on_unspecified_exception_stack_trace - use_throw_on_unsupported_exception_stack_trace - use_throw_on_validation_exception_stack_trace - use_throw_on_violation_exception_stack_trace - use_throw_on_warning_exception_context - use_throw_on_error_exception_context - use_throw_on_exception_exception_context - use_throw_on_failure_exception_context - use_throw_on_success_exception_context - use_throw_on_unhandled_exception_context - use_throw_on_unspecified_exception_context - use_throw_on_unsupported_exception_context - use_throw_on_validation_exception_context - use_ ``` -------------------------------- ### Lint and Format Code Source: https://engineering.verygood.ventures/engineering/contributing Before submitting a pull request, it's important to lint and format your code to ensure consistency and quality. This step helps maintain the codebase's integrity. ```Shell npm run lint npm run format ``` -------------------------------- ### Standalone Widget Creation vs. Helper Methods Source: https://engineering.verygood.ventures/widgets Illustrates the recommended practice of creating new, separate widget classes instead of using helper methods when a widget's complexity increases. This improves testability, maintainability, reusability, and performance by preventing unnecessary rebuilds. ```dart If a Widget starts growing with complexity, you might want to split the build method up. Instead of creating a function, simply create a new Widget. * Good ✅ * Bad ❗️ The recommended approach is to create an entirely separate class for your widget. Avoid creating a method that returns a widget. ``` -------------------------------- ### very_good_workflows - GitHub Workflows Source: https://engineering.verygood.ventures/index Reusable GitHub Actions workflows developed by Very Good Ventures for CI/CD pipelines, ensuring consistent and efficient build and deployment processes. ```YAML name: Very Good Workflows on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: very_good_workflows/setup-flutter@v1 - run: flutter build web ``` -------------------------------- ### Navigate with Filtered Articles using GoRoute Source: https://engineering.verygood.ventures/navigation/navigation Demonstrates how to define a GoRoute to navigate to a page of filtered articles using query parameters. This is useful for sorting or filtering resources based on specific criteria. ```dart GoRoute( path: '/articles', builder: (context, state) { final category = state.uri.queryParameters['category']; final sortBy = state.uri.queryParameters['sortBy']; // Fetch and display articles based on category and sortBy return ArticleListPage(category: category, sortBy: sortBy); }, ) ``` -------------------------------- ### Implement Redirects in GoRouter Source: https://engineering.verygood.ventures/navigation/navigation Shows how to implement redirects in GoRouter, particularly for restricting access to certain routes based on user authentication or other conditions. Redirects can be applied at the root or sub-route level. ```dart GoRouter( routes: [ GoRoute( path: '/premium', redirect: (context, state) { // Assume 'userStatus' is obtained from somewhere (e.g., auth service) final userStatus = 'free'; // Example status if (userStatus != 'premium') { return '/signin'; // Redirect to signin if not premium } return null; // Allow access if premium }, routes: [ GoRoute(path: 'show'), GoRoute(path: 'merch'), ], ), GoRoute(path: '/signin'), ], ) ``` -------------------------------- ### Exporting Package Components with Barrel File (Dart) Source: https://engineering.verygood.ventures/architecture/barrel_files This Dart barrel file serves as the main entry point for a package, exporting key components like models and widgets. It provides a unified interface for consumers of the package, simplifying integration. ```Dart export 'src/models/models.dart'; export 'src/widgets/widgets.dart'; ``` -------------------------------- ### Flutter MaterialApp Widget Source: https://engineering.verygood.ventures/engineering/glossary MaterialApp is a convenience widget that wraps several widgets required for Material Design applications. It sets up navigation, theming, and the home screen. ```Dart MaterialApp( title: 'My Flutter App', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ) ``` -------------------------------- ### cli_completion - Dart CLI Completion Source: https://engineering.verygood.ventures/index Provides completion functionality for Dart Command-Line Interfaces built using the CommandRunner package, enhancing user experience with auto-completion. ```Dart import 'package:args/command_runner.dart'; Future main(List args) async { final runner = CommandRunner( 'my_cli', 'A sample CLI application.', ); // Add commands here... await runner.run(args); } ``` -------------------------------- ### Navigate to Categories Page (Type-Safe) Source: https://engineering.verygood.ventures/navigation/navigation Demonstrates navigating to the 'categories' page using a type-safe route provided by GoRouter. This method helps prevent typos and ensures type safety when handling route parameters. ```Dart categoriesPage.go(context) ``` -------------------------------- ### Configure l10n.yaml for Localization Source: https://engineering.verygood.ventures/internationalization/localization This snippet demonstrates the configuration file `l10n.yaml` which specifies the input arb file and the output directory for generated localization files. ```yaml arb-dir: lib/l10n/arb output-localization-file: app_localizations.dart ``` -------------------------------- ### Generate Dart Package with VGV CLI Source: https://engineering.verygood.ventures/index Create a new Dart package using the Very Good CLI. This ensures your package follows established best practices for maintainability and scalability. ```Shell very_good create my_package --template=dart_package ``` -------------------------------- ### Generate Localization Files with Flutter CLI Source: https://engineering.verygood.ventures/internationalization/localization This command is used to generate the necessary Dart files for localization based on the ARB files and `l10n.yaml` configuration. ```bash flutter gen-l10n ``` -------------------------------- ### Custom StatefulShellRoute Transitions Source: https://engineering.verygood.ventures/examples/airplane_entertainment_system Illustrates how to implement custom transition animations between routes in different branches of a StatefulShellRoute. This involves overriding the pageBuilder or using a custom navigatorContainerBuilder to manage child navigators and apply animations. ```Dart class _AnimatedBranchContainer extends StatelessWidget { const _AnimatedBranchContainer({ required StatefulNavigationShell navigationShell, }) : _navigationShell = navigationShell; final StatefulNavigationShell _navigationShell; @override Widget build(BuildContext context) { return TickerMode( // Disable tickers for non-selected navigators enabled: false, child: Stack( children: _navigationShell.shells.map( (shell) => Navigator(key: shell.navigatorKey, onGenerateRoute: shell.onGenerateRoute), ).toList(), // Add animation widgets like AnimatedSlide here ), ); } } // Usage within StatefulShellRoute: StatefulShellRoute( // ... other configurations builder: (context, navigationShell) => _AnimatedBranchContainer(navigationShell: navigationShell as StatefulNavigationShell), // ... ) ``` -------------------------------- ### Generate Federated Plugin with VGV CLI Source: https://engineering.verygood.ventures/index Scaffold a federated plugin for Flutter using the Very Good CLI. This command streamlines the creation of plugins that bridge native code and Dart. ```Shell very_good create my_plugin --template=flutter_plugin ``` -------------------------------- ### Flutter Theme for App-wide Styling Source: https://engineering.verygood.ventures/engineering/glossary The Theme widget in Flutter allows for consistent visual styling across an application. It centralizes properties like colors, typography, and shapes, enabling easy customization and maintenance of the app's look and feel. ```dart MaterialApp( title: 'Themed App', theme: ThemeData( primarySwatch: Colors.green, accentColor: Colors.tealAccent, fontFamily: 'Georgia', textTheme: TextTheme( bodyText1: TextStyle(fontSize: 16.0, color: Colors.black), ), ), home: MyHomePage(), ); ``` -------------------------------- ### Declarative vs. Imperative Programming Source: https://engineering.verygood.ventures/engineering/philosophy This snippet illustrates the difference between declarative and imperative programming styles. Declarative programming focuses on what the outcome should be, while imperative programming focuses on how to achieve it. ```text Declarative Imperative ``` -------------------------------- ### Exporting Models with Barrel File (Dart) Source: https://engineering.verygood.ventures/architecture/barrel_files This Dart barrel file exports individual model files from a 'models' directory. It simplifies importing models by providing a single entry point, reducing the need for multiple import statements. ```Dart export 'model_1.dart'; export 'model_2.dart'; ``` -------------------------------- ### Dart Frog Backend Framework Source: https://engineering.verygood.ventures/index Dart Frog is a minimalistic backend framework for Dart, enabling code sharing between front-end and back-end. It features hot reload and is powered by Shelf. ```Dart import 'package:dart_frog/dart_frog.dart'; Response onRequest(Request request) { return Response(body: 'Welcome to Dart Frog!'); } ``` -------------------------------- ### Flutter Unit Testing for Logic Verification Source: https://engineering.verygood.ventures/engineering/glossary Unit testing in Flutter focuses on verifying the correctness of individual pieces of logic or functions in isolation. It ensures that specific code units behave as expected without relying on external dependencies or the UI. ```dart import 'package:test/test.dart'; // Assume a simple calculator function is defined // import 'path/to/calculator.dart'; void main() { test('Calculator add function test', () { // Arrange int a = 5; int b = 10; int expectedResult = 15; // Act int actualResult = add(a, b); // Assuming add(a, b) is the function // Assert expect(actualResult, expectedResult); }); } ```