diff --git a/.github/workflows/.env b/.github/workflows/.env index 98a7efb..6eef3cd 100644 --- a/.github/workflows/.env +++ b/.github/workflows/.env @@ -1 +1 @@ -FLUTTER_VERSION=3.24.3 +FLUTTER_VERSION=3.35.2 diff --git a/.github/workflows/test-flutter.yaml b/.github/workflows/test-flutter.yaml index f3605be..363c041 100644 --- a/.github/workflows/test-flutter.yaml +++ b/.github/workflows/test-flutter.yaml @@ -10,7 +10,14 @@ jobs: test: runs-on: macos-latest strategy: - matrix: { dir: ['example/simple_app', 'example/multi_packages_app/app', 'example/multi_packages_app/theme'] } + matrix: + include: + - dir: example/simple_app + name: simple_app + - dir: example/multi_packages_app/app + name: multi_packages_app_app + - dir: example/multi_packages_app/theme + name: multi_packages_app_theme defaults: run: working-directory: ${{ matrix.dir }} @@ -42,3 +49,11 @@ jobs: - name: Run tests run: flutter test --no-pub --test-randomize-ordering-seed random + + - name: Upload golden test failures + if: failure() + uses: actions/upload-artifact@v4 + with: + name: golden-failures-${{ matrix.name }} + path: ${{ matrix.dir }}/test/**/failures/ + if-no-files-found: ignore diff --git a/CHANGELOG.md b/CHANGELOG.md index e72a2ae..efb9080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## 0.10.0 + +* feat: Add support for 2-button and 3-button navigation for Android devices. + ```dart + WindowConfigData( + systemNavBar = SystemNavBarData.threeButton(), + ) + // or + WindowConfigData( + systemNavBar = SystemNavBarData.twoButton(), + ) + ``` +* **BREAKING**: refactor: replaced `homeIndicator` by `systemNavBar` in `WindowConfigData` for the home gesture indicator: + ```diff + WindowConfigData( + - homeIndicator = HomeIndicatorData(bottomPadding, size) + + systemNavBar = SystemNavBarData.gestureIndicator(bottomPadding, size) + ) + ``` + ## 0.9.1 * feat: await image now works with ShapeDecopration diff --git a/example/multi_packages_app/app/pubspec.lock b/example/multi_packages_app/app/pubspec.lock index 829a550..58219db 100644 --- a/example/multi_packages_app/app/pubspec.lock +++ b/example/multi_packages_app/app/pubspec.lock @@ -7,7 +7,7 @@ packages: path: "../../.." relative: true source: path - version: "0.7.2" + version: "0.10.0" async: dependency: transitive description: @@ -28,26 +28,26 @@ packages: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.1" cupertino_icons: dependency: "direct main" description: @@ -68,10 +68,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" file: dependency: transitive description: @@ -94,34 +94,34 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" matcher: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -142,10 +142,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" multi_packages_example_theme: dependency: "direct main" description: @@ -165,10 +165,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" platform: dependency: transitive description: @@ -189,7 +189,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -202,18 +202,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: @@ -234,10 +234,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.6" theodo_analysis: dependency: "direct dev" description: @@ -250,10 +250,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -263,5 +263,5 @@ packages: source: hosted version: "14.2.5" sdks: - dart: ">=3.3.0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/example/multi_packages_app/app/test/src/preview/desktop-app_multi_packages.png b/example/multi_packages_app/app/test/src/preview/desktop-app_multi_packages.png index 02c124a..166ffda 100644 Binary files a/example/multi_packages_app/app/test/src/preview/desktop-app_multi_packages.png and b/example/multi_packages_app/app/test/src/preview/desktop-app_multi_packages.png differ diff --git a/example/multi_packages_app/app/test/src/preview/desktop-app_multi_packages_with_keyboard.png b/example/multi_packages_app/app/test/src/preview/desktop-app_multi_packages_with_keyboard.png index 255f045..85b5f58 100644 Binary files a/example/multi_packages_app/app/test/src/preview/desktop-app_multi_packages_with_keyboard.png and b/example/multi_packages_app/app/test/src/preview/desktop-app_multi_packages_with_keyboard.png differ diff --git a/example/multi_packages_app/app/test/src/preview/iPadPro-app_multi_packages.png b/example/multi_packages_app/app/test/src/preview/iPadPro-app_multi_packages.png index b896597..034b058 100644 Binary files a/example/multi_packages_app/app/test/src/preview/iPadPro-app_multi_packages.png and b/example/multi_packages_app/app/test/src/preview/iPadPro-app_multi_packages.png differ diff --git a/example/multi_packages_app/app/test/src/preview/iPadPro-app_multi_packages_with_keyboard.png b/example/multi_packages_app/app/test/src/preview/iPadPro-app_multi_packages_with_keyboard.png index 4faca76..eba251c 100644 Binary files a/example/multi_packages_app/app/test/src/preview/iPadPro-app_multi_packages_with_keyboard.png and b/example/multi_packages_app/app/test/src/preview/iPadPro-app_multi_packages_with_keyboard.png differ diff --git a/example/multi_packages_app/app/test/src/preview/iPhone_16-app_multi_packages.png b/example/multi_packages_app/app/test/src/preview/iPhone_16-app_multi_packages.png index a871ac0..9997651 100644 Binary files a/example/multi_packages_app/app/test/src/preview/iPhone_16-app_multi_packages.png and b/example/multi_packages_app/app/test/src/preview/iPhone_16-app_multi_packages.png differ diff --git a/example/multi_packages_app/app/test/src/preview/iPhone_16-app_multi_packages_with_keyboard.png b/example/multi_packages_app/app/test/src/preview/iPhone_16-app_multi_packages_with_keyboard.png index 99ba414..e236318 100644 Binary files a/example/multi_packages_app/app/test/src/preview/iPhone_16-app_multi_packages_with_keyboard.png and b/example/multi_packages_app/app/test/src/preview/iPhone_16-app_multi_packages_with_keyboard.png differ diff --git a/example/multi_packages_app/app/test/src/preview/iPhone_8-app_multi_packages.png b/example/multi_packages_app/app/test/src/preview/iPhone_8-app_multi_packages.png index 33f1fab..e481e9f 100644 Binary files a/example/multi_packages_app/app/test/src/preview/iPhone_8-app_multi_packages.png and b/example/multi_packages_app/app/test/src/preview/iPhone_8-app_multi_packages.png differ diff --git a/example/multi_packages_app/app/test/src/preview/iPhone_8-app_multi_packages_with_keyboard.png b/example/multi_packages_app/app/test/src/preview/iPhone_8-app_multi_packages_with_keyboard.png index 1e7bf48..4a088be 100644 Binary files a/example/multi_packages_app/app/test/src/preview/iPhone_8-app_multi_packages_with_keyboard.png and b/example/multi_packages_app/app/test/src/preview/iPhone_8-app_multi_packages_with_keyboard.png differ diff --git a/example/multi_packages_app/app/test/src/preview/pixel_9-app_multi_packages.png b/example/multi_packages_app/app/test/src/preview/pixel_9-app_multi_packages.png index ca18808..31aed53 100644 Binary files a/example/multi_packages_app/app/test/src/preview/pixel_9-app_multi_packages.png and b/example/multi_packages_app/app/test/src/preview/pixel_9-app_multi_packages.png differ diff --git a/example/multi_packages_app/app/test/src/preview/pixel_9-app_multi_packages_with_keyboard.png b/example/multi_packages_app/app/test/src/preview/pixel_9-app_multi_packages_with_keyboard.png index ed20c1c..629413e 100644 Binary files a/example/multi_packages_app/app/test/src/preview/pixel_9-app_multi_packages_with_keyboard.png and b/example/multi_packages_app/app/test/src/preview/pixel_9-app_multi_packages_with_keyboard.png differ diff --git a/example/multi_packages_app/theme/pubspec.lock b/example/multi_packages_app/theme/pubspec.lock index fd39919..737d2ca 100644 --- a/example/multi_packages_app/theme/pubspec.lock +++ b/example/multi_packages_app/theme/pubspec.lock @@ -7,7 +7,7 @@ packages: path: "../../.." relative: true source: path - version: "0.7.2" + version: "0.10.0" async: dependency: transitive description: @@ -28,26 +28,26 @@ packages: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.1" cupertino_icons: dependency: "direct main" description: @@ -68,10 +68,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" file: dependency: transitive description: @@ -94,34 +94,34 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" matcher: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -142,10 +142,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" package_config: dependency: transitive description: @@ -158,10 +158,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" platform: dependency: transitive description: @@ -182,7 +182,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -195,18 +195,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: @@ -227,10 +227,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.6" theodo_analysis: dependency: "direct dev" description: @@ -243,10 +243,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -256,5 +256,5 @@ packages: source: hosted version: "14.2.5" sdks: - dart: ">=3.3.0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/example/simple_app/pubspec.lock b/example/simple_app/pubspec.lock index 862d79c..e0afe6e 100644 --- a/example/simple_app/pubspec.lock +++ b/example/simple_app/pubspec.lock @@ -7,7 +7,7 @@ packages: path: "../.." relative: true source: path - version: "0.7.2" + version: "0.10.0" async: dependency: transitive description: @@ -28,26 +28,26 @@ packages: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.1" cupertino_icons: dependency: "direct main" description: @@ -68,10 +68,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" file: dependency: transitive description: @@ -94,34 +94,34 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" matcher: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -142,10 +142,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" package_config: dependency: transitive description: @@ -158,10 +158,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" platform: dependency: transitive description: @@ -182,7 +182,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -195,18 +195,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: @@ -227,10 +227,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.6" theodo_analysis: dependency: "direct dev" description: @@ -243,10 +243,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -256,5 +256,5 @@ packages: source: hosted version: "14.2.5" sdks: - dart: ">=3.3.0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/example/simple_app/test/flutter_test_config.dart b/example/simple_app/test/flutter_test_config.dart index d4d1c9d..866c904 100644 --- a/example/simple_app/test/flutter_test_config.dart +++ b/example/simple_app/test/flutter_test_config.dart @@ -4,12 +4,19 @@ import 'package:adaptive_test/adaptive_test.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; +final pixel5TwoButton = pixel5ThreeButton.copyWith( + name: 'pixel_5_two_button', + systemNavBar: const SystemNavBarData.twoButton(), +); + final defaultDeviceConfigs = { iPhone8, iPhone16, iPadPro, desktop, pixel9, + pixel5ThreeButton, + pixel5TwoButton }; Future testExecutable(FutureOr Function() testMain) async { diff --git a/example/simple_app/test/src/preview/custom_path_desktop.png b/example/simple_app/test/src/preview/custom_path_desktop.png index 02c124a..166ffda 100644 Binary files a/example/simple_app/test/src/preview/custom_path_desktop.png and b/example/simple_app/test/src/preview/custom_path_desktop.png differ diff --git a/example/simple_app/test/src/preview/custom_path_iPadPro.png b/example/simple_app/test/src/preview/custom_path_iPadPro.png index b896597..034b058 100644 Binary files a/example/simple_app/test/src/preview/custom_path_iPadPro.png and b/example/simple_app/test/src/preview/custom_path_iPadPro.png differ diff --git a/example/simple_app/test/src/preview/custom_path_iPhone_16.png b/example/simple_app/test/src/preview/custom_path_iPhone_16.png index a871ac0..9997651 100644 Binary files a/example/simple_app/test/src/preview/custom_path_iPhone_16.png and b/example/simple_app/test/src/preview/custom_path_iPhone_16.png differ diff --git a/example/simple_app/test/src/preview/custom_path_iPhone_8.png b/example/simple_app/test/src/preview/custom_path_iPhone_8.png index 33f1fab..e481e9f 100644 Binary files a/example/simple_app/test/src/preview/custom_path_iPhone_8.png and b/example/simple_app/test/src/preview/custom_path_iPhone_8.png differ diff --git a/example/simple_app/test/src/preview/custom_path_pixel_5_three_button.png b/example/simple_app/test/src/preview/custom_path_pixel_5_three_button.png new file mode 100644 index 0000000..4931dc2 Binary files /dev/null and b/example/simple_app/test/src/preview/custom_path_pixel_5_three_button.png differ diff --git a/example/simple_app/test/src/preview/custom_path_pixel_5_two_button.png b/example/simple_app/test/src/preview/custom_path_pixel_5_two_button.png new file mode 100644 index 0000000..6a123da Binary files /dev/null and b/example/simple_app/test/src/preview/custom_path_pixel_5_two_button.png differ diff --git a/example/simple_app/test/src/preview/custom_path_pixel_9.png b/example/simple_app/test/src/preview/custom_path_pixel_9.png index ca18808..31aed53 100644 Binary files a/example/simple_app/test/src/preview/custom_path_pixel_9.png and b/example/simple_app/test/src/preview/custom_path_pixel_9.png differ diff --git a/example/simple_app/test/src/preview/desktop-app_fade_in_image.png b/example/simple_app/test/src/preview/desktop-app_fade_in_image.png index 02c124a..166ffda 100644 Binary files a/example/simple_app/test/src/preview/desktop-app_fade_in_image.png and b/example/simple_app/test/src/preview/desktop-app_fade_in_image.png differ diff --git a/example/simple_app/test/src/preview/desktop-app_simple.png b/example/simple_app/test/src/preview/desktop-app_simple.png index 02c124a..166ffda 100644 Binary files a/example/simple_app/test/src/preview/desktop-app_simple.png and b/example/simple_app/test/src/preview/desktop-app_simple.png differ diff --git a/example/simple_app/test/src/preview/desktop-app_simple_with_keyboard.png b/example/simple_app/test/src/preview/desktop-app_simple_with_keyboard.png index 255f045..85b5f58 100644 Binary files a/example/simple_app/test/src/preview/desktop-app_simple_with_keyboard.png and b/example/simple_app/test/src/preview/desktop-app_simple_with_keyboard.png differ diff --git a/example/simple_app/test/src/preview/iPadPro-app_fade_in_image.png b/example/simple_app/test/src/preview/iPadPro-app_fade_in_image.png index b896597..034b058 100644 Binary files a/example/simple_app/test/src/preview/iPadPro-app_fade_in_image.png and b/example/simple_app/test/src/preview/iPadPro-app_fade_in_image.png differ diff --git a/example/simple_app/test/src/preview/iPadPro-app_simple.png b/example/simple_app/test/src/preview/iPadPro-app_simple.png index b896597..034b058 100644 Binary files a/example/simple_app/test/src/preview/iPadPro-app_simple.png and b/example/simple_app/test/src/preview/iPadPro-app_simple.png differ diff --git a/example/simple_app/test/src/preview/iPadPro-app_simple_with_keyboard.png b/example/simple_app/test/src/preview/iPadPro-app_simple_with_keyboard.png index 4faca76..eba251c 100644 Binary files a/example/simple_app/test/src/preview/iPadPro-app_simple_with_keyboard.png and b/example/simple_app/test/src/preview/iPadPro-app_simple_with_keyboard.png differ diff --git a/example/simple_app/test/src/preview/iPhone_16-app_fade_in_image.png b/example/simple_app/test/src/preview/iPhone_16-app_fade_in_image.png index a871ac0..9997651 100644 Binary files a/example/simple_app/test/src/preview/iPhone_16-app_fade_in_image.png and b/example/simple_app/test/src/preview/iPhone_16-app_fade_in_image.png differ diff --git a/example/simple_app/test/src/preview/iPhone_16-app_simple.png b/example/simple_app/test/src/preview/iPhone_16-app_simple.png index a871ac0..9997651 100644 Binary files a/example/simple_app/test/src/preview/iPhone_16-app_simple.png and b/example/simple_app/test/src/preview/iPhone_16-app_simple.png differ diff --git a/example/simple_app/test/src/preview/iPhone_16-app_simple_with_keyboard.png b/example/simple_app/test/src/preview/iPhone_16-app_simple_with_keyboard.png index 99ba414..e236318 100644 Binary files a/example/simple_app/test/src/preview/iPhone_16-app_simple_with_keyboard.png and b/example/simple_app/test/src/preview/iPhone_16-app_simple_with_keyboard.png differ diff --git a/example/simple_app/test/src/preview/iPhone_8-app_fade_in_image.png b/example/simple_app/test/src/preview/iPhone_8-app_fade_in_image.png index 33f1fab..e481e9f 100644 Binary files a/example/simple_app/test/src/preview/iPhone_8-app_fade_in_image.png and b/example/simple_app/test/src/preview/iPhone_8-app_fade_in_image.png differ diff --git a/example/simple_app/test/src/preview/iPhone_8-app_simple.png b/example/simple_app/test/src/preview/iPhone_8-app_simple.png index 33f1fab..e481e9f 100644 Binary files a/example/simple_app/test/src/preview/iPhone_8-app_simple.png and b/example/simple_app/test/src/preview/iPhone_8-app_simple.png differ diff --git a/example/simple_app/test/src/preview/iPhone_8-app_simple_with_keyboard.png b/example/simple_app/test/src/preview/iPhone_8-app_simple_with_keyboard.png index 1e7bf48..4a088be 100644 Binary files a/example/simple_app/test/src/preview/iPhone_8-app_simple_with_keyboard.png and b/example/simple_app/test/src/preview/iPhone_8-app_simple_with_keyboard.png differ diff --git a/example/simple_app/test/src/preview/pixel_5_three_button-app_fade_in_image.png b/example/simple_app/test/src/preview/pixel_5_three_button-app_fade_in_image.png new file mode 100644 index 0000000..4931dc2 Binary files /dev/null and b/example/simple_app/test/src/preview/pixel_5_three_button-app_fade_in_image.png differ diff --git a/example/simple_app/test/src/preview/pixel_5_three_button-app_simple.png b/example/simple_app/test/src/preview/pixel_5_three_button-app_simple.png new file mode 100644 index 0000000..4931dc2 Binary files /dev/null and b/example/simple_app/test/src/preview/pixel_5_three_button-app_simple.png differ diff --git a/example/simple_app/test/src/preview/pixel_5_three_button-app_simple_with_keyboard.png b/example/simple_app/test/src/preview/pixel_5_three_button-app_simple_with_keyboard.png new file mode 100644 index 0000000..f93bf7b Binary files /dev/null and b/example/simple_app/test/src/preview/pixel_5_three_button-app_simple_with_keyboard.png differ diff --git a/example/simple_app/test/src/preview/pixel_5_two_button-app_fade_in_image.png b/example/simple_app/test/src/preview/pixel_5_two_button-app_fade_in_image.png new file mode 100644 index 0000000..6a123da Binary files /dev/null and b/example/simple_app/test/src/preview/pixel_5_two_button-app_fade_in_image.png differ diff --git a/example/simple_app/test/src/preview/pixel_5_two_button-app_simple.png b/example/simple_app/test/src/preview/pixel_5_two_button-app_simple.png new file mode 100644 index 0000000..6a123da Binary files /dev/null and b/example/simple_app/test/src/preview/pixel_5_two_button-app_simple.png differ diff --git a/example/simple_app/test/src/preview/pixel_5_two_button-app_simple_with_keyboard.png b/example/simple_app/test/src/preview/pixel_5_two_button-app_simple_with_keyboard.png new file mode 100644 index 0000000..4795dbe Binary files /dev/null and b/example/simple_app/test/src/preview/pixel_5_two_button-app_simple_with_keyboard.png differ diff --git a/example/simple_app/test/src/preview/pixel_9-app_fade_in_image.png b/example/simple_app/test/src/preview/pixel_9-app_fade_in_image.png index ca18808..31aed53 100644 Binary files a/example/simple_app/test/src/preview/pixel_9-app_fade_in_image.png and b/example/simple_app/test/src/preview/pixel_9-app_fade_in_image.png differ diff --git a/example/simple_app/test/src/preview/pixel_9-app_simple.png b/example/simple_app/test/src/preview/pixel_9-app_simple.png index ca18808..31aed53 100644 Binary files a/example/simple_app/test/src/preview/pixel_9-app_simple.png and b/example/simple_app/test/src/preview/pixel_9-app_simple.png differ diff --git a/example/simple_app/test/src/preview/pixel_9-app_simple_with_keyboard.png b/example/simple_app/test/src/preview/pixel_9-app_simple_with_keyboard.png index ed20c1c..629413e 100644 Binary files a/example/simple_app/test/src/preview/pixel_9-app_simple_with_keyboard.png and b/example/simple_app/test/src/preview/pixel_9-app_simple_with_keyboard.png differ diff --git a/lib/adaptive_test.dart b/lib/adaptive_test.dart index 0cce820..33a304e 100644 --- a/lib/adaptive_test.dart +++ b/lib/adaptive_test.dart @@ -1,10 +1,15 @@ export 'src/adaptive/adaptive_test.dart'; export 'src/adaptive/devices_data.dart'; export 'src/adaptive/widgets/adaptive_wrapper.dart'; -export 'src/adaptive/window_configuration.dart'; -export 'src/adaptive/window_size.dart'; +export 'src/adaptive/window_configuration_tester.dart'; +export 'src/adaptive/window_config.dart'; export 'src/configuration.dart'; export 'src/helpers/await_images.dart'; export 'src/helpers/fonts_loader.dart'; export 'src/helpers/goldens_difference.dart'; export 'src/helpers/skip_test_extension.dart'; +export 'src/adaptive/window_config_data/window_config_data.dart'; +export 'src/adaptive/window_config_data/system_nav_bar_data.dart' + show SystemNavBarData; +export 'src/adaptive/window_config_data/punch_hole_data.dart'; +export 'src/adaptive/window_config_data/dynamic_island_data.dart'; diff --git a/lib/src/adaptive/adaptive_test.dart b/lib/src/adaptive/adaptive_test.dart index ce30375..47f6f38 100644 --- a/lib/src/adaptive/adaptive_test.dart +++ b/lib/src/adaptive/adaptive_test.dart @@ -1,8 +1,8 @@ import 'dart:io'; import 'package:adaptive_test/src/adaptive/widgets/adaptive_wrapper.dart'; -import 'package:adaptive_test/src/adaptive/window_configuration.dart'; -import 'package:adaptive_test/src/adaptive/window_size.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/window_config_data.dart'; +import 'package:adaptive_test/src/adaptive/window_configuration_tester.dart'; import 'package:adaptive_test/src/configuration.dart'; import 'package:adaptive_test/src/helpers/await_images.dart'; import 'package:adaptive_test/src/helpers/skip_test_extension.dart'; diff --git a/lib/src/adaptive/devices_data.dart b/lib/src/adaptive/devices_data.dart index 976d646..96ecd3b 100644 --- a/lib/src/adaptive/devices_data.dart +++ b/lib/src/adaptive/devices_data.dart @@ -1,4 +1,7 @@ -import 'package:adaptive_test/src/adaptive/window_size.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/dynamic_island_data.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/system_nav_bar_data.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/punch_hole_data.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/window_config_data.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/painting.dart'; @@ -9,6 +12,7 @@ enum _Device { iPadPro, desktop, pixel_5, + pixel_5_three_button, pixel_9; String get keyboardName => 'assets/keyboards/${this.name}.png'; @@ -39,7 +43,7 @@ final WindowConfigData iPhone13 = WindowConfigData( borderRadius: const BorderRadius.all( Radius.circular(47), ), - homeIndicator: const HomeIndicatorData(8, Size(139, 5)), + systemNavBar: const SystemNavBarData.gestureIndicator(8, Size(139, 5)), notchSize: const Size(154, 32), targetPlatform: TargetPlatform.iOS, keyboardName: _Device.iPhone_13.keyboardName, @@ -56,7 +60,7 @@ final WindowConfigData iPhone16 = WindowConfigData( borderRadius: const BorderRadius.all( Radius.circular(55), ), - homeIndicator: const HomeIndicatorData(8, Size(140, 5)), + systemNavBar: const SystemNavBarData.gestureIndicator(8, Size(140, 5)), dynamicIsland: DynamicIslandData(11, Size(125, 37)), targetPlatform: TargetPlatform.iOS, keyboardName: _Device.iPhone_16.keyboardName, @@ -73,13 +77,20 @@ final WindowConfigData pixel5 = WindowConfigData( borderRadius: const BorderRadius.all( Radius.circular(32), ), - homeIndicator: const HomeIndicatorData(8, Size(72, 2)), + systemNavBar: const SystemNavBarData.gestureIndicator(8, Size(72, 2)), targetPlatform: TargetPlatform.android, punchHole: const PunchHoleData(Offset(12, 12), 25), keyboardName: _Device.pixel_5.keyboardName, keyboardPackage: _keyboardPackage, ); +/// [WindowConfigData] for a Google Pixel 5 alternative with 3-button navbar. +final WindowConfigData pixel5ThreeButton = pixel5.copyWith( + name: _Device.pixel_5_three_button.name, + safeAreaPadding: const EdgeInsets.only(top: 49, bottom: 48), + systemNavBar: const SystemNavBarData.threeButton(), +); + /// [WindowConfigData] for a Google Pixel 9. final WindowConfigData pixel9 = WindowConfigData( _Device.pixel_9.name, @@ -90,7 +101,7 @@ final WindowConfigData pixel9 = WindowConfigData( borderRadius: const BorderRadius.all( Radius.circular(55), ), - homeIndicator: const HomeIndicatorData(10, Size(108, 4)), + systemNavBar: const SystemNavBarData.gestureIndicator(10, Size(108, 4)), targetPlatform: TargetPlatform.android, punchHole: const PunchHoleData(Offset(190, 17), 31), keyboardName: _Device.pixel_9.keyboardName, @@ -107,7 +118,7 @@ final WindowConfigData iPadPro = WindowConfigData( borderRadius: const BorderRadius.all( Radius.circular(24), ), - homeIndicator: const HomeIndicatorData(8, Size(315, 5)), + systemNavBar: const SystemNavBarData.gestureIndicator(8, Size(315, 5)), targetPlatform: TargetPlatform.iOS, keyboardName: _Device.iPadPro.keyboardName, keyboardPackage: _keyboardPackage, diff --git a/lib/src/adaptive/widgets/adaptive_wrapper.dart b/lib/src/adaptive/widgets/adaptive_wrapper.dart index 235d03a..a259f81 100644 --- a/lib/src/adaptive/widgets/adaptive_wrapper.dart +++ b/lib/src/adaptive/widgets/adaptive_wrapper.dart @@ -1,7 +1,8 @@ import 'package:adaptive_test/src/adaptive/widgets/layers/hardware_layer.dart'; import 'package:adaptive_test/src/adaptive/widgets/layers/keyboard_layer.dart'; -import 'package:adaptive_test/src/adaptive/widgets/layers/system_layer.dart'; -import 'package:adaptive_test/src/adaptive/window_size.dart'; +import 'package:adaptive_test/src/adaptive/widgets/layers/system_nav_bar_layer.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/window_config_data.dart'; +import 'package:adaptive_test/src/adaptive/window_config.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -9,7 +10,7 @@ import 'package:flutter_test/flutter_test.dart'; /// /// See also: /// * [HardwareLayer] -/// * [SystemLayer] +/// * [SystemNavBarLayer] /// * [KeyboardLayer] class AdaptiveWrapper extends StatelessWidget { const AdaptiveWrapper({ @@ -27,7 +28,7 @@ class AdaptiveWrapper extends StatelessWidget { return WindowConfig( windowConfig: windowConfig, child: HardwareLayer( - child: SystemLayer( + child: SystemNavBarLayer( child: KeyboardLayer( tester: tester, child: child, diff --git a/lib/src/adaptive/widgets/layers/system_layer.dart b/lib/src/adaptive/widgets/layers/gesture_indicator_system_nav_bar_layer.dart similarity index 53% rename from lib/src/adaptive/widgets/layers/system_layer.dart rename to lib/src/adaptive/widgets/layers/gesture_indicator_system_nav_bar_layer.dart index b205c02..122d650 100644 --- a/lib/src/adaptive/widgets/layers/system_layer.dart +++ b/lib/src/adaptive/widgets/layers/gesture_indicator_system_nav_bar_layer.dart @@ -1,36 +1,36 @@ -import 'package:adaptive_test/src/adaptive/window_size.dart'; +import 'package:adaptive_test/src/adaptive/window_config.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/system_nav_bar_data.dart'; import 'package:flutter/material.dart'; -class SystemLayer extends StatelessWidget { - const SystemLayer({ +class GestureIndicatorSystemNavBarLayer extends StatelessWidget { + const GestureIndicatorSystemNavBarLayer({ + required this.gestureIndicator, required this.child, super.key, }); + final GestureIndicatorSystemNavBarData gestureIndicator; final Widget child; @override Widget build(BuildContext context) { final windowConfig = WindowConfig.of(context); - final homeIndicator = windowConfig.homeIndicator; - if (homeIndicator == null) return child; - return Directionality( textDirection: TextDirection.ltr, child: Stack( children: [ child, Positioned( - bottom: homeIndicator.bottom, + bottom: gestureIndicator.bottom, width: windowConfig.size.width, child: Center( child: Container( - height: homeIndicator.size.height, - width: homeIndicator.size.width, + height: gestureIndicator.size.height, + width: gestureIndicator.size.width, decoration: BoxDecoration( borderRadius: - BorderRadius.circular(homeIndicator.size.height), + BorderRadius.circular(gestureIndicator.size.height), color: Colors.black, ), ), diff --git a/lib/src/adaptive/widgets/layers/hardware_layer.dart b/lib/src/adaptive/widgets/layers/hardware_layer.dart index e91ba38..37743e2 100644 --- a/lib/src/adaptive/widgets/layers/hardware_layer.dart +++ b/lib/src/adaptive/widgets/layers/hardware_layer.dart @@ -1,4 +1,4 @@ -import 'package:adaptive_test/src/adaptive/window_size.dart'; +import 'package:adaptive_test/src/adaptive/window_config.dart'; import 'package:flutter/material.dart'; /// Widget wrapper that paint hardware elements over a child. diff --git a/lib/src/adaptive/widgets/layers/keyboard_layer.dart b/lib/src/adaptive/widgets/layers/keyboard_layer.dart index ee51377..b5d832e 100644 --- a/lib/src/adaptive/widgets/layers/keyboard_layer.dart +++ b/lib/src/adaptive/widgets/layers/keyboard_layer.dart @@ -1,5 +1,5 @@ -import 'package:adaptive_test/src/adaptive/window_configuration.dart'; -import 'package:adaptive_test/src/adaptive/window_size.dart'; +import 'package:adaptive_test/src/adaptive/window_configuration_tester.dart'; +import 'package:adaptive_test/src/adaptive/window_config.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/lib/src/adaptive/widgets/layers/system_nav_bar_layer.dart b/lib/src/adaptive/widgets/layers/system_nav_bar_layer.dart new file mode 100644 index 0000000..c36a0c1 --- /dev/null +++ b/lib/src/adaptive/widgets/layers/system_nav_bar_layer.dart @@ -0,0 +1,45 @@ +import 'package:adaptive_test/src/adaptive/widgets/layers/gesture_indicator_system_nav_bar_layer.dart'; +import 'package:adaptive_test/src/adaptive/widgets/layers/three_button_system_nav_bar_layer.dart'; +import 'package:adaptive_test/src/adaptive/widgets/layers/two_button_system_nav_bar_layer.dart'; +import 'package:adaptive_test/src/adaptive/window_config.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/system_nav_bar_data.dart'; +import 'package:flutter/material.dart'; + +class SystemNavBarLayer extends StatelessWidget { + const SystemNavBarLayer({ + required this.child, + super.key, + }); + + final Widget child; + + @override + Widget build(BuildContext context) { + final windowConfig = WindowConfig.of(context); + + final systemNavBarData = windowConfig.systemNavBar; + + switch (systemNavBarData) { + case GestureIndicatorSystemNavBarData(): + return GestureIndicatorSystemNavBarLayer( + gestureIndicator: systemNavBarData, + child: child, + ); + + case ThreeButtonSystemNavBarData(): + return ThreeButtonSystemNavBarLayer( + threeButtonNavBar: systemNavBarData, + child: child, + ); + + case TwoButtonSystemNavBarData(): + return TwoButtonSystemNavBarLayer( + twoButtonNavBar: systemNavBarData, + child: child, + ); + + case null: + return child; + } + } +} diff --git a/lib/src/adaptive/widgets/layers/three_button_system_nav_bar_layer.dart b/lib/src/adaptive/widgets/layers/three_button_system_nav_bar_layer.dart new file mode 100644 index 0000000..53c2134 --- /dev/null +++ b/lib/src/adaptive/widgets/layers/three_button_system_nav_bar_layer.dart @@ -0,0 +1,52 @@ +import 'package:adaptive_test/src/adaptive/window_config.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/system_nav_bar_data.dart'; +import 'package:flutter/material.dart'; + +class ThreeButtonSystemNavBarLayer extends StatelessWidget { + const ThreeButtonSystemNavBarLayer({ + required this.threeButtonNavBar, + required this.child, + super.key, + }); + + final ThreeButtonSystemNavBarData threeButtonNavBar; + final Widget child; + + @override + Widget build(BuildContext context) { + final windowConfig = WindowConfig.of(context); + + return Directionality( + textDirection: TextDirection.ltr, + child: Stack( + children: [ + child, + Positioned( + bottom: threeButtonNavBar.bottomPadding, + width: windowConfig.size.width, + child: Container( + height: threeButtonNavBar.height, + color: threeButtonNavBar.backgroundColor, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: const [ + Icons.arrow_back_ios_rounded, + Icons.circle, + Icons.square_rounded + ] + .map( + (iconData) => Icon( + iconData, + color: threeButtonNavBar.iconColor, + size: threeButtonNavBar.iconSize, + ), + ) + .toList(), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/src/adaptive/widgets/layers/two_button_system_nav_bar_layer.dart b/lib/src/adaptive/widgets/layers/two_button_system_nav_bar_layer.dart new file mode 100644 index 0000000..01227b4 --- /dev/null +++ b/lib/src/adaptive/widgets/layers/two_button_system_nav_bar_layer.dart @@ -0,0 +1,64 @@ +import 'package:adaptive_test/src/adaptive/window_config.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/system_nav_bar_data.dart'; +import 'package:flutter/material.dart'; + +class TwoButtonSystemNavBarLayer extends StatelessWidget { + const TwoButtonSystemNavBarLayer({ + required this.twoButtonNavBar, + required this.child, + super.key, + }); + + final TwoButtonSystemNavBarData twoButtonNavBar; + final Widget child; + + @override + Widget build(BuildContext context) { + final windowConfig = WindowConfig.of(context); + + return Directionality( + textDirection: TextDirection.ltr, + child: Stack( + children: [ + child, + Positioned( + bottom: twoButtonNavBar.bottomPadding, + width: windowConfig.size.width, + child: Container( + height: twoButtonNavBar.height, + color: twoButtonNavBar.backgroundColor, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + // Back button + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Icon( + Icons.arrow_back, + color: twoButtonNavBar.iconColor, + ), + ), + // Home pill (centered visually) + Center( + child: Container( + height: twoButtonNavBar.homeHeight, + width: twoButtonNavBar.homeWidth, + decoration: BoxDecoration( + color: twoButtonNavBar.iconColor, + borderRadius: + BorderRadius.circular(twoButtonNavBar.homeHeight), + ), + ), + ), + + // Right side is empty (no tasks button) + const SizedBox(width: 48), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/src/adaptive/window_config.dart b/lib/src/adaptive/window_config.dart new file mode 100644 index 0000000..f3017eb --- /dev/null +++ b/lib/src/adaptive/window_config.dart @@ -0,0 +1,40 @@ +import 'package:adaptive_test/src/adaptive/window_config_data/window_config_data.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +class WindowVariant extends ValueVariant { + WindowVariant(this.windowConfigs) : super(windowConfigs); + + final Set windowConfigs; + + @override + String describeValue(WindowConfigData value) => value.name; +} + +/// Establish a subtree in which adaptive window resolves to the given data. +/// Use `WindowConfig.of(context)` to retrieve the data in any child widget. +/// +/// See also: [WindowConfigData]. +class WindowConfig extends InheritedWidget { + const WindowConfig({ + required this.windowConfig, + required super.child, + super.key, + }); + + final WindowConfigData windowConfig; + + static WindowConfigData of(BuildContext context) { + final result = context + .dependOnInheritedWidgetOfExactType() + ?.windowConfig; + assert(result != null, 'No WindowConfig found in context'); + + // ignore: avoid-non-null-assertion, protected by assertion + return result!; + } + + @override + bool updateShouldNotify(WindowConfig oldWidget) => + oldWidget.windowConfig != windowConfig; +} diff --git a/lib/src/adaptive/window_config_data/dynamic_island_data.dart b/lib/src/adaptive/window_config_data/dynamic_island_data.dart new file mode 100644 index 0000000..1f09086 --- /dev/null +++ b/lib/src/adaptive/window_config_data/dynamic_island_data.dart @@ -0,0 +1,19 @@ +import 'dart:ui'; + +import 'package:equatable/equatable.dart'; + +/// Describe the dynamic island on top of apps, expressed in `dp`. +/// +/// This is null when the device has no dynamic island. +class DynamicIslandData extends Equatable { + const DynamicIslandData(this.top, this.size); + + /// top offset of the indicator, expressed in `dp`. + final double top; + + /// Size of the indicator, expressed in `dp`. + final Size size; + + @override + List get props => [top, size]; +} diff --git a/lib/src/adaptive/window_config_data/punch_hole_data.dart b/lib/src/adaptive/window_config_data/punch_hole_data.dart new file mode 100644 index 0000000..e760503 --- /dev/null +++ b/lib/src/adaptive/window_config_data/punch_hole_data.dart @@ -0,0 +1,13 @@ +import 'dart:ui'; + +import 'package:equatable/equatable.dart'; + +/// Describe the size of Android physical screen camera punch hole in `dp`, +class PunchHoleData extends Equatable { + const PunchHoleData(this.offset, this.radius); + final Offset offset; + final double radius; + + @override + List get props => [offset, radius]; +} diff --git a/lib/src/adaptive/window_config_data/system_nav_bar_data.dart b/lib/src/adaptive/window_config_data/system_nav_bar_data.dart new file mode 100644 index 0000000..0f41918 --- /dev/null +++ b/lib/src/adaptive/window_config_data/system_nav_bar_data.dart @@ -0,0 +1,130 @@ +import 'dart:ui'; + +import 'package:equatable/equatable.dart'; + +sealed class SystemNavBarData extends Equatable { + const SystemNavBarData(); + + /// Display the gesture indicator for the system navigation + /// + /// [bottom] The bottom offset of the indicator, expressed in `dp`. + /// [size] The size of the indicator, expressed in `dp`. + const factory SystemNavBarData.gestureIndicator( + double bottom, + Size size, + ) = GestureIndicatorSystemNavBarData; + + /// Display the three-button navigation bar + /// + /// [height] The height of the navigation bar, expressed in `dp`. + /// [backgroundColor] The background color of the navigation bar. + /// [iconColor] The color of the icons in the navigation bar. + /// [iconSize] The size of the icons in the navigation bar. + /// [bottomPadding] The distance from the screen bottom to the navigation bar. + const factory SystemNavBarData.threeButton({ + double height, + Color backgroundColor, + Color iconColor, + double iconSize, + double bottomPadding, + }) = ThreeButtonSystemNavBarData; + + /// Describe the OS two-button navigation bar. + /// + /// [height] The height of the navigation bar, expressed in `dp`. + /// [backgroundColor] The background color of the navigation bar. + /// [iconColor] The color of the icons in the navigation bar. + /// [homeWidth] The width of the home button, expressed in `dp`. + /// [homeHeight] The height of the home button, expressed in `dp`. + /// [bottomPadding] The distance from the screen bottom to the navigation bar. + const factory SystemNavBarData.twoButton({ + double height, + Color backgroundColor, + Color iconColor, + double homeWidth, + double homeHeight, + double bottomPadding, + }) = TwoButtonSystemNavBarData; +} + +/// Describe the OS gesture indicator on bottom of apps, expressed in `dp`. +/// +/// This is null when the device has no gesture indicator. +class GestureIndicatorSystemNavBarData extends SystemNavBarData { + const GestureIndicatorSystemNavBarData(this.bottom, this.size); + + /// Bottom offset of the indicator, expressed in `dp`. + final double bottom; + + /// Size of the indicator, expressed in `dp`. + final Size size; + + @override + List get props => [bottom, size]; +} + +/// Describe the OS three-button navigation bar. +/// +/// This is null when the device does not use a three-button navigation bar. +/// Do not use with HomeIndicatorData. +class ThreeButtonSystemNavBarData extends SystemNavBarData { + const ThreeButtonSystemNavBarData({ + this.height = 48.0, + this.backgroundColor = const Color.fromRGBO(0, 0, 0, .1), + this.iconColor = const Color.fromRGBO(40, 40, 40, .6), + this.iconSize = 24.0, + this.bottomPadding = 0.0, + }); + + /// Height of the navigation bar, expressed in `dp`. + final double height; + + /// Background color of the navigation bar. + final Color backgroundColor; + + /// Color of the icons in the navigation bar. + final Color iconColor; + + /// Size of the icons in the navigation bar. + final double iconSize; + + /// Distance from the screen bottom to the navigation bar. + final double bottomPadding; + + @override + List get props => [ + height, + backgroundColor, + iconColor, + iconSize, + bottomPadding, + ]; +} + +class TwoButtonSystemNavBarData extends SystemNavBarData { + const TwoButtonSystemNavBarData({ + this.height = 48.0, + this.backgroundColor = const Color.fromRGBO(0, 0, 0, .1), + this.iconColor = const Color.fromRGBO(40, 40, 40, .6), + this.homeWidth = 60.0, + this.homeHeight = 6.0, + this.bottomPadding = 0.0, + }); + + final double height; // total bar height + final Color backgroundColor; // bar background + final Color iconColor; // color of back arrow + final double homeWidth; // pill width + final double homeHeight; // pill height + final double bottomPadding; // distance from bottom + + @override + List get props => [ + height, + backgroundColor, + iconColor, + homeWidth, + homeHeight, + bottomPadding, + ]; +} diff --git a/lib/src/adaptive/window_size.dart b/lib/src/adaptive/window_config_data/window_config_data.dart similarity index 63% rename from lib/src/adaptive/window_size.dart rename to lib/src/adaptive/window_config_data/window_config_data.dart index f6be0c3..43ad610 100644 --- a/lib/src/adaptive/window_size.dart +++ b/lib/src/adaptive/window_config_data/window_config_data.dart @@ -1,86 +1,10 @@ +import 'package:adaptive_test/src/adaptive/window_config_data/dynamic_island_data.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/system_nav_bar_data.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/punch_hole_data.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -class WindowVariant extends ValueVariant { - WindowVariant(this.windowConfigs) : super(windowConfigs); - - final Set windowConfigs; - - @override - String describeValue(WindowConfigData value) => value.name; -} - -/// Describe the size of Android physical screen camera punch hole in `dp`, -class PunchHoleData extends Equatable { - const PunchHoleData(this.offset, this.radius); - final Offset offset; - final double radius; - - @override - List get props => [offset, radius]; -} - -/// Describe the OS gesture indicator on bottom of apps, expressed in `dp`. -/// -/// This is null when the device has no gesture indicator. -class HomeIndicatorData extends Equatable { - const HomeIndicatorData(this.bottom, this.size); - - /// Bottom offset of the indicator, expressed in `dp`. - final double bottom; - - /// Size of the indicator, expressed in `dp`. - final Size size; - - @override - List get props => [bottom, size]; -} - -/// Describe the dynamic island on top of apps, expressed in `dp`. -/// -/// This is null when the device has no dynamic island. -class DynamicIslandData extends Equatable { - const DynamicIslandData(this.top, this.size); - - /// top offset of the indicator, expressed in `dp`. - final double top; - - /// Size of the indicator, expressed in `dp`. - final Size size; - - @override - List get props => [top, size]; -} - -/// Establish a subtree in which adaptive window resolves to the given data. -/// Use `WindowConfig.of(context)` to retrieve the data in any child widget. -/// -/// See also: [WindowConfigData]. -class WindowConfig extends InheritedWidget { - const WindowConfig({ - required this.windowConfig, - required super.child, - super.key, - }); - - final WindowConfigData windowConfig; - - static WindowConfigData of(BuildContext context) { - final result = context - .dependOnInheritedWidgetOfExactType() - ?.windowConfig; - assert(result != null, 'No WindowConfig found in context'); - - // ignore: avoid-non-null-assertion, protected by assertion - return result!; - } - - @override - bool updateShouldNotify(WindowConfig oldWidget) => - oldWidget.windowConfig != windowConfig; -} - /// A Data class that describe a device properties that will impact design. class WindowConfigData extends Equatable { WindowConfigData( @@ -96,7 +20,7 @@ class WindowConfigData extends Equatable { this.notchSize, this.dynamicIsland, this.punchHole, - this.homeIndicator, + this.systemNavBar, }) : viewInsets = ViewPaddingImpl( bottom: keyboardSize?.height ?? 0, ) * @@ -139,10 +63,10 @@ class WindowConfigData extends Equatable { /// See: [PunchHoleData] final PunchHoleData? punchHole; - /// Describe the OS gesture indicator on bottom of apps, expressed in `dp`. + /// Describe the OS system navigation bar on bottom of apps /// - /// This is null when the device has no gesture indicator. - final HomeIndicatorData? homeIndicator; + /// This is null when the device has no navigation bar. + final SystemNavBarData? systemNavBar; /// Device Platform. /// @@ -181,7 +105,7 @@ class WindowConfigData extends Equatable { keyboardSize, notchSize, punchHole, - homeIndicator, + systemNavBar, targetPlatform, borderRadius, viewInsets, @@ -191,6 +115,44 @@ class WindowConfigData extends Equatable { keyboardPackage, dynamicIsland, ]; + + WindowConfigData copyWith({ + String? name, + Size? size, + double? pixelDensity, + TargetPlatform? targetPlatform, + BorderRadius? borderRadius, + EdgeInsets? safeAreaPadding, + String? keyboardName, + String? keyboardPackage, + Size? keyboardSize, + Size? notchSize, + DynamicIslandData? dynamicIsland, + PunchHoleData? punchHole, + SystemNavBarData? systemNavBar, + }) { + final newDensity = pixelDensity ?? this.pixelDensity; + + return WindowConfigData( + name ?? this.name, + size: size ?? this.size, + pixelDensity: newDensity, + targetPlatform: targetPlatform ?? this.targetPlatform, + borderRadius: borderRadius ?? this.borderRadius, + safeAreaPadding: safeAreaPadding ?? + EdgeInsets.only( + bottom: this.padding.bottom / newDensity, + top: this.padding.top / newDensity, + ), + keyboardName: keyboardName ?? this.keyboardName, + keyboardPackage: keyboardPackage ?? this.keyboardPackage, + keyboardSize: keyboardSize ?? this.keyboardSize, + notchSize: notchSize ?? this.notchSize, + dynamicIsland: dynamicIsland ?? this.dynamicIsland, + punchHole: punchHole ?? this.punchHole, + systemNavBar: systemNavBar ?? this.systemNavBar, + ); + } } /// Implementation of the abstract class [FakeViewPadding]. diff --git a/lib/src/adaptive/window_configuration.dart b/lib/src/adaptive/window_configuration_tester.dart similarity index 94% rename from lib/src/adaptive/window_configuration.dart rename to lib/src/adaptive/window_configuration_tester.dart index fd8912a..5053b04 100644 --- a/lib/src/adaptive/window_configuration.dart +++ b/lib/src/adaptive/window_configuration_tester.dart @@ -1,4 +1,4 @@ -import 'package:adaptive_test/src/adaptive/window_size.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/window_config_data.dart'; import 'package:flutter_test/flutter_test.dart'; /// Dart extension to add configuration functions to a [WidgetTester] object, diff --git a/lib/src/configuration.dart b/lib/src/configuration.dart index 44008a5..5cafc1a 100644 --- a/lib/src/configuration.dart +++ b/lib/src/configuration.dart @@ -1,4 +1,5 @@ -import 'package:adaptive_test/src/adaptive/window_size.dart'; +import 'package:adaptive_test/src/adaptive/window_config_data/window_config_data.dart'; +import 'package:adaptive_test/src/adaptive/window_config.dart'; import 'package:flutter/material.dart'; /// Singleton class that configures global variables for the test. diff --git a/pubspec.yaml b/pubspec.yaml index 535e2ca..0606ba5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: adaptive_test description: >- A Flutter package to generate adaptive golden files during widget tests. -version: 0.9.1 +version: 0.10.0 homepage: https://github.com/bamlab/adaptive_test repository: https://github.com/bamlab/adaptive_test