Animate mobile search from the bottom

Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <klopez4212@gmail.com>
This commit is contained in:
kenny lopez
2026-10-15 07:59:31 -04:00
parent e707134442
commit 617ecc801c
2 changed files with 53 additions and 4 deletions

View File

@@ -105,8 +105,24 @@ class HomePage extends HookConsumerWidget {
onSearch: () => Navigator.of(context).push(
PageRouteBuilder<void>(
allowSnapshotting: false,
transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero,
transitionDuration: reducedMotion
? Duration.zero
: const Duration(milliseconds: 260),
reverseTransitionDuration: reducedMotion
? Duration.zero
: const Duration(milliseconds: 220),
transitionsBuilder: (_, animation, secondaryAnimation, child) =>
reducedMotion
? child
: SlideTransition(
position: animation.drive(
Tween(
begin: const Offset(0, 1),
end: Offset.zero,
).chain(CurveTween(curve: Curves.easeOutCubic)),
),
child: child,
),
pageBuilder: (_, animation, secondaryAnimation) =>
const SearchPage(),
),

View File

@@ -147,8 +147,11 @@ void main() {
expect(find.byType(SearchPage), findsOneWidget);
final searchRoute = ModalRoute.of(tester.element(find.byType(SearchPage)))!;
expect(searchRoute.allowSnapshotting, isFalse);
expect(searchRoute.transitionDuration, Duration.zero);
expect(searchRoute.reverseTransitionDuration, Duration.zero);
expect(searchRoute.transitionDuration, const Duration(milliseconds: 260));
expect(
searchRoute.reverseTransitionDuration,
const Duration(milliseconds: 220),
);
Navigator.of(tester.element(find.byType(SearchPage))).pop();
await tester.pumpAndSettle();
expect(find.byType(SearchPage), findsNothing);
@@ -157,6 +160,36 @@ void main() {
debugDefaultTargetPlatformOverride = null;
});
for (final reducedMotion in [false, true]) {
testWidgets('search slides vertically, reduced motion: $reducedMotion', (
tester,
) async {
await tester.pumpWidget(
await buildHome(disableAnimations: reducedMotion),
);
await tester.pumpAndSettle();
await tester.tap(find.byTooltip('Search'));
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
final search = find.byType(SearchPage);
expect(search, findsOneWidget);
expect(tester.getTopLeft(search).dx, 0);
expect(tester.getTopLeft(search).dy, reducedMotion ? 0 : greaterThan(0));
await tester.pumpAndSettle();
expect(tester.getTopLeft(search).dy, 0);
Navigator.of(tester.element(search)).pop();
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
if (reducedMotion) {
expect(search, findsNothing);
} else {
expect(tester.getTopLeft(search).dy, greaterThan(0));
}
await tester.pumpAndSettle();
expect(search, findsNothing);
});
}
testWidgets('keeps creation beside the tabs and search beside the avatar', (
tester,
) async {