Skip to content

Commit

Permalink
feat:✨Added feature to add action buttons for the tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
Sahil-Simform committed Oct 24, 2024
1 parent 2c7ab28 commit a3452d6
Show file tree
Hide file tree
Showing 11 changed files with 786 additions and 522 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [4.0.0]

- Feature ✨: Added Action widget for tooltip

## [3.0.1]

- Feature [#475](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/475) - Add
Expand All @@ -9,7 +13,6 @@
- Fixed [#449](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/449) - Null check operator used on a null value
- [BREAKING] Improvement [#400](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/400) - remove Builder widget
- Fixed [#435](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/435) - Extra padding when add targetShapeBorder
- Feature [#466](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/pull/466) - Provide tooltip action buttons

## [2.1.1]
- Fixed [#425](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/425) - Unhandled breaking change in v2.1.0
Expand Down
120 changes: 60 additions & 60 deletions README.md

Large diffs are not rendered by default.

78 changes: 67 additions & 11 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MyApp extends StatelessWidget {
builder: (context) => const MailPage(),
globalTooltipActionConfig: const TooltipActionConfig(
position: TooltipActionPosition.inside,
alignment: TooltipActionAlignment.spread,
alignment: MainAxisAlignment.spaceBetween,
),
),
),
Expand Down Expand Up @@ -186,7 +186,7 @@ class _MailPageState extends State<MailPage> {
debugPrint('Barrier clicked'),
tooltipActionConfig:
const TooltipActionConfig(
alignment: TooltipActionAlignment.right,
alignment: MainAxisAlignment.end,
position: TooltipActionPosition.outside,
gapBetweenContentAndAction: 10,
),
Expand Down Expand Up @@ -236,7 +236,20 @@ class _MailPageState extends State<MailPage> {
"Tap to see profile which contains user's name, profile picture, mobile number and country",
tooltipBackgroundColor: Theme.of(context).primaryColor,
textColor: Colors.white,
onTargetClick: () {
print('target cliecked');
},
disposeOnTap: false,
onToolTipClick: () {
print('clicked tool tip');
},
disableDefaultTargetGestures: true,
targetShapeBorder: const CircleBorder(),
tooltipActionConfig: const TooltipActionConfig(
alignment: MainAxisAlignment.spaceBetween,
gapBetweenContentAndAction: 10,
position: TooltipActionPosition.outside,
),
tooltipActions: [
TooltipActionButton.withDefault(
backgroundColor: Colors.transparent,
Expand All @@ -249,7 +262,7 @@ class _MailPageState extends State<MailPage> {
textStyle: const TextStyle(
color: Colors.pinkAccent,
),
)
),
],
child: Container(
padding: const EdgeInsets.all(5),
Expand Down Expand Up @@ -308,8 +321,8 @@ class _MailPageState extends State<MailPage> {
targetShapeBorder: const CircleBorder(),
showArrow: false,
tooltipActionConfig: const TooltipActionConfig(
alignment: TooltipActionAlignment.spread,
actionGap: 15,
alignment: MainAxisAlignment.spaceBetween,
actionGap: 12,
),
tooltipActions: [
TooltipActionButton.withDefault(
Expand All @@ -324,7 +337,7 @@ class _MailPageState extends State<MailPage> {
color: Colors.pink,
)),
TooltipActionButton.withDefault(
type: TooltipDefaultActionType.next,
type: TooltipDefaultActionType.skip,
name: 'Close',
tailIcon: const ActionButtonIcon.withIcon(
icon: Icon(
Expand All @@ -333,10 +346,6 @@ class _MailPageState extends State<MailPage> {
size: 15,
),
),
onTap: () {
// Write your code on button tap
ShowCaseWidget.of(context).next();
},
),
],
child: FloatingActionButton(
Expand Down Expand Up @@ -375,8 +384,37 @@ class _MailPageState extends State<MailPage> {
child: Showcase(
key: key,
description: 'Tap to check mail',
tooltipPosition: TooltipPosition.top,
disposeOnTap: true,
tooltipActionConfig: const TooltipActionConfig(
alignment: MainAxisAlignment.spaceBetween,
actionGap: 15,
position: TooltipActionPosition.outside,
gapBetweenContentAndAction: 16,
),
tooltipActions: [
TooltipActionButton.withDefault(
type: TooltipDefaultActionType.previous,
name: 'Back',
onTap: () {
// Write your code on button tap
ShowCaseWidget.of(context).previous();
},
backgroundColor: Colors.pink.shade50,
textStyle: const TextStyle(
color: Colors.pink,
)),
TooltipActionButton.withDefault(
type: TooltipDefaultActionType.skip,
name: 'Close',
tailIcon: const ActionButtonIcon.withIcon(
icon: Icon(
Icons.close,
color: Colors.white,
size: 15,
),
),
),
],
onTargetClick: () {
Navigator.push<void>(
context,
Expand Down Expand Up @@ -475,6 +513,24 @@ class MailTile extends StatelessWidget {
key: showCaseKey!,
height: 50,
width: 140,
tooltipActionConfig: const TooltipActionConfig(
alignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
tooltipActions: [
TooltipActionButton.withDefault(
backgroundColor: Colors.transparent,
type: TooltipDefaultActionType.previous,
padding: EdgeInsets.zero,
),
TooltipActionButton.withDefault(
type: TooltipDefaultActionType.next,
backgroundColor: Colors.white,
textStyle: const TextStyle(
color: Colors.pinkAccent,
),
),
],
targetShapeBorder: const CircleBorder(),
targetBorderRadius: const BorderRadius.all(
Radius.circular(150),
Expand Down
27 changes: 26 additions & 1 deletion lib/src/enum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,18 @@

import 'package:flutter/cupertino.dart';

import 'showcase_widget.dart';

enum TooltipPosition { top, bottom }

enum TooltipActionPosition { outside, inside }
enum TooltipActionPosition {
outside,
inside;

bool get isInside => this == inside;

bool get isOutside => this == outside;
}

enum TooltipActionAlignment {
left(MainAxisAlignment.start),
Expand All @@ -47,4 +56,20 @@ enum TooltipDefaultActionType {
});

final String actionName;

void onTap(ShowCaseWidgetState showCaseState) {
switch (this) {
case TooltipDefaultActionType.next:
showCaseState.next();
break;
case TooltipDefaultActionType.previous:
showCaseState.previous();
break;
case TooltipDefaultActionType.skip:
showCaseState.dismiss();
break;
default:
throw ArgumentError('Invalid tooltip default action type');
}
}
}
41 changes: 41 additions & 0 deletions lib/src/models/tooltip_action_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,60 @@ import 'package:flutter/material.dart';
import '../../showcaseview.dart';

class TooltipActionButton {
/// To Provide Background color to the action
final Color? backgroundColor;

/// To Provide borderRadius to the action
///
/// Defaults to const BorderRadius.all(Radius.circular(50)),
final BorderRadius? borderRadius;

/// To Provide textStyle to the action text
///
/// Defaults to const TextStyle(color: Colors.white,),
final TextStyle? textStyle;

/// To Provide padding to the action widget
///
/// Defaults to const EdgeInsets.symmetric(horizontal: 15,vertical: 4,)
final EdgeInsets? padding;

/// To Provide a custom widget for the action in [TooltipActionButton.custom]
final Widget? button;

/// To Provide a leading icon for the action
final ActionButtonIcon? leadIcon;

/// To Provide a tail icon for the action
final ActionButtonIcon? tailIcon;

/// To Provide a action type
final TooltipDefaultActionType? type;

/// To Provide a text for action
///
/// If type is provided then it will take type name
final String? name;

/// To Provide a onTap for action
///
/// If type is provided then it will take type's OnTap
final VoidCallback? onTap;

/// To Provide a border for action
final double? borderWidth;

/// To Provide a borderColor for action
final Color? borderColor;

/// To show or hide action for the first tooltip
///
/// defaults to true
final bool shouldShowForFirstTooltip;

/// To show or hide action for the hide tooltip
///
/// defaults to true
final bool shouldShowForLastTooltip;

TooltipActionButton.withDefault({
Expand Down
10 changes: 8 additions & 2 deletions lib/src/models/tooltip_action_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import '../../showcaseview.dart';

class TooltipActionConfig {
const TooltipActionConfig({
this.alignment = TooltipActionAlignment.left,
this.alignment = MainAxisAlignment.spaceBetween,
this.actionGap = 5,
this.padding = EdgeInsets.zero,
this.position = TooltipActionPosition.inside,
this.gapBetweenContentAndAction = 10,
this.crossAxisAlignment = CrossAxisAlignment.start,
});

/// Defines tooltip action widget position.
Expand All @@ -20,7 +21,7 @@ class TooltipActionConfig {
/// Defines the alignment of actions buttons of tooltip action widget
///
/// Default to [TooltipActionAlignment.left]
final TooltipActionAlignment alignment;
final MainAxisAlignment alignment;

/// Defines the gap between the actions buttons of tooltip action widget
///
Expand All @@ -36,4 +37,9 @@ class TooltipActionConfig {
///
/// Default to 10.0
final double gapBetweenContentAndAction;

/// Defines running direction alignment for the Action widgets.
///
/// Default to [crossAxisAlignment.start]
final CrossAxisAlignment crossAxisAlignment;
}
48 changes: 38 additions & 10 deletions lib/src/showcase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:showcaseview/showcaseview.dart';

import '../showcaseview.dart';
import 'get_position.dart';
import 'layout_overlays.dart';
import 'shape_clipper.dart';
Expand Down Expand Up @@ -317,8 +317,8 @@ class Showcase extends StatefulWidget {
this.toolTipSlideEndDistance = 7,
this.toolTipMargin = 14,
this.tooltipActionConfig,
}) : width = null,
height = null,
}) : height = null,
width = null,
container = null,
assert(overlayOpacity >= 0.0 && overlayOpacity <= 1.0,
"overlay opacity must be between 0 and 1."),
Expand Down Expand Up @@ -655,9 +655,6 @@ class _ShowcaseState extends State<Showcase> {
descriptionTextDirection: widget.descriptionTextDirection,
toolTipSlideEndDistance: widget.toolTipSlideEndDistance,
toolTipMargin: widget.toolTipMargin,
tooltipActionPosition: widget.tooltipActionPosition,
gapBetweenContentAndAction: widget.gapBetweenContentAndAction,
showCaseState: ShowCaseWidget.of(context),
tooltipActionConfig: _getTooltipActionConfig(),
tooltipActions: _getTooltipActions(),
),
Expand All @@ -666,10 +663,41 @@ class _ShowcaseState extends State<Showcase> {
);
}

List<TooltipActionButton> _getTooltipActions() =>
(widget.tooltipActions?.isEmpty ?? true)
? ShowCaseWidget.of(context).globalTooltipActions ?? []
: widget.tooltipActions ?? [];
List<Widget> _getTooltipActions() {
final showCaseState = ShowCaseWidget.of(context);
final actionData = (widget.tooltipActions?.isEmpty ?? true)
? showCaseState.globalTooltipActions ?? []
: widget.tooltipActions ?? [];

final actionWidgets = <Widget>[];
for (var action = 0; action < actionData.length; action++) {
/// This checks that if it is first or last tooltip and
/// [shouldShowForLastTooltip] or [shouldShowForFirstTooltip] is true
/// then we will ignore that action
if (((showCaseState.activeWidgetId == 0 &&
actionData[action].shouldShowForFirstTooltip) ||
(showCaseState.activeWidgetId ==
(showCaseState.ids?.length ?? 0) - 1 &&
!actionData[action].shouldShowForLastTooltip)) &&
(widget.tooltipActions?.isEmpty ?? true)) {
continue;
}
actionWidgets.add(
Padding(
padding: EdgeInsetsDirectional.only(
end: action < actionData.length - 1
? _getTooltipActionConfig().actionGap
: 0,
),
child: TooltipActionButtonWidget(
config: actionData[action],
showCaseState: ShowCaseWidget.of(context),
),
),
);
}
return actionWidgets;
}

TooltipActionConfig _getTooltipActionConfig() {
final showCaseState = ShowCaseWidget.of(context);
Expand Down
4 changes: 4 additions & 0 deletions lib/src/showcase_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ class ShowCaseWidget extends StatefulWidget {
/// Enable/disable showcase globally. Enabled by default.
final bool enableShowcase;

/// Global action to apply on every tooltip widget
final List<TooltipActionButton>? globalTooltipActions;

/// Global Config for tooltip action to auto apply for all the toolTip
final TooltipActionConfig? globalTooltipActionConfig;

const ShowCaseWidget({
Expand Down Expand Up @@ -132,6 +135,7 @@ class ShowCaseWidgetState extends State<ShowCaseWidget> {
Key? anchoredOverlayKey;

late final TooltipActionConfig? globalTooltipActionConfig;

late final List<TooltipActionButton>? globalTooltipActions;

/// These properties are only here so that it can be accessed by
Expand Down
Loading

0 comments on commit a3452d6

Please sign in to comment.