Skip to content

Commit

Permalink
✨ Tooltip action widget
Browse files Browse the repository at this point in the history
  • Loading branch information
faiyaz-shaikh committed Mar 30, 2023
1 parent 5495cee commit a7c83ff
Show file tree
Hide file tree
Showing 5 changed files with 340 additions and 124 deletions.
113 changes: 93 additions & 20 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,29 @@ class _MailPageState extends State<MailPage> {
color: Theme.of(context).primaryColor,
),
),
toolTipAction: ToolTipAction(
actionOne: ActionWidgetConfig(
actionTitle: 'Prev',
onActionTap:
ShowCaseWidget.of(context)
.previous,
),
actionTwo: ActionWidgetConfig(
actionTitle: 'Next',
decoration: BoxDecoration(
color:
Theme.of(context).primaryColor,
borderRadius:
BorderRadius.circular(20),
),
padding: const EdgeInsets.all(10),
onActionTap:
ShowCaseWidget.of(context).next,
),
actionPadding:
const EdgeInsets.symmetric(
vertical: 5),
),
),
const SizedBox(
width: 10,
Expand Down Expand Up @@ -236,6 +259,23 @@ class _MailPageState extends State<MailPage> {
),
child: Image.asset('assets/simform.png'),
),
toolTipAction: ToolTipAction(
actionOne: ActionWidgetConfig(
actionTitle: 'Prev',
onActionTap: ShowCaseWidget.of(context).previous,
textStyle: const TextStyle(color: Colors.white),
),
actionTwo: ActionWidgetConfig(
actionTitle: 'Next',
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
padding: const EdgeInsets.all(10),
onActionTap: ShowCaseWidget.of(context).next,
),
actionPadding: const EdgeInsets.symmetric(vertical: 5),
),
),
const SizedBox(
width: 12,
Expand Down Expand Up @@ -297,6 +337,22 @@ class _MailPageState extends State<MailPage> {
Icons.add,
),
),
toolTipAction: ToolTipAction(
actionOne: ActionWidgetConfig(
actionTitle: 'Prev',
onActionTap: ShowCaseWidget.of(context).previous,
),
actionTwo: ActionWidgetConfig(
actionTitle: 'Next',
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(20),
),
padding: const EdgeInsets.all(10),
onActionTap: ShowCaseWidget.of(context).next,
),
actionPadding: const EdgeInsets.symmetric(vertical: 5),
),
),
);
}
Expand All @@ -315,27 +371,44 @@ class _MailPageState extends State<MailPage> {
child: Container(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Showcase(
key: key,
description: 'Tap to check mail',
tooltipPosition: TooltipPosition.top,
disposeOnTap: true,
onTargetClick: () {
Navigator.push<void>(
context,
MaterialPageRoute<void>(
builder: (_) => const Detail(),
),
).then((_) {
setState(() {
ShowCaseWidget.of(context).startShowCase([_four, _five]);
});
key: key,
description: 'Tap to check mail',
tooltipPosition: TooltipPosition.top,
disposeOnTap: true,
onTargetClick: () {
Navigator.push<void>(
context,
MaterialPageRoute<void>(
builder: (_) => const Detail(),
),
).then((_) {
setState(() {
ShowCaseWidget.of(context).startShowCase([_four, _five]);
});
},
child: MailTile(
mail: mail,
showCaseKey: _four,
showCaseDetail: showCaseDetail,
)),
});
},
child: MailTile(
mail: mail,
showCaseKey: _four,
showCaseDetail: showCaseDetail,
),
toolTipAction: ToolTipAction(
actionOne: ActionWidgetConfig(
actionTitle: 'Prev',
onActionTap: ShowCaseWidget.of(context).previous,
),
actionTwo: ActionWidgetConfig(
actionTitle: 'Next',
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(20),
),
padding: const EdgeInsets.all(10),
onActionTap: ShowCaseWidget.of(context).next,
),
actionPadding: const EdgeInsets.symmetric(vertical: 5),
),
),
),
);
}
Expand Down
1 change: 1 addition & 0 deletions lib/showcaseview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ library showcaseview;
export 'src/enum.dart';
export 'src/showcase.dart';
export 'src/showcase_widget.dart';
export 'src/tooltip_action.dart';
7 changes: 7 additions & 0 deletions lib/src/showcase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import 'get_position.dart';
import 'layout_overlays.dart';
import 'shape_clipper.dart';
import 'showcase_widget.dart';
import 'tooltip_action.dart';
import 'tooltip_widget.dart';

class Showcase extends StatefulWidget {
Expand Down Expand Up @@ -232,6 +233,9 @@ class Showcase extends StatefulWidget {
/// Provides padding around the description. Default padding is zero.
final EdgeInsets? descriptionPadding;

/// Provides tooltip action
final ToolTipAction? toolTipAction;

/// Provides text direction of tooltip title.
final TextDirection? titleTextDirection;

Expand Down Expand Up @@ -285,6 +289,7 @@ class Showcase extends StatefulWidget {
this.tooltipPosition,
this.titlePadding,
this.descriptionPadding,
this.toolTipAction,
this.titleTextDirection,
this.descriptionTextDirection,
this.onBarrierClick,
Expand Down Expand Up @@ -343,6 +348,7 @@ class Showcase extends StatefulWidget {
tooltipPadding = const EdgeInsets.symmetric(vertical: 8),
titlePadding = null,
descriptionPadding = null,
toolTipAction = null,
titleTextDirection = null,
descriptionTextDirection = null,
assert(overlayOpacity >= 0.0 && overlayOpacity <= 1.0,
Expand Down Expand Up @@ -571,6 +577,7 @@ class _ShowcaseState extends State<Showcase> {
tooltipPosition: widget.tooltipPosition,
titlePadding: widget.titlePadding,
descriptionPadding: widget.descriptionPadding,
toolTipAction: widget.toolTipAction,
titleTextDirection: widget.titleTextDirection,
descriptionTextDirection: widget.descriptionTextDirection,
),
Expand Down
102 changes: 102 additions & 0 deletions lib/src/tooltip_action.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import 'package:flutter/material.dart';

class ToolTipAction extends StatelessWidget {
const ToolTipAction({
Key? key,
this.actionOne,
this.actionTwo,
this.actionPadding,
this.alignment = WrapAlignment.spaceBetween,
this.crossAxisAlignment = WrapCrossAlignment.center,
}) : actions = null,
super(key: key);

const ToolTipAction.customAction({
Key? key,
this.actions,
this.actionPadding,
this.alignment = WrapAlignment.spaceBetween,
this.crossAxisAlignment = WrapCrossAlignment.center,
}) : actionOne = null,
actionTwo = null,
super(key: key);

/// Define configuration of first action
final ActionWidgetConfig? actionOne;

/// Define configuration of second action
final ActionWidgetConfig? actionTwo;

/// Define padding of action widget
final EdgeInsets? actionPadding;

/// Define configuration of list of action
final List<ActionWidgetConfig>? actions;

/// Define alignment of actions
final WrapAlignment alignment;

/// Define crossAxisAlignment of actions
final WrapCrossAlignment crossAxisAlignment;

@override
Widget build(BuildContext context) {
return Padding(
padding: actionPadding ?? EdgeInsets.zero,
child: Wrap(
alignment: alignment,
crossAxisAlignment: crossAxisAlignment,
children: actions != null
? [for (final action in actions!) getActionWidget(action)]
: [getActionWidget(actionOne), getActionWidget(actionTwo)],
),
);
}

Widget getActionWidget(ActionWidgetConfig? actionWidgetConfig) {
if (actionWidgetConfig == null) return const SizedBox();
return GestureDetector(
onTap: actionWidgetConfig.onActionTap,
child: Container(
decoration: actionWidgetConfig.decoration,
padding: actionWidgetConfig.padding,
margin: actionWidgetConfig.margin,
child: Text(
actionWidgetConfig.actionTitle,
style: actionWidgetConfig.textStyle,
maxLines: 1,
),
),
);
}
}

class ActionWidgetConfig {
const ActionWidgetConfig({
Key? key,
required this.actionTitle,
this.decoration,
this.padding,
this.margin,
this.textStyle,
required this.onActionTap,
});

/// Defines title of action
final String actionTitle;

/// Defines decoration of action
final BoxDecoration? decoration;

/// Provide padding to the action
final EdgeInsets? padding;

/// Provide margin to the action
final EdgeInsets? margin;

/// Define text style of action
final TextStyle? textStyle;

/// Called when user tap on action
final VoidCallback onActionTap;
}

0 comments on commit a7c83ff

Please sign in to comment.