├── .gitignore ├── samples_intl_tools ├── lib │ ├── l10n │ │ ├── app_es.arb │ │ └── app_en.arb │ ├── hello_world.dart │ ├── intl_localizations_delegate.dart │ └── main.dart ├── l10n.yaml ├── build.yaml ├── .dart_tool │ └── flutter_gen │ │ ├── pubspec.yaml │ │ └── gen_l10n │ │ ├── app_localizations_en.dart │ │ └── app_localizations_es.dart ├── stories │ └── intl_stories.dart ├── .metadata ├── pubspec.yaml ├── .gitignore ├── README.md └── analysis_options.yaml ├── samples_easy_localization ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── Podfile.lock │ ├── .gitignore │ └── Podfile ├── assets │ └── translations │ │ ├── en-US.json │ │ └── es.json ├── build.yaml ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── easy_localization_sample │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── macos │ ├── .gitignore │ ├── Runner │ │ ├── Configs │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ ├── Warnings.xcconfig │ │ │ └── AppInfo.xcconfig │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app_icon_128.png │ │ │ │ ├── app_icon_16.png │ │ │ │ ├── app_icon_256.png │ │ │ │ ├── app_icon_32.png │ │ │ │ ├── app_icon_512.png │ │ │ │ ├── app_icon_64.png │ │ │ │ ├── app_icon_1024.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Release.entitlements │ │ ├── DebugProfile.entitlements │ │ ├── MainFlutterWindow.swift │ │ └── Info.plist │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Podfile.lock │ └── Podfile ├── web │ ├── favicon.png │ ├── icons │ │ ├── Icon-192.png │ │ └── Icon-512.png │ ├── manifest.json │ └── index.html ├── analysis_options.yaml ├── stories │ └── easy_localization_stories.dart ├── .metadata ├── pubspec.yaml ├── lib │ ├── localized_widgets.dart │ ├── main.dart │ └── easy_localizations_delegate.dart ├── README.md └── .gitignore ├── _assets ├── themed-screen.png ├── localized-screen.png └── fetch-complex-list.png ├── samples_booking ├── build.yaml ├── assets │ ├── hotel │ │ ├── hotel_1.png │ │ ├── hotel_2.png │ │ ├── hotel_3.png │ │ ├── hotel_4.png │ │ ├── hotel_5.png │ │ └── hotel_booking.png │ └── fonts │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-Medium.ttf │ │ ├── Roboto-Regular.ttf │ │ ├── WorkSans-Bold.ttf │ │ ├── WorkSans-Medium.ttf │ │ ├── WorkSans-Regular.ttf │ │ └── WorkSans-SemiBold.ttf ├── analysis_options.yaml ├── .metadata ├── monarch.yaml ├── README.md ├── locale │ ├── i18n_en.json │ └── i18n_es.json ├── LICENSE ├── .gitignore ├── pubspec.yaml ├── stories │ └── booking_stories.dart └── lib │ ├── booking │ ├── model │ │ ├── popular_filter_list.dart │ │ └── booking_list_data.dart │ ├── booking_app_theme.dart │ └── slider_view.dart │ ├── localizations.dart │ └── main.dart ├── samples_patterns ├── build.yaml ├── assets │ ├── monarch_m.png │ ├── monarch_m_200.png │ └── google_fonts │ │ ├── OpenSans-Bold.ttf │ │ ├── OpenSans-Light.ttf │ │ ├── OpenSans-Regular.ttf │ │ ├── OpenSans-SemiBold.ttf │ │ ├── OpenSans-BoldItalic.ttf │ │ ├── OpenSans-ExtraBold.ttf │ │ ├── OpenSans-LightItalic.ttf │ │ ├── OpenSans-RegularItalic.ttf │ │ ├── OpenSans-ExtraBoldItalic.ttf │ │ └── OpenSans-SemiBoldItalic.ttf ├── analysis_options.yaml ├── locale │ ├── i18n_en.json │ └── i18n_es.json ├── lib │ ├── provider │ │ ├── current_date.dart │ │ ├── provider_example_list.dart │ │ ├── shopping_cart_change_notifier.dart │ │ ├── provider_screen.dart │ │ └── change_notifier_screen.dart │ ├── animations │ │ ├── lottie │ │ │ └── lottie_animated_widget.dart │ │ └── flutter │ │ │ ├── resizable_box.dart │ │ │ ├── progress_button.dart │ │ │ └── collapsable_box.dart │ ├── bloc │ │ ├── list_complex │ │ │ ├── item.dart │ │ │ ├── list_state.dart │ │ │ ├── repository.dart │ │ │ ├── list_cubit.dart │ │ │ └── list_complex_screen.dart │ │ ├── bloc_example_list.dart │ │ └── bloc_counter │ │ │ └── bloc_counter_screen.dart │ ├── platform_route.dart │ ├── dialogs │ │ ├── scaffold_messenger.dart │ │ ├── bottom_sheet.dart │ │ └── alert_dialog.dart │ ├── navigation │ │ ├── simple_navigation.dart │ │ └── named_routes.dart │ ├── themes │ │ ├── custom_theme.dart │ │ └── themed_screen.dart │ ├── text_fields │ │ ├── obscurable_text_field.dart │ │ └── single_value_text_field.dart │ ├── internationalization │ │ ├── localized_screen.dart │ │ └── localizations.dart │ ├── content_list │ │ ├── animated_tap.dart │ │ └── content_list_screen.dart │ └── main.dart ├── stories │ ├── themed_screen_stories.dart │ ├── internationalization_stories.dart │ ├── scaffold_messenger_stories.dart │ ├── bloc_counter_view_stories.dart │ ├── obscurable_text_field_stories.dart │ ├── content_list_screen_stories.dart │ ├── images_stories.dart │ ├── mocked_repository.dart │ ├── provider_screen_stories.dart │ ├── animations_stories.dart │ ├── navigation_stories.dart │ ├── main_stories.dart │ ├── provider_change_notifier_screen_stories.dart │ ├── provider_navigation_stories.dart │ ├── dialog_stories.dart │ └── bloc_complex_list_stories.dart ├── .metadata ├── README.md ├── .gitignore ├── pubspec.yaml └── test │ └── obscurable_text_field_test.dart ├── samples_riverpod ├── build.yaml ├── .metadata ├── lib │ ├── main.dart │ └── hello_world.dart ├── README.md ├── pubspec.yaml ├── stories │ └── riverpod_stories.dart ├── .gitignore └── analysis_options.yaml ├── test ├── README.md ├── pubspec.yaml ├── .gitignore ├── samples_test.dart └── test_utils.dart └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | */pubspec.lock -------------------------------------------------------------------------------- /samples_intl_tools/lib/l10n/app_es.arb: -------------------------------------------------------------------------------- 1 | { 2 | "helloWorld": "¡Hola Mundo!" 3 | } -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /_assets/themed-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/_assets/themed-screen.png -------------------------------------------------------------------------------- /_assets/localized-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/_assets/localized-screen.png -------------------------------------------------------------------------------- /_assets/fetch-complex-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/_assets/fetch-complex-list.png -------------------------------------------------------------------------------- /samples_booking/build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | sources: 4 | - $package$ 5 | - lib/** 6 | - stories/** -------------------------------------------------------------------------------- /samples_intl_tools/l10n.yaml: -------------------------------------------------------------------------------- 1 | arb-dir: lib/l10n 2 | template-arb-file: app_en.arb 3 | output-localization-file: app_localizations.dart -------------------------------------------------------------------------------- /samples_patterns/build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | sources: 4 | - $package$ 5 | - lib/** 6 | - stories/** -------------------------------------------------------------------------------- /samples_riverpod/build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | sources: 4 | - $package$ 5 | - lib/** 6 | - stories/** -------------------------------------------------------------------------------- /samples_easy_localization/assets/translations/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hello World", 3 | "question": "Is it lunch time?" 4 | } -------------------------------------------------------------------------------- /samples_intl_tools/build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | sources: 4 | - $package$ 5 | - lib/** 6 | - stories/** -------------------------------------------------------------------------------- /samples_patterns/assets/monarch_m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/monarch_m.png -------------------------------------------------------------------------------- /samples_booking/assets/hotel/hotel_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/hotel/hotel_1.png -------------------------------------------------------------------------------- /samples_booking/assets/hotel/hotel_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/hotel/hotel_2.png -------------------------------------------------------------------------------- /samples_booking/assets/hotel/hotel_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/hotel/hotel_3.png -------------------------------------------------------------------------------- /samples_booking/assets/hotel/hotel_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/hotel/hotel_4.png -------------------------------------------------------------------------------- /samples_booking/assets/hotel/hotel_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/hotel/hotel_5.png -------------------------------------------------------------------------------- /samples_easy_localization/assets/translations/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hola Mundo", 3 | "question": "¿Es la hora del almuerzo?" 4 | } -------------------------------------------------------------------------------- /samples_easy_localization/build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | sources: 4 | - $package$ 5 | - lib/** 6 | - stories/** -------------------------------------------------------------------------------- /samples_easy_localization/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /samples_easy_localization/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/web/favicon.png -------------------------------------------------------------------------------- /samples_patterns/assets/monarch_m_200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/monarch_m_200.png -------------------------------------------------------------------------------- /samples_booking/assets/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /samples_patterns/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:lints/recommended.yaml 2 | 3 | linter: 4 | rules: 5 | non_constant_identifier_names: false -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | Integration tests to verify that the monarch samples projects work 2 | with the latest Flutter SDK and the latest Monarch versions. 3 | -------------------------------------------------------------------------------- /samples_booking/assets/fonts/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/fonts/Roboto-Medium.ttf -------------------------------------------------------------------------------- /samples_booking/assets/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /samples_booking/assets/fonts/WorkSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/fonts/WorkSans-Bold.ttf -------------------------------------------------------------------------------- /samples_booking/assets/fonts/WorkSans-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/fonts/WorkSans-Medium.ttf -------------------------------------------------------------------------------- /samples_booking/assets/hotel/hotel_booking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/hotel/hotel_booking.png -------------------------------------------------------------------------------- /samples_easy_localization/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/web/icons/Icon-192.png -------------------------------------------------------------------------------- /samples_easy_localization/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/web/icons/Icon-512.png -------------------------------------------------------------------------------- /samples_booking/assets/fonts/WorkSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/fonts/WorkSans-Regular.ttf -------------------------------------------------------------------------------- /samples_booking/assets/fonts/WorkSans-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_booking/assets/fonts/WorkSans-SemiBold.ttf -------------------------------------------------------------------------------- /samples_easy_localization/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-Light.ttf -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-SemiBold.ttf -------------------------------------------------------------------------------- /samples_intl_tools/.dart_tool/flutter_gen/pubspec.yaml: -------------------------------------------------------------------------------- 1 | # Generated by the flutter tool 2 | name: synthetic_package 3 | description: The Flutter application's synthetic package. 4 | -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-ExtraBold.ttf -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-LightItalic.ttf -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-RegularItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-RegularItalic.ttf -------------------------------------------------------------------------------- /samples_intl_tools/lib/l10n/app_en.arb: -------------------------------------------------------------------------------- 1 | { 2 | "helloWorld": "Hello World!", 3 | "@helloWorld": { 4 | "description": "The conventional newborn programmer greeting" 5 | } 6 | } -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /samples_patterns/assets/google_fonts/OpenSans-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_patterns/assets/google_fonts/OpenSans-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /samples_easy_localization/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /samples_booking/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | linter: 4 | rules: 5 | non_constant_identifier_names: false 6 | prefer_const_constructors: false 7 | -------------------------------------------------------------------------------- /samples_easy_localization/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:lints/recommended.yaml 2 | 3 | linter: 4 | rules: 5 | non_constant_identifier_names: false 6 | implementation_imports: false -------------------------------------------------------------------------------- /samples_easy_localization/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /samples_intl_tools/stories/intl_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:monarch_samples_intl_tools/hello_world.dart'; 3 | 4 | Widget helloWorld() => const HelloWorld(); 5 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples_patterns/locale/i18n_en.json: -------------------------------------------------------------------------------- 1 | { 2 | "sample.title": "Translations example", 3 | "sample.headline": "Translated Title", 4 | "sample.subheader": "This is a subtitle", 5 | "sample.content": "Example content" 6 | } 7 | -------------------------------------------------------------------------------- /samples_patterns/locale/i18n_es.json: -------------------------------------------------------------------------------- 1 | { 2 | "sample.title": "Ejemplo de traducción", 3 | "sample.headline": "Título traducido", 4 | "sample.subheader": "Esto es un subtítulo", 5 | "sample.content": "Contenido de ejemplo" 6 | } 7 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dropsource/monarch_samples/HEAD/samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /samples_patterns/lib/provider/current_date.dart: -------------------------------------------------------------------------------- 1 | class CurrentDate { 2 | final Function? currentDateFn; 3 | 4 | CurrentDate({this.currentDateFn}); 5 | 6 | String? currentDateAsString() { 7 | return currentDateFn!(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/kotlin/com/example/easy_localization_sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.easy_localization_sample 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /samples_patterns/stories/themed_screen_stories.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: non_constant_identifier_names 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:monarch_samples_patterns/themes/themed_screen.dart'; 4 | 5 | Widget themed_screen_example() => ThemedScreen(); 6 | -------------------------------------------------------------------------------- /samples_patterns/stories/internationalization_stories.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: non_constant_identifier_names 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:monarch_samples_patterns/internationalization/localized_screen.dart'; 4 | 5 | Widget localized_screen() => LocalizedScreen(); 6 | -------------------------------------------------------------------------------- /test/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: monarch_samples_test 2 | description: Integration tests for monarch_samples 3 | version: 1.0.0 4 | 5 | environment: 6 | sdk: '>=2.16.1 <4.0.0' 7 | 8 | dev_dependencies: 9 | test_process: 10 | path: 11 | async: 12 | monarch_utils: 13 | monarch_io_utils: 14 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples_easy_localization/stories/easy_localization_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:monarch_easy_localization_sample/localized_widgets.dart'; 3 | 4 | Widget title() => LocalizedTitle(); 5 | Widget question() => LocalizedQuestion(); 6 | Widget upper() => UpperLocalizedTitle(); 7 | -------------------------------------------------------------------------------- /samples_patterns/stories/scaffold_messenger_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:monarch_samples_patterns/dialogs/scaffold_messenger.dart'; 3 | 4 | Widget scaffold_messenger_app() => ScaffoldMessengerExampleApp(); 5 | 6 | Widget scaffold_messenger() => ScaffoldMessengerExample(); 7 | -------------------------------------------------------------------------------- /samples_easy_localization/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples_easy_localization/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples_intl_tools/.dart_tool/flutter_gen/gen_l10n/app_localizations_en.dart: -------------------------------------------------------------------------------- 1 | import 'app_localizations.dart'; 2 | 3 | /// The translations for English (`en`). 4 | class AppLocalizationsEn extends AppLocalizations { 5 | AppLocalizationsEn([String locale = 'en']) : super(locale); 6 | 7 | @override 8 | String get helloWorld => 'Hello World!'; 9 | } 10 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples_booking/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 18116933e77adc82f80866c928266a5b4f1ed645 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /samples_intl_tools/.dart_tool/flutter_gen/gen_l10n/app_localizations_es.dart: -------------------------------------------------------------------------------- 1 | import 'app_localizations.dart'; 2 | 3 | /// The translations for Spanish Castilian (`es`). 4 | class AppLocalizationsEs extends AppLocalizations { 5 | AppLocalizationsEs([String locale = 'es']) : super(locale); 6 | 7 | @override 8 | String get helloWorld => '¡Hola Mundo!'; 9 | } 10 | -------------------------------------------------------------------------------- /samples_patterns/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: c5a4b4029c0798f37c4a39b479d7cb75daa7b05c 8 | channel: unknown 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /samples_riverpod/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: cf4400006550b70f28e4b4af815151d1e74846c6 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /samples_intl_tools/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: cf4400006550b70f28e4b4af815151d1e74846c6 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /samples_easy_localization/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 1d9032c7e1d867f071f2277eb1673e8f9b0274e3 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import shared_preferences_foundation 9 | 10 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 11 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 12 | } 13 | -------------------------------------------------------------------------------- /samples_intl_tools/lib/hello_world.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter_gen/gen_l10n/app_localizations.dart'; 3 | 4 | class HelloWorld extends StatelessWidget { 5 | const HelloWorld({Key? key}) : super(key: key); 6 | @override 7 | Widget build(BuildContext context) { 8 | return Center(child: Text(AppLocalizations.of(context)!.helloWorld)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /samples_riverpod/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | import 'package:samples_riverpod/hello_world.dart'; 4 | 5 | void main() { 6 | runApp( 7 | ProviderScope( 8 | child: Scaffold( 9 | appBar: AppBar(title: const Text('Monarch + Riverpod Example')), 10 | body: const HelloWorld()), 11 | ), 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples_intl_tools/lib/intl_localizations_delegate.dart: -------------------------------------------------------------------------------- 1 | import 'package:monarch_annotations/monarch_annotations.dart'; 2 | import 'package:flutter_gen/gen_l10n/app_localizations.dart'; 3 | 4 | /// The MonarchLocale items you declare here will show up in the Monarch 5 | /// UI. You can then test your stories using these locales. 6 | @MonarchLocalizations([MonarchLocale('en'), MonarchLocale('es')]) 7 | const myDelegate = AppLocalizations.delegate; 8 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /samples_patterns/stories/bloc_counter_view_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:monarch_samples_patterns/bloc/bloc_counter/bloc_counter_screen.dart'; 4 | 5 | Widget zero() => 6 | BlocProvider.value(value: CounterCubit(), child: BlocCounterView()); 7 | 8 | Widget nonzero() => BlocProvider.value( 9 | value: CounterCubit(initialState: 100), child: BlocCounterView()); 10 | -------------------------------------------------------------------------------- /samples_patterns/stories/obscurable_text_field_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:monarch_samples_patterns/text_fields/obscurable_text_field.dart'; 3 | 4 | Widget obscured_text() => ObscurableTextfield( 5 | value: 'P@ssw0rd!', 6 | ); 7 | 8 | Widget clear_text() => ObscurableTextfield( 9 | value: 'P@ssw0rd!', 10 | obscureText: false, 11 | ); 12 | 13 | Widget empty_text() => ObscurableTextfield(); 14 | -------------------------------------------------------------------------------- /samples_riverpod/README.md: -------------------------------------------------------------------------------- 1 | # monarch_samples_riverpod 2 | 3 | Monarch sample code and stories using [Riverpod](https://riverpod.dev/). 4 | 5 | _Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs. Find out more at https://monarchapp.io_ 6 | 7 | ## Running the sample stories 8 | 9 | 1. Make sure you already have Monarch [installed](https://monarchapp.io/docs/install). 10 | 2. `flutter pub get` 11 | 3. `monarch run` 12 | -------------------------------------------------------------------------------- /samples_booking/monarch.yaml: -------------------------------------------------------------------------------- 1 | devices: 2 | - id: iphone-16-pro 3 | name: iPhone 16 Pro 4 | height: 874 5 | width: 402 6 | device_pixel_ratio: 3 7 | platform: ios 8 | - id: android-pixel-7 9 | name: Google Pixel 7 10 | height: 923 11 | width: 415 12 | device_pixel_ratio: 2.6 13 | platform: android 14 | - id: large-screen-01 15 | name: Large Screen 01 16 | height: 1080 17 | width: 1920 18 | device_pixel_ratio: 1 19 | platform: macos -------------------------------------------------------------------------------- /samples_riverpod/lib/hello_world.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | 4 | final helloWorldProvider = Provider((_) => 'Hello world'); 5 | 6 | class HelloWorld extends ConsumerWidget { 7 | const HelloWorld({Key? key}) : super(key: key); 8 | @override 9 | Widget build(BuildContext context, WidgetRef ref) { 10 | final String value = ref.watch(helloWorldProvider); 11 | return Center(child: Text(value)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /samples_booking/README.md: -------------------------------------------------------------------------------- 1 | # monarch_samples_booking 2 | 3 | Monarch sample code and stories using a pretty booking theme. The 4 | [Monarch website](https://monarchapp.io/) showcases this project. 5 | 6 | The booking theme is based on one of the templates in 7 | [Best-Flutter-UI-Templates](https://github.com/mitesh77/Best-Flutter-UI-Templates). 8 | 9 | ## Running the sample stories 10 | 11 | 1. Make sure you already have Monarch [installed](https://monarchapp.io/docs/install). 12 | 2. `flutter pub get` 13 | 3. `monarch run` 14 | -------------------------------------------------------------------------------- /samples_easy_localization/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /samples_riverpod/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: samples_riverpod 2 | description: Monarch sample code and stories using Riverpod. 3 | publish_to: 'none' 4 | 5 | version: 1.0.0 6 | 7 | environment: 8 | sdk: ">=2.15.0 <3.0.0" 9 | flutter: ">=2.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | flutter_riverpod: ^2.3.6 15 | cupertino_icons: ^1.0.2 16 | 17 | dev_dependencies: 18 | flutter_test: 19 | sdk: flutter 20 | flutter_lints: ^2.0.1 21 | monarch: ^3.0.0 22 | build_runner: ^2.1.11 23 | 24 | flutter: 25 | uses-material-design: true -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples_intl_tools/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:monarch_samples_intl_tools/hello_world.dart'; 3 | 4 | void main() { 5 | runApp(const MyApp()); 6 | } 7 | 8 | class MyApp extends StatelessWidget { 9 | const MyApp({Key? key}) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return MaterialApp( 14 | title: 'Monarch intl tools sample', 15 | theme: ThemeData( 16 | primarySwatch: Colors.blue, 17 | ), 18 | home: const HelloWorld(), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /samples_booking/locale/i18n_en.json: -------------------------------------------------------------------------------- 1 | { 2 | "type-of-accommodation": "Type of accommodation", 3 | "distance-from-center": "Distance from city center", 4 | "popular-filters": "Popular filters", 5 | "price-1-night": "Price (for 1 night)", 6 | "filters": "Filters", 7 | "free-breakfast": "Free Breakfast", 8 | "free-parking": "Free Parking", 9 | "free-wi-fi": "Free Wi-Fi", 10 | "pool": "Pool", 11 | "pet-friendly": "Pet Friendly", 12 | "all": "All", 13 | "apartment": "Apartment", 14 | "home": "Home", 15 | "hotel": "Hotel", 16 | "resort": "Resort", 17 | "villa": "Villa", 18 | "less-than": "Less than" 19 | } -------------------------------------------------------------------------------- /samples_patterns/lib/animations/lottie/lottie_animated_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:lottie/lottie.dart'; 3 | 4 | class LottieAnimatedWidget extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Container( 8 | padding: EdgeInsets.all(16), 9 | child: Column( 10 | children: [ 11 | Text('This is Lottie Animation from assets'), 12 | SizedBox( 13 | height: 16, 14 | ), 15 | Lottie.asset('assets/LottieLogo1.json'), 16 | ], 17 | ), 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples_booking/locale/i18n_es.json: -------------------------------------------------------------------------------- 1 | { 2 | "type-of-accommodation": "Tipo de hospedaje", 3 | "distance-from-center": "Distancia del centro", 4 | "popular-filters": "Filtros populares", 5 | "price-1-night": "Precio (por 1 noche)", 6 | "filters": "Filtros", 7 | "free-breakfast": "Desayuno Gratis", 8 | "free-parking": "Parqueo Gratis", 9 | "free-wi-fi": "Wi-Fi Gratis", 10 | "pool": "Piscina", 11 | "pet-friendly": "Acepta mascotas", 12 | "all": "Todos", 13 | "apartment": "Departamento", 14 | "home": "Hogar", 15 | "hotel": "Hotel", 16 | "resort": "Resort", 17 | "villa": "Villa", 18 | "less-than": "Menos de" 19 | } -------------------------------------------------------------------------------- /samples_intl_tools/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: monarch_samples_intl_tools 2 | description: Monarch sample code and stories using intl package and tools 3 | 4 | publish_to: 'none' 5 | 6 | version: 1.0.0 7 | 8 | environment: 9 | sdk: ">=2.15.0 <3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | flutter_localizations: 15 | sdk: flutter 16 | intl: ^0.18.0 17 | 18 | cupertino_icons: ^1.0.2 19 | 20 | dev_dependencies: 21 | flutter_test: 22 | sdk: flutter 23 | 24 | flutter_lints: ^2.0.1 25 | monarch: ^3.0.0 26 | build_runner: ^2.1.11 27 | 28 | flutter: 29 | generate: true 30 | uses-material-design: true 31 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - shared_preferences (0.0.1): 4 | - Flutter 5 | 6 | DEPENDENCIES: 7 | - Flutter (from `Flutter`) 8 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) 9 | 10 | EXTERNAL SOURCES: 11 | Flutter: 12 | :path: Flutter 13 | shared_preferences: 14 | :path: ".symlinks/plugins/shared_preferences/ios" 15 | 16 | SPEC CHECKSUMS: 17 | Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a 18 | shared_preferences: 5033afbb22d372e15aff8ff766df9021b845f273 19 | 20 | PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c 21 | 22 | COCOAPODS: 1.10.0 23 | -------------------------------------------------------------------------------- /samples_patterns/lib/bloc/list_complex/item.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class Item extends Equatable { 4 | const Item({ 5 | required this.id, 6 | required this.value, 7 | this.isDeleting = false, 8 | }); 9 | 10 | final String id; 11 | final String value; 12 | final bool isDeleting; 13 | 14 | Item copyWith({String? id, String? value, bool? isDeleting}) { 15 | return Item( 16 | id: id ?? this.id, 17 | value: value ?? this.value, 18 | isDeleting: isDeleting ?? this.isDeleting, 19 | ); 20 | } 21 | 22 | @override 23 | List get props => [id, value, isDeleting]; 24 | } 25 | -------------------------------------------------------------------------------- /samples_riverpod/stories/riverpod_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | import 'package:samples_riverpod/hello_world.dart'; 4 | 5 | ProviderScope providerOverride( 6 | {required String value, required Widget child}) => 7 | ProviderScope( 8 | overrides: [helloWorldProvider.overrideWithValue(value)], child: child); 9 | 10 | Widget hello() => providerOverride(value: 'Hello', child: const HelloWorld()); 11 | 12 | Widget foo() => providerOverride(value: 'foo', child: const HelloWorld()); 13 | 14 | Widget bar() => providerOverride(value: 'bar', child: const HelloWorld()); 15 | -------------------------------------------------------------------------------- /samples_easy_localization/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: monarch_easy_localization_sample 2 | description: Monarch sample code and stories using easy_localization package 3 | 4 | publish_to: 'none' 5 | version: 1.0.0 6 | 7 | environment: 8 | sdk: '>=2.12.0 <3.0.0' 9 | 10 | dependencies: 11 | easy_localization: ^3.0.0 12 | flutter: 13 | sdk: flutter 14 | monarch_annotations: ^1.0.0 15 | 16 | cupertino_icons: ^1.0.2 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | lints: ^2.1.0 22 | monarch: ^3.0.0 23 | build_runner: ^2.1.11 24 | 25 | flutter: 26 | assets: 27 | - assets/translations/ 28 | 29 | uses-material-design: true 30 | 31 | -------------------------------------------------------------------------------- /samples_patterns/stories/content_list_screen_stories.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: non_constant_identifier_names 2 | import 'package:flutter/material.dart'; 3 | import 'package:monarch_samples_patterns/content_list/content_list_screen.dart'; 4 | 5 | final defaultTitle = 'Browse groceries categories'; 6 | 7 | Widget empty_list() => ContentListScreen( 8 | categories: [], 9 | title: defaultTitle, 10 | ); 11 | 12 | Widget populated_list() => ContentListScreen( 13 | categories: [ 14 | Category(label: 'Produce'), 15 | Category(label: 'Bakery'), 16 | Category(label: 'Canned Goods'), 17 | ], 18 | title: defaultTitle, 19 | ); 20 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /samples_easy_localization/lib/localized_widgets.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:easy_localization/easy_localization.dart'; 3 | 4 | class LocalizedTitle extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Text('title').tr(); 8 | } 9 | } 10 | 11 | class UpperLocalizedTitle extends StatelessWidget { 12 | @override 13 | Widget build(BuildContext context) { 14 | var upper = 'title'.tr().toUpperCase(); 15 | return Text(upper); 16 | } 17 | } 18 | 19 | class LocalizedQuestion extends StatelessWidget { 20 | @override 21 | Widget build(BuildContext context) { 22 | return Text('question').tr(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples_patterns/stories/images_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | Widget too_big() => Center( 4 | child: Column(children: [ 5 | SizedBox( 6 | width: 200, 7 | child: Image.asset('assets/monarch_m.png'), 8 | ), 9 | Text('Click "Highlight Oversized Images".'), 10 | Text('Image should flip.') 11 | ])); 12 | 13 | Widget just_right() => Center( 14 | child: Column(children: [ 15 | SizedBox( 16 | width: 200, 17 | child: Image.asset('assets/monarch_m_200.png'), 18 | ), 19 | Text('Click "Highlight Oversized Images".'), 20 | Text('Image is the right size, it should not flip.') 21 | ])); 22 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /samples_patterns/lib/bloc/list_complex/list_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | import 'item.dart'; 4 | 5 | enum ListStatus { loading, success, failure } 6 | 7 | class ListState extends Equatable { 8 | const ListState._({ 9 | this.status = ListStatus.loading, 10 | this.items = const [], 11 | }); 12 | 13 | const ListState.loading() : this._(); 14 | 15 | const ListState.success(List items) 16 | : this._(status: ListStatus.success, items: items); 17 | 18 | const ListState.failure() : this._(status: ListStatus.failure); 19 | 20 | final ListStatus status; 21 | final List items; 22 | 23 | @override 24 | List get props => [status, items]; 25 | } 26 | -------------------------------------------------------------------------------- /samples_easy_localization/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easy_localization_sample", 3 | "short_name": "easy_localization_sample", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = easy_localization_sample 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.easyLocalizationSample 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2021 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /samples_patterns/stories/mocked_repository.dart: -------------------------------------------------------------------------------- 1 | import 'package:monarch_samples_patterns/bloc/list_complex/item.dart'; 2 | import 'package:monarch_samples_patterns/bloc/list_complex/repository.dart'; 3 | 4 | class MockedRepository implements Repository { 5 | @override 6 | Future> fetchItems() { 7 | return Future.delayed( 8 | Duration(seconds: 1), 9 | () => const [ 10 | Item(id: '1', value: 'Fetched'), 11 | Item(id: '2', value: 'From'), 12 | Item(id: '3', value: 'Mock'), 13 | Item(id: '4', value: 'Repository'), 14 | ]); 15 | } 16 | 17 | @override 18 | Future deleteItem(String id) { 19 | return Future.value(null); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /samples_patterns/lib/platform_route.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | 5 | Route platformRoute( 6 | BuildContext context, { 7 | required WidgetBuilder builder, 8 | required RouteSettings settings, 9 | bool fullscreenDialog = false, 10 | }) { 11 | if (Theme.of(context).platform == TargetPlatform.iOS) { 12 | return CupertinoPageRoute( 13 | builder: builder, 14 | settings: settings, 15 | fullscreenDialog: fullscreenDialog, 16 | ); 17 | } else { 18 | return MaterialPageRoute( 19 | builder: builder, 20 | settings: settings, 21 | fullscreenDialog: fullscreenDialog, 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples_easy_localization/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FlutterMacOS (1.0.0) 3 | - shared_preferences_macos (0.0.1): 4 | - FlutterMacOS 5 | 6 | DEPENDENCIES: 7 | - FlutterMacOS (from `Flutter/ephemeral`) 8 | - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) 9 | 10 | EXTERNAL SOURCES: 11 | FlutterMacOS: 12 | :path: Flutter/ephemeral 13 | shared_preferences_macos: 14 | :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos 15 | 16 | SPEC CHECKSUMS: 17 | FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 18 | shared_preferences_macos: 480ce071d0666e37cef23fe6c702293a3d21799e 19 | 20 | PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c 21 | 22 | COCOAPODS: 1.10.0 23 | -------------------------------------------------------------------------------- /samples_patterns/stories/provider_screen_stories.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: non_constant_identifier_names 2 | import 'package:flutter/material.dart'; 3 | import 'package:monarch_samples_patterns/provider/current_date.dart'; 4 | import 'package:monarch_samples_patterns/provider/provider_screen.dart'; 5 | import 'package:provider/provider.dart'; 6 | 7 | Widget past_date() => Provider.value( 8 | value: CurrentDate( 9 | currentDateFn: () => 'Jan 1, 1970', 10 | ), 11 | child: ProviderScreen()); 12 | 13 | Widget current_date_different_format() => Provider.value( 14 | value: CurrentDate( 15 | currentDateFn: () => DateTime.now().toString(), 16 | ), 17 | child: ProviderScreen()); 18 | 19 | Widget future_date() => Provider.value( 20 | value: CurrentDate( 21 | currentDateFn: () => 'Jan 1, 2030', 22 | ), 23 | child: ProviderScreen()); 24 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples_patterns/README.md: -------------------------------------------------------------------------------- 1 | # monarch_samples_patterns 2 | 3 | Monarch sample code and stories using several patterns. 4 | 5 | _Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs. Find out more at https://monarchapp.io_ 6 | 7 | This project provides examples of using Monarch with the following patterns: 8 | - bloc 9 | - cubit 10 | - lists 11 | - internationalization 12 | - provider 13 | - change notifier 14 | - themes 15 | - dialogs, alerts, banners 16 | - widget tests 17 | - animations 18 | - navigation 19 | - images 20 | 21 | ## Running the sample stories 22 | 23 | 1. Make sure you already have Monarch [installed](https://monarchapp.io/docs/install). 24 | 2. `flutter pub get` 25 | 3. `monarch run` 26 | 27 | ## Running the sample tests 28 | The sample code for how to call stories from tests is under the test directory. 29 | To run the tests use `flutter test` or run it directly from your IDE. -------------------------------------------------------------------------------- /samples_patterns/lib/bloc/list_complex/repository.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:math'; 3 | 4 | import 'item.dart'; 5 | 6 | abstract class Repository { 7 | Future> fetchItems(); 8 | 9 | Future deleteItem(String id); 10 | } 11 | 12 | class RepositoryImpl implements Repository { 13 | final _random = Random(); 14 | 15 | int _randomRange(int min, int max) => min + _random.nextInt(max - min); 16 | 17 | @override 18 | Future> fetchItems() async { 19 | await Future.delayed(Duration(seconds: _randomRange(1, 5))); 20 | return List.of(_generateItemsList(10)); 21 | } 22 | 23 | List _generateItemsList(int length) { 24 | return List.generate( 25 | length, 26 | (index) => Item(id: '$index', value: 'Item $index'), 27 | ); 28 | } 29 | 30 | @override 31 | Future deleteItem(String id) async { 32 | await Future.delayed(Duration(seconds: _randomRange(1, 5))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /samples_patterns/stories/animations_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:monarch_samples_patterns/animations/flutter/resizable_box.dart'; 3 | import 'package:monarch_samples_patterns/animations/flutter/progress_button.dart'; 4 | import 'package:monarch_samples_patterns/animations/flutter/collapsable_box.dart'; 5 | import 'package:monarch_samples_patterns/animations/lottie/lottie_animated_widget.dart'; 6 | 7 | Widget lottie_animated_widget() => LottieAnimatedWidget(); 8 | 9 | Widget implicit_animation_example() => ResizableBox(); 10 | 11 | Widget explicit_animation_example() => CollapsableBox(); 12 | 13 | Widget progress_button_default() => ProgressButton( 14 | 'Sign up', 15 | onPressed: () {}, 16 | ); 17 | 18 | Widget progress_button_disabled() => ProgressButton( 19 | 'Sign up', 20 | onPressed: null, 21 | ); 22 | 23 | Widget progress_button_spinning() => ProgressButton( 24 | 'Loading', 25 | loading: true, 26 | onPressed: () {}, 27 | ); 28 | -------------------------------------------------------------------------------- /samples_booking/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2021 Dropsource 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /samples_booking/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | .monarch/ 49 | 50 | # Platform folders ignored on sample project 51 | /android/* 52 | /ios/* 53 | /macos/* 54 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | .monarch/ 49 | 50 | # Platform folders ignored on sample project 51 | /android/* 52 | /ios/* 53 | /macos/* 54 | /web/* 55 | -------------------------------------------------------------------------------- /samples_patterns/stories/navigation_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:monarch_samples_patterns/navigation/named_routes.dart'; 4 | import 'package:monarch_samples_patterns/navigation/simple_navigation.dart'; 5 | 6 | Widget simple_navigation() => Navigator( 7 | onGenerateRoute: (RouteSettings settings) => 8 | MaterialPageRoute(builder: (_) => FirstRoute(), settings: settings)); 9 | 10 | Widget named_routes() => Navigator( 11 | initialRoute: '/', 12 | onGenerateRoute: (RouteSettings settings) { 13 | WidgetBuilder builder; 14 | switch (settings.name) { 15 | case '/': 16 | builder = (BuildContext context) => const FirstScreen(); 17 | break; 18 | case '/second': 19 | builder = (BuildContext context) => const SecondScreen(); 20 | break; 21 | default: 22 | throw Exception('Unexpected route: ${settings.name}'); 23 | } 24 | return MaterialPageRoute(builder: builder, settings: settings); 25 | }); 26 | -------------------------------------------------------------------------------- /samples_easy_localization/README.md: -------------------------------------------------------------------------------- 1 | # monarch_easy_localization_sample 2 | 3 | Monarch sample code and stories using the [easy_localization](https://github.com/aissat/easy_localization) package. 4 | 5 | _Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs. Find out more at https://monarchapp.io_ 6 | 7 | To use easy_localization with Monarch you have to define your own `LocalizationsDelegate`. You can then annotate an instance of that delegate with the `MonarchLocalizations` annotation. 8 | 9 | You can see the sample implementation in [lib/easy_localizations_delegate.dart](lib/easy_localizations_delegate.dart). 10 | 11 | This `LocalizationsDelegate` definition is only for Monarch. Your easy_localization app won't need it. 12 | 13 | To run the easy_localization sample stories: 14 | ``` 15 | `monarch run` 16 | ``` 17 | 18 | To run the easy_localization demo app: 19 | ``` 20 | flutter run 21 | ``` 22 | 23 | If you need more details, here are the [Monarch internationalization docs](https://monarchapp.io/docs/internationalization). -------------------------------------------------------------------------------- /samples_patterns/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | .monarch/ 49 | 50 | # Platform folders ignored on sample project 51 | /android/* 52 | /ios/* 53 | /macos/* 54 | /web/* 55 | -------------------------------------------------------------------------------- /samples_easy_localization/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | # Monarch related 49 | .monarch/ 50 | 51 | # Platform folders ignored on sample project 52 | /android/* 53 | /ios/* 54 | /macos/* 55 | -------------------------------------------------------------------------------- /samples_patterns/lib/dialogs/scaffold_messenger.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Flutter code sample for [ScaffoldMessenger]. 4 | 5 | class ScaffoldMessengerExampleApp extends StatelessWidget { 6 | const ScaffoldMessengerExampleApp({super.key}); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | home: Scaffold( 12 | appBar: AppBar(title: const Text('ScaffoldMessenger Sample')), 13 | body: const Center( 14 | child: ScaffoldMessengerExample(), 15 | ), 16 | ), 17 | ); 18 | } 19 | } 20 | 21 | class ScaffoldMessengerExample extends StatelessWidget { 22 | const ScaffoldMessengerExample({super.key}); 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return OutlinedButton( 27 | onPressed: () { 28 | ScaffoldMessenger.of(context).showSnackBar( 29 | const SnackBar( 30 | content: Text('A SnackBar has been shown.'), 31 | ), 32 | ); 33 | }, 34 | child: const Text('Show SnackBar'), 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples_riverpod/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | # Monarch related 49 | .monarch/ 50 | 51 | # Platform folders ignored on sample project 52 | /android/* 53 | /ios/* 54 | /macos/* 55 | /web/* 56 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /samples_patterns/lib/navigation/simple_navigation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FirstRoute extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Scaffold( 7 | appBar: AppBar( 8 | title: Text('First Route'), 9 | ), 10 | body: Center( 11 | child: ElevatedButton( 12 | onPressed: () { 13 | Navigator.push( 14 | context, 15 | MaterialPageRoute(builder: (context) => SecondRoute()), 16 | ); 17 | }, 18 | child: Text('Open route'), 19 | ), 20 | ), 21 | ); 22 | } 23 | } 24 | 25 | class SecondRoute extends StatelessWidget { 26 | @override 27 | Widget build(BuildContext context) { 28 | return Scaffold( 29 | appBar: AppBar( 30 | title: Text('Second Route'), 31 | ), 32 | body: Center( 33 | child: ElevatedButton( 34 | onPressed: () { 35 | Navigator.pop(context); 36 | }, 37 | child: Text('Go back!'), 38 | ), 39 | ), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /samples_patterns/lib/bloc/list_complex/list_cubit.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:bloc/bloc.dart'; 3 | 4 | import 'list_state.dart'; 5 | import 'repository.dart'; 6 | 7 | class ListCubit extends Cubit { 8 | ListCubit( 9 | {required this.repository, 10 | ListState defaultState = const ListState.loading()}) 11 | : super(defaultState); 12 | 13 | final Repository repository; 14 | 15 | Future fetchList() async { 16 | try { 17 | final items = await repository.fetchItems(); 18 | emit(ListState.success(items)); 19 | } on Exception { 20 | emit(const ListState.failure()); 21 | } 22 | } 23 | 24 | Future deleteItem(String id) async { 25 | final deleteInProgress = state.items.map((item) { 26 | return item.id == id ? item.copyWith(isDeleting: true) : item; 27 | }).toList(); 28 | 29 | emit(ListState.success(deleteInProgress)); 30 | 31 | unawaited(repository.deleteItem(id).then((_) { 32 | final deleteSuccess = List.of(state.items) 33 | ..removeWhere((element) => element.id == id); 34 | emit(ListState.success(deleteSuccess)); 35 | })); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples_intl_tools/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | # Monarch related 49 | .monarch/ 50 | 51 | # Platform folders ignored on sample project 52 | /android/* 53 | /ios/* 54 | /macos/* 55 | /web/* 56 | 57 | # Include .dart_tool/flutter_gen in repo 58 | .dart_tool/* 59 | !.dart_tool/flutter_gen/ -------------------------------------------------------------------------------- /samples_patterns/lib/provider/provider_example_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | import '../content_list/content_list_screen.dart'; 4 | import 'provider_screen.dart'; 5 | import '../platform_route.dart'; 6 | import 'change_notifier_screen.dart'; 7 | 8 | class ProviderExampleListScreen extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return ContentListScreen( 12 | title: 'Provider examples', 13 | categories: [ 14 | Category( 15 | label: 'Using Provider', 16 | onClick: () { 17 | Navigator.of(context).push(ProviderScreen.route(context)); 18 | }), 19 | Category( 20 | label: 'Using Change Notifier Provider', 21 | onClick: () { 22 | Navigator.of(context).push(ChangeNotifierScreen.route(context)); 23 | }) 24 | ], 25 | ); 26 | } 27 | 28 | static String tag = 'provider-example-list-screen'; 29 | 30 | static Route route(BuildContext context) => platformRoute( 31 | context, 32 | builder: (_) => ProviderExampleListScreen(), 33 | settings: RouteSettings(name: tag), 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /samples_patterns/lib/bloc/bloc_example_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:monarch_samples_patterns/bloc/list_complex/list_complex_screen.dart'; 3 | import 'package:monarch_samples_patterns/content_list/content_list_screen.dart'; 4 | 5 | import '../platform_route.dart'; 6 | import 'bloc_counter/bloc_counter_screen.dart'; 7 | 8 | class BlocExampleListScreen extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return ContentListScreen( 12 | title: 'Bloc examples', 13 | categories: [ 14 | Category( 15 | label: 'Bloc Counter', 16 | onClick: () { 17 | Navigator.of(context).push(BlocCounterScreen.route(context)); 18 | }), 19 | Category( 20 | label: 'Bloc Complex List', 21 | onClick: () { 22 | Navigator.of(context).push(ListComplexScreen.route(context)); 23 | }), 24 | ], 25 | ); 26 | } 27 | 28 | static String tag = 'bloc-complex-list-screen'; 29 | 30 | static Route route(BuildContext context) => platformRoute( 31 | context, 32 | builder: (_) => BlocExampleListScreen(), 33 | settings: RouteSettings(name: tag), 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /samples_easy_localization/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:easy_localization/easy_localization.dart'; 3 | 4 | import 'localized_widgets.dart'; 5 | 6 | void main() async { 7 | WidgetsFlutterBinding.ensureInitialized(); 8 | await EasyLocalization.ensureInitialized(); 9 | runApp( 10 | EasyLocalization( 11 | supportedLocales: [Locale('en', 'US'), Locale('es')], 12 | path: 'assets/translations', 13 | fallbackLocale: Locale('es'), 14 | startLocale: Locale('es'), 15 | // startLocale: Locale('en','US'), 16 | child: SampleApp()), 17 | ); 18 | } 19 | 20 | class SampleApp extends StatelessWidget { 21 | @override 22 | Widget build(BuildContext context) { 23 | return MaterialApp( 24 | localizationsDelegates: context.localizationDelegates, 25 | supportedLocales: context.supportedLocales, 26 | locale: Locale('es'), 27 | home: SamplePage(), 28 | ); 29 | } 30 | } 31 | 32 | class SamplePage extends StatelessWidget { 33 | @override 34 | Widget build(BuildContext context) { 35 | return Scaffold( 36 | appBar: AppBar( 37 | title: LocalizedTitle(), 38 | ), 39 | body: Center( 40 | child: LocalizedQuestion(), 41 | ), 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples_patterns/lib/themes/custom_theme.dart: -------------------------------------------------------------------------------- 1 | /// Monarch Themes Documentation: 2 | /// https://monarchapp.io/docs/themes 3 | 4 | import 'package:flutter/material.dart'; 5 | import 'package:monarch_annotations/monarch_annotations.dart'; 6 | 7 | @MonarchTheme('Monarch Theme') 8 | ThemeData get monarchTheme => ThemeData.dark().copyWith( 9 | primaryColor: monarchPrimaryColor, 10 | colorScheme: 11 | ThemeData.dark().colorScheme.copyWith(secondary: monarchAccentColor), 12 | scaffoldBackgroundColor: monarchBackgroundColor, 13 | textTheme: TextTheme( 14 | headline5: TextStyle( 15 | color: monarchPrimaryColor, 16 | fontSize: 34.0, 17 | fontWeight: FontWeight.w600), 18 | headline6: TextStyle( 19 | color: monarchPrimaryColor, 20 | fontSize: 26, 21 | fontWeight: FontWeight.w600), 22 | bodyText1: TextStyle( 23 | color: monarchTextColor, fontSize: 20, fontWeight: FontWeight.w600), 24 | bodyText2: TextStyle( 25 | color: monarchTextColor, 26 | fontSize: 14, 27 | fontWeight: FontWeight.w500))); 28 | 29 | const monarchPrimaryColor = Color(0xff00b3b8); 30 | const monarchAccentColor = Color(0xff00c5ca); 31 | const monarchBackgroundColor = Color(0xff2c2c32); 32 | const monarchTextColor = Color(0xfff5f6f7); 33 | -------------------------------------------------------------------------------- /samples_booking/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: monarch_samples_booking 2 | description: Monarch sample code and stories using a pretty booking theme 3 | publish_to: 'none' 4 | 5 | version: 2.0.0 6 | 7 | environment: 8 | sdk: ^3.7.0 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | cupertino_icons: ^1.0.2 14 | font_awesome_flutter: ^10.4.0 15 | flutter_rating_bar: ^4.0.0 16 | intl: ^0.19.0 17 | animations: ^2.0.0 18 | monarch_annotations: ^1.0.0 19 | 20 | dev_dependencies: 21 | monarch: ^3.0.0 22 | build_runner: ^2.1.11 23 | flutter_lints: ^5.0.0 24 | 25 | flutter: 26 | uses-material-design: true 27 | 28 | assets: 29 | - locale/i18n_en.json 30 | - locale/i18n_es.json 31 | - assets/hotel/ 32 | 33 | fonts: 34 | - family: WorkSans 35 | fonts: 36 | - asset: assets/fonts/WorkSans-Regular.ttf 37 | - asset: assets/fonts/WorkSans-Medium.ttf 38 | weight: 500 39 | - asset: assets/fonts/WorkSans-SemiBold.ttf 40 | weight: 600 41 | - asset: assets/fonts/WorkSans-Bold.ttf 42 | weight: 700 43 | - family: Roboto 44 | fonts: 45 | - asset: assets/fonts/Roboto-Bold.ttf 46 | - asset: assets/fonts/Roboto-Regular.ttf 47 | - asset: assets/fonts/Roboto-Medium.ttf 48 | weight: 400 -------------------------------------------------------------------------------- /samples_intl_tools/README.md: -------------------------------------------------------------------------------- 1 | # monarch_samples_intl_tools 2 | 3 | Monarch sample code and stories using [intl](https://github.com/dart-lang/intl) 4 | package and tools. 5 | 6 | _Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs. Find out more at https://monarchapp.io_ 7 | 8 | To use intl tools with Monarch you have to annotate the generated `LocalizationsDelegate` 9 | with the `MonarchLocalizations` annotation. To annotate it, you will have to 10 | create a new dart library in your lib directory, then import the generated 11 | source file so you can annotate an instance of your `LocalizationsDelegate`. 12 | 13 | You can see the sample implementation in 14 | [lib/intl_localizations_delegate.dart](lib/intl_localizations_delegate.dart) 15 | 16 | This `LocalizationsDelegate` definition is only for Monarch. Your intl app 17 | won't need it. 18 | 19 | To run the intl sample stories: 20 | 1. `flutter pub get` 21 | 2. Run the intl code generation: `flutter pub run build_runner build` 22 | 3. Run monarch: `monarch run` 23 | 4. Once the Monarch UI launches, select a story, then change the locale 24 | using the Locale dropdown, see how the story changes based on the locale 25 | selected. 26 | 27 | If you need more details, here are the [Monarch internationalization docs](https://monarchapp.io/docs/internationalization). 28 | -------------------------------------------------------------------------------- /samples_booking/stories/booking_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:monarch_samples_booking/booking/booking_home_screen.dart'; 2 | import 'package:monarch_samples_booking/booking/booking_list.dart'; 3 | import 'package:monarch_samples_booking/booking/calendar_popup.dart'; 4 | import 'package:monarch_samples_booking/booking/filters_screen.dart'; 5 | import 'package:monarch_samples_booking/booking/model/booking_list_data.dart'; 6 | import 'package:flutter/material.dart'; 7 | 8 | Widget app_bar() => Column(children: const [BookingAppBar()]); 9 | Widget search_bar() => Column(children: const [BookingSearchBar()]); 10 | Widget search_and_choose() => Column(children: [ 11 | BookingSearchBar(), 12 | BookingChooseSection( 13 | startDate: DateTime.now(), 14 | endDate: DateTime.now().add(const Duration(days: 3)), 15 | ) 16 | ]); 17 | Widget filter_bar() => Column(children: const [BookingFilterBar()]); 18 | 19 | Widget listing() => BookingListAnimated(list: [BookingListData.listings[0]]); 20 | Widget listings() => BookingListAnimated(list: BookingListData.listings); 21 | 22 | Widget calendar() => CalendarPopUp( 23 | barrierDismissible: true, 24 | minimumDate: DateTime.now(), 25 | initialStartDate: DateTime.now(), 26 | initialEndDate: DateTime.now().add(const Duration(days: 5)), 27 | ); 28 | 29 | Widget filters() => FiltersScreen(); 30 | 31 | Widget screen() => BookingHomeScreen(); 32 | -------------------------------------------------------------------------------- /samples_patterns/lib/navigation/named_routes.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FirstScreen extends StatelessWidget { 4 | const FirstScreen({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Scaffold( 9 | appBar: AppBar( 10 | title: const Text('First Screen'), 11 | ), 12 | body: Center( 13 | child: ElevatedButton( 14 | // Within the `FirstScreen` widget 15 | onPressed: () { 16 | // Navigate to the second screen using a named route. 17 | Navigator.pushNamed(context, '/second'); 18 | }, 19 | child: const Text('Launch screen'), 20 | ), 21 | ), 22 | ); 23 | } 24 | } 25 | 26 | class SecondScreen extends StatelessWidget { 27 | const SecondScreen({Key? key}) : super(key: key); 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return Scaffold( 32 | appBar: AppBar( 33 | title: const Text('Second Screen'), 34 | ), 35 | body: Center( 36 | child: ElevatedButton( 37 | // Within the SecondScreen widget 38 | onPressed: () { 39 | // Navigate back to the first screen by popping the current route 40 | // off the stack. 41 | Navigator.pop(context); 42 | }, 43 | child: const Text('Go back!'), 44 | ), 45 | ), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /samples_patterns/lib/text_fields/obscurable_text_field.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'single_value_text_field.dart'; 5 | 6 | class ObscurableTextfield extends StatefulWidget { 7 | final String? value; 8 | final bool obscureText; 9 | 10 | ObscurableTextfield({Key? key, this.value, this.obscureText = true}) 11 | : super(key: key); 12 | 13 | @override 14 | State createState() => _ObscurableTextFieldState(); 15 | } 16 | 17 | class _ObscurableTextFieldState extends State { 18 | late bool _obscureText; 19 | 20 | @override 21 | void initState() { 22 | super.initState(); 23 | _obscureText = widget.obscureText; 24 | } 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return Padding( 29 | padding: EdgeInsets.all(15), 30 | child: SingleValueTextfield( 31 | key: widget.key, 32 | value: widget.value, 33 | obscureText: _obscureText, 34 | suffixIcon: _buildToggleableIconButton(context), 35 | )); 36 | } 37 | 38 | Widget _buildToggleableIconButton(BuildContext context) => IconButton( 39 | icon: Icon( 40 | _obscureText ? Icons.remove_red_eye_outlined : Icons.remove_red_eye, 41 | color: Theme.of(context).colorScheme.secondary, 42 | ), 43 | onPressed: () => setState(() => _obscureText = !_obscureText), 44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /samples_patterns/lib/animations/flutter/resizable_box.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:monarch_samples_patterns/themes/custom_theme.dart'; 3 | 4 | class ResizableBox extends StatefulWidget { 5 | @override 6 | State createState() => _ResizableBoxState(); 7 | } 8 | 9 | class _ResizableBoxState extends State { 10 | var _bigger = false; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return Column( 15 | mainAxisAlignment: MainAxisAlignment.start, 16 | mainAxisSize: MainAxisSize.min, 17 | children: [ 18 | AnimatedContainer( 19 | width: _bigger ? 500 : 100, 20 | duration: Duration(milliseconds: 200), 21 | curve: Curves.easeInOutQuint, 22 | decoration: BoxDecoration( 23 | gradient: RadialGradient( 24 | colors: [monarchPrimaryColor, Colors.transparent], 25 | stops: [0, _bigger ? 1.0 : 0])), 26 | child: Padding( 27 | padding: const EdgeInsets.all(8.0), 28 | child: Image.asset('assets/monarch_m.png'), 29 | ), 30 | ), 31 | TextButton( 32 | onPressed: () => setState(() { 33 | _bigger = !_bigger; 34 | }), 35 | child: Text( 36 | 'Resize me!', 37 | style: TextStyle(color: monarchAccentColor), 38 | ), 39 | ), 40 | ], 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /samples_patterns/lib/animations/flutter/progress_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ProgressButton extends TextButton { 4 | ProgressButton( 5 | String text, { 6 | onPressed, 7 | Color? color, 8 | Key? key, 9 | Color? progressColor, 10 | double textSize = 16, 11 | bool loading = false, 12 | }) : super( 13 | key: key, 14 | onPressed: loading ? null : onPressed, 15 | style: TextButton.styleFrom( 16 | primary: Colors.white, 17 | backgroundColor: Colors.teal, 18 | shape: const RoundedRectangleBorder( 19 | borderRadius: BorderRadius.all(Radius.circular(5))), 20 | ), 21 | child: loading 22 | ? Padding( 23 | padding: const EdgeInsets.all(0.0), 24 | child: SizedBox( 25 | width: 16, 26 | height: 16, 27 | child: CircularProgressIndicator( 28 | valueColor: 29 | AlwaysStoppedAnimation(Colors.white)), 30 | )) 31 | : Text( 32 | text, 33 | maxLines: 1, 34 | overflow: TextOverflow.ellipsis, 35 | style: TextStyle( 36 | fontSize: textSize, 37 | fontWeight: FontWeight.normal, 38 | ), 39 | ), 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /samples_patterns/lib/provider/shopping_cart_change_notifier.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'package:intl/intl.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | 5 | class ShoppingCartChangeNotifier extends ChangeNotifier { 6 | final List _products; 7 | 8 | ShoppingCartChangeNotifier({required List products}) 9 | : _products = products; 10 | 11 | factory ShoppingCartChangeNotifier.empty() { 12 | return ShoppingCartChangeNotifier(products: []); 13 | } 14 | 15 | factory ShoppingCartChangeNotifier.prefilled(List products) { 16 | return ShoppingCartChangeNotifier(products: products); 17 | } 18 | 19 | UnmodifiableListView get items => UnmodifiableListView(_products); 20 | 21 | String get totalPrice => items 22 | .fold(0.0, (double sum, product) => sum + product.price) 23 | .formattedPrice; 24 | 25 | void add(Product product) { 26 | _products.add(product); 27 | notifyListeners(); 28 | } 29 | 30 | void remove(Product product) { 31 | _products.add(product); 32 | notifyListeners(); 33 | } 34 | } 35 | 36 | class Product { 37 | final String name; 38 | final double price; 39 | 40 | Product({required this.name, required this.price}); 41 | 42 | String get formattedPrice => price.formattedPrice; 43 | } 44 | 45 | final formatCurrency = NumberFormat.simpleCurrency(); 46 | 47 | extension StringUtils on double { 48 | String get formattedPrice => formatCurrency.format(this); 49 | } 50 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /samples_booking/lib/booking/model/popular_filter_list.dart: -------------------------------------------------------------------------------- 1 | class PopularFilterListData { 2 | PopularFilterListData({ 3 | this.titleTxt = '', 4 | this.isSelected = false, 5 | }); 6 | 7 | String titleTxt; 8 | bool isSelected; 9 | 10 | static List popularFList = [ 11 | PopularFilterListData( 12 | titleTxt: 'free-breakfast', 13 | isSelected: true, 14 | ), 15 | PopularFilterListData( 16 | titleTxt: 'free-parking', 17 | isSelected: false, 18 | ), 19 | PopularFilterListData( 20 | titleTxt: 'free-wi-fi', 21 | isSelected: true, 22 | ), 23 | PopularFilterListData( 24 | titleTxt: 'pool', 25 | isSelected: true, 26 | ), 27 | PopularFilterListData( 28 | titleTxt: 'pet-friendly', 29 | isSelected: false, 30 | ), 31 | ]; 32 | 33 | static List accomodationList = [ 34 | PopularFilterListData( 35 | titleTxt: 'all', 36 | isSelected: false, 37 | ), 38 | PopularFilterListData( 39 | titleTxt: 'apartment', 40 | isSelected: true, 41 | ), 42 | PopularFilterListData( 43 | titleTxt: 'home', 44 | isSelected: true, 45 | ), 46 | PopularFilterListData( 47 | titleTxt: 'hotel', 48 | isSelected: false, 49 | ), 50 | PopularFilterListData( 51 | titleTxt: 'resort', 52 | isSelected: false, 53 | ), 54 | PopularFilterListData( 55 | titleTxt: 'villa', 56 | isSelected: false, 57 | ), 58 | ]; 59 | } 60 | -------------------------------------------------------------------------------- /samples_patterns/lib/internationalization/localized_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../platform_route.dart'; 5 | import 'localizations.dart'; 6 | 7 | class LocalizedScreen extends StatelessWidget { 8 | static String tag = 'localized-screen'; 9 | 10 | static Route route(BuildContext context) => platformRoute( 11 | context, 12 | builder: (_) => LocalizedScreen(), 13 | settings: RouteSettings(name: tag), 14 | ); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | final localizations = SampleLocalizations.of(context)!; 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text(localizations.text('sample.title')), 22 | ), 23 | body: Container( 24 | padding: EdgeInsets.all(16), 25 | child: Column( 26 | mainAxisSize: MainAxisSize.min, 27 | crossAxisAlignment: CrossAxisAlignment.start, 28 | children: [ 29 | Text(localizations.text('sample.headline')), 30 | Text(localizations.text('sample.subheader')), 31 | SizedBox( 32 | height: 16, 33 | ), 34 | Text(localizations.text('sample.content')), 35 | ] 36 | .map((widget) => Padding( 37 | padding: EdgeInsets.all(8), 38 | child: widget, 39 | )) 40 | .toList(), 41 | ), 42 | )); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples_patterns/stories/main_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | import 'package:intl/intl.dart'; 5 | import 'package:monarch_samples_patterns/bloc/list_complex/list_cubit.dart'; 6 | import 'package:monarch_samples_patterns/bloc/list_complex/repository.dart'; 7 | import 'package:monarch_samples_patterns/main.dart'; 8 | import 'package:monarch_samples_patterns/provider/current_date.dart'; 9 | import 'package:monarch_samples_patterns/provider/shopping_cart_change_notifier.dart'; 10 | import 'package:provider/provider.dart'; 11 | 12 | Widget main_multi_providers_navigation() => MultiProvider( 13 | providers: [ 14 | Provider( 15 | create: (_) => CurrentDate( 16 | currentDateFn: () => 17 | DateFormat.yMMMEd().format(DateTime.now())), 18 | ), 19 | ChangeNotifierProvider( 20 | create: (_) => ShoppingCartChangeNotifier.empty()) 21 | ], 22 | child: MultiBlocProvider( 23 | providers: [ 24 | BlocProvider( 25 | create: (_) => 26 | ListCubit(repository: RepositoryImpl())..fetchList(), 27 | ), 28 | ], 29 | child: Navigator( 30 | initialRoute: 'story_nav', 31 | onGenerateRoute: (RouteSettings settings) => MaterialPageRoute( 32 | builder: (_) => Main(), settings: settings)))); 33 | -------------------------------------------------------------------------------- /samples_riverpod/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /samples_intl_tools/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Monarch 4 | 5 |

6 | 7 | # Monarch Samples 8 | 9 | This repo is a curated collection of sample projects which show Monarch working with 10 | various packages, patterns and tools. 11 | 12 | _Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs. Find out more at https://monarchapp.io_ 13 | 14 | ### Sample projects 15 | 16 | - [samples_patterns](/samples_patterns) provides examples of using Monarch 17 | with the following patterns: 18 | - bloc 19 | - cubit 20 | - lists 21 | - internationalization 22 | - provider 23 | - change notifier 24 | - themes 25 | - dialogs, alerts, banners 26 | - widget tests 27 | - animations 28 | - navigation 29 | - images 30 | - [samples_booking](/samples_booking) uses a pretty booking theme. The [Monarch 31 | website](https://monarchapp.io/) showcases this project. 32 | - [samples_intl_tools](/samples_intl_tools) shows internationalization in Monarch 33 | using the [intl](https://github.com/dart-lang/intl) package and tools. 34 | - [samples_riverpod](/samples_riverpod) uses Monarch with the state-management library 35 | [Riverpod](https://riverpod.dev/). 36 | - [samples_easy_localization](/samples_easy_localization) shows internationalization 37 | in Monarch using the [easy_localization](https://github.com/aissat/easy_localization) package. 38 | -------------------------------------------------------------------------------- /test/samples_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:test/test.dart'; 2 | import 'test_utils.dart'; 3 | 4 | void main() async { 5 | testSampleProject('samples_booking'); 6 | testSampleProject('samples_easy_localization'); 7 | testSampleProject('samples_intl_tools'); 8 | testSampleProject('samples_patterns'); 9 | testSampleProject('samples_riverpod'); 10 | } 11 | 12 | void testSampleProject(String projectName) { 13 | group(projectName, () { 14 | setUp(() async { 15 | var result = await runFlutterPubGet(projectName); 16 | expect(result.exitCode, 0); 17 | }); 18 | 19 | test('can run monarch', () async { 20 | await runMonarchAndVerify(projectName); 21 | }); 22 | 23 | tearDown(() async { 24 | await killMonarch(projectName); 25 | }); 26 | }); 27 | } 28 | 29 | Future runMonarchAndVerify(String projectName) async { 30 | var monarchRun = await startTestProcess(monarch_exe, ['run', '-v'], 31 | workingDirectory: getWorkingDirectory('samples_booking')); 32 | var stdout_ = monarchRun.stdout; 33 | await expectLater(stdout_, emitsThrough('Starting Monarch.')); 34 | await expectLater(stdout_, emitsThrough('Preparing stories...')); 35 | await expectLater(stdout_, emitsThrough('Launching Monarch app...')); 36 | await expectLater(stdout_, emitsThrough('Attaching to stories...')); 37 | await expectLater(stdout_, emitsThrough('Setting up stories watch...')); 38 | await expectLater(stdout_, emitsThrough('Monarch key commands:')); 39 | await expectLater(stdout_, emitsThrough(startsWith('Monarch is ready.'))); 40 | monarchRun.kill(); 41 | await monarchRun.shouldExit(); 42 | } 43 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples_easy_localization/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | easy_localization_sample 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | easy_localization_sample 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /samples_booking/lib/booking/model/booking_list_data.dart: -------------------------------------------------------------------------------- 1 | class BookingListData { 2 | BookingListData({ 3 | this.imagePath = '', 4 | this.titleTxt = '', 5 | this.subTxt = "", 6 | this.dist = 1.8, 7 | this.reviews = 80, 8 | this.rating = 4.5, 9 | this.perNight = 180, 10 | }); 11 | 12 | String imagePath; 13 | String titleTxt; 14 | String subTxt; 15 | double dist; 16 | double rating; 17 | int reviews; 18 | int perNight; 19 | 20 | static List listings = [ 21 | BookingListData( 22 | imagePath: 'assets/hotel/hotel_1.png', 23 | titleTxt: 'Grand Royal Hotel', 24 | subTxt: 'Wembley, London', 25 | dist: 2.0, 26 | reviews: 80, 27 | rating: 4.4, 28 | perNight: 180, 29 | ), 30 | BookingListData( 31 | imagePath: 'assets/hotel/hotel_2.png', 32 | titleTxt: 'Queen Hotel', 33 | subTxt: 'Wembley, London', 34 | dist: 4.0, 35 | reviews: 74, 36 | rating: 4.5, 37 | perNight: 200, 38 | ), 39 | BookingListData( 40 | imagePath: 'assets/hotel/hotel_3.png', 41 | titleTxt: 'Grand Royal Hotel', 42 | subTxt: 'Wembley, London', 43 | dist: 3.0, 44 | reviews: 62, 45 | rating: 4.0, 46 | perNight: 60, 47 | ), 48 | BookingListData( 49 | imagePath: 'assets/hotel/hotel_4.png', 50 | titleTxt: 'Queen Hotel', 51 | subTxt: 'Wembley, London', 52 | dist: 7.0, 53 | reviews: 90, 54 | rating: 4.4, 55 | perNight: 170, 56 | ), 57 | BookingListData( 58 | imagePath: 'assets/hotel/hotel_5.png', 59 | titleTxt: 'Grand Royal Hotel', 60 | subTxt: 'Wembley, London', 61 | dist: 2.0, 62 | reviews: 240, 63 | rating: 4.5, 64 | perNight: 200, 65 | ), 66 | ]; 67 | } 68 | -------------------------------------------------------------------------------- /samples_patterns/lib/provider/provider_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | 5 | import 'current_date.dart'; 6 | import '../platform_route.dart'; 7 | 8 | class ProviderScreen extends StatelessWidget { 9 | static String tag = 'read-from-provider-screen'; 10 | 11 | static Route route(BuildContext context) => platformRoute( 12 | context, 13 | builder: (_) => ProviderScreen(), 14 | settings: RouteSettings(name: tag), 15 | ); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text('Using Provider'), 22 | ), 23 | body: Container( 24 | padding: EdgeInsets.all(16), 25 | child: Column( 26 | mainAxisSize: MainAxisSize.min, 27 | crossAxisAlignment: CrossAxisAlignment.start, 28 | children: [ 29 | Text('I got this value from Provider.of()'), 30 | Text('Today is ${_getDate(context)}'), 31 | SizedBox( 32 | height: 16, 33 | ), 34 | Text('I got this value using Consumer'), 35 | Consumer( 36 | builder: (context, model, child) => 37 | Text('Today is ${model.currentDateAsString()}'), 38 | ) 39 | ] 40 | .map((widget) => Padding( 41 | padding: EdgeInsets.all(8), 42 | child: widget, 43 | )) 44 | .toList(), 45 | ), 46 | )); 47 | } 48 | 49 | String? _getDate(BuildContext context) { 50 | return Provider.of(context, listen: false) 51 | .currentDateAsString(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /samples_easy_localization/lib/easy_localizations_delegate.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:monarch_annotations/monarch_annotations.dart'; 5 | import 'package:easy_localization/easy_localization.dart'; 6 | import 'package:easy_localization/src/localization.dart'; 7 | import 'package:easy_localization/src/translations.dart'; 8 | 9 | /// To use easy_localization with Monarch you have to define your own 10 | /// [LocalizationsDelegate]. In the [load] method you would then load your 11 | /// translations, and then use those translations to load the 12 | /// [Localization.instance] that easy_localization uses. 13 | class MyEasyLocalizationsDelegate extends LocalizationsDelegate { 14 | const MyEasyLocalizationsDelegate(); 15 | 16 | @override 17 | Future load(Locale locale) async { 18 | var assetLoader = const RootBundleAssetLoader(); 19 | // or use your own asset loader 20 | 21 | var data = await assetLoader.load('assets/translations', locale); 22 | var translations = Translations(data); 23 | 24 | Localization.load(locale, translations: translations); 25 | return Localization.instance; 26 | } 27 | 28 | @override 29 | bool shouldReload(covariant LocalizationsDelegate old) => true; 30 | 31 | @override 32 | bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode); 33 | } 34 | 35 | @MonarchLocalizations([MonarchLocale('en', 'US'), MonarchLocale('es')]) 36 | const myEasyLocalizationsDelegate = MyEasyLocalizationsDelegate(); 37 | 38 | /// Once you have your delegate, you can create an instance of it 39 | /// and annotate it with the `MonarchLocalizations` annotation. 40 | /// If you need more details, you can read the Monarch internationalization 41 | /// docs here: https://monarchapp.io/docs/internationalization 42 | -------------------------------------------------------------------------------- /samples_patterns/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: monarch_samples_patterns 2 | description: Monarch sample code and stories using several patterns 3 | 4 | publish_to: 'none' 5 | version: 1.1.0 6 | 7 | environment: 8 | sdk: '>=2.17.0 <4.0.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | flutter_localizations: 14 | sdk: flutter 15 | provider: ^6.0.1 16 | flutter_bloc: ^8.1.3 17 | bloc: ^8.1.2 18 | equatable: ^2.0.0 19 | 20 | cupertino_icons: ^1.0.2 21 | 22 | #animations 23 | lottie: ^2.3.2 24 | 25 | dev_dependencies: 26 | flutter_test: 27 | sdk: flutter 28 | lints: ^2.1.0 29 | monarch: ^3.0.0 30 | build_runner: ^2.1.11 31 | 32 | flutter: 33 | assets: 34 | - locale/i18n_en.json 35 | - locale/i18n_es.json 36 | - assets/ 37 | 38 | uses-material-design: true 39 | 40 | fonts: 41 | - family: OpenSans 42 | fonts: 43 | - asset: assets/google_fonts/OpenSans-Light.ttf 44 | weight: 300 45 | style: normal 46 | - asset: assets/google_fonts/OpenSans-LightItalic.ttf 47 | weight: 300 48 | style: italic 49 | - asset: assets/google_fonts/OpenSans-Regular.ttf 50 | weight: 400 51 | style: normal 52 | - asset: assets/google_fonts/OpenSans-RegularItalic.ttf 53 | weight: 400 54 | style: italic 55 | - asset: assets/google_fonts/OpenSans-SemiBold.ttf 56 | weight: 500 57 | style: normal 58 | - asset: assets/google_fonts/OpenSans-SemiBoldItalic.ttf 59 | weight: 500 60 | style: italic 61 | - asset: assets/google_fonts/OpenSans-Bold.ttf 62 | weight: 600 63 | - asset: assets/google_fonts/OpenSans-BoldItalic.ttf 64 | weight: 600 65 | style: italic 66 | - asset: assets/google_fonts/OpenSans-ExtraBold.ttf 67 | weight: 700 68 | - asset: assets/google_fonts/OpenSans-ExtraBoldItalic.ttf 69 | weight: 700 70 | style: italic 71 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 30 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 37 | applicationId "com.example.easy_localization_sample" 38 | minSdkVersion 16 39 | targetSdkVersion 30 40 | versionCode flutterVersionCode.toInteger() 41 | versionName flutterVersionName 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 59 | } 60 | -------------------------------------------------------------------------------- /samples_patterns/stories/provider_change_notifier_screen_stories.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: non_constant_identifier_names 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:monarch_samples_patterns/provider/change_notifier_screen.dart'; 4 | import 'package:monarch_samples_patterns/provider/shopping_cart_change_notifier.dart'; 5 | import 'package:provider/provider.dart'; 6 | 7 | Widget empty_cart() => ChangeNotifierProvider.value( 8 | value: ShoppingCartChangeNotifier.empty(), child: ChangeNotifierScreen()); 9 | 10 | Widget sample_cart() => ChangeNotifierProvider.value( 11 | value: ShoppingCartChangeNotifier.prefilled([ 12 | Product(name: 'Flutter by example - Ebook', price: 19.99), 13 | Product(name: 'Flutter in action - Ebook', price: 17.99), 14 | Product(name: 'Mastering Flutter - Ebook', price: 14.99), 15 | ]), 16 | child: ChangeNotifierScreen()); 17 | 18 | Widget really_long_product_names_cart() => ChangeNotifierProvider.value( 19 | value: ShoppingCartChangeNotifier.prefilled([ 20 | Product( 21 | name: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ', 22 | price: 19.99), 23 | Product( 24 | name: 25 | 'Ut a lorem ut dolor congue ornare sed non urna. Cras lectus ex, commodo sed ante sit amet, finibus feugiat orci.', 26 | price: 17.99), 27 | Product( 28 | name: 29 | 'Maecenas erat libero, sodales eu tortor quis, porttitor pellentesque ligula. Aliquam eu mi sapien. Proin egestas convallis accumsan.', 30 | price: 14.99), 31 | ]), 32 | child: ChangeNotifierScreen()); 33 | 34 | Widget expensive_ebooks_cart() => ChangeNotifierProvider.value( 35 | value: ShoppingCartChangeNotifier.prefilled([ 36 | Product(name: 'Flutter by example - Ebook', price: 119000.99), 37 | Product(name: 'Flutter in action - Ebook', price: 175000.99), 38 | Product(name: 'Mastering Flutter - Ebook', price: 999999999.99), 39 | ]), 40 | child: ChangeNotifierScreen()); 41 | -------------------------------------------------------------------------------- /samples_patterns/stories/provider_navigation_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'package:intl/intl.dart'; 5 | 6 | import 'package:monarch_samples_patterns/provider/current_date.dart'; 7 | import 'package:monarch_samples_patterns/provider/provider_example_list.dart'; 8 | import 'package:monarch_samples_patterns/provider/shopping_cart_change_notifier.dart'; 9 | import 'package:provider/provider.dart'; 10 | 11 | Widget today_empty_cart() => MultiProvider( 12 | providers: [ 13 | Provider( 14 | create: (_) => CurrentDate( 15 | currentDateFn: () => 16 | DateFormat.yMMMEd().format(DateTime.now())), 17 | ), 18 | ChangeNotifierProvider( 19 | create: (_) => ShoppingCartChangeNotifier.empty()) 20 | ], 21 | child: Navigator( 22 | initialRoute: 'story_nav', 23 | onGenerateRoute: (RouteSettings settings) => MaterialPageRoute( 24 | builder: (_) => ProviderExampleListScreen(), 25 | settings: settings))); 26 | 27 | Widget future_filled_cart() => MultiProvider( 28 | providers: [ 29 | Provider( 30 | create: (_) => CurrentDate(currentDateFn: () => 'Jan 1, 2030'), 31 | ), 32 | ChangeNotifierProvider( 33 | create: (_) => ShoppingCartChangeNotifier.prefilled([ 34 | Product(name: 'Flutter by example - Ebook', price: 19.99), 35 | Product(name: 'Flutter in action - Ebook', price: 17.99), 36 | Product(name: 'Mastering Flutter - Ebook', price: 14.99), 37 | ])) 38 | ], 39 | child: Navigator( 40 | initialRoute: 'story_nav', 41 | onGenerateRoute: (RouteSettings settings) => MaterialPageRoute( 42 | builder: (_) => ProviderExampleListScreen(), 43 | settings: settings))); 44 | -------------------------------------------------------------------------------- /samples_patterns/lib/provider/change_notifier_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | 5 | import '../provider/shopping_cart_change_notifier.dart'; 6 | import '../platform_route.dart'; 7 | 8 | class ChangeNotifierScreen extends StatelessWidget { 9 | static String tag = 'change-notification-screen'; 10 | 11 | static Route route(BuildContext context) => platformRoute( 12 | context, 13 | builder: (_) => ChangeNotifierScreen(), 14 | settings: RouteSettings(name: tag), 15 | ); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: Text('Using Change Notifier Provider'), 22 | ), 23 | body: Container( 24 | padding: EdgeInsets.all(16), 25 | child: Consumer( 26 | builder: (context, cart, _) => Column( 27 | mainAxisSize: MainAxisSize.min, 28 | crossAxisAlignment: CrossAxisAlignment.start, 29 | children: cart.items 30 | .map((product) => Padding( 31 | padding: const EdgeInsets.only(top: 8.0), 32 | child: Row( 33 | children: [ 34 | Expanded( 35 | child: Text(product.name), 36 | ), 37 | Text(product.formattedPrice) 38 | ], 39 | ), 40 | )) 41 | .cast() 42 | .toList() 43 | ..add(Padding( 44 | padding: const EdgeInsets.only(top: 16.0), 45 | child: Row( 46 | children: [ 47 | Expanded(child: Text('Total order value: ')), 48 | Text(cart.totalPrice) 49 | ], 50 | ), 51 | )))), 52 | )); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples_patterns/lib/themes/themed_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../platform_route.dart'; 5 | import 'custom_theme.dart'; 6 | 7 | class ThemedScreen extends StatelessWidget { 8 | static String tag = 'themed-screen'; 9 | 10 | static Route route(BuildContext context) => platformRoute( 11 | context, 12 | builder: (_) => ThemedScreen(), 13 | settings: RouteSettings(name: tag), 14 | ); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Scaffold( 19 | appBar: AppBar( 20 | title: Text( 21 | 'Themed screen', 22 | ), 23 | ), 24 | body: Container( 25 | padding: EdgeInsets.all(16), 26 | child: Column( 27 | mainAxisSize: MainAxisSize.min, 28 | crossAxisAlignment: CrossAxisAlignment.start, 29 | children: [ 30 | Text('This is headline 5', 31 | style: Theme.of(context).textTheme.headline5), 32 | Text('Here is headline 6', 33 | style: Theme.of(context).textTheme.headline6), 34 | SizedBox( 35 | height: 16, 36 | ), 37 | Text('This is text body 1', 38 | style: Theme.of(context).textTheme.bodyText1), 39 | Text('And this is text body 2', 40 | style: Theme.of(context).textTheme.bodyText2), 41 | ] 42 | .map((widget) => Padding( 43 | padding: EdgeInsets.all(8), 44 | child: widget, 45 | )) 46 | .toList(), 47 | ), 48 | )); 49 | } 50 | } 51 | 52 | class MonarchThemedScreen extends StatelessWidget { 53 | static String tag = 'monarch-themed-screen'; 54 | 55 | static Route route(BuildContext context) => platformRoute( 56 | context, 57 | builder: (_) => MonarchThemedScreen(), 58 | settings: RouteSettings(name: tag), 59 | ); 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | return Theme(data: monarchTheme, child: ThemedScreen()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /samples_patterns/stories/dialog_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:monarch_samples_patterns/dialogs/alert_dialog.dart'; 3 | import 'package:monarch_samples_patterns/dialogs/bottom_sheet.dart'; 4 | 5 | Widget show_bottom_sheet() => BottomSheetButton(); 6 | 7 | Widget show_modal_bottom_sheet() => ModalBottomSheetButton(); 8 | 9 | Widget scaffold_bottom_sheet() => ScaffoldBottomSheet(); 10 | 11 | Widget show_dialog() => Center( 12 | child: Builder( 13 | builder: (BuildContext context) => TextButton( 14 | onPressed: () => showDialog( 15 | context: context, builder: (_) => alert_dialog_one_button()), 16 | child: Text('Show Dialog'), 17 | ), 18 | )); 19 | 20 | Widget alert_dialog_one_button() => CustomAlertDialog( 21 | content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 22 | title: 'Integer a semper mauris.', 23 | // contentColor: Colors.black, 24 | button1OnPressed: () => {}, 25 | button1Text: 'Let\'s go!', 26 | buttonTextColor: Colors.green); 27 | 28 | Widget alert_dialog_two_buttons() => CustomAlertDialog( 29 | content: 30 | 'Mauris sem neque, lobortis eget faucibus non, semper ut mi. Quisque ' 31 | 'laoreet lacus nibh, sit amet commodo ipsum feugiat in. Pellentesque' 32 | ' id diam sed orci dapibus ornare vitae id diam. Nam sollicitudin ' 33 | 'consectetur nibh, eget cursus massa porta sed. Sed malesuada fringilla' 34 | ' massa, vitae tempus augue placerat nec. Mauris id velit blandit, ' 35 | 'ullamcorper ipsum id, molestie nisi. Suspendisse potenti. Vivamus ' 36 | 'ut diam in dui dictum maximus at et erat. Sed viverra erat sed ' 37 | 'sapien sollicitudin tincidunt. Morbi molestie erat faucibus dui ' 38 | 'suscipit finibus. Nullam ultrices, justo vitae malesuada tincidunt,' 39 | ' tellus orci dictum nisl, porta cursus lorem eros non velit.' 40 | ' Etiam ullamcorper eget mi in vestibulum.', 41 | title: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', 42 | button1OnPressed: () => {}, 43 | button1Text: 'Got it', 44 | button2Text: 'Nope', 45 | button2OnPressed: () => {}, 46 | buttonTextColor: Colors.orange); 47 | -------------------------------------------------------------------------------- /samples_patterns/stories/bloc_complex_list_stories.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:monarch_samples_patterns/bloc/list_complex/item.dart'; 4 | import 'package:monarch_samples_patterns/bloc/list_complex/list_complex_screen.dart'; 5 | import 'package:monarch_samples_patterns/bloc/list_complex/list_cubit.dart'; 6 | import 'package:monarch_samples_patterns/bloc/list_complex/list_state.dart'; 7 | 8 | import 'mocked_repository.dart'; 9 | 10 | Widget loading() => BlocProvider.value( 11 | value: ListCubit( 12 | repository: MockedRepository(), 13 | defaultState: const ListState.loading()), 14 | child: ListComplexScreen()); 15 | 16 | Widget fetch() { 17 | final listCubit = ListCubit(repository: MockedRepository()); 18 | listCubit.fetchList(); 19 | return BlocProvider.value(value: listCubit, child: ListComplexScreen()); 20 | } 21 | 22 | Widget success() => BlocProvider.value( 23 | value: ListCubit( 24 | repository: MockedRepository(), 25 | defaultState: const ListState.success([ 26 | Item(id: '1', value: 'Hello'), 27 | Item(id: '2', value: 'World'), 28 | Item(id: '3', value: 'From'), 29 | Item(id: '4', value: 'Monarch'), 30 | ])), 31 | child: ListComplexScreen()); 32 | 33 | Widget deleting() => BlocProvider.value( 34 | value: ListCubit( 35 | repository: MockedRepository(), 36 | defaultState: const ListState.success([ 37 | Item(id: '1', value: 'Hello', isDeleting: true), 38 | Item(id: '2', value: 'World'), 39 | Item(id: '3', value: 'From'), 40 | Item(id: '4', value: 'Monarch'), 41 | ])), 42 | child: ListComplexScreen()); 43 | 44 | Widget failure() => BlocProvider.value( 45 | value: ListCubit( 46 | repository: MockedRepository(), 47 | defaultState: const ListState.failure()), 48 | child: ListComplexScreen()); 49 | 50 | Widget long_list() { 51 | var items = []; 52 | for (var i = 0; i < 100; i++) { 53 | items.add(Item(id: i.toString(), value: 'Item $i')); 54 | } 55 | return BlocProvider.value( 56 | value: ListCubit( 57 | repository: MockedRepository(), 58 | defaultState: ListState.success(items)), 59 | child: ListComplexScreen()); 60 | } 61 | -------------------------------------------------------------------------------- /samples_patterns/lib/bloc/bloc_counter/bloc_counter_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | import '../../platform_route.dart'; 7 | 8 | class BlocCounterScreen extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return BlocProvider( 12 | create: (_) => CounterCubit(), 13 | child: BlocCounterView(), 14 | ); 15 | } 16 | 17 | static String tag = 'bloc-counter-screen'; 18 | 19 | static Route route(BuildContext context) => platformRoute( 20 | context, 21 | builder: (_) => BlocCounterScreen(), 22 | settings: RouteSettings(name: tag), 23 | ); 24 | } 25 | 26 | class BlocCounterView extends StatelessWidget { 27 | @override 28 | Widget build(BuildContext context) { 29 | final textTheme = Theme.of(context).textTheme; 30 | return Scaffold( 31 | appBar: AppBar(title: const Text('Counter')), 32 | body: Center( 33 | child: BlocBuilder( 34 | builder: (context, state) { 35 | return Text('$state', style: textTheme.headline2); 36 | }, 37 | ), 38 | ), 39 | floatingActionButton: Column( 40 | mainAxisAlignment: MainAxisAlignment.end, 41 | crossAxisAlignment: CrossAxisAlignment.end, 42 | children: [ 43 | FloatingActionButton( 44 | key: const Key('counterView_increment_floatingActionButton'), 45 | heroTag: 'counter_increment', 46 | onPressed: () => context.read().increment(), 47 | child: const Icon(Icons.add), 48 | ), 49 | const SizedBox(height: 8), 50 | FloatingActionButton( 51 | key: const Key('counterView_decrement_floatingActionButton'), 52 | heroTag: 'counter_decrement', 53 | onPressed: () => context.read().decrement(), 54 | child: const Icon(Icons.remove), 55 | ), 56 | ], 57 | ), 58 | ); 59 | } 60 | } 61 | 62 | class CounterCubit extends Cubit { 63 | CounterCubit({int initialState = 0}) : super(initialState); 64 | 65 | void increment() => emit(state + 1); 66 | 67 | void decrement() => emit(state - 1); 68 | } 69 | -------------------------------------------------------------------------------- /samples_easy_localization/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /samples_patterns/lib/text_fields/single_value_text_field.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | class SingleValueTextfield extends TextFormField { 5 | SingleValueTextfield({ 6 | Key? key, 7 | String? value, 8 | String? hint, 9 | FocusNode? focusNode, 10 | ValueChanged? onChanged, 11 | ValueChanged? onSaved, 12 | ValueChanged? onFieldSubmitted, 13 | VoidCallback? onEditingComplete, 14 | VoidCallback? onTap, 15 | FormFieldValidator? validator, 16 | bool autofocus = true, 17 | bool obscureText = false, 18 | TextInputAction textInputAction = TextInputAction.next, 19 | TextInputType? keyboardType, 20 | TextCapitalization textCapitalization = TextCapitalization.none, 21 | int? maxLength, 22 | List? inputFormatters, 23 | bool autocorrect = false, 24 | bool enabled = true, 25 | TextEditingController? controller, 26 | Widget? suffixIcon, 27 | }) : super( 28 | key: key, 29 | initialValue: value, 30 | autofocus: autofocus, 31 | focusNode: focusNode, 32 | obscureText: obscureText, 33 | controller: controller, 34 | style: TextStyle( 35 | fontSize: 16, 36 | fontWeight: FontWeight.w600, 37 | ), 38 | decoration: InputDecoration( 39 | hintText: hint, 40 | filled: true, 41 | labelText: (value ?? '').isNotEmpty ? hint : null, 42 | suffixIcon: suffixIcon, 43 | enabledBorder: OutlineInputBorder( 44 | borderSide: BorderSide(), 45 | borderRadius: BorderRadius.all(Radius.circular(10)), 46 | ), 47 | focusedBorder: OutlineInputBorder( 48 | borderSide: BorderSide(), 49 | ), 50 | ), 51 | onChanged: onChanged, 52 | onSaved: onSaved, 53 | onTap: onTap, 54 | onEditingComplete: onEditingComplete, 55 | onFieldSubmitted: onFieldSubmitted, 56 | textInputAction: textInputAction, 57 | validator: validator, 58 | keyboardType: keyboardType, 59 | maxLength: maxLength, 60 | maxLines: 1, 61 | inputFormatters: inputFormatters, 62 | textCapitalization: textCapitalization, 63 | autocorrect: autocorrect, 64 | enabled: enabled, 65 | ); 66 | } 67 | -------------------------------------------------------------------------------- /samples_booking/lib/booking/booking_app_theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:monarch_annotations/monarch_annotations.dart'; 3 | 4 | @MonarchTheme('Booking Light') 5 | ThemeData get bookingLightTheme => BookingAppTheme.buildLightTheme(); 6 | 7 | @MonarchTheme('Booking Dark') 8 | ThemeData get bookingDarkTheme => BookingAppTheme.buildDarkTheme(); 9 | 10 | 11 | const monarchPrimaryColor = Color(0xff00b3b8); 12 | const monarchAccentColor = Color(0xff00c5ca); 13 | 14 | // const primaryColor = Color(0xFF54D3C2); 15 | const primaryColor = monarchPrimaryColor; 16 | 17 | class BookingAppTheme { 18 | static TextTheme _buildTextTheme(TextTheme base) { 19 | const String fontName = 'WorkSans'; 20 | return base.copyWith( 21 | headlineLarge: base.headlineLarge?.copyWith(fontFamily: fontName), 22 | headlineMedium: base.headlineMedium?.copyWith(fontFamily: fontName), 23 | headlineSmall: base.headlineSmall?.copyWith(fontFamily: fontName), 24 | labelMedium: base.labelMedium?.copyWith(fontFamily: fontName), 25 | bodyLarge: base.bodyLarge?.copyWith(fontFamily: fontName), 26 | bodyMedium: base.bodyMedium?.copyWith(fontFamily: fontName), 27 | titleLarge: base.titleLarge?.copyWith(fontFamily: fontName), 28 | titleMedium: base.titleMedium?.copyWith(fontFamily: fontName), 29 | ); 30 | } 31 | 32 | static ThemeData buildLightTheme() { 33 | final ColorScheme colorScheme = const ColorScheme.light().copyWith( 34 | primary: primaryColor, 35 | ); 36 | final ThemeData base = ThemeData.light(); 37 | return _buildTheme(colorScheme, base, Colors.grey); 38 | } 39 | 40 | static ThemeData buildDarkTheme() { 41 | final ColorScheme colorScheme = const ColorScheme.dark().copyWith( 42 | primary: primaryColor, 43 | ); 44 | final ThemeData base = ThemeData.dark(); 45 | return _buildTheme(colorScheme, base, Colors.black); 46 | } 47 | 48 | static ThemeData _buildTheme(ColorScheme colorScheme, ThemeData base, Color shadowColor) { 49 | return base.copyWith( 50 | colorScheme: colorScheme, 51 | primaryColor: primaryColor, 52 | shadowColor: shadowColor, 53 | splashFactory: InkRipple.splashFactory, 54 | buttonTheme: ButtonThemeData( 55 | colorScheme: colorScheme, 56 | textTheme: ButtonTextTheme.primary, 57 | ), 58 | textTheme: _buildTextTheme(base.textTheme), 59 | primaryTextTheme: _buildTextTheme(base.primaryTextTheme), 60 | platform: TargetPlatform.iOS, 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /samples_patterns/lib/bloc/list_complex/list_complex_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | 5 | import '../../platform_route.dart'; 6 | import 'item.dart'; 7 | import 'list_cubit.dart'; 8 | import 'list_state.dart'; 9 | 10 | class ListComplexScreen extends StatelessWidget { 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold( 14 | appBar: AppBar(title: const Text('Complex List')), 15 | body: BlocBuilder( 16 | builder: (context, state) { 17 | switch (state.status) { 18 | case ListStatus.failure: 19 | return const Center(child: Text('Oops something went wrong!')); 20 | case ListStatus.success: 21 | return _ListView(items: state.items); 22 | default: 23 | return const Center(child: CircularProgressIndicator()); 24 | } 25 | }, 26 | ), 27 | ); 28 | } 29 | 30 | static String tag = 'list-complex-screen'; 31 | 32 | static Route route(BuildContext context) => platformRoute( 33 | context, 34 | builder: (_) => ListComplexScreen(), 35 | settings: RouteSettings(name: tag), 36 | ); 37 | } 38 | 39 | class _ListView extends StatelessWidget { 40 | const _ListView({Key? key, required this.items}) : super(key: key); 41 | 42 | final List items; 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | return items.isEmpty 47 | ? const Center(child: Text('no content')) 48 | : ListView.builder( 49 | itemBuilder: (BuildContext context, int index) { 50 | return _ItemTile( 51 | item: items[index], 52 | onDeletePressed: (id) { 53 | context.read().deleteItem(id); 54 | }, 55 | ); 56 | }, 57 | itemCount: items.length, 58 | ); 59 | } 60 | } 61 | 62 | class _ItemTile extends StatelessWidget { 63 | const _ItemTile({ 64 | Key? key, 65 | required this.item, 66 | required this.onDeletePressed, 67 | }) : super(key: key); 68 | 69 | final Item item; 70 | final ValueSetter onDeletePressed; 71 | 72 | @override 73 | Widget build(BuildContext context) { 74 | return ListTile( 75 | leading: Text('#${item.id}'), 76 | title: Text(item.value), 77 | trailing: item.isDeleting 78 | ? const CircularProgressIndicator() 79 | : IconButton( 80 | icon: const Icon(Icons.delete, color: Colors.red), 81 | onPressed: () => onDeletePressed(item.id), 82 | ), 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /samples_patterns/lib/dialogs/bottom_sheet.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class BottomSheetButton extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Center( 7 | child: TextButton( 8 | onPressed: () => showBottomSheet( 9 | context: context, 10 | elevation: 1.5, 11 | shape: RoundedRectangleBorder( 12 | borderRadius: BorderRadius.vertical(), 13 | ), 14 | backgroundColor: Theme.of(context).dialogBackgroundColor, 15 | builder: (ctx) => Container( 16 | height: 200, 17 | child: Center( 18 | child: Text('Bottom sheet', 19 | style: Theme.of(context).textTheme.headline6), 20 | ))), 21 | style: TextButton.styleFrom( 22 | primary: Theme.of(context).primaryColor, 23 | backgroundColor: Theme.of(context).backgroundColor), 24 | child: Text('Show bottom sheet'))); 25 | } 26 | } 27 | 28 | class ModalBottomSheetButton extends StatelessWidget { 29 | @override 30 | Widget build(BuildContext context) { 31 | return Center( 32 | child: TextButton( 33 | onPressed: () => showModalBottomSheet( 34 | context: context, 35 | elevation: 1.5, 36 | shape: RoundedRectangleBorder( 37 | borderRadius: BorderRadius.vertical(), 38 | ), 39 | backgroundColor: Theme.of(context).dialogBackgroundColor, 40 | builder: (ctx) => Container( 41 | height: 200, 42 | child: Center( 43 | child: Text('Modal bottom sheet', 44 | style: Theme.of(context).textTheme.headline6), 45 | ))), 46 | style: TextButton.styleFrom( 47 | primary: Theme.of(context).primaryColor, 48 | backgroundColor: Theme.of(context).backgroundColor), 49 | child: Text('Show modal bottom sheet'))); 50 | } 51 | } 52 | 53 | class ScaffoldBottomSheet extends StatelessWidget { 54 | @override 55 | Widget build(BuildContext context) { 56 | return Scaffold( 57 | body: Center( 58 | child: 59 | Text('Scaffold', style: Theme.of(context).textTheme.headline5)), 60 | bottomSheet: Container( 61 | height: 200, 62 | color: Theme.of(context).dialogBackgroundColor, 63 | child: Center( 64 | child: Text('Scaffold bottom sheet', 65 | style: Theme.of(context).textTheme.headline6), 66 | )), 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /samples_patterns/lib/content_list/animated_tap.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | class AnimatedTap extends StatefulWidget { 5 | AnimatedTap({ 6 | Key? key, 7 | required this.child, 8 | this.onPressed, 9 | this.start = 0.0, 10 | this.end = 0.04, 11 | this.duration = const Duration(milliseconds: 70), 12 | this.giveHapticFeedback = true, 13 | this.behavior = HitTestBehavior.opaque, 14 | }) : super(key: key); 15 | final Widget child; 16 | final Function(BuildContext)? onPressed; 17 | final double start, end; 18 | final Duration duration; 19 | final bool giveHapticFeedback; 20 | final HitTestBehavior behavior; 21 | @override 22 | _AnimatedTapState createState() => _AnimatedTapState(); 23 | } 24 | 25 | class _AnimatedTapState extends State { 26 | double _end = 0; 27 | bool _cancelled = false; 28 | bool _released = false; 29 | 30 | bool get hasHandler => widget.onPressed != null; 31 | 32 | void _onTapDown(TapDownDetails details) { 33 | setState(() { 34 | _released = false; 35 | _cancelled = false; 36 | _end = widget.end; 37 | }); 38 | if (widget.giveHapticFeedback) { 39 | HapticFeedback.lightImpact(); 40 | } 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return TweenAnimationBuilder( 46 | tween: Tween(begin: widget.start, end: _end), 47 | duration: widget.duration, 48 | builder: (BuildContext context, double size, Widget? child) { 49 | var _transformScale = 1 - size; 50 | 51 | return GestureDetector( 52 | behavior: widget.behavior, 53 | onTapDown: hasHandler ? _onTapDown : null, 54 | onTapCancel: hasHandler 55 | ? () => setState(() { 56 | _cancelled = true; 57 | _released = true; 58 | _end = 0; 59 | }) 60 | : null, 61 | onTapUp: hasHandler 62 | ? (_) => setState(() { 63 | _released = true; 64 | _end = size == widget.end ? 0 : _end; 65 | }) 66 | : null, 67 | child: Transform.scale( 68 | scale: _transformScale, 69 | child: widget.child, 70 | ), 71 | ); 72 | }, 73 | onEnd: () { 74 | // Animation is done and was not cancelled 75 | if (_end == 0 && !_cancelled) { 76 | if (hasHandler) { 77 | widget.onPressed!(context); 78 | } 79 | } else if (_end == widget.end && _released) { 80 | setState(() => _end = 0); 81 | } 82 | }, 83 | child: widget.child, 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /samples_patterns/lib/content_list/content_list_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'animated_tap.dart'; 4 | 5 | class ContentListScreen extends StatelessWidget { 6 | final List categories; 7 | final String title; 8 | 9 | const ContentListScreen( 10 | {Key? key, required this.categories, required this.title}) 11 | : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | appBar: AppBar( 17 | title: Text(title), 18 | ), 19 | body: categories.isEmpty 20 | ? NoContentWidget() 21 | : _buildContentList(categories), 22 | ); 23 | } 24 | 25 | Widget _buildContentList(List categories) { 26 | return Padding( 27 | padding: const EdgeInsets.only(top: 16), 28 | child: ListView.builder( 29 | itemBuilder: (context, index) => Padding( 30 | padding: EdgeInsets.symmetric(horizontal: 16), 31 | child: CategoryItem( 32 | label: categories[index].label, 33 | key: Key('category-card-$index'), 34 | onClick: () => categories[index].onClick?.call(), 35 | )), 36 | itemCount: categories.length, 37 | ), 38 | ); 39 | } 40 | } 41 | 42 | class Category { 43 | final String label; 44 | final VoidCallback? onClick; 45 | 46 | Category({required this.label, this.onClick}); 47 | } 48 | 49 | class NoContentWidget extends StatelessWidget { 50 | @override 51 | Widget build(BuildContext context) { 52 | return Center( 53 | child: Text('No categories available'), 54 | ); 55 | } 56 | } 57 | 58 | class CategoryItem extends AnimatedTap { 59 | final String label; 60 | final VoidCallback? onClick; 61 | 62 | CategoryItem({ 63 | Key? key, 64 | required this.label, 65 | this.onClick, 66 | }) : super( 67 | key: key, 68 | child: CategoryCard(label: label), 69 | onPressed: (_) => onClick?.call()); 70 | } 71 | 72 | class CategoryCard extends StatelessWidget { 73 | final String label; 74 | 75 | const CategoryCard({Key? key, required this.label}) : super(key: key); 76 | 77 | @override 78 | Widget build(BuildContext context) { 79 | final theme = Theme.of(context); 80 | return Container( 81 | decoration: BoxDecoration( 82 | borderRadius: BorderRadius.all(Radius.circular(15)), 83 | color: theme.cardColor, 84 | boxShadow: [ 85 | BoxShadow( 86 | color: theme.shadowColor, 87 | blurRadius: 6, 88 | offset: Offset(0, 5), 89 | ), 90 | ], 91 | ), 92 | margin: const EdgeInsets.symmetric(vertical: 5), 93 | padding: const EdgeInsets.all(15), 94 | clipBehavior: Clip.hardEdge, 95 | child: Text(label), 96 | ); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /samples_patterns/lib/dialogs/alert_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | class _CustomAlertDialog extends StatelessWidget { 5 | _CustomAlertDialog( 6 | {required this.title, 7 | required this.content, 8 | this.button1Text, 9 | this.button1OnPressed, 10 | this.button2Text, 11 | this.button2OnPressed, 12 | this.titleColor, 13 | this.buttonTextColor = Colors.deepOrangeAccent, 14 | this.contentColor}); 15 | 16 | final String title; 17 | final Widget content; 18 | final String? button1Text; 19 | final VoidCallback? button1OnPressed; 20 | final String? button2Text; 21 | final VoidCallback? button2OnPressed; 22 | final Color? titleColor; 23 | final Color? buttonTextColor; 24 | final Color? contentColor; 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | final theme = Theme.of(context); 29 | return AlertDialog( 30 | titlePadding: const EdgeInsets.all(15.0), 31 | contentPadding: const EdgeInsets.all(15.0), 32 | backgroundColor: theme.dialogBackgroundColor, 33 | shape: RoundedRectangleBorder( 34 | borderRadius: BorderRadius.all(Radius.circular(15.0))), 35 | title: Text(title, 36 | style: TextStyle(fontWeight: FontWeight.w100, fontSize: 15)), 37 | content: content, 38 | actions: [ 39 | if (button2Text != null) ...[ 40 | TextButton( 41 | key: Key('custom-dialog-negative-button-key'), 42 | onPressed: button2OnPressed, 43 | child: Text(button2Text!, 44 | style: TextStyle( 45 | color: buttonTextColor, 46 | )), 47 | ) 48 | ], 49 | if (button1Text != null) ...[ 50 | TextButton( 51 | key: Key('custom-dialog-positive-button-key'), 52 | onPressed: button1OnPressed, 53 | child: Text(button1Text!, 54 | style: TextStyle( 55 | color: buttonTextColor, 56 | )), 57 | ) 58 | ] 59 | ], 60 | ); 61 | } 62 | } 63 | 64 | class CustomAlertDialog extends _CustomAlertDialog { 65 | CustomAlertDialog( 66 | {required String title, 67 | String? content, 68 | String? button1Text, 69 | VoidCallback? button1OnPressed, 70 | String? button2Text, 71 | VoidCallback? button2OnPressed, 72 | Color? contentColor, 73 | Color? buttonTextColor}) 74 | : super( 75 | title: title, 76 | content: content != null 77 | ? Text(content, 78 | style: TextStyle(fontSize: 13, color: contentColor)) 79 | : SizedBox.shrink(), 80 | button1Text: button1Text, 81 | button1OnPressed: button1OnPressed, 82 | button2Text: button2Text, 83 | button2OnPressed: button2OnPressed, 84 | buttonTextColor: buttonTextColor); 85 | } 86 | -------------------------------------------------------------------------------- /samples_patterns/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bloc/flutter_bloc.dart'; 3 | import 'package:flutter_localizations/flutter_localizations.dart'; 4 | import 'package:intl/intl.dart'; 5 | import 'package:provider/provider.dart'; 6 | 7 | import 'bloc/bloc_example_list.dart'; 8 | import 'bloc/list_complex/list_cubit.dart'; 9 | import 'bloc/list_complex/repository.dart'; 10 | import 'content_list/content_list_screen.dart'; 11 | import 'internationalization/localizations.dart'; 12 | import 'internationalization/localized_screen.dart'; 13 | import 'provider/current_date.dart'; 14 | import 'provider/provider_example_list.dart'; 15 | import 'provider/shopping_cart_change_notifier.dart'; 16 | import 'themes/themed_screen.dart'; 17 | 18 | void main() { 19 | runApp(MyApp()); 20 | } 21 | 22 | class MyApp extends StatelessWidget { 23 | @override 24 | Widget build(BuildContext context) { 25 | return MultiProvider( 26 | providers: [ 27 | Provider( 28 | create: (_) => CurrentDate( 29 | currentDateFn: () => DateFormat.yMMMEd().format(DateTime.now())), 30 | ), 31 | ChangeNotifierProvider( 32 | create: (_) => ShoppingCartChangeNotifier.empty()) 33 | ], 34 | child: MultiBlocProvider( 35 | providers: [ 36 | BlocProvider( 37 | create: (_) => ListCubit(repository: RepositoryImpl())..fetchList(), 38 | ), 39 | ], 40 | child: MaterialApp( 41 | title: 'Monarch Demo', 42 | theme: ThemeData( 43 | primarySwatch: Colors.blue, 44 | ), 45 | navigatorKey: GlobalKey(), 46 | locale: localizationDelegate.defaultLocale, 47 | supportedLocales: localizationDelegate.supportedLocales, 48 | localizationsDelegates: [ 49 | localizationDelegate, 50 | ...GlobalMaterialLocalizations.delegates, 51 | ], 52 | home: Main()), 53 | ), 54 | ); 55 | } 56 | } 57 | 58 | class Main extends StatelessWidget { 59 | @override 60 | Widget build(BuildContext context) { 61 | return ContentListScreen( 62 | title: 'Monarch Demo - ${Navigator.of(context).widget.initialRoute!}', 63 | categories: [ 64 | Category( 65 | label: 'Provider', 66 | onClick: () => Navigator.of(context) 67 | .push(ProviderExampleListScreen.route(context))), 68 | Category( 69 | label: 'Bloc', 70 | onClick: () => Navigator.of(context) 71 | .push(BlocExampleListScreen.route(context))), 72 | Category( 73 | label: 'Internationalization', 74 | onClick: () => 75 | Navigator.of(context).push(LocalizedScreen.route(context))), 76 | Category( 77 | label: 'Themes', 78 | onClick: () => 79 | Navigator.of(context).push(MonarchThemedScreen.route(context))), 80 | ], 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /samples_booking/lib/localizations.dart: -------------------------------------------------------------------------------- 1 | /// Monarch Internationalization Documentation: 2 | /// https://monarchapp.io/docs/internationalization 3 | 4 | import 'dart:convert'; 5 | import 'dart:ui'; 6 | 7 | import 'package:flutter/services.dart'; 8 | import 'package:flutter/widgets.dart' 9 | show BuildContext, Locale, Localizations, LocalizationsDelegate; 10 | import 'package:monarch_annotations/monarch_annotations.dart'; 11 | 12 | const _english = Locale('en', 'US'); 13 | const _spanish = Locale('es', 'US'); 14 | 15 | @MonarchLocalizations([MonarchLocale('en', 'US'), MonarchLocale('es', 'US')]) 16 | SampleLocalizationsDelegate get localizationDelegate => 17 | SampleLocalizationsDelegate( 18 | FileTranslationsBundleLoader('locale'), 19 | supportedLocales: [_english, _spanish], 20 | defaultLocale: _english, 21 | ); 22 | 23 | class SampleLocalizationsDelegate 24 | extends LocalizationsDelegate { 25 | final TranslationsBundleLoader bundleLoader; 26 | final Locale defaultLocale; 27 | final List supportedLocales; 28 | 29 | const SampleLocalizationsDelegate( 30 | this.bundleLoader, { 31 | this.supportedLocales = const [_english, _spanish], 32 | required this.defaultLocale, 33 | }); 34 | 35 | List get supportedLanguages => 36 | supportedLocales.map((l) => l.languageCode).toList(); 37 | 38 | @override 39 | bool isSupported(Locale locale) => 40 | supportedLanguages.contains(locale.languageCode); 41 | 42 | @override 43 | Future load(Locale locale) => 44 | SampleLocalizations.load(locale, bundleLoader); 45 | 46 | @override 47 | bool shouldReload(SampleLocalizationsDelegate old) => false; 48 | } 49 | 50 | class SampleLocalizations { 51 | Locale locale; 52 | 53 | static Map _localizedValues = {}; 54 | 55 | static SampleLocalizations? of(BuildContext context) { 56 | return Localizations.of(context, SampleLocalizations); 57 | } 58 | 59 | SampleLocalizations(this.locale); 60 | 61 | String text(String key) { 62 | return _localizedValues[key] ?? '_$key'; 63 | } 64 | 65 | static Future load( 66 | Locale locale, 67 | TranslationsBundleLoader loader, 68 | ) async { 69 | var translations = SampleLocalizations(locale); 70 | _localizedValues = await loader.loadTranslationsDictionary(locale); 71 | return translations; 72 | } 73 | 74 | String get currentLanguage => locale.languageCode; 75 | } 76 | 77 | abstract class TranslationsBundleLoader { 78 | TranslationsBundleLoader(); 79 | 80 | Future> loadTranslationsDictionary(Locale locale); 81 | } 82 | 83 | class FileTranslationsBundleLoader extends TranslationsBundleLoader { 84 | final String path; 85 | final AssetBundle? bundle; 86 | FileTranslationsBundleLoader(this.path, {this.bundle}) : super(); 87 | 88 | @override 89 | Future> loadTranslationsDictionary(Locale locale) async { 90 | var jsonContent = await (bundle ?? rootBundle) 91 | .loadString('$path/i18n_${locale.languageCode}.json'); 92 | return json.decode(jsonContent); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /samples_patterns/lib/internationalization/localizations.dart: -------------------------------------------------------------------------------- 1 | /// Monarch Internationalization Documentation: 2 | /// https://monarchapp.io/docs/internationalization 3 | 4 | import 'dart:convert'; 5 | 6 | import 'package:flutter/services.dart'; 7 | import 'package:flutter/widgets.dart' 8 | show BuildContext, Locale, Localizations, LocalizationsDelegate; 9 | import 'package:monarch_annotations/monarch_annotations.dart'; 10 | 11 | const _english = Locale('en', 'US'); 12 | const _spanish = Locale('es', 'US'); 13 | 14 | @MonarchLocalizations([MonarchLocale('en', 'US'), MonarchLocale('es', 'US')]) 15 | SampleLocalizationsDelegate get localizationDelegate => 16 | SampleLocalizationsDelegate( 17 | FileTranslationsBundleLoader('locale'), 18 | supportedLocales: [_english, _spanish], 19 | defaultLocale: _english, 20 | ); 21 | 22 | class SampleLocalizationsDelegate 23 | extends LocalizationsDelegate { 24 | final TranslationsBundleLoader bundleLoader; 25 | final Locale defaultLocale; 26 | final List supportedLocales; 27 | 28 | const SampleLocalizationsDelegate( 29 | this.bundleLoader, { 30 | this.supportedLocales = const [_english, _spanish], 31 | required this.defaultLocale, 32 | }); 33 | 34 | List get supportedLanguages => 35 | supportedLocales.map((l) => l.languageCode).toList(); 36 | 37 | @override 38 | bool isSupported(Locale locale) => 39 | supportedLanguages.contains(locale.languageCode); 40 | 41 | @override 42 | Future load(Locale locale) => 43 | SampleLocalizations.load(locale, bundleLoader); 44 | 45 | @override 46 | bool shouldReload(SampleLocalizationsDelegate old) => false; 47 | } 48 | 49 | class SampleLocalizations { 50 | Locale locale; 51 | 52 | static Map _localizedValues = {}; 53 | 54 | static SampleLocalizations? of(BuildContext context) { 55 | return Localizations.of(context, SampleLocalizations); 56 | } 57 | 58 | SampleLocalizations(this.locale); 59 | 60 | String text(String key) { 61 | return _localizedValues[key] ?? '_$key'; 62 | } 63 | 64 | static Future load( 65 | Locale locale, 66 | TranslationsBundleLoader loader, 67 | ) async { 68 | var translations = SampleLocalizations(locale); 69 | _localizedValues = await loader.loadTranslationsDictionary(locale); 70 | return translations; 71 | } 72 | 73 | String get currentLanguage => locale.languageCode; 74 | } 75 | 76 | abstract class TranslationsBundleLoader { 77 | TranslationsBundleLoader(); 78 | 79 | Future> loadTranslationsDictionary(Locale locale); 80 | } 81 | 82 | class FileTranslationsBundleLoader extends TranslationsBundleLoader { 83 | final String path; 84 | final AssetBundle? bundle; 85 | FileTranslationsBundleLoader(this.path, {this.bundle}) : super(); 86 | 87 | @override 88 | Future> loadTranslationsDictionary(Locale locale) async { 89 | var jsonContent = await (bundle ?? rootBundle) 90 | .loadString('$path/i18n_${locale.languageCode}.json'); 91 | return json.decode(jsonContent); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /samples_patterns/test/obscurable_text_field_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | 4 | import '../stories/obscurable_text_field_stories.dart' as stories; 5 | 6 | void main() { 7 | testWidgets('Should display reveal password icon when text obscure is true', 8 | (WidgetTester tester) async { 9 | // Build widget imported from story 10 | await tester.pumpWidget(materializeTextField(stories.obscured_text)); 11 | 12 | // Verify that correct icon is displayed. 13 | expect(find.byIcon(Icons.remove_red_eye_outlined), findsOneWidget); 14 | expect(find.byIcon(Icons.remove_red_eye), findsNothing); 15 | 16 | // Verify underlying TextField is set to obscure text 17 | final finder = find.byType(TextField); 18 | final input = tester.firstWidget(finder); 19 | expect(input.obscureText, true); 20 | }); 21 | 22 | testWidgets('Should display obscure password icon when text obscure is false', 23 | (WidgetTester tester) async { 24 | // Build widget imported from story 25 | await tester.pumpWidget(materializeTextField(stories.clear_text)); 26 | 27 | // Verify that correct icon is displayed. 28 | expect(find.byIcon(Icons.remove_red_eye), findsOneWidget); 29 | expect(find.byIcon(Icons.remove_red_eye_outlined), findsNothing); 30 | 31 | // Verify underlying TextField is set to clear text 32 | final finder = find.byType(TextField); 33 | final input = tester.firstWidget(finder); 34 | expect(input.obscureText, false); 35 | }); 36 | 37 | testWidgets('Clicking on reveal/obscure icon should toggle obscure text', 38 | (WidgetTester tester) async { 39 | // Build widget imported from story, we start with obscured text field 40 | await tester.pumpWidget(materializeTextField(stories.obscured_text)); 41 | 42 | // Let's tap on the reveal icon to make it viewable 43 | await tester.tap(find.byIcon(Icons.remove_red_eye_outlined)); 44 | 45 | await tester.pump(Duration(milliseconds: 200)); 46 | 47 | // Verify that obscure text icon is visible and text is clear 48 | { 49 | expect(find.byIcon(Icons.remove_red_eye), findsOneWidget); 50 | final finder = find.byType(TextField); 51 | final input = tester.firstWidget(finder); 52 | expect(input.obscureText, false); 53 | } 54 | 55 | // Now let's obscure it again by clicking the eye icon 56 | await tester.tap(find.byIcon(Icons.remove_red_eye)); 57 | 58 | await tester.pump(Duration(milliseconds: 200)); 59 | 60 | // Verify reveal icon shows and text is obscured 61 | { 62 | expect(find.byIcon(Icons.remove_red_eye_outlined), findsOneWidget); 63 | final finder = find.byType(TextField); 64 | final input = tester.firstWidget(finder); 65 | expect(input.obscureText, true); 66 | } 67 | }); 68 | } 69 | 70 | /// TextField widgets require a Material widget ancestor. Monarch automatically 71 | /// adds the required ancestor. Tests run outside of Monarch thus we need to 72 | /// add the Material widget ancestor here. 73 | MaterialApp materializeTextField(Widget Function() story) => MaterialApp( 74 | home: Scaffold(body: story()), 75 | ); 76 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /samples_easy_localization/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /samples_easy_localization/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | 71 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /samples_patterns/lib/animations/flutter/collapsable_box.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:monarch_samples_patterns/themes/custom_theme.dart'; 4 | 5 | class CollapsableBox extends StatefulWidget { 6 | @override 7 | State createState() => _CollapsableBoxState(); 8 | } 9 | 10 | class _CollapsableBoxState extends State 11 | with SingleTickerProviderStateMixin { 12 | late AnimationController _controller; 13 | late Animation _rotation, _expansion; 14 | bool _isExpanded = false; 15 | 16 | @override 17 | void initState() { 18 | super.initState(); 19 | _controller = 20 | AnimationController(vsync: this, duration: Duration(milliseconds: 250)); 21 | _expansion = CurvedAnimation(parent: _controller, curve: Curves.easeInOut); 22 | _rotation = Tween(begin: 0.0, end: 3.14).animate(_controller); 23 | 24 | _handleAnimation(); 25 | } 26 | 27 | void _handleAnimation() { 28 | if (_isExpanded) { 29 | _controller.forward(); 30 | } else { 31 | _controller.reverse(); 32 | } 33 | } 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | return Container( 38 | decoration: BoxDecoration( 39 | color: Theme.of(context).cardColor, 40 | borderRadius: BorderRadius.all( 41 | const Radius.circular(20.0), 42 | ), 43 | boxShadow: [ 44 | BoxShadow( 45 | color: Color.fromARGB(100, 0, 0, 0), 46 | blurRadius: 2, 47 | offset: Offset(0, 3)), 48 | ], 49 | ), 50 | child: Stack(children: [ 51 | Padding( 52 | padding: const EdgeInsets.all(16.0), 53 | child: Wrap( 54 | children: [ 55 | _buildLogo(), 56 | SizeTransition( 57 | sizeFactor: _expansion, 58 | axisAlignment: 1.0, 59 | child: _buildExpandableArea(context), 60 | ) 61 | ], 62 | ), 63 | ), 64 | _buildFab(), 65 | ]), 66 | ); 67 | } 68 | 69 | Positioned _buildFab() { 70 | return Positioned( 71 | bottom: 10, 72 | right: 4, 73 | child: AnimatedBuilder( 74 | animation: _rotation, 75 | builder: (context, child) => Transform.rotate( 76 | angle: _rotation.value, 77 | child: RawMaterialButton( 78 | onPressed: () { 79 | setState(() { 80 | _isExpanded = !_isExpanded; 81 | _handleAnimation(); 82 | }); 83 | }, 84 | constraints: BoxConstraints.tight(Size(40, 40)), 85 | elevation: 0.0, 86 | fillColor: monarchAccentColor, 87 | padding: EdgeInsets.all(0.0), 88 | shape: CircleBorder(), 89 | child: Icon(Icons.arrow_downward, size: 20, color: Colors.white), 90 | ), 91 | ), 92 | ), 93 | ); 94 | } 95 | 96 | Column _buildExpandableArea(BuildContext context) { 97 | return Column( 98 | crossAxisAlignment: CrossAxisAlignment.stretch, 99 | children: [ 100 | Divider( 101 | color: monarchPrimaryColor, 102 | ), 103 | Text('Monarch is awesome', 104 | style: Theme.of(context).textTheme.headline5), 105 | SizedBox( 106 | height: 80, 107 | ) 108 | ], 109 | ); 110 | } 111 | 112 | SizedBox _buildLogo() { 113 | return SizedBox( 114 | width: 200, 115 | child: Image.asset('assets/monarch_m.png'), 116 | ); 117 | } 118 | 119 | @override 120 | void dispose() { 121 | _controller.dispose(); 122 | super.dispose(); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /samples_booking/lib/booking/slider_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../localizations.dart'; 3 | 4 | class SliderView extends StatefulWidget { 5 | const SliderView({Key? key, this.onChangedistValue, this.distValue}) 6 | : super(key: key); 7 | 8 | final Function(double)? onChangedistValue; 9 | final double? distValue; 10 | 11 | @override 12 | _SliderViewState createState() => _SliderViewState(); 13 | } 14 | 15 | class _SliderViewState extends State { 16 | double distValue = 50.0; 17 | 18 | @override 19 | void initState() { 20 | distValue = widget.distValue!; 21 | super.initState(); 22 | } 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | var loc = SampleLocalizations.of(context)!; 27 | return Container( 28 | child: Column( 29 | children: [ 30 | Row( 31 | children: [ 32 | Expanded( 33 | flex: distValue.round(), 34 | child: const SizedBox(), 35 | ), 36 | Container( 37 | width: 170, 38 | child: Text( 39 | '${loc.text('less-than')} ${(distValue / 10).toStringAsFixed(1)} Km', 40 | textAlign: TextAlign.center, 41 | style: Theme.of(context) 42 | .textTheme 43 | .bodyMedium! 44 | .copyWith(fontSize: 16), 45 | ), 46 | ), 47 | Expanded( 48 | flex: 100 - distValue.round(), 49 | child: const SizedBox(), 50 | ), 51 | ], 52 | ), 53 | SliderTheme( 54 | data: SliderTheme.of(context).copyWith( 55 | thumbShape: CustomThumbShape(), 56 | ), 57 | child: Slider( 58 | onChanged: (double value) { 59 | setState(() { 60 | distValue = value; 61 | }); 62 | try { 63 | widget.onChangedistValue!(distValue); 64 | } catch (_) {} 65 | }, 66 | min: 0, 67 | max: 100, 68 | divisions: 100, 69 | value: distValue, 70 | ), 71 | ), 72 | ], 73 | ), 74 | ); 75 | } 76 | } 77 | 78 | class CustomThumbShape extends SliderComponentShape { 79 | static const double _thumbSize = 3.0; 80 | static const double _disabledThumbSize = 3.0; 81 | 82 | @override 83 | Size getPreferredSize(bool isEnabled, bool isDiscrete) { 84 | return isEnabled 85 | ? const Size.fromRadius(_thumbSize) 86 | : const Size.fromRadius(_disabledThumbSize); 87 | } 88 | 89 | static final Animatable sizeTween = Tween( 90 | begin: _disabledThumbSize, 91 | end: _thumbSize, 92 | ); 93 | 94 | @override 95 | void paint( 96 | PaintingContext context, 97 | Offset center, { 98 | Animation? activationAnimation, 99 | Animation? enableAnimation, 100 | bool? isDiscrete, 101 | TextPainter? labelPainter, 102 | RenderBox? parentBox, 103 | Size? sizeWithOverflow, 104 | SliderThemeData? sliderTheme, 105 | TextDirection textDirection = TextDirection.ltr, 106 | double? textScaleFactor, 107 | double? value, 108 | }) { 109 | final Canvas canvas = context.canvas; 110 | final ColorTween colorTween = ColorTween( 111 | begin: sliderTheme?.disabledThumbColor, 112 | end: sliderTheme?.thumbColor, 113 | ); 114 | canvas.drawPath( 115 | Path() 116 | ..addOval(Rect.fromPoints(Offset(center.dx + 12, center.dy + 12), 117 | Offset(center.dx - 12, center.dy - 12))) 118 | ..fillType = PathFillType.evenOdd, 119 | Paint() 120 | ..color = Colors.black.withOpacity(0.5) 121 | ..maskFilter = 122 | MaskFilter.blur(BlurStyle.normal, convertRadiusToSigma(8))); 123 | 124 | final Paint cPaint = Paint(); 125 | cPaint.color = Colors.white; 126 | cPaint.strokeWidth = 14 / 2; 127 | canvas.drawCircle(Offset(center.dx, center.dy), 12, cPaint); 128 | cPaint.color = colorTween.evaluate(enableAnimation!)!; 129 | canvas.drawCircle(Offset(center.dx, center.dy), 10, cPaint); 130 | } 131 | 132 | double convertRadiusToSigma(double radius) { 133 | return radius * 0.57735 + 0.5; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /test/test_utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:test_process/test_process.dart'; 3 | import 'package:test/test.dart'; 4 | import 'package:monarch_utils/timers.dart'; 5 | import 'package:monarch_io_utils/monarch_io_utils.dart'; 6 | import 'package:path/path.dart' as p; 7 | 8 | /// Returns the monarch exe path as set by environment variable 9 | /// MONARCH_EXE; if not set, then the monarch exe should be 10 | /// sourced in the environment PATH before running these tests. 11 | String monarch_exe = Platform.environment['MONARCH_EXE'] ?? 'monarch'; 12 | 13 | /// Returns the flutter exe path as set by environment variables 14 | /// FLUTTER_EXE; if not set, then the flutter exe should be sourced 15 | /// in the environment PATH before running these tests. 16 | String flutter_exe = Platform.environment['FLUTTER_EXE'] ?? 'flutter'; 17 | 18 | /// 250ms delay. 19 | Future get briefly => Future.delayed(const Duration(milliseconds: 250)); 20 | 21 | Future killMonarch(String projectName) async { 22 | await futureForPlatform( 23 | macos: () async { 24 | await runProcess('pkill', ['Monarch']); 25 | await runProcess('pkill', [ 26 | '-f', 27 | '.dart_tool/build/generated/$projectName/lib/main_monarch.g.dart' 28 | ]); 29 | }, 30 | windows: () async { 31 | await runProcess( 32 | 'taskkill', ['/F', '/IM', 'monarch_windows_app.exe', '/T']); 33 | await runProcess('taskkill', ['/F', '/IM', 'monarch.exe', '/T']); 34 | }, 35 | linux: () async { 36 | await runProcess('pkill', ['-f', 'monarch_linux_app']); 37 | await runProcess('pkill', ['-f', 'monarch.run']); 38 | await runProcess('pkill', [ 39 | '-f', 40 | '.dart_tool/build/generated/$projectName/lib/main_monarch.g.dart' 41 | ]); 42 | }, 43 | ); 44 | } 45 | 46 | String prettyCommand(String executable, Iterable arguments) => 47 | '$executable ${arguments.join(' ')}'; 48 | 49 | void print_(String message) { 50 | if (Platform.environment.containsKey('VERBOSE')) { 51 | print(message); 52 | } 53 | } 54 | 55 | Future runProcess(String executable, List arguments, 56 | {String? workingDirectory, 57 | Map? environment, 58 | bool includeParentEnvironment = true}) => 59 | Process.run(executable, arguments, 60 | workingDirectory: workingDirectory, 61 | environment: environment, 62 | includeParentEnvironment: includeParentEnvironment, 63 | runInShell: Platform.isWindows); 64 | 65 | Future startTestProcess( 66 | String executable, Iterable arguments, 67 | {String? workingDirectory, 68 | Map? environment, 69 | bool includeParentEnvironment = true, 70 | bool runInShell = false, 71 | String? description, 72 | bool forwardStdio = false}) => 73 | TestProcess.start(executable, arguments, 74 | workingDirectory: workingDirectory, 75 | includeParentEnvironment: includeParentEnvironment, 76 | runInShell: Platform.isWindows, 77 | description: description, 78 | forwardStdio: forwardStdio); 79 | 80 | String getWorkingDirectory(String projectName) => p.join('..', projectName); 81 | 82 | Future runFlutterPubGet(String projectName) async { 83 | return runProcess(flutter_exe, ['pub', 'get'], 84 | workingDirectory: getWorkingDirectory(projectName)); 85 | } 86 | 87 | Future runMonarchInit(String projectName, 88 | {required String workingDirectory, required IOSink sink}) async { 89 | await setEmailCapturedFlag(); 90 | var process = await startTestProcess(monarch_exe, ['init', '-v'], 91 | workingDirectory: workingDirectory); 92 | var heartbeat = Heartbeat('`${process.description}`', print_)..start(); 93 | await expectLater(process.stdout, 94 | emitsThrough('Monarch successfully initialized in this project.')); 95 | await process.shouldExit(); 96 | heartbeat.complete(); 97 | } 98 | 99 | Future setEmailCapturedFlag() => 100 | emailCapturedFile.writeAsString('1', mode: FileMode.write); 101 | 102 | Future resetEmailCapturedFlag() => emailCapturedFile.delete(); 103 | 104 | String get userDirectoryEnvironmentVariable => 105 | valueForPlatform(macos: 'HOME', windows: 'USERPROFILE', linux: 'HOME'); 106 | 107 | String? get userDirectoryPath => 108 | Platform.environment[userDirectoryEnvironmentVariable]; 109 | 110 | String get dataDirectoryRelativePath => valueForPlatform( 111 | macos: 'Library/Application Support/com.dropsource.monarch/data', 112 | windows: r'AppData\Local\Monarch\data', 113 | linux: '.config/monarch/data'); 114 | 115 | File get emailCapturedFile => File(p.join( 116 | userDirectoryPath!, dataDirectoryRelativePath, 'email_captured.info')); 117 | -------------------------------------------------------------------------------- /samples_booking/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() { 4 | runApp(const MyApp()); 5 | } 6 | 7 | class MyApp extends StatelessWidget { 8 | const MyApp({Key? key}) : super(key: key); 9 | 10 | // This widget is the root of your application. 11 | @override 12 | Widget build(BuildContext context) { 13 | return MaterialApp( 14 | title: 'Flutter Demo', 15 | theme: ThemeData( 16 | // This is the theme of your application. 17 | // 18 | // Try running your application with "flutter run". You'll see the 19 | // application has a blue toolbar. Then, without quitting the app, try 20 | // changing the primarySwatch below to Colors.green and then invoke 21 | // "hot reload" (press "r" in the console where you ran "flutter run", 22 | // or simply save your changes to "hot reload" in a Flutter IDE). 23 | // Notice that the counter didn't reset back to zero; the application 24 | // is not restarted. 25 | primarySwatch: Colors.blue, 26 | ), 27 | home: const MyHomePage(title: 'Flutter Demo Home Page'), 28 | ); 29 | } 30 | } 31 | 32 | class MyHomePage extends StatefulWidget { 33 | const MyHomePage({Key? key, required this.title}) : super(key: key); 34 | 35 | // This widget is the home page of your application. It is stateful, meaning 36 | // that it has a State object (defined below) that contains fields that affect 37 | // how it looks. 38 | 39 | // This class is the configuration for the state. It holds the values (in this 40 | // case the title) provided by the parent (in this case the App widget) and 41 | // used by the build method of the State. Fields in a Widget subclass are 42 | // always marked "final". 43 | 44 | final String title; 45 | 46 | @override 47 | State createState() => _MyHomePageState(); 48 | } 49 | 50 | class _MyHomePageState extends State { 51 | int _counter = 0; 52 | 53 | void _incrementCounter() { 54 | setState(() { 55 | // This call to setState tells the Flutter framework that something has 56 | // changed in this State, which causes it to rerun the build method below 57 | // so that the display can reflect the updated values. If we changed 58 | // _counter without calling setState(), then the build method would not be 59 | // called again, and so nothing would appear to happen. 60 | _counter++; 61 | }); 62 | } 63 | 64 | @override 65 | Widget build(BuildContext context) { 66 | // This method is rerun every time setState is called, for instance as done 67 | // by the _incrementCounter method above. 68 | // 69 | // The Flutter framework has been optimized to make rerunning build methods 70 | // fast, so that you can just rebuild anything that needs updating rather 71 | // than having to individually change instances of widgets. 72 | return Scaffold( 73 | appBar: AppBar( 74 | // Here we take the value from the MyHomePage object that was created by 75 | // the App.build method, and use it to set our appbar title. 76 | title: Text(widget.title), 77 | ), 78 | body: Center( 79 | // Center is a layout widget. It takes a single child and positions it 80 | // in the middle of the parent. 81 | child: Column( 82 | // Column is also a layout widget. It takes a list of children and 83 | // arranges them vertically. By default, it sizes itself to fit its 84 | // children horizontally, and tries to be as tall as its parent. 85 | // 86 | // Invoke "debug painting" (press "p" in the console, choose the 87 | // "Toggle Debug Paint" action from the Flutter Inspector in Android 88 | // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) 89 | // to see the wireframe for each widget. 90 | // 91 | // Column has various properties to control how it sizes itself and 92 | // how it positions its children. Here we use mainAxisAlignment to 93 | // center the children vertically; the main axis here is the vertical 94 | // axis because Columns are vertical (the cross axis would be 95 | // horizontal). 96 | mainAxisAlignment: MainAxisAlignment.center, 97 | children: [ 98 | const Text( 99 | 'You have pushed the button this many times:', 100 | ), 101 | Text( 102 | '$_counter', 103 | style: Theme.of(context).textTheme.headlineMedium, 104 | ), 105 | ], 106 | ), 107 | ), 108 | floatingActionButton: FloatingActionButton( 109 | onPressed: _incrementCounter, 110 | tooltip: 'Increment', 111 | child: const Icon(Icons.add), 112 | ), // This trailing comma makes auto-formatting nicer for build methods. 113 | ); 114 | } 115 | } 116 | --------------------------------------------------------------------------------