From ca4537d8ff0ae16a0c111f4d4a90006f07037e66 Mon Sep 17 00:00:00 2001 From: Erick Zanardo Date: Wed, 6 Dec 2023 15:30:53 -0300 Subject: [PATCH] feat: adding hover to sources navigation arrows --- lib/home/widgets/sources_carousel_view.dart | 40 ++++++++++--- .../widgets/sources_carousel_view_test.dart | 57 +++++++++++++++++++ 2 files changed, 89 insertions(+), 8 deletions(-) diff --git a/lib/home/widgets/sources_carousel_view.dart b/lib/home/widgets/sources_carousel_view.dart index eda2b7d..b809df7 100644 --- a/lib/home/widgets/sources_carousel_view.dart +++ b/lib/home/widgets/sources_carousel_view.dart @@ -371,10 +371,12 @@ class _NavigationButtons extends StatelessWidget { GoPreviousButton( onBackPressed: onBackPressed, ), + const SizedBox(width: 4), Text( counter, style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: color), ), + const SizedBox(width: 4), GoNextButton( onNextPressed: onNextPressed, ), @@ -392,7 +394,7 @@ class GoPreviousButton extends StatelessWidget { @override Widget build(BuildContext context) { const color = VertexColors.white; - return _NavigationButton( + return NavigationButton( icon: vertexIcons.arrowBack.image(color: color), onTap: onBackPressed, ); @@ -408,31 +410,53 @@ class GoNextButton extends StatelessWidget { @override Widget build(BuildContext context) { const color = VertexColors.white; - return _NavigationButton( + return NavigationButton( icon: vertexIcons.arrowForward.image(color: color), onTap: onNextPressed, ); } } -class _NavigationButton extends StatelessWidget { - const _NavigationButton({ +class NavigationButton extends StatefulWidget { + @visibleForTesting + const NavigationButton({ required this.icon, required this.onTap, + super.key, }); final Widget icon; final VoidCallback onTap; + @override + State createState() => _NavigationButtonState(); +} + +class _NavigationButtonState extends State { + var _isHovering = false; + @override Widget build(BuildContext context) { return InkWell( - onTap: onTap, + onHover: (bool hover) { + setState(() { + _isHovering = hover; + }); + }, + onTap: widget.onTap, child: SizedBox.square( dimension: 48, - child: Padding( - padding: const EdgeInsets.all(12), - child: icon, + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + color: _isHovering + ? VertexColors.white.withOpacity(.1) + : Colors.transparent, + ), + child: Padding( + padding: const EdgeInsets.all(12), + child: widget.icon, + ), ), ), ); diff --git a/test/home/widgets/sources_carousel_view_test.dart b/test/home/widgets/sources_carousel_view_test.dart index 95f3b63..64e5db3 100644 --- a/test/home/widgets/sources_carousel_view_test.dart +++ b/test/home/widgets/sources_carousel_view_test.dart @@ -1,4 +1,5 @@ import 'package:api_client/api_client.dart'; +import 'package:app_ui/app_ui.dart'; import 'package:bloc_test/bloc_test.dart'; import 'package:dash_ai_search/home/home.dart'; import 'package:flutter/material.dart'; @@ -257,4 +258,60 @@ void main() { }, ); }); + + group('NavigationButton', () { + testWidgets('renders', (tester) async { + await tester.pumpApp( + NavigationButton( + icon: Icon(Icons.arrow_back_ios), + onTap: () {}, + ), + ); + + expect(find.byType(InkWell), findsOneWidget); + }); + + testWidgets('renders', (tester) async { + await tester.pumpApp( + NavigationButton( + icon: Icon(Icons.arrow_back_ios), + onTap: () {}, + ), + ); + + expect(find.byType(InkWell), findsOneWidget); + }); + + testWidgets('adds the hover circle when hovered', (tester) async { + await tester.pumpApp( + NavigationButton( + icon: Icon(Icons.arrow_back_ios), + onTap: () {}, + ), + ); + + var decoratedBox = tester.widget( + find.byType(DecoratedBox), + ); + + expect( + (decoratedBox.decoration as BoxDecoration).color, + Colors.transparent, + ); + + final inkWell = tester.widget(find.byType(InkWell)); + inkWell.onHover?.call(true); + + await tester.pump(); + + decoratedBox = tester.widget( + find.byType(DecoratedBox), + ); + + expect( + (decoratedBox.decoration as BoxDecoration).color, + VertexColors.white.withOpacity(0.1), + ); + }); + }); }