Skip to content
This repository has been archived by the owner on Jan 9, 2024. It is now read-only.

Commit

Permalink
fix: cta style (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
omartinma authored Nov 30, 2023
1 parent 9c140de commit 84dfc6f
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 35 deletions.
4 changes: 3 additions & 1 deletion lib/home/widgets/results_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,9 @@ class _SeeSourceAnswersButtonState extends State<SeeSourceAnswersButton>
height: 64,
child: TertiaryCTA(
label: l10n.seeSourceAnswers,
icon: vertexIcons.arrowForward.image(),
icon: vertexIcons.arrowForward.image(
color: VertexColors.white,
),
onPressed: () =>
context.read<HomeBloc>().add(const SeeSourceAnswersRequested()),
),
Expand Down
4 changes: 3 additions & 1 deletion lib/home/widgets/welcome_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ class _WelcomeView extends StatelessWidget {
),
const SizedBox(height: 40),
PrimaryCTA(
icon: vertexIcons.arrowForward.image(),
icon: vertexIcons.arrowForward.image(
color: VertexColors.googleBlue,
),
label: l10n.startAsking,
onPressed: () =>
context.read<HomeBloc>().add(const FromWelcomeToQuestion()),
Expand Down
Binary file modified packages/app_ui/assets/icons/arrow_back.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/app_ui/assets/icons/arrow_forward.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions packages/app_ui/lib/src/theme/vertex_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class VertexTheme {
textTheme: _textTheme,
inputDecorationTheme: _inputDecorationTheme,
useMaterial3: true,
elevatedButtonTheme: _elevatedButtonTheme,
textButtonTheme: _textButtonTheme,
);
}

Expand Down Expand Up @@ -55,4 +57,23 @@ class VertexTheme {
contentPadding: const EdgeInsets.symmetric(vertical: 32),
);
}

static ElevatedButtonThemeData get _elevatedButtonTheme {
return ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
textStyle: _textTheme.bodyMedium,
backgroundColor: VertexColors.googleBlue,
foregroundColor: VertexColors.white,
),
);
}

static TextButtonThemeData get _textButtonTheme {
return TextButtonThemeData(
style: TextButton.styleFrom(
textStyle: _textTheme.bodyMedium,
foregroundColor: VertexColors.white,
),
);
}
}
35 changes: 16 additions & 19 deletions packages/app_ui/lib/src/widgets/primary_cta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class PrimaryCTA extends StatelessWidget {
super.key,
});

/// The image that will be displayed on the left side of the button.
final Image? icon;
/// The widget that will be displayed on the left side of the button.
final Widget? icon;

/// The text that will be displayed on the right side of the button.
final String label;
Expand All @@ -27,31 +27,28 @@ class PrimaryCTA extends StatelessWidget {
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
VertexColors.googleBlue,
),
padding: MaterialStatePropertyAll(
EdgeInsets.only(
left: icon != null ? 24 : 32,
top: 20,
bottom: 20,
right: 32,
),
style: ElevatedButton.styleFrom(
padding: EdgeInsets.only(
left: icon != null ? 8 : 32,
top: 20,
bottom: 20,
right: 32,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null) icon!,
if (icon != null)
Padding(
padding: const EdgeInsets.only(right: 16),
child: CircleAvatar(
backgroundColor: VertexColors.white,
child: SizedBox.square(dimension: 24, child: icon),
),
),
Text(
label,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
color: VertexColors.white,
),
),
],
),
Expand Down
65 changes: 51 additions & 14 deletions packages/app_ui/lib/src/widgets/tertiary_cta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import 'package:flutter/material.dart';

/// {@template tertiary_cta}
/// TertiaryCTA
/// side.
/// {@endtemplate}
class TertiaryCTA extends StatelessWidget {
class TertiaryCTA extends StatefulWidget {
/// {@macro tertiary_cta}
const TertiaryCTA({
required this.label,
Expand All @@ -14,31 +13,69 @@ class TertiaryCTA extends StatelessWidget {
super.key,
});

/// The image that will be displayed on the left side of the button.
final Image? icon;
/// The icon that will be displayed on the left side of the button.
final Widget? icon;

/// The text that will be displayed on the right side of the button.
final String label;

/// The callback that will be called when the button is tapped.
final VoidCallback? onPressed;

@override
State<TertiaryCTA> createState() => _TertiaryCTAState();
}

class _TertiaryCTAState extends State<TertiaryCTA>
with SingleTickerProviderStateMixin {
final DecorationTween decorationTween = DecorationTween(
begin: const BoxDecoration(),
end: const BoxDecoration(
border: Border(
bottom: BorderSide(color: VertexColors.white, width: 2),
),
),
);

late final AnimationController _controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 300),
);

@override
Widget build(BuildContext context) {
return TextButton(
onPressed: onPressed,
onPressed: widget.onPressed,
style: const ButtonStyle(
overlayColor: MaterialStatePropertyAll(Colors.transparent),
),
onHover: (hovered) {
if (hovered) {
_controller.forward(from: 0);
} else {
_controller.reverse(from: 1);
}
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null) icon!,
Expanded(
child: Text(
label,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
color: VertexColors.white,
if (widget.icon != null)
Padding(
padding: const EdgeInsets.only(right: 4),
child: SizedBox.square(
dimension: 24,
child: widget.icon,
),
),
Flexible(
child: DecoratedBoxTransition(
decoration: decorationTween.animate(_controller),
child: Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Text(
widget.label,
textAlign: TextAlign.center,
),
),
),
),
Expand Down
29 changes: 29 additions & 0 deletions packages/app_ui/test/src/widgets/tertiary_cta_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:app_ui/app_ui.dart';
import 'package:app_ui/src/generated/assets.gen.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

import '../helpers/helpers.dart';
Expand Down Expand Up @@ -33,5 +35,32 @@ void main() {
await tester.tap(find.byType(TertiaryCTA));
expect(called, isTrue);
});

testWidgets('animates on hover', (tester) async {
await tester.pumpApp(
TertiaryCTA(
icon: Assets.icons.arrowForward.image(),
label: 'label',
onPressed: () {},
),
);
var status = AnimationStatus.dismissed;
final widget = tester
.widget<DecoratedBoxTransition>(find.byType(DecoratedBoxTransition));
widget.decoration.addStatusListener((newstatus) {
status = newstatus;
});
final center = tester.getCenter(find.byType(TertiaryCTA));
final gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer();
await gesture.moveTo(center);
expect(status, AnimationStatus.forward);
await tester.pumpAndSettle();
expect(status, AnimationStatus.completed);
await gesture.moveTo(Offset(1000, 1000));
expect(status, AnimationStatus.reverse);
await tester.pumpAndSettle();
expect(status, AnimationStatus.dismissed);
});
});
}

0 comments on commit 84dfc6f

Please sign in to comment.