create-flutterinit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.ts +3 -0
- package/package.json +46 -0
- package/templates/base/.cursor/rules/flutter-project.mdc.hbs +132 -0
- package/templates/base/AGENTS.md.hbs +137 -0
- package/templates/base/DESIGN.md.hbs +149 -0
- package/templates/base/README.md.hbs +19 -0
- package/templates/base/SETUP.md.hbs +253 -0
- package/templates/base/analysis_options.yaml +88 -0
- package/templates/base/assets/.keep +1 -0
- package/templates/base/assets/icons/apple.svg +1 -0
- package/templates/base/assets/icons/facebook.svg +1 -0
- package/templates/base/assets/icons/google.svg +1 -0
- package/templates/base/assets/images/.gitkeep +0 -0
- package/templates/base/flutter_native_splash.yaml.hbs +8 -0
- package/templates/base/lib/main.dart.hbs +43 -0
- package/templates/base/lib/src/app.dart.hbs +105 -0
- package/templates/base/lib/src/config/app_config.dart.hbs +112 -0
- package/templates/base/lib/src/extensions/collection_extension.dart.hbs +55 -0
- package/templates/base/lib/src/extensions/context_extension.dart.hbs +167 -0
- package/templates/base/lib/src/extensions/date_time_extension.dart.hbs +40 -0
- package/templates/base/lib/src/extensions/extensions.dart.hbs +6 -0
- package/templates/base/lib/src/extensions/num_extension.dart.hbs +14 -0
- package/templates/base/lib/src/extensions/string_extension.dart.hbs +91 -0
- package/templates/base/lib/src/extensions/widget_extension.dart.hbs +47 -0
- package/templates/base/lib/src/imports/core_imports.dart.hbs +50 -0
- package/templates/base/lib/src/imports/imports.dart.hbs +2 -0
- package/templates/base/lib/src/imports/packages_imports.dart.hbs +110 -0
- package/templates/base/lib/src/routing/(isGetX)@app_bindings.dart.hbs +23 -0
- package/templates/base/lib/src/routing/app_router.dart.hbs +252 -0
- package/templates/base/lib/src/routing/app_routes.dart.hbs +46 -0
- package/templates/base/lib/src/routing/global_navigator.dart.hbs +15 -0
- package/templates/base/lib/src/services/auth_service.dart.hbs +78 -0
- package/templates/base/lib/src/services/copy_service.dart.hbs +16 -0
- package/templates/base/lib/src/services/internet_connection_service.dart.hbs +10 -0
- package/templates/base/lib/src/services/services.dart.hbs +45 -0
- package/templates/base/lib/src/shared/app_assets.dart.hbs +15 -0
- package/templates/base/lib/src/shared/enums/app_status.dart.hbs +40 -0
- package/templates/base/lib/src/shared/enums/button_enums.dart.hbs +22 -0
- package/templates/base/lib/src/shared/enums/enums.dart.hbs +3 -0
- package/templates/base/lib/src/shared/enums/snack_bar_type.dart.hbs +22 -0
- package/templates/base/lib/src/shared/helpers/format_number.dart.hbs +18 -0
- package/templates/base/lib/src/shared/helpers/imports.dart.hbs +3 -0
- package/templates/base/lib/src/shared/helpers/show_app_sheet.dart.hbs +42 -0
- package/templates/base/lib/src/shared/helpers/show_dialog.dart.hbs +49 -0
- package/templates/base/lib/src/shared/helpers/show_toast.dart.hbs +92 -0
- package/templates/base/lib/src/shared/hooks/hooks.dart.hbs +13 -0
- package/templates/base/lib/src/shared/hooks/use_copy.dart.hbs +41 -0
- package/templates/base/lib/src/shared/hooks/use_timer.dart.hbs +158 -0
- package/templates/base/lib/src/shared/shared.dart.hbs +12 -0
- package/templates/base/lib/src/shared/widgets/app_button.dart.hbs +144 -0
- package/templates/base/lib/src/shared/widgets/app_card.dart.hbs +126 -0
- package/templates/base/lib/src/shared/widgets/app_divider.dart.hbs +88 -0
- package/templates/base/lib/src/shared/widgets/app_empty_state.dart.hbs +73 -0
- package/templates/base/lib/src/shared/widgets/app_error_widget.dart.hbs +69 -0
- package/templates/base/lib/src/shared/widgets/app_icon.dart.hbs +25 -0
- package/templates/base/lib/src/shared/widgets/app_loading.dart.hbs +54 -0
- package/templates/base/lib/src/shared/widgets/app_text_field.dart.hbs +89 -0
- package/templates/base/lib/src/shared/widgets/app_top_bar.dart.hbs +105 -0
- package/templates/base/lib/src/shared/widgets/common_image.dart.hbs +120 -0
- package/templates/base/lib/src/shared/widgets/toast/imports.dart.hbs +4 -0
- package/templates/base/lib/src/shared/widgets/toast/raw_toast.dart.hbs +109 -0
- package/templates/base/lib/src/shared/widgets/toast/toast.dart.hbs +142 -0
- package/templates/base/lib/src/shared/widgets/toast/toast_card.dart.hbs +57 -0
- package/templates/base/lib/src/shared/widgets/widgets.dart.hbs +14 -0
- package/templates/base/lib/src/shared/wrappers/(isRiverpod,isProvider,isBloc,isGetX,isMobX)@state_wrapper.dart.hbs +51 -0
- package/templates/base/lib/src/shared/wrappers/(supportsLocalization)@localization_wrapper.dart.hbs +25 -0
- package/templates/base/lib/src/shared/wrappers/(usesScreenutil)@screen_util_wrapper.dart.hbs +27 -0
- package/templates/base/lib/src/shared/wrappers/(usesSkeletonizer)@skeleton_wrapper.dart.hbs +81 -0
- package/templates/base/lib/src/shared/wrappers/session_listener_wrapper.dart.hbs +258 -0
- package/templates/base/lib/src/shared/wrappers/wrappers.dart.hbs +15 -0
- package/templates/base/lib/src/theme/app_borders.dart.hbs +70 -0
- package/templates/base/lib/src/theme/app_curves.dart.hbs +69 -0
- package/templates/base/lib/src/theme/app_durations.dart.hbs +48 -0
- package/templates/base/lib/src/theme/app_shadows.dart.hbs +73 -0
- package/templates/base/lib/src/theme/app_spacing.dart.hbs +80 -0
- package/templates/base/lib/src/theme/color_schemes.dart.hbs +126 -0
- package/templates/base/lib/src/theme/text_theme.dart.hbs +167 -0
- package/templates/base/lib/src/theme/theme.dart.hbs +431 -0
- package/templates/base/lib/src/theme/theme_constants.dart.hbs +20 -0
- package/templates/base/lib/src/utils/app_utils.dart.hbs +46 -0
- package/templates/base/lib/src/utils/debouncer.dart.hbs +31 -0
- package/templates/base/lib/src/utils/error_handler.dart.hbs +14 -0
- package/templates/base/lib/src/utils/failure.dart.hbs +30 -0
- package/templates/base/lib/src/utils/input_formatters.dart.hbs +27 -0
- package/templates/base/lib/src/utils/logger.dart.hbs +37 -0
- package/templates/base/lib/src/utils/platform_info.dart.hbs +13 -0
- package/templates/base/lib/src/utils/task_runner.dart.hbs +42 -0
- package/templates/base/lib/src/utils/typedefs.dart.hbs +6 -0
- package/templates/base/lib/src/utils/utils.dart.hbs +9 -0
- package/templates/base/pubspec.yaml.hbs +256 -0
- package/templates/base/test/widget_test.dart.hbs +56 -0
- package/templates/overlays/architecture/clean/architecture.md +6 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/architecture.md +5 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/architecture.md +6 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/datasources/local/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/datasources/remote/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/usecases/auth/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@auth_view_model.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/widgets/.gitkeep +0 -0
- package/templates/overlays/architecture/mvc/architecture.md +5 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/services/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/services/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/architecture.md +6 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/auth_view_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/backend/appwrite/lib/src/services/(usesAppwriteAuth)@auth_service.dart.hbs +101 -0
- package/templates/overlays/backend/custom/lib/src/services/auth_service.dart.hbs +158 -0
- package/templates/overlays/backend/firebase/lib/src/services/(usesFirebaseAuth)@auth_service.dart.hbs +96 -0
- package/templates/overlays/backend/supabase/lib/src/services/(usesSupabaseAuth)@auth_service.dart.hbs +97 -0
- package/templates/overlays/device/app_version_update/lib/src/services/(usesAppVersionUpdate)@version_update_service.dart.hbs +118 -0
- package/templates/overlays/device/device_info/lib/src/services/(usesDeviceInfoPlus)@device_info_service.dart.hbs +54 -0
- package/templates/overlays/extras/dotenv/.env.hbs +33 -0
- package/templates/overlays/extras/flavors/lib/src/flavors.dart.hbs +15 -0
- package/templates/overlays/extras/localization/assets/translations/en.json.hbs +47 -0
- package/templates/overlays/media/lib/src/services/(usesImagePicker,usesFilePicker)@media_service.dart.hbs +148 -0
- package/templates/overlays/networking/cached_image/lib/src/shared/widgets/app_cached_image.dart.hbs +160 -0
- package/templates/overlays/networking/dio/lib/src/services/(usesDio)@dio_service.dart.hbs +50 -0
- package/templates/overlays/networking/http/lib/src/services/(usesHttp)@http_service.dart.hbs +82 -0
- package/templates/overlays/storage/hive/lib/src/services/(usesHive)@hive_service.dart.hbs +59 -0
- package/templates/overlays/storage/secure_storage/lib/src/services/(usesSecureStorage)@secure_storage_service.dart.hbs +39 -0
- package/templates/overlays/storage/shared_preferences/lib/src/services/(usesSharedPreferences)@storage_service.dart.hbs +53 -0
- package/templates/overlays/utilities/geolocator/lib/src/services/(usesGeolocator)@location_service.dart.hbs +78 -0
- package/templates/overlays/utilities/path_provider/lib/src/services/(usesPathProvider)@path_service.dart.hbs +30 -0
- package/templates/overlays/utilities/permission_handler/lib/src/services/(usesPermissionHandler)@permission_service.dart.hbs +28 -0
- package/templates/overlays/utilities/permission_handler/lib/src/shared/hooks/use_permission.dart.hbs +44 -0
- package/templates/overlays/utilities/share_plus/lib/src/services/(usesSharePlus)@share_service.dart.hbs +22 -0
- package/templates/overlays/utilities/share_plus/lib/src/shared/hooks/use_share.dart.hbs +26 -0
- package/templates/overlays/utilities/url_launcher/lib/src/services/(usesUrlLauncher)@url_launcher_service.dart.hbs +37 -0
- package/templates/overlays/utilities/url_launcher/lib/src/shared/hooks/use_launch_url.dart.hbs +52 -0
- package/templates/partials/features/auth/auth_logic.hbs +611 -0
- package/templates/partials/features/auth/auth_repository.hbs +32 -0
- package/templates/partials/features/auth/auth_repository_impl.hbs +116 -0
- package/templates/partials/features/auth/forgot_password_screen.hbs +368 -0
- package/templates/partials/features/auth/login_screen.hbs +540 -0
- package/templates/partials/features/auth/session_provider.hbs +437 -0
- package/templates/partials/features/auth/signup_screen.hbs +511 -0
- package/templates/partials/features/auth/user_model.hbs +23 -0
- package/templates/partials/features/home/home_page.hbs +156 -0
- package/templates/partials/features/onboarding/onboarding_page.hbs +264 -0
- package/templates/partials/llm/add-feature-workflow.hbs +38 -0
- package/templates/partials/llm/architecture-rules.hbs +92 -0
- package/templates/partials/llm/backend-rules.hbs +30 -0
- package/templates/partials/llm/build-runner-note.hbs +15 -0
- package/templates/partials/llm/design-quick-ref.hbs +14 -0
- package/templates/partials/llm/design-quick-reference.hbs +14 -0
- package/templates/partials/llm/navigation-rules.hbs +27 -0
- package/templates/partials/llm/networking-rules.hbs +16 -0
- package/templates/partials/llm/packages-list.hbs +26 -0
- package/templates/partials/llm/services-conventions.hbs +20 -0
- package/templates/partials/llm/stack-summary.hbs +22 -0
- package/templates/partials/llm/state-management-rules.hbs +40 -0
- package/templates/partials/state_label.hbs +1 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import 'package:{{flags.appSnake}}/src/imports/core_imports.dart';
|
|
2
|
+
{{#unless flags.isNoneState}}
|
|
3
|
+
import 'package:{{flags.appSnake}}/src/imports/packages_imports.dart';
|
|
4
|
+
{{/unless}}
|
|
5
|
+
|
|
6
|
+
{{#if flags.isRiverpod}}
|
|
7
|
+
import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}presentation/providers/session_provider.dart{{else if (eq architecture "mvc")}}controllers/auth/session_provider.dart{{else if (eq architecture "mvvm")}}ui/auth/providers/session_provider.dart{{else}}features/auth/presentation/providers/session_provider.dart{{/if}}';
|
|
8
|
+
{{else if flags.isBloc}}
|
|
9
|
+
import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}presentation/providers/session_bloc.dart{{else if (eq architecture "mvc")}}controllers/auth/session_bloc.dart{{else if (eq architecture "mvvm")}}ui/auth/bloc/session_bloc.dart{{else}}features/auth/presentation/providers/session_bloc.dart{{/if}}';
|
|
10
|
+
{{else if flags.isGetX}}
|
|
11
|
+
import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}presentation/providers/session_controller.dart{{else if (eq architecture "mvc")}}controllers/auth/session_controller.dart{{else if (eq architecture "mvvm")}}ui/auth/controllers/session_controller.dart{{else}}features/auth/presentation/providers/session_controller.dart{{/if}}';
|
|
12
|
+
{{else if flags.isMobX}}
|
|
13
|
+
import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}presentation/providers/session_store.dart{{else if (eq architecture "mvc")}}controllers/auth/session_store.dart{{else if (eq architecture "mvvm")}}ui/auth/stores/session_store.dart{{else}}features/auth/presentation/providers/session_store.dart{{/if}}';
|
|
14
|
+
{{else if flags.isProvider}}
|
|
15
|
+
import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}presentation/providers/session_provider.dart{{else if (eq architecture "mvc")}}controllers/auth/session_provider.dart{{else if (eq architecture "mvvm")}}ui/auth/providers/session_provider.dart{{else}}features/auth/presentation/providers/session_provider.dart{{/if}}';
|
|
16
|
+
{{else if flags.isNoneState}}
|
|
17
|
+
// No session listener needed for NoneState — widget rebuilds are manual
|
|
18
|
+
{{else}}
|
|
19
|
+
// session_manager not easily retrieved via context globally if not using Provider, assuming single instance
|
|
20
|
+
import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}presentation/providers/session_manager.dart{{else if (eq architecture "mvc")}}controllers/auth/session_manager.dart{{else if (eq architecture "mvvm")}}ui/auth/view_models/session_manager.dart{{else}}features/auth/presentation/providers/session_manager.dart{{/if}}';
|
|
21
|
+
{{/if}}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
{{#if flags.isRiverpod}}
|
|
25
|
+
class SessionListenerWrapper extends ConsumerWidget {
|
|
26
|
+
final Widget child;
|
|
27
|
+
const SessionListenerWrapper({super.key, required this.child});
|
|
28
|
+
|
|
29
|
+
@override
|
|
30
|
+
Widget build(BuildContext context, WidgetRef ref) {
|
|
31
|
+
ref.listen<SessionState>(sessionProvider, (prev, next) {
|
|
32
|
+
if (next.status != SessionStatus.unknown) {
|
|
33
|
+
{{#if flags.usesFlutterNativeSplash}}
|
|
34
|
+
FlutterNativeSplash.remove();
|
|
35
|
+
{{/if}}
|
|
36
|
+
if (next.status == SessionStatus.authenticated) {
|
|
37
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
38
|
+
context.go(AppRoutes.home);
|
|
39
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
40
|
+
context.replaceRoute(const HomeRoute());
|
|
41
|
+
{{else}}
|
|
42
|
+
Navigator.pushReplacementNamed(context, AppRoutes.home);
|
|
43
|
+
{{/if}}
|
|
44
|
+
} else if (next.status == SessionStatus.unauthenticated) {
|
|
45
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
46
|
+
context.go(AppRoutes.onboarding);
|
|
47
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
48
|
+
context.replaceRoute(const OnboardingRoute());
|
|
49
|
+
{{else}}
|
|
50
|
+
Navigator.pushReplacementNamed(context, AppRoutes.onboarding);
|
|
51
|
+
{{/if}}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return child;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
{{else if flags.isBloc}}
|
|
60
|
+
class SessionListenerWrapper extends StatelessWidget {
|
|
61
|
+
final Widget child;
|
|
62
|
+
const SessionListenerWrapper({super.key, required this.child});
|
|
63
|
+
|
|
64
|
+
@override
|
|
65
|
+
Widget build(BuildContext context) {
|
|
66
|
+
return BlocListener<SessionBloc, SessionState>(
|
|
67
|
+
listenWhen: (prev, next) => prev.status != next.status,
|
|
68
|
+
listener: (context, state) {
|
|
69
|
+
if (state.status != SessionStatus.unknown) {
|
|
70
|
+
{{#if flags.usesFlutterNativeSplash}}
|
|
71
|
+
FlutterNativeSplash.remove();
|
|
72
|
+
{{/if}}
|
|
73
|
+
if (state.status == SessionStatus.authenticated) {
|
|
74
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
75
|
+
context.go(AppRoutes.home);
|
|
76
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
77
|
+
context.replaceRoute(const HomeRoute());
|
|
78
|
+
{{else}}
|
|
79
|
+
Navigator.pushReplacementNamed(context, AppRoutes.home);
|
|
80
|
+
{{/if}}
|
|
81
|
+
} else if (state.status == SessionStatus.unauthenticated) {
|
|
82
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
83
|
+
context.go(AppRoutes.onboarding);
|
|
84
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
85
|
+
context.replaceRoute(const OnboardingRoute());
|
|
86
|
+
{{else}}
|
|
87
|
+
Navigator.pushReplacementNamed(context, AppRoutes.onboarding);
|
|
88
|
+
{{/if}}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
child: child,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
{{else if flags.isGetX}}
|
|
97
|
+
class SessionListenerWrapper extends StatefulWidget {
|
|
98
|
+
final Widget child;
|
|
99
|
+
const SessionListenerWrapper({super.key, required this.child});
|
|
100
|
+
|
|
101
|
+
@override
|
|
102
|
+
State<SessionListenerWrapper> createState() => _SessionListenerWrapperState();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
class _SessionListenerWrapperState extends State<SessionListenerWrapper> {
|
|
106
|
+
Worker? _worker;
|
|
107
|
+
|
|
108
|
+
@override
|
|
109
|
+
void initState() {
|
|
110
|
+
super.initState();
|
|
111
|
+
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
112
|
+
final session = Get.find<SessionController>();
|
|
113
|
+
_worker = ever(session.status, (status) {
|
|
114
|
+
if (status != SessionStatus.unknown) {
|
|
115
|
+
{{#if flags.usesFlutterNativeSplash}}
|
|
116
|
+
FlutterNativeSplash.remove();
|
|
117
|
+
{{/if}}
|
|
118
|
+
if (status == SessionStatus.authenticated) {
|
|
119
|
+
Get.offAllNamed(AppRoutes.home);
|
|
120
|
+
} else if (status == SessionStatus.unauthenticated) {
|
|
121
|
+
Get.offAllNamed(AppRoutes.onboarding);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}, condition: () => session.status.value != SessionStatus.unknown);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@override
|
|
129
|
+
void dispose() {
|
|
130
|
+
_worker?.dispose();
|
|
131
|
+
super.dispose();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@override
|
|
135
|
+
Widget build(BuildContext context) {
|
|
136
|
+
return widget.child;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
{{else if flags.isMobX}}
|
|
140
|
+
class SessionListenerWrapper extends StatefulWidget {
|
|
141
|
+
final Widget child;
|
|
142
|
+
const SessionListenerWrapper({super.key, required this.child});
|
|
143
|
+
|
|
144
|
+
@override
|
|
145
|
+
State<SessionListenerWrapper> createState() => _SessionListenerWrapperState();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
class _SessionListenerWrapperState extends State<SessionListenerWrapper> {
|
|
149
|
+
late final ReactionDisposer _disposer;
|
|
150
|
+
|
|
151
|
+
@override
|
|
152
|
+
void didChangeDependencies() {
|
|
153
|
+
super.didChangeDependencies();
|
|
154
|
+
final sessionStore = Provider.of<SessionStore>(context, listen: false);
|
|
155
|
+
_disposer = reaction(
|
|
156
|
+
(_) => sessionStore.status,
|
|
157
|
+
(SessionStatus status) {
|
|
158
|
+
if (status != SessionStatus.unknown) {
|
|
159
|
+
{{#if flags.usesFlutterNativeSplash}}
|
|
160
|
+
FlutterNativeSplash.remove();
|
|
161
|
+
{{/if}}
|
|
162
|
+
if (status == SessionStatus.authenticated) {
|
|
163
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
164
|
+
context.go(AppRoutes.home);
|
|
165
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
166
|
+
context.replaceRoute(const HomeRoute());
|
|
167
|
+
{{else}}
|
|
168
|
+
Navigator.pushReplacementNamed(context, AppRoutes.home);
|
|
169
|
+
{{/if}}
|
|
170
|
+
} else if (status == SessionStatus.unauthenticated) {
|
|
171
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
172
|
+
context.go(AppRoutes.onboarding);
|
|
173
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
174
|
+
context.replaceRoute(const OnboardingRoute());
|
|
175
|
+
{{else}}
|
|
176
|
+
Navigator.pushReplacementNamed(context, AppRoutes.onboarding);
|
|
177
|
+
{{/if}}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
fireImmediately: true,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@override
|
|
186
|
+
void dispose() {
|
|
187
|
+
_disposer();
|
|
188
|
+
super.dispose();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@override
|
|
192
|
+
Widget build(BuildContext context) {
|
|
193
|
+
return widget.child;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
{{else if flags.isProvider}}
|
|
197
|
+
class SessionListenerWrapper extends StatefulWidget {
|
|
198
|
+
final Widget child;
|
|
199
|
+
const SessionListenerWrapper({super.key, required this.child});
|
|
200
|
+
|
|
201
|
+
@override
|
|
202
|
+
State<SessionListenerWrapper> createState() => _SessionListenerWrapperState();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
class _SessionListenerWrapperState extends State<SessionListenerWrapper> {
|
|
206
|
+
@override
|
|
207
|
+
void didChangeDependencies() {
|
|
208
|
+
super.didChangeDependencies();
|
|
209
|
+
final session = Provider.of<SessionProvider>(context);
|
|
210
|
+
if (session.status != SessionStatus.unknown) {
|
|
211
|
+
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
212
|
+
if (!mounted) return;
|
|
213
|
+
{{#if flags.usesFlutterNativeSplash}}
|
|
214
|
+
FlutterNativeSplash.remove();
|
|
215
|
+
{{/if}}
|
|
216
|
+
if (session.status == SessionStatus.authenticated) {
|
|
217
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
218
|
+
context.go(AppRoutes.home);
|
|
219
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
220
|
+
context.replaceRoute(const HomeRoute());
|
|
221
|
+
{{else}}
|
|
222
|
+
Navigator.pushReplacementNamed(context, AppRoutes.home);
|
|
223
|
+
{{/if}}
|
|
224
|
+
} else if (session.status == SessionStatus.unauthenticated) {
|
|
225
|
+
{{#if (eq flags.routerPackage "go_router")}}
|
|
226
|
+
context.go(AppRoutes.onboarding);
|
|
227
|
+
{{else if (eq flags.routerPackage "auto_route")}}
|
|
228
|
+
context.replaceRoute(const OnboardingRoute());
|
|
229
|
+
{{else}}
|
|
230
|
+
Navigator.pushReplacementNamed(context, AppRoutes.onboarding);
|
|
231
|
+
{{/if}}
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@override
|
|
238
|
+
Widget build(BuildContext context) {
|
|
239
|
+
return widget.child;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
{{else}}
|
|
243
|
+
class SessionListenerWrapper extends StatefulWidget {
|
|
244
|
+
final Widget child;
|
|
245
|
+
const SessionListenerWrapper({super.key, required this.child});
|
|
246
|
+
|
|
247
|
+
@override
|
|
248
|
+
State<SessionListenerWrapper> createState() => _SessionListenerWrapperState();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
class _SessionListenerWrapperState extends State<SessionListenerWrapper> {
|
|
252
|
+
// Logic left to implement for vanilla flutter. Ideally pass SessionManager logic.
|
|
253
|
+
@override
|
|
254
|
+
Widget build(BuildContext context) {
|
|
255
|
+
return widget.child;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
{{/if}}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
{{#if flags.usesScreenutil}}
|
|
3
|
+
export 'screen_util_wrapper.dart';
|
|
4
|
+
{{/if}}
|
|
5
|
+
{{#if flags.usesSkeletonizer}}
|
|
6
|
+
export 'skeleton_wrapper.dart';
|
|
7
|
+
{{/if}}
|
|
8
|
+
{{#if flags.supportsLocalization}}
|
|
9
|
+
export 'localization_wrapper.dart';
|
|
10
|
+
{{/if}}
|
|
11
|
+
{{#if (or flags.isRiverpod flags.isProvider flags.isBloc flags.isGetX flags.isMobX)}}
|
|
12
|
+
export 'state_wrapper.dart';
|
|
13
|
+
{{/if}}
|
|
14
|
+
|
|
15
|
+
export 'session_listener_wrapper.dart';
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
|
|
3
|
+
/// Reusable border radii and border shapes used across the app.
|
|
4
|
+
///
|
|
5
|
+
/// Usage:
|
|
6
|
+
/// ```dart
|
|
7
|
+
/// Container(decoration: BoxDecoration(borderRadius: AppBorders.md))
|
|
8
|
+
/// ```
|
|
9
|
+
abstract final class AppBorders {
|
|
10
|
+
AppBorders._();
|
|
11
|
+
|
|
12
|
+
// ── Border Radii ──────────────────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
/// 4 pt — subtle rounding, used for small chips, badges.
|
|
15
|
+
static const BorderRadius xs = BorderRadius.all(Radius.circular(4));
|
|
16
|
+
|
|
17
|
+
/// 8 pt — standard rounding for buttons, text fields.
|
|
18
|
+
static const BorderRadius sm = BorderRadius.all(Radius.circular(8));
|
|
19
|
+
|
|
20
|
+
/// 12 pt — medium rounding for cards, list tiles.
|
|
21
|
+
static const BorderRadius md = BorderRadius.all(Radius.circular(12));
|
|
22
|
+
|
|
23
|
+
/// 16 pt — large rounding for modals, bottom sheets.
|
|
24
|
+
static const BorderRadius lg = BorderRadius.all(Radius.circular(16));
|
|
25
|
+
|
|
26
|
+
/// 24 pt — extra large rounding for dialogs, feature cards.
|
|
27
|
+
static const BorderRadius xl = BorderRadius.all(Radius.circular(24));
|
|
28
|
+
|
|
29
|
+
/// 28 pt — Material 3 bottom sheet top radius.
|
|
30
|
+
static const BorderRadius bottomSheet = BorderRadius.vertical(
|
|
31
|
+
top: Radius.circular(28),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
/// Fully circular (pill/stadium shape).
|
|
35
|
+
static const BorderRadius full = BorderRadius.all(Radius.circular(999));
|
|
36
|
+
|
|
37
|
+
// ── Semantic aliases ──────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
/// Default button border radius.
|
|
40
|
+
static const BorderRadius button = lg;
|
|
41
|
+
|
|
42
|
+
/// Default card border radius.
|
|
43
|
+
static const BorderRadius card = md;
|
|
44
|
+
|
|
45
|
+
/// Default input field border radius.
|
|
46
|
+
static const BorderRadius input = sm;
|
|
47
|
+
|
|
48
|
+
/// Default dialog border radius.
|
|
49
|
+
static const BorderRadius dialog = xl;
|
|
50
|
+
|
|
51
|
+
// ── RoundedRectangleBorder shapes (for ShapeBorder APIs) ─────────────────
|
|
52
|
+
|
|
53
|
+
/// Small rounded rectangle shape (8 pt).
|
|
54
|
+
static const RoundedRectangleBorder shapeSm = RoundedRectangleBorder(
|
|
55
|
+
borderRadius: sm,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
/// Medium rounded rectangle shape (12 pt).
|
|
59
|
+
static const RoundedRectangleBorder shapeMd = RoundedRectangleBorder(
|
|
60
|
+
borderRadius: md,
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
/// Large rounded rectangle shape (16 pt).
|
|
64
|
+
static const RoundedRectangleBorder shapeLg = RoundedRectangleBorder(
|
|
65
|
+
borderRadius: lg,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
/// Fully circular/stadium shape.
|
|
69
|
+
static const StadiumBorder stadium = StadiumBorder();
|
|
70
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
|
|
3
|
+
/// Named animation curves following Material 3 motion guidelines.
|
|
4
|
+
///
|
|
5
|
+
/// Material 3 defines four core easing families:
|
|
6
|
+
/// - **Standard** — most UI transitions
|
|
7
|
+
/// - **Emphasized** — important / expressive transitions
|
|
8
|
+
/// - **Decelerate** — elements entering the screen
|
|
9
|
+
/// - **Accelerate** — elements leaving the screen
|
|
10
|
+
///
|
|
11
|
+
/// Usage:
|
|
12
|
+
/// ```dart
|
|
13
|
+
/// AnimatedContainer(
|
|
14
|
+
/// duration: AppDurations.normal,
|
|
15
|
+
/// curve: AppCurves.standard,
|
|
16
|
+
/// )
|
|
17
|
+
/// ```
|
|
18
|
+
abstract final class AppCurves {
|
|
19
|
+
AppCurves._();
|
|
20
|
+
|
|
21
|
+
// ── Material 3 Core Easing ────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
/// Standard easing — for most UI transitions (enter + exit both).
|
|
24
|
+
/// Equivalent to M3 "Standard" curve.
|
|
25
|
+
static const Curve standard = Curves.easeInOut;
|
|
26
|
+
|
|
27
|
+
/// Emphasized easing — for important, expressive transitions.
|
|
28
|
+
/// More dramatic entry, used for large elements or hero moments.
|
|
29
|
+
static const Curve emphasized = Curves.easeInOutCubicEmphasized;
|
|
30
|
+
|
|
31
|
+
/// Decelerate — for elements entering the screen (fly-in).
|
|
32
|
+
/// Starts fast, slows down to a gentle stop.
|
|
33
|
+
static const Curve decelerate = Curves.decelerate;
|
|
34
|
+
|
|
35
|
+
/// Accelerate — for elements leaving the screen (fly-out).
|
|
36
|
+
/// Starts slow, picks up speed as it exits.
|
|
37
|
+
static const Curve accelerate = Curves.easeIn;
|
|
38
|
+
|
|
39
|
+
// ── Additional utility curves ─────────────────────────────────────────────
|
|
40
|
+
|
|
41
|
+
/// Spring-like overshoot — fun, bouncy interactions (FABs, cards).
|
|
42
|
+
static const Curve spring = Curves.elasticOut;
|
|
43
|
+
|
|
44
|
+
/// Ease out back — slight overshoot then settle; good for scaling pop-ins.
|
|
45
|
+
static const Curve easeOutBack = Curves.easeOutBack;
|
|
46
|
+
|
|
47
|
+
/// Linear — only for continuous loops (loaders, shimmer).
|
|
48
|
+
static const Curve linear = Curves.linear;
|
|
49
|
+
|
|
50
|
+
/// Ease in out cubic — smooth, natural-feeling transitions.
|
|
51
|
+
static const Curve smooth = Curves.easeInOutCubic;
|
|
52
|
+
|
|
53
|
+
// ── Semantic aliases ──────────────────────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
/// For page enter transitions.
|
|
56
|
+
static const Curve pageEnter = decelerate;
|
|
57
|
+
|
|
58
|
+
/// For page exit transitions.
|
|
59
|
+
static const Curve pageExit = accelerate;
|
|
60
|
+
|
|
61
|
+
/// For popups and dialogs appearing.
|
|
62
|
+
static const Curve popupOpen = emphasized;
|
|
63
|
+
|
|
64
|
+
/// For modals and sheets closing.
|
|
65
|
+
static const Curve popupClose = standard;
|
|
66
|
+
|
|
67
|
+
/// For micro-interactions (button press, toggle).
|
|
68
|
+
static const Curve microInteraction = easeOutBack;
|
|
69
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// Named animation duration constants following Material 3 motion guidelines.
|
|
2
|
+
///
|
|
3
|
+
/// Usage:
|
|
4
|
+
/// ```dart
|
|
5
|
+
/// AnimatedContainer(duration: AppDurations.normal, curve: AppCurves.standard)
|
|
6
|
+
/// ```
|
|
7
|
+
abstract final class AppDurations {
|
|
8
|
+
AppDurations._();
|
|
9
|
+
|
|
10
|
+
/// 50 ms — nearly instant, icon state swaps.
|
|
11
|
+
static const Duration instant = Duration(milliseconds: 50);
|
|
12
|
+
|
|
13
|
+
/// 100 ms — very fast micro-interaction (ripple, press feedback).
|
|
14
|
+
static const Duration veryFast = Duration(milliseconds: 100);
|
|
15
|
+
|
|
16
|
+
/// 150 ms — fast transition for small, contained elements (checkboxes, chips).
|
|
17
|
+
static const Duration fast = Duration(milliseconds: 150);
|
|
18
|
+
|
|
19
|
+
/// 200 ms — quick transition, tab indicator, list item highlight.
|
|
20
|
+
static const Duration quick = Duration(milliseconds: 200);
|
|
21
|
+
|
|
22
|
+
/// 300 ms — standard transition for most UI animations.
|
|
23
|
+
/// Follows Material 3 "standard" motion duration guideline.
|
|
24
|
+
static const Duration normal = Duration(milliseconds: 300);
|
|
25
|
+
|
|
26
|
+
/// 400 ms — medium transition for page elements entering from off-screen.
|
|
27
|
+
static const Duration medium = Duration(milliseconds: 400);
|
|
28
|
+
|
|
29
|
+
/// 500 ms — slow, deliberate reveal of large surfaces (drawers, dialogs).
|
|
30
|
+
static const Duration slow = Duration(milliseconds: 500);
|
|
31
|
+
|
|
32
|
+
/// 700 ms — very slow, for complex choreographed sequences.
|
|
33
|
+
static const Duration verySlow = Duration(milliseconds: 700);
|
|
34
|
+
|
|
35
|
+
/// 1000 ms — skeleton/shimmer cycle base duration.
|
|
36
|
+
static const Duration shimmer = Duration(milliseconds: 1000);
|
|
37
|
+
|
|
38
|
+
// ── Semantic aliases ──────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
/// Recommended duration for page transitions.
|
|
41
|
+
static const Duration pageTransition = medium;
|
|
42
|
+
|
|
43
|
+
/// Recommended duration for in-place widget transitions (show/hide).
|
|
44
|
+
static const Duration widgetTransition = normal;
|
|
45
|
+
|
|
46
|
+
/// Recommended duration for micro-interactions (button press, hover).
|
|
47
|
+
static const Duration microInteraction = fast;
|
|
48
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
|
|
3
|
+
/// Predefined box shadows aligned with Material 3 elevation tiers.
|
|
4
|
+
///
|
|
5
|
+
/// Usage:
|
|
6
|
+
/// ```dart
|
|
7
|
+
/// Container(
|
|
8
|
+
/// decoration: BoxDecoration(
|
|
9
|
+
/// boxShadow: AppShadows.card,
|
|
10
|
+
/// ),
|
|
11
|
+
/// )
|
|
12
|
+
/// ```
|
|
13
|
+
abstract final class AppShadows {
|
|
14
|
+
AppShadows._();
|
|
15
|
+
|
|
16
|
+
/// No shadow — flat, tonal surface (elevation 0).
|
|
17
|
+
static const List<BoxShadow> none = [];
|
|
18
|
+
|
|
19
|
+
/// Minimal shadow — barely lifted surfaces (elevation 1).
|
|
20
|
+
/// Use for: toggle surfaces, filled cards on white background.
|
|
21
|
+
static const List<BoxShadow> subtle = [
|
|
22
|
+
BoxShadow(
|
|
23
|
+
color: Color(0x0D000000), // 5% black
|
|
24
|
+
blurRadius: 2,
|
|
25
|
+
offset: Offset(0, 1),
|
|
26
|
+
),
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/// Card shadow — clearly elevated content (elevation 2–3).
|
|
30
|
+
/// Use for: cards, list items that are tappable, floating elements.
|
|
31
|
+
static const List<BoxShadow> card = [
|
|
32
|
+
BoxShadow(
|
|
33
|
+
color: Color(0x14000000), // 8% black
|
|
34
|
+
blurRadius: 8,
|
|
35
|
+
offset: Offset(0, 2),
|
|
36
|
+
),
|
|
37
|
+
BoxShadow(
|
|
38
|
+
color: Color(0x0A000000), // 4% black
|
|
39
|
+
blurRadius: 2,
|
|
40
|
+
offset: Offset(0, 1),
|
|
41
|
+
),
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
/// Elevated shadow — significantly raised surface (elevation 6–8).
|
|
45
|
+
/// Use for: FABs, dropdown menus, tooltips.
|
|
46
|
+
static const List<BoxShadow> elevated = [
|
|
47
|
+
BoxShadow(
|
|
48
|
+
color: Color(0x1F000000), // 12% black
|
|
49
|
+
blurRadius: 16,
|
|
50
|
+
offset: Offset(0, 6),
|
|
51
|
+
),
|
|
52
|
+
BoxShadow(
|
|
53
|
+
color: Color(0x0F000000), // 6% black
|
|
54
|
+
blurRadius: 4,
|
|
55
|
+
offset: Offset(0, 2),
|
|
56
|
+
),
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
/// Modal shadow — overlay surfaces, dialogs, bottom sheets (elevation 12+).
|
|
60
|
+
/// Use for: dialogs, modals, side sheets.
|
|
61
|
+
static const List<BoxShadow> modal = [
|
|
62
|
+
BoxShadow(
|
|
63
|
+
color: Color(0x29000000), // 16% black
|
|
64
|
+
blurRadius: 32,
|
|
65
|
+
offset: Offset(0, 12),
|
|
66
|
+
),
|
|
67
|
+
BoxShadow(
|
|
68
|
+
color: Color(0x14000000), // 8% black
|
|
69
|
+
blurRadius: 8,
|
|
70
|
+
offset: Offset(0, 4),
|
|
71
|
+
),
|
|
72
|
+
];
|
|
73
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{{#if flags.usesScreenutil}}
|
|
2
|
+
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
3
|
+
{{/if}}
|
|
4
|
+
|
|
5
|
+
/// Named spacing constants aligned with an 8-pt grid.
|
|
6
|
+
///
|
|
7
|
+
/// Usage:
|
|
8
|
+
/// ```dart
|
|
9
|
+
/// SizedBox(height: AppSpacing.md) // 16 pt gap
|
|
10
|
+
/// Padding(padding: EdgeInsets.all(AppSpacing.lg))
|
|
11
|
+
/// ```
|
|
12
|
+
abstract final class AppSpacing {
|
|
13
|
+
AppSpacing._();
|
|
14
|
+
|
|
15
|
+
static const double _xxs = 2;
|
|
16
|
+
static const double _xs = 4;
|
|
17
|
+
static const double _sm = 8;
|
|
18
|
+
static const double _ms = 12;
|
|
19
|
+
static const double _md = 16;
|
|
20
|
+
static const double _ml = 20;
|
|
21
|
+
static const double _lg = 24;
|
|
22
|
+
static const double _xl = 32;
|
|
23
|
+
static const double _xxl = 48;
|
|
24
|
+
static const double _xxxl = 64;
|
|
25
|
+
|
|
26
|
+
/// 2 pt — hairline gap, icon-to-label spacing.
|
|
27
|
+
static double get xxs => {{#if flags.usesScreenutil}}_xxs.r{{else}}_xxs{{/if}};
|
|
28
|
+
|
|
29
|
+
/// 4 pt — tightest spacing, between tightly coupled elements.
|
|
30
|
+
static double get xs => {{#if flags.usesScreenutil}}_xs.r{{else}}_xs{{/if}};
|
|
31
|
+
|
|
32
|
+
/// 8 pt — small spacing, inside compact components (chip padding, icon gap).
|
|
33
|
+
static double get sm => {{#if flags.usesScreenutil}}_sm.r{{else}}_sm{{/if}};
|
|
34
|
+
|
|
35
|
+
/// 12 pt — medium-small, inner card padding on dense layouts.
|
|
36
|
+
static double get ms => {{#if flags.usesScreenutil}}_ms.r{{else}}_ms{{/if}};
|
|
37
|
+
|
|
38
|
+
/// 16 pt — base unit, standard component padding and list item gaps.
|
|
39
|
+
static double get md => {{#if flags.usesScreenutil}}_md.r{{else}}_md{{/if}};
|
|
40
|
+
|
|
41
|
+
/// 20 pt — medium-large, comfortable section spacing.
|
|
42
|
+
static double get ml => {{#if flags.usesScreenutil}}_ml.r{{else}}_ml{{/if}};
|
|
43
|
+
|
|
44
|
+
/// 24 pt — large, between content sections on a page.
|
|
45
|
+
static double get lg => {{#if flags.usesScreenutil}}_lg.r{{else}}_lg{{/if}};
|
|
46
|
+
|
|
47
|
+
/// 32 pt — extra large, major section breaks or hero padding.
|
|
48
|
+
static double get xl => {{#if flags.usesScreenutil}}_xl.r{{else}}_xl{{/if}};
|
|
49
|
+
|
|
50
|
+
/// 48 pt — 2× large, top-of-page safe area offsets, empty state padding.
|
|
51
|
+
static double get xxl => {{#if flags.usesScreenutil}}_xxl.r{{else}}_xxl{{/if}};
|
|
52
|
+
|
|
53
|
+
/// 64 pt — maximum, full-bleed header heights.
|
|
54
|
+
static double get xxxl => {{#if flags.usesScreenutil}}_xxxl.r{{else}}_xxxl{{/if}};
|
|
55
|
+
|
|
56
|
+
// ── Semantic aliases ──────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
/// Standard horizontal page margin.
|
|
59
|
+
static double get pagePadding => md;
|
|
60
|
+
|
|
61
|
+
/// Gap between list/grid items.
|
|
62
|
+
static double get itemGap => sm;
|
|
63
|
+
|
|
64
|
+
/// Inner padding for cards.
|
|
65
|
+
static double get cardPadding => md;
|
|
66
|
+
|
|
67
|
+
/// Vertical gap between form fields.
|
|
68
|
+
static double get formFieldGap => ms;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
{{#unless flags.usesScreenutil}}
|
|
72
|
+
/// Extension to provide identity scaling when ScreenUtil is disabled.
|
|
73
|
+
/// This allows using .h, .w, .sp, .r on numbers without conditional checks.
|
|
74
|
+
extension ResponsiveNumberExtension on num {
|
|
75
|
+
double get h => toDouble();
|
|
76
|
+
double get w => toDouble();
|
|
77
|
+
double get sp => toDouble();
|
|
78
|
+
double get r => toDouble();
|
|
79
|
+
}
|
|
80
|
+
{{/unless}}
|