diff --git a/diagrams/app-architecture/architecture-docs.fig b/diagrams/app-architecture/architecture-docs.fig index b27367bb5a0..c15a078e4da 100644 Binary files a/diagrams/app-architecture/architecture-docs.fig and b/diagrams/app-architecture/architecture-docs.fig differ diff --git a/examples/cookbook/architecture/command/analysis_options.yaml b/examples/app-architecture/command/analysis_options.yaml similarity index 100% rename from examples/cookbook/architecture/command/analysis_options.yaml rename to examples/app-architecture/command/analysis_options.yaml diff --git a/examples/cookbook/architecture/command/lib/command.dart b/examples/app-architecture/command/lib/command.dart similarity index 100% rename from examples/cookbook/architecture/command/lib/command.dart rename to examples/app-architecture/command/lib/command.dart diff --git a/examples/cookbook/architecture/command/lib/extended_command.dart b/examples/app-architecture/command/lib/extended_command.dart similarity index 100% rename from examples/cookbook/architecture/command/lib/extended_command.dart rename to examples/app-architecture/command/lib/extended_command.dart diff --git a/examples/cookbook/architecture/command/lib/main.dart b/examples/app-architecture/command/lib/main.dart similarity index 100% rename from examples/cookbook/architecture/command/lib/main.dart rename to examples/app-architecture/command/lib/main.dart diff --git a/examples/cookbook/architecture/command/lib/no_command.dart b/examples/app-architecture/command/lib/no_command.dart similarity index 100% rename from examples/cookbook/architecture/command/lib/no_command.dart rename to examples/app-architecture/command/lib/no_command.dart diff --git a/examples/cookbook/architecture/command/lib/result.dart b/examples/app-architecture/command/lib/result.dart similarity index 100% rename from examples/cookbook/architecture/command/lib/result.dart rename to examples/app-architecture/command/lib/result.dart diff --git a/examples/cookbook/architecture/command/lib/simple_command.dart b/examples/app-architecture/command/lib/simple_command.dart similarity index 100% rename from examples/cookbook/architecture/command/lib/simple_command.dart rename to examples/app-architecture/command/lib/simple_command.dart diff --git a/examples/cookbook/architecture/command/pubspec.yaml b/examples/app-architecture/command/pubspec.yaml similarity index 86% rename from examples/cookbook/architecture/command/pubspec.yaml rename to examples/app-architecture/command/pubspec.yaml index 02ace9942d5..5350840c63b 100644 --- a/examples/cookbook/architecture/command/pubspec.yaml +++ b/examples/app-architecture/command/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: dev_dependencies: example_utils: - path: ../../../example_utils + path: ../../example_utils flutter: uses-material-design: true diff --git a/examples/cookbook/architecture/offline_first/analysis_options.yaml b/examples/app-architecture/offline_first/analysis_options.yaml similarity index 100% rename from examples/cookbook/architecture/offline_first/analysis_options.yaml rename to examples/app-architecture/offline_first/analysis_options.yaml diff --git a/examples/cookbook/architecture/offline_first/lib/data/repositories/user_profile_repository.dart b/examples/app-architecture/offline_first/lib/data/repositories/user_profile_repository.dart similarity index 100% rename from examples/cookbook/architecture/offline_first/lib/data/repositories/user_profile_repository.dart rename to examples/app-architecture/offline_first/lib/data/repositories/user_profile_repository.dart diff --git a/examples/cookbook/architecture/offline_first/lib/data/services/api_client_service.dart b/examples/app-architecture/offline_first/lib/data/services/api_client_service.dart similarity index 100% rename from examples/cookbook/architecture/offline_first/lib/data/services/api_client_service.dart rename to examples/app-architecture/offline_first/lib/data/services/api_client_service.dart diff --git a/examples/cookbook/architecture/offline_first/lib/data/services/database_service.dart b/examples/app-architecture/offline_first/lib/data/services/database_service.dart similarity index 100% rename from examples/cookbook/architecture/offline_first/lib/data/services/database_service.dart rename to examples/app-architecture/offline_first/lib/data/services/database_service.dart diff --git a/examples/cookbook/architecture/offline_first/lib/domain/model/user_profile.dart b/examples/app-architecture/offline_first/lib/domain/model/user_profile.dart similarity index 100% rename from examples/cookbook/architecture/offline_first/lib/domain/model/user_profile.dart rename to examples/app-architecture/offline_first/lib/domain/model/user_profile.dart diff --git a/examples/cookbook/architecture/offline_first/lib/domain/model/user_profile.freezed.dart b/examples/app-architecture/offline_first/lib/domain/model/user_profile.freezed.dart similarity index 100% rename from examples/cookbook/architecture/offline_first/lib/domain/model/user_profile.freezed.dart rename to examples/app-architecture/offline_first/lib/domain/model/user_profile.freezed.dart diff --git a/examples/cookbook/architecture/offline_first/lib/main.dart b/examples/app-architecture/offline_first/lib/main.dart similarity index 100% rename from examples/cookbook/architecture/offline_first/lib/main.dart rename to examples/app-architecture/offline_first/lib/main.dart diff --git a/examples/cookbook/architecture/offline_first/lib/ui/user_profile/user_profile_screen.dart b/examples/app-architecture/offline_first/lib/ui/user_profile/user_profile_screen.dart similarity index 100% rename from examples/cookbook/architecture/offline_first/lib/ui/user_profile/user_profile_screen.dart rename to examples/app-architecture/offline_first/lib/ui/user_profile/user_profile_screen.dart diff --git a/examples/cookbook/architecture/offline_first/lib/ui/user_profile/user_profile_viewmodel.dart b/examples/app-architecture/offline_first/lib/ui/user_profile/user_profile_viewmodel.dart similarity index 100% rename from examples/cookbook/architecture/offline_first/lib/ui/user_profile/user_profile_viewmodel.dart rename to examples/app-architecture/offline_first/lib/ui/user_profile/user_profile_viewmodel.dart diff --git a/examples/cookbook/architecture/offline_first/pubspec.yaml b/examples/app-architecture/offline_first/pubspec.yaml similarity index 90% rename from examples/cookbook/architecture/offline_first/pubspec.yaml rename to examples/app-architecture/offline_first/pubspec.yaml index 53b60947671..43d103e3718 100644 --- a/examples/cookbook/architecture/offline_first/pubspec.yaml +++ b/examples/app-architecture/offline_first/pubspec.yaml @@ -15,7 +15,7 @@ dev_dependencies: build_runner: ^2.4.13 freezed: ^2.5.7 example_utils: - path: ../../../example_utils + path: ../../example_utils flutter: uses-material-design: true diff --git a/examples/cookbook/architecture/optimistic-state/analysis_options.yaml b/examples/app-architecture/optimistic-state/analysis_options.yaml similarity index 100% rename from examples/cookbook/architecture/optimistic-state/analysis_options.yaml rename to examples/app-architecture/optimistic-state/analysis_options.yaml diff --git a/examples/cookbook/architecture/optimistic-state/lib/main.dart b/examples/app-architecture/optimistic-state/lib/main.dart similarity index 100% rename from examples/cookbook/architecture/optimistic-state/lib/main.dart rename to examples/app-architecture/optimistic-state/lib/main.dart diff --git a/examples/cookbook/architecture/optimistic-state/lib/starter.dart b/examples/app-architecture/optimistic-state/lib/starter.dart similarity index 100% rename from examples/cookbook/architecture/optimistic-state/lib/starter.dart rename to examples/app-architecture/optimistic-state/lib/starter.dart diff --git a/examples/cookbook/architecture/optimistic-state/pubspec.yaml b/examples/app-architecture/optimistic-state/pubspec.yaml similarity index 87% rename from examples/cookbook/architecture/optimistic-state/pubspec.yaml rename to examples/app-architecture/optimistic-state/pubspec.yaml index b8c953092ab..78871f6b5a9 100644 --- a/examples/cookbook/architecture/optimistic-state/pubspec.yaml +++ b/examples/app-architecture/optimistic-state/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: dev_dependencies: example_utils: - path: ../../../example_utils + path: ../../example_utils flutter: uses-material-design: true diff --git a/examples/cookbook/architecture/result/analysis_options.yaml b/examples/app-architecture/result/analysis_options.yaml similarity index 100% rename from examples/cookbook/architecture/result/analysis_options.yaml rename to examples/app-architecture/result/analysis_options.yaml diff --git a/examples/cookbook/architecture/result/lib/main.dart b/examples/app-architecture/result/lib/main.dart similarity index 100% rename from examples/cookbook/architecture/result/lib/main.dart rename to examples/app-architecture/result/lib/main.dart diff --git a/examples/cookbook/architecture/result/lib/no_result.dart b/examples/app-architecture/result/lib/no_result.dart similarity index 100% rename from examples/cookbook/architecture/result/lib/no_result.dart rename to examples/app-architecture/result/lib/no_result.dart diff --git a/examples/cookbook/architecture/result/lib/result.dart b/examples/app-architecture/result/lib/result.dart similarity index 100% rename from examples/cookbook/architecture/result/lib/result.dart rename to examples/app-architecture/result/lib/result.dart diff --git a/examples/cookbook/architecture/result/lib/simple_result.dart b/examples/app-architecture/result/lib/simple_result.dart similarity index 100% rename from examples/cookbook/architecture/result/lib/simple_result.dart rename to examples/app-architecture/result/lib/simple_result.dart diff --git a/examples/cookbook/architecture/result/pubspec.yaml b/examples/app-architecture/result/pubspec.yaml similarity index 86% rename from examples/cookbook/architecture/result/pubspec.yaml rename to examples/app-architecture/result/pubspec.yaml index e4563a19af9..055757eb6c9 100644 --- a/examples/cookbook/architecture/result/pubspec.yaml +++ b/examples/app-architecture/result/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: dev_dependencies: example_utils: - path: ../../../example_utils + path: ../../example_utils flutter: uses-material-design: true diff --git a/examples/cookbook/architecture/todo_data_service/analysis_options.yaml b/examples/app-architecture/todo_data_service/analysis_options.yaml similarity index 100% rename from examples/cookbook/architecture/todo_data_service/analysis_options.yaml rename to examples/app-architecture/todo_data_service/analysis_options.yaml diff --git a/examples/cookbook/architecture/todo_data_service/lib/business/model/todo.dart b/examples/app-architecture/todo_data_service/lib/business/model/todo.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/business/model/todo.dart rename to examples/app-architecture/todo_data_service/lib/business/model/todo.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/business/model/todo.freezed.dart b/examples/app-architecture/todo_data_service/lib/business/model/todo.freezed.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/business/model/todo.freezed.dart rename to examples/app-architecture/todo_data_service/lib/business/model/todo.freezed.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/data/repositories/theme_repository.dart b/examples/app-architecture/todo_data_service/lib/data/repositories/theme_repository.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/data/repositories/theme_repository.dart rename to examples/app-architecture/todo_data_service/lib/data/repositories/theme_repository.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/data/repositories/todo_repository.dart b/examples/app-architecture/todo_data_service/lib/data/repositories/todo_repository.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/data/repositories/todo_repository.dart rename to examples/app-architecture/todo_data_service/lib/data/repositories/todo_repository.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/data/services/database_service.dart b/examples/app-architecture/todo_data_service/lib/data/services/database_service.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/data/services/database_service.dart rename to examples/app-architecture/todo_data_service/lib/data/services/database_service.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/data/services/shared_preferences_service.dart b/examples/app-architecture/todo_data_service/lib/data/services/shared_preferences_service.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/data/services/shared_preferences_service.dart rename to examples/app-architecture/todo_data_service/lib/data/services/shared_preferences_service.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/main.dart b/examples/app-architecture/todo_data_service/lib/main.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/main.dart rename to examples/app-architecture/todo_data_service/lib/main.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/main_app_viewmodel.dart b/examples/app-architecture/todo_data_service/lib/main_app_viewmodel.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/main_app_viewmodel.dart rename to examples/app-architecture/todo_data_service/lib/main_app_viewmodel.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/ui/theme_config/viewmodel/theme_switch_viewmodel.dart b/examples/app-architecture/todo_data_service/lib/ui/theme_config/viewmodel/theme_switch_viewmodel.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/ui/theme_config/viewmodel/theme_switch_viewmodel.dart rename to examples/app-architecture/todo_data_service/lib/ui/theme_config/viewmodel/theme_switch_viewmodel.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/ui/theme_config/widgets/theme_switch.dart b/examples/app-architecture/todo_data_service/lib/ui/theme_config/widgets/theme_switch.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/ui/theme_config/widgets/theme_switch.dart rename to examples/app-architecture/todo_data_service/lib/ui/theme_config/widgets/theme_switch.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/ui/todo_list/viewmodel/todo_list_viewmodel.dart b/examples/app-architecture/todo_data_service/lib/ui/todo_list/viewmodel/todo_list_viewmodel.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/ui/todo_list/viewmodel/todo_list_viewmodel.dart rename to examples/app-architecture/todo_data_service/lib/ui/todo_list/viewmodel/todo_list_viewmodel.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/ui/todo_list/widgets/todo_list_screen.dart b/examples/app-architecture/todo_data_service/lib/ui/todo_list/widgets/todo_list_screen.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/ui/todo_list/widgets/todo_list_screen.dart rename to examples/app-architecture/todo_data_service/lib/ui/todo_list/widgets/todo_list_screen.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/utils/command.dart b/examples/app-architecture/todo_data_service/lib/utils/command.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/utils/command.dart rename to examples/app-architecture/todo_data_service/lib/utils/command.dart diff --git a/examples/cookbook/architecture/todo_data_service/lib/utils/result.dart b/examples/app-architecture/todo_data_service/lib/utils/result.dart similarity index 100% rename from examples/cookbook/architecture/todo_data_service/lib/utils/result.dart rename to examples/app-architecture/todo_data_service/lib/utils/result.dart diff --git a/examples/cookbook/architecture/todo_data_service/pubspec.yaml b/examples/app-architecture/todo_data_service/pubspec.yaml similarity index 93% rename from examples/cookbook/architecture/todo_data_service/pubspec.yaml rename to examples/app-architecture/todo_data_service/pubspec.yaml index d9692bccb70..6f1f11f67f0 100644 --- a/examples/cookbook/architecture/todo_data_service/pubspec.yaml +++ b/examples/app-architecture/todo_data_service/pubspec.yaml @@ -21,7 +21,7 @@ dev_dependencies: freezed: ^2.5.7 json_serializable: ^6.8.0 example_utils: - path: ../../../example_utils + path: ../../example_utils flutter: uses-material-design: true \ No newline at end of file diff --git a/src/_data/sidenav.yml b/src/_data/sidenav.yml index 505236fe4d6..355529b7eaf 100644 --- a/src/_data/sidenav.yml +++ b/src/_data/sidenav.yml @@ -443,20 +443,7 @@ - title: Recommendations permalink: /app-architecture/recommendations - title: Design patterns - permalink: /cookbook/architecture - children: - - title: Optimistic state - permalink: /cookbook/architecture/optimistic-state - - title: Command - permalink: /cookbook/architecture/command - - title: Result - permalink: /cookbook/architecture/result - - title: "Persistent storage architecture: Key-value data" - permalink: /cookbook/architecture/key-value-data - - title: "Persistent storage architecture: SQL" - permalink: /cookbook/architecture/sql - - title: Offline-first - permalink: /cookbook/architecture/offline-first + permalink: /app-architecture/design-patterns - title: Platform integration permalink: /platform-integration diff --git a/src/_includes/expansion-list.html b/src/_includes/expansion-list.html new file mode 100644 index 00000000000..a8865261570 --- /dev/null +++ b/src/_includes/expansion-list.html @@ -0,0 +1,58 @@ +{%- comment -%} +This component expects a list of article or page objects. +The frontmatter of each article should have the following attributes: +- title: String - name of the article +- description: String - 1-2 sentence description of the article +- contentTags: List - A short list of items that describe what the reader + can expect from the content or describe meta information about the article. + i.e. data, user-experience OR tutorial, 10 minute read +- iconPath: String - the path to an image that is shown in next to the title +{%- endcomment -%} + +
+ {% for item in list -%} + {% assign id = baseId | append: '-expansion-' | append: forloop.index -%} + {% if item.expanded -%} + {% assign expanded = 'true' -%} + {% assign show = 'show' -%} + {% else -%} + {% assign class = 'collapsed' -%} + {% assign expanded = 'false' -%} + {% assign show = '' -%} + {% endif -%} + + {% endfor -%} +
diff --git a/src/_sass/base/_variables.scss b/src/_sass/base/_variables.scss index c6d8b62b10a..8b05feccbc8 100644 --- a/src/_sass/base/_variables.scss +++ b/src/_sass/base/_variables.scss @@ -21,9 +21,11 @@ $site-color-sub-grey: #8d9399; $site-color-nav-links: #6E7274; $site-color-body: #212121; // Poor contrast with links $site-color-body-light: color.scale($site-color-body, $lightness: 20%); +$site-color-body-caption: color.scale($site-color-body, $lightness: 30%); $site-color-footer: #303c42; $site-color-primary: $flutter-color-blue-500; $twitter-color: #60CAF6; +$site-color-panel-background: color.scale($site-color-primary, $lightness: 95%); // Fonts $font-size-base-weight: 400; diff --git a/src/_sass/components/_expansion-list.scss b/src/_sass/components/_expansion-list.scss new file mode 100644 index 00000000000..52b190a9fa0 --- /dev/null +++ b/src/_sass/components/_expansion-list.scss @@ -0,0 +1,149 @@ +@use '../base/variables' as *; +@use '../vendor/bootstrap'; + +.expansion-panel-list { + background: $site-color-panel-background; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 12px; + margin-top: 2rem; + margin-bottom: 2rem; + + // Rotates chevron + @mixin collapsible() { + display: flex; + align-items: center; + justify-content: space-between; + padding-right: 1rem; + + // Border radius to match entire list, so focus outline matches. + border-radius: 12px; + + // Add padding on small screens, because images aren't displayed. + @include bootstrap.media-breakpoint-down(sm) { + padding-left: 1rem; + + &:first-child { + // Add extra space above first expansion panel. + padding-top: 0.5rem; + } + } + + &::after { + // Duplicated since Firefox doesn't support content alt text. + content: 'keyboard_arrow_down'; + content: 'keyboard_arrow_down' / ''; + font: $site-font-icon; + transition: transform .25s ease-in-out; + } + + .collapsing { + transition-duration: .2s; + } + + &:not(.collapsed) { + &::after { + transform: rotate(180deg); + } + } + } + + .expansion-panel { + > a { + // Adds display:flex, align:center, and justify:space-between. + @include collapsible(); + } + + a:hover { + text-decoration: none; + } + } + + .expansion-panel-title { + display: flex; + flex-direction: row; + align-items: center; + + .expansion-panel-title-leading { + height: 8rem; + width: 8rem; + margin: .5rem; + padding: 1rem; + + // Hide leading image on small screens. + display: none; + + @include bootstrap.media-breakpoint-up(md) { + display: flex; + flex: 1 0 auto; + } + + img { + margin: auto; + } + } + + .expansion-panel-title-content { + .content-title { + color: $site-color-black; + font-size: 1rem; + font-weight: 500; + margin-bottom: .25rem; + + @include bootstrap.media-breakpoint-up(md) { + font-size: 1.25rem; + } + } + + .content-description { + color: $site-color-body; + margin-bottom: $site-spacer / 2; + } + + .content-tags { + display: flex; + flex-direction: row; + list-style: none; + padding-left: 0; + margin-bottom: .75rem; + + .tag { + color: $site-color-body-caption; + font-size: .8rem; + line-height: 1; + margin-bottom: 0; + + &::after { + // Duplicated since Firefox doesn't support content alt text. + content: ' |\00a0'; + content: ' |\00a0' / ''; + } + + &:last-child::after { + content: ''; + } + } + } + } + } + + .expansion-panel-body { + margin: auto; + width: 90%; + border-top: .05rem solid rgba(0, 0, 0, 0.125); + + p { + color: $site-color-body; + margin-top: 1.5rem; + } + + .separator { + margin-bottom: 3rem; + } + } + + :last-child { + .expansion-panel-body { + border-bottom: none; + } + } +} diff --git a/src/_sass/site.scss b/src/_sass/site.scss index ba28e88610c..2133a96dd6d 100644 --- a/src/_sass/site.scss +++ b/src/_sass/site.scss @@ -16,6 +16,7 @@ @use 'components/content'; @use 'components/cookie-notice'; @use 'components/d2h'; +@use 'components/expansion-list'; @use 'components/footer'; @use 'components/header'; @use 'components/juicy-button'; diff --git a/src/content/app-architecture/case-study/data-layer.md b/src/content/app-architecture/case-study/data-layer.md index 3c8e7edfa79..6a871713eaa 100644 --- a/src/content/app-architecture/case-study/data-layer.md +++ b/src/content/app-architecture/case-study/data-layer.md @@ -239,7 +239,7 @@ completing the cycle. [`APIClient`]: https://github.com/flutter/samples/blob/main/compass_app/app/lib/data/services/api/api_client.dart [`sealed`]: {{site.dart-site}}/language/class-modifiers#sealed [`BookingRepository` classes on GitHub]: https://github.com/flutter/samples/tree/main/compass_app/app/lib/data/repositories/booking -[Result cookbook recipe]: /cookbook/architecture +[Result cookbook recipe]: /app-architecture/design-patterns/result [//]: # (todo ewindmill@ - update Result link after #11444 lands) diff --git a/src/content/app-architecture/design-patterns.md b/src/content/app-architecture/design-patterns.md new file mode 100644 index 00000000000..e4581d0e417 --- /dev/null +++ b/src/content/app-architecture/design-patterns.md @@ -0,0 +1,26 @@ +--- +title: Architecture design patterns +short-title: Design patterns +description: >- + A collection of articles about useful design patterns for + building Flutter applications. +prev: + title: Recommendations + path: /app-architecture/recommendations +toc: false +--- + +If you've already read through the [architecture guide][] page, +or if you're comfortable with Flutter and the MVVM pattern, +the following articles are for you. + +These articles aren't about high-level app architecture, +rather they're about solving specific design problems that improve your +application's code base regardless of how you've architected your app. +That said, the articles do assume the MVVM pattern laid out on the +previous pages in the code examples. + +{% assign recipes = collections.design-patterns | sort: "data.order" -%} +{% render expansion-list.html, list: recipes, baseId: 'design-patterns' %} + +[architecture guide]: /app-architecture/guide diff --git a/src/content/cookbook/architecture/command.md b/src/content/app-architecture/design-patterns/command.md similarity index 97% rename from src/content/cookbook/architecture/command.md rename to src/content/app-architecture/design-patterns/command.md index 4269112aeee..974825fbb1c 100644 --- a/src/content/cookbook/architecture/command.md +++ b/src/content/app-architecture/design-patterns/command.md @@ -1,13 +1,18 @@ --- -title: Command pattern -description: >- - Learn how to improve your view models with commands. +title: The command pattern +description: "Simplify view model logic by implementing a Command class." +contentTags: + - mvvm + - asynchronous dart + - state +iconPath: /assets/images/docs/app-architecture/design-patterns/command-icon.svg +order: 4 js: - defer: true url: /assets/js/inject_dartpad.js --- - + [Model-View-ViewModel (MVVM)][] is a design pattern that separates a feature of an application into three parts: @@ -626,7 +631,7 @@ final class Command1 extends Command { ``` [Compass App example]: {{site.repo.samples}}/tree/main/compass_app -[`Result` class]: /cookbook/architecture/result +[`Result` class]: /app-architecture/design-patterns/result [pub.dev]: {{site.pub}} [`flutter_command`]: {{site.pub-pkg}}/flutter_command [`ChangeNotifier`]: /get-started/fundamentals/state-management diff --git a/src/content/app-architecture/design-patterns/design-patterns.json b/src/content/app-architecture/design-patterns/design-patterns.json new file mode 100644 index 00000000000..3f2929c1265 --- /dev/null +++ b/src/content/app-architecture/design-patterns/design-patterns.json @@ -0,0 +1,3 @@ +{ + "tags": "design-patterns" +} diff --git a/src/content/cookbook/architecture/key-value-data.md b/src/content/app-architecture/design-patterns/key-value-data.md similarity index 96% rename from src/content/cookbook/architecture/key-value-data.md rename to src/content/app-architecture/design-patterns/key-value-data.md index 507e14f07b3..81b5b2b5008 100644 --- a/src/content/cookbook/architecture/key-value-data.md +++ b/src/content/app-architecture/design-patterns/key-value-data.md @@ -1,12 +1,18 @@ --- title: "Persistent storage architecture: Key-value data" -description: Create a service to store key-value data +description: Save application data to a user's on-device key-value store. +contentTags: + - data + - shared-preferences + - dark mode +iconPath: /assets/images/docs/app-architecture/design-patterns/kv-store-icon.svg +order: 1 js: - defer: true url: /assets/js/inject_dartpad.js --- - + Most Flutter applications, no matter how small or big they are, require storing data on the user’s device at some point, such as API keys, @@ -358,5 +364,5 @@ ListenableBuilder( [Flutter architecture design]: /app-architecture [Store key-value data on disk]: /cookbook/persistence/key-value -[Persistent Storage Architecture: SQL]: /cookbook/architecture/sql +[Persistent Storage Architecture: SQL]: /app-architecture/design-patterns/sql [`/examples/cookbook/architecture/todo_data_service/`]: {{site.repo.this}}/tree/main/examples/cookbook/architecture/todo_data_service/ diff --git a/src/content/cookbook/architecture/offline-first.md b/src/content/app-architecture/design-patterns/offline-first.md similarity index 97% rename from src/content/cookbook/architecture/offline-first.md rename to src/content/app-architecture/design-patterns/offline-first.md index 40b202ed249..23ae3e6f3c3 100644 --- a/src/content/cookbook/architecture/offline-first.md +++ b/src/content/app-architecture/design-patterns/offline-first.md @@ -1,12 +1,18 @@ --- title: "Offline-first support" -description: Create an app with offline-first support. +description: Implement offline-first support for one feature in an application. +contentTags: + - data + - user experience + - repository pattern +iconPath: /assets/images/docs/app-architecture/design-patterns/offline-first-icon.svg +order: 3 js: - defer: true url: /assets/js/inject_dartpad.js --- - + An offline-first application is an app capable of offering most or all of its functionality while being disconnected from the internet. @@ -516,9 +522,9 @@ take into account the device status and your application needs, as different applications may have different requirements. [Flutter Architecture guidelines]:/app-architecture -[Persistent Storage Architecture: SQL]:/cookbook/architecture/sql +[Persistent Storage Architecture: SQL]:/app-architecture/design-patterns/sql [`freezed`]:{{site.pub}}/packages/freezed -[Optimistic State design pattern]:/cookbook/architecture/optimistic-state +[Optimistic State design pattern]:/app-architecture/design-patterns/optimistic-state [`workmanager`]:{{site.pub}}/packages/workmanager [`connectivity_plus`]:{{site.pub}}/packages/connectivity_plus [`battery_plus`]:{{site.pub}}/packages/battery_plus diff --git a/src/content/cookbook/architecture/optimistic-state.md b/src/content/app-architecture/design-patterns/optimistic-state.md similarity index 98% rename from src/content/cookbook/architecture/optimistic-state.md rename to src/content/app-architecture/design-patterns/optimistic-state.md index f1d714dd4f2..54b902014b4 100644 --- a/src/content/cookbook/architecture/optimistic-state.md +++ b/src/content/app-architecture/design-patterns/optimistic-state.md @@ -1,12 +1,17 @@ --- -title: Optimistic State -description: Improve the perception of responsivenes of views with a state. +title: Optimistic state +description: "Improve the perception of responsiveness of an application by implementing optimistic state." +contentTags: + - user experience + - asynchronous dart +iconPath: /assets/images/docs/app-architecture/design-patterns/optimistic-state-icon.svg +order: 0 js: - defer: true url: /assets/js/inject_dartpad.js --- - + When building user experiences, the perception of performance is sometimes just as important as diff --git a/src/content/cookbook/architecture/result.md b/src/content/app-architecture/design-patterns/result.md similarity index 97% rename from src/content/cookbook/architecture/result.md rename to src/content/app-architecture/design-patterns/result.md index 11f8d9b824b..8d56d5c6930 100644 --- a/src/content/cookbook/architecture/result.md +++ b/src/content/app-architecture/design-patterns/result.md @@ -1,13 +1,17 @@ --- -title: Result class -description: >- - Learn to handle errors and return values with a result class. +title: Error handling with Result objects +description: "Improve error handling across classes with Result objects." +contentTags: + - error handling + - services +iconPath: /assets/images/docs/app-architecture/design-patterns/result-icon.svg +order: 5 js: - defer: true url: /assets/js/inject_dartpad.js --- - + Dart provides a built-in error handling mechanism with the ability to throw and catch exceptions. diff --git a/src/content/cookbook/architecture/sql.md b/src/content/app-architecture/design-patterns/sql.md similarity index 97% rename from src/content/cookbook/architecture/sql.md rename to src/content/app-architecture/design-patterns/sql.md index 6b80c5a8046..16d0d3496e0 100644 --- a/src/content/cookbook/architecture/sql.md +++ b/src/content/app-architecture/design-patterns/sql.md @@ -1,12 +1,17 @@ --- title: "Persistent storage architecture: SQL" -description: Create a service to store complex data with SQL +description: Save complex application data to a user's device with SQL. +contentTags: + - data + - SQL +iconPath: /assets/images/docs/app-architecture/design-patterns/sql-icon.svg +order: 2 js: - defer: true url: /assets/js/inject_dartpad.js --- - + Most Flutter applications, no matter how small or big they are, @@ -477,7 +482,7 @@ TodoListScreen( [Flutter architecture recommendations]:/app-architecture [MVVM pattern]:/get-started/fundamentals/state-management#using-mvvm-for-your-applications-architecture [Persist data with SQLite]:/cookbook/persistence/sqlite -[Persistent storage architecture: Key-value data]:/cookbook/architecture/key-value-data +[Persistent storage architecture: Key-value data]:/app-architecture/design-patterns/key-value-data [`/examples/cookbook/architecture/todo_data_service/`]: {{site.repo.this}}/tree/main/examples/cookbook/architecture/todo_data_service/ [`sqflite_common_ffi_web`]:{{site.pub}}/packages/sqflite_common_ffi_web [`sqflite_common_ffi`]:{{site.pub}}/packages/sqflite_common_ffi diff --git a/src/content/app-architecture/recommendations.md b/src/content/app-architecture/recommendations.md index 1c3d79218c7..260329883f5 100644 --- a/src/content/app-architecture/recommendations.md +++ b/src/content/app-architecture/recommendations.md @@ -6,6 +6,9 @@ description: > prev: title: Architecture case study path: /app-architecture/case-study +next: + title: Design patterns + path: /app-architecture/design-patterns --- This page presents architecture best practices, why they matter, and diff --git a/src/content/assets/images/docs/app-architecture/design-patterns/command-icon.svg b/src/content/assets/images/docs/app-architecture/design-patterns/command-icon.svg new file mode 100644 index 00000000000..6d96c6e2c38 --- /dev/null +++ b/src/content/assets/images/docs/app-architecture/design-patterns/command-icon.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/assets/images/docs/app-architecture/design-patterns/kv-store-icon.svg b/src/content/assets/images/docs/app-architecture/design-patterns/kv-store-icon.svg new file mode 100644 index 00000000000..18d3d418f11 --- /dev/null +++ b/src/content/assets/images/docs/app-architecture/design-patterns/kv-store-icon.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/assets/images/docs/app-architecture/design-patterns/offline-first-icon.svg b/src/content/assets/images/docs/app-architecture/design-patterns/offline-first-icon.svg new file mode 100644 index 00000000000..84fe4c60fd2 --- /dev/null +++ b/src/content/assets/images/docs/app-architecture/design-patterns/offline-first-icon.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/assets/images/docs/app-architecture/design-patterns/optimistic-state-icon.svg b/src/content/assets/images/docs/app-architecture/design-patterns/optimistic-state-icon.svg new file mode 100644 index 00000000000..660105760a8 --- /dev/null +++ b/src/content/assets/images/docs/app-architecture/design-patterns/optimistic-state-icon.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/assets/images/docs/app-architecture/design-patterns/result-icon.svg b/src/content/assets/images/docs/app-architecture/design-patterns/result-icon.svg new file mode 100644 index 00000000000..1526a86b0d5 --- /dev/null +++ b/src/content/assets/images/docs/app-architecture/design-patterns/result-icon.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/assets/images/docs/app-architecture/design-patterns/sql-icon.svg b/src/content/assets/images/docs/app-architecture/design-patterns/sql-icon.svg new file mode 100644 index 00000000000..236773a651c --- /dev/null +++ b/src/content/assets/images/docs/app-architecture/design-patterns/sql-icon.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/cookbook/architecture/index.md b/src/content/cookbook/architecture/index.md deleted file mode 100644 index f02fc84f810..00000000000 --- a/src/content/cookbook/architecture/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Design patterns -description: A catalog of recipes for application architecture design patterns. ---- - -{% include docs/cookbook-group-index.md %}