diff --git a/README.md b/README.md index a807bb72..e1300abb 100644 --- a/README.md +++ b/README.md @@ -1,393 +1,42 @@ ![Showcase View - Simform LLC.](https://raw.githubusercontent.com/SimformSolutionsPvtLtd/flutter_showcaseview/master/preview/banner.png) - # ShowCaseView [![Build](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/actions/workflows/flutter.yaml/badge.svg?branch=master)](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/actions) [![showcaseview](https://img.shields.io/pub/v/showcaseview?label=showcaseview)](https://pub.dev/packages/showcaseview) -A Flutter package allows you to Showcase/Highlight your widgets. +A Flutter package that allows you to showcase/highlight your widgets step by step, providing interactive tutorials for your application's UI. -_Check out other amazing open-source [Flutter libraries](https://pub.dev/publishers/simform.com/packages) and [Mobile libraries](https://github.com/SimformSolutionsPvtLtd/Awesome-Mobile-Libraries) developed by Simform Solutions!_ +_Check out other amazing open-source [Flutter libraries](https://simform-flutter-packages.web.app) and [Mobile libraries](https://github.com/SimformSolutionsPvtLtd/Awesome-Mobile-Libraries) developed by Simform Solutions!_ ## Preview -![The example app running in Android](https://raw.githubusercontent.com/SimformSolutionsPvtLtd/flutter_showcaseview/master/preview/showcaseview.gif) - -## Migration guide for release 4.0.0 +![The example app running on mobile](https://raw.githubusercontent.com/SimformSolutionsPvtLtd/flutter_showcaseview/master/preview/showcaseview.gif) -Renamed parameters `titleAlignment` to `titleTextAlign` and `descriptionAlignment` -to `descriptionTextAlign` to correspond it more with the TextAlign property.`titleAlignment` -and `descriptionAlignment` will be used for widget alignment. +## Features -Before: -```dart -Showcase( - titleAlignment: TextAlign.center, - descriptionAlignment: TextAlign.center, -), -``` - -After: -```dart -Showcase( - titleTextAlign: TextAlign.center, - descriptionTextAlign: TextAlign.center, -), -``` +- Guide users through your app by highlighting specific widgets step by step. +- Customize tooltips with titles, descriptions, and styling. +- Handles scrolling the widget into view for showcasing. +- Support for custom tooltip widgets. +- Animation and transition effects for tooltip. +- Options to showcase multiple widgets at the same time. -## Getting Started +## Documentation -1. Add dependency to `pubspec.yaml` +Visit our [documentation](https://simform-flutter-packages.web.app/showCaseView) site for all implementation details, usage instructions, code examples, and advanced features. - *Get the latest version in the 'Installing' tab on [pub.dev](https://pub.dev/packages/showcaseview)* +## Installation -```dart +```yaml dependencies: - showcaseview: -``` - -2. Import the package -```dart -import 'package:showcaseview/showcaseview.dart'; -``` - -3. Register a `ShowCaseView` widget. -```dart - void initState() { - super.initState(); - ShowcaseView.register(scope: scopeName); - ); -``` - -4. Adding a `Showcase` widget. -```dart -GlobalKey _one = GlobalKey(); -GlobalKey _two = GlobalKey(); -GlobalKey _three = GlobalKey(); - -... - -Showcase( - key: _one, - title: 'Menu', - description: 'Click here to see menu options', - child: Icon( - Icons.menu, - color: Colors.black45, - ), -), - -Showcase.withWidget( - key: _three, - height: 80, - width: 140, - targetShapeBorder: CircleBorder(), - container: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ... - ], - ), - child: ..., -), -``` - -5. Starting the `ShowCase`: - -- If you have a single showcase, then you can start the `ShowCaseView` using the code below: - -```dart -someEvent() { - ShowCaseView.get().startShowCase([_one, _two, _three]); -} + showcaseview: ``` -- If you have multiple ShowcaseViews, then you can start the `ShowCaseView` using the code below, - which is recommended: - -```dart -someEvent() { - ShowCaseView.getNamed(scopeName).startShowCase([_one, _two, _three]); -} -``` - -If you want to start the `ShowCaseView` as soon as your UI built up then use below code: - -```dart -WidgetsBinding.instance.addPostFrameCallback((_) => - ShowCaseWidget.of(context).startShowCase([_one, _two, _three]) -); -``` - -If you have some animation or transition in your UI and you want to start the `ShowCaseView` after -that then use below code: - -```dart -WidgetsBinding.instance.addPostFrameCallback((_) => - ShowCaseWidget.of(context).startShowCase([_one, _two, _three], delay: "Animation Duration") -); -``` - -## How to use - -Check out the **example** app in the [example](example) directory or the 'Example' tab on -pub.dartlang.org for a more complete example. - -## MultiShowcaseView - -To show multiple showcase at the same time provide same key to showcase. -Note: auto scroll to showcase will not work in case of the multi-showcase and we will use property -of first initialized showcase for common things like barrier tap and colors. - -```dart - -GlobalKey _one = GlobalKey(); -... - -Showcase - ( - key: _one, - title: 'Showcase one', - description: 'Click here to see menu options', - child: Icon( - Icons.menu, - color: Colors.black45, - ), -), - -Showcase( - key: _one, - title: 'Showcase two', - description: 'Click here to see menu options', - child: Icon( - Icons.menu, - color:Colors.black45, - ), -), -``` - -## Scrolling to active showcase - -Auto Scrolling to active showcase feature will not work properly in scroll views that renders widgets on demand(ex, ListView, GridView). - -In order to scroll to a widget it needs to be attached with widget tree. So, If you are using a scrollview that renders widgets on demand, it is possible that the widget on which showcase is applied is not attached in widget tree. So, flutter won't be able to scroll to that widget. - -So, If you want to make a scroll view that contains less number of children widget then prefer to use SingleChildScrollView. - -If using SingleChildScrollView is not an option, then you can assign a ScrollController to that scrollview and manually scroll to the position where showcase widget gets rendered. You can add that code in onStart method of `ShowCaseWidget`. - -Example: - -```dart -// This controller will be assigned to respected sctollview. -final _controller = ScrollController(); - -ShowCaseView.register -( - onStart: (index, key) { - if(index == 0) { - WidgetsBinding.instance.addPostFrameCallback((_) { - // If showcase widget is at offset 1000 in the listview. - // If you don't know the exact position of the showcase widget, - // You can provide nearest possible location. - // - // In this case providing 990 instead of 1000 will work as well. - _controller.jumpTo(1000); - }); - } - }, -); -``` - -## Custom Showcase Widget - -You can create a custom showcase widget using `Showcase.withWidget`: - -```dart -Showcase.withWidget -( - key: _customKey, - height: 80, - width: 140, - targetShapeBorder: CircleBorder(), - container: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text("This is a custom widget!", style: TextStyle(color: Colors.white)), - SizedBox(height: 10), - Text("You can add any content here.", style: TextStyle(color: Colors.white)), - ], - ), - child: FloatingActionButton( - onPressed: () {}, - child: Icon(Icons.add), - ), -) -``` - -### Using Tooltip Actions - -You can add action buttons to your tooltips to enhance user interaction: - -```dart -Showcase -( -key: _actionKey, -title: 'Profile', -description: 'Tap to view your profile', -tooltipActions: [ -TooltipActionButton( -type: TooltipActionButtonType.next, -name: 'NEXT', -onTap: () { -// Custom action when next is pressed -print("Next pressed"); -}, -), -TooltipActionButton( -type: TooltipActionButtonType.skip, -name: 'SKIP', -), -], -tooltipActionConfig: TooltipActionConfig( -position: TooltipActionPosition.outside, -alignment: MainAxisAlignment.center, -), -child: CircleAvatar( -child: Icon(Icons.person) -, -) -, -) -``` - -### Custom Action Buttons - -Create custom action buttons with `TooltipActionButton.custom`: - -```dart -Showcase -( -key: _customActionKey, -title: 'Custom Actions', -description: 'This showcase has custom action buttons', -tooltipActions: [ -TooltipActionButton.custom( -button: Container( -padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4), -decoration: BoxDecoration( -color: Colors.blue, -borderRadius: BorderRadius.circular(8), -), -child: Row( -children: [ -Icon(Icons.arrow_forward, color: Colors.white, size: 18), -SizedBox(width: 5), -Text('Continue', style: TextStyle(color: Colors.white)), -], -), -), -onTap: () { -// Custom action -}, -), -], -child: ListTile( -leading: Icon(Icons.star), -title: Text('Featured Item'), -), -) -``` - -### Floating Action Widget - -Add a floating action widget that appears during the showcase: - -```dart -Showcase -( -key: _floatingKey, -title: 'Swipe Gesture', -description: 'Swipe left or right to navigate', -floatingActionWidget: (context) => Container( -width: 200, -height: 100, -padding: EdgeInsets.all(10), -margin: EdgeInsets.only(bottom: 50), -decoration: BoxDecoration( -color: Colors.white, -borderRadius: BorderRadius.circular(10), -boxShadow: [ -BoxShadow(color: Colors.black26, blurRadius: 10, offset: Offset(0, 5)) -], -), -child: Column( -children: [ -Icon(Icons.swipe, size: 40), -Text('Swipe to continue', style: TextStyle(fontWeight: FontWeight.bold)), -Text('Use your finger to navigate between items'), -], -), -), -child: Card( -child: ListTile( -title: Text('Swipeable Item'), -subtitle: Text('Try swiping this item' -) -, -) -, -) -, -) -``` - -## Functions of `ShowCaseView.get()` and `ShowCaseView.getNamed(scopeName)`: - -| Function Name | Description | -|---------------|-----------------------------------------------------| -| startShowCase | Starting the showcase | -| next | Starts next showcase | -| previous | Starts previous showcase | -| dismiss | Dismisses all showcases | -| unRegister | UnRegister all showcases and the showcaseView scope | - -## Main Contributors - - - - - - - - - - -

Sahil Totala

Vatsal Tanna

Sanket Kachhela

Happy Makadiya

Ujas Majithiya

Aditya Chavda
+## Support +For questions, issues, or feature requests, [create an issue](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues) on GitHub or reach out via the GitHub Discussions tab. We're happy to help and encourage community contributions. +To contribute documentation updates specifically, please make changes to the doc/documentation.md file and submit a pull request. ## License -```text -MIT License - -Copyright (c) 2021 Simform Solutions - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -``` +This project is licensed under the MIT License - see the [LICENSE](https://simform-flutter-packages.web.app/showCaseView/license) file for details. diff --git a/doc/documentation.md b/doc/documentation.md new file mode 100644 index 00000000..5c6f22cf --- /dev/null +++ b/doc/documentation.md @@ -0,0 +1,738 @@ +# Overview + +A Flutter package that allows you to showcase or highlight your widgets step by step, providing +interactive tutorials for your application's UI. + +## Preview + +![The example app running on mobile](https://raw.githubusercontent.com/SimformSolutionsPvtLtd/flutter_showcaseview/master/preview/showcaseview.gif) + +## Features + +- Guide user through your app by highlighting specific widget step by step. +- Customize tooltips with titles, descriptions, and styling. +- Handles scrolling the widget into view for showcasing. +- Support for custom tooltip widgets. +- Animation and transition effects for tooltip. +- Options to showcase multiple widget at the same time. + +## Key Components + +- **ShowcaseView**: The class that manages showcase interactions and various configurations. +- **Showcase**: A widget to be wrapped on the your widget enabling creation of a showcase with + the default tooltip. +- **Showcase.withWidget**: A widget to be wrapped on the your widget enabling creation of a + custom showcase tooltip. + +## Main Use Cases + +- App onboarding experiences. +- Feature introduction. +- User guidance through complex interfaces. +- Highlighting new features. + +## Installation + +```yaml +dependencies: + showcaseview: +``` + +## Basic Implementation + +```dart +// Import the package +import 'package:showcaseview/showcaseview.dart'; + +// Register the showcase view +ShowcaseView.register(); + +// Define global keys for your showcases +GlobalKey _one = GlobalKey(); + +// Add showcases to widgets +Showcase( + key: _one, + title: 'Menu', + description: 'Click here to see menu options', + child: Icon(Icons.menu), +), + +// Start the showcase +void startShowcase() { + ShowcaseView.get().startShowCase([_one]); +} + +// Dispose the showcase view +ShowcaseView.get().unregister(); +``` + +## Customizations + +The package offers extensive customization options for: +- Tooltip appearance and positioning. +- Text styling and alignment. +- Overlay colors and opacity. +- Animation effects and durations. +- Interactive controls. +- Auto-scrolling behavior. + +# Installation + +To use the ShowCaseView package in your Flutter project, follow these steps: + +## 1. Add dependency to `pubspec.yaml` + +Add the following dependency to your project's `pubspec.yaml` file: + +```yaml +dependencies: + showcaseview: +``` + +## 2. Install packages + +Run the following command to install the package: + +```bash +flutter pub get +``` + +## 3. Import the package + +Add the import statement in your Dart files where you want to use ShowCaseView: + +```dart +import 'package:showcaseview/showcaseview.dart'; +``` + +Now you're ready to use ShowCaseView in your Flutter application! + +# Basic Usage + +This guide covers the fundamental implementation of ShowCaseView in your Flutter application. + +## Setup ShowCaseView + +First, register `ShowcaseView` and optionally add configurations as per your requirements: + +```dart +ShowcaseView.register(); +``` + +You can add many more configurations than shown below. For more details, refer to the [API +Reference](https://pub.dev/documentation/showcaseview/latest/showcaseview/). + +```dart +ShowcaseView.register( + autoPlayDelay: const Duration(seconds: 3), + globalFloatingActionWidget: (showcaseContext) => FloatingActionWidget( + left: 16, + bottom: 16, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: () => ShowcaseView.get().dismiss(), + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xffEE5366), + ), + child: const Text( + 'Skip', + style: TextStyle( + color: Colors.white, + fontSize: 15, + ), + ), + ), + ), + ), + globalTooltipActionConfig: const TooltipActionConfig( + position: TooltipActionPosition.inside, + alignment: MainAxisAlignment.spaceBetween, + actionGap: 20, + ), + globalTooltipActions: [ + TooltipActionButton( + type: TooltipDefaultActionType.previous, + textStyle: const TextStyle( + color: Colors.white, + ), + // Here we don't need previous action for the first showcase widget + // so we hide this action for the first showcase widget + hideActionWidgetForShowcase: [_firstShowcaseWidget], + ), + TooltipActionButton( + type: TooltipDefaultActionType.next, + textStyle: const TextStyle( + color: Colors.white, + ), + // Here we don't need next action for the last showcase widget so we + // hide this action for the last showcase widget + hideActionWidgetForShowcase: [_lastShowcaseWidget], + ), + ], +); +``` + +## Define Global Keys + +Create global keys for each widget you want to showcase: + +```dart +// Define in your widget class +final GlobalKey _one = GlobalKey(); +final GlobalKey _two = GlobalKey(); +final GlobalKey _three = GlobalKey(); +``` + +## Add Showcase to Widgets + +Wrap each target widget with a `Showcase` widget for a showcase with default tooltip: + +```dart +Showcase( + key: _one, + title: 'Menu', + description: 'Click here to see menu options', + child: Icon( + Icons.menu, + color: Colors.black45, + ), +) +``` + +## Start the Showcase + +There are several ways to start the showcase sequence: + +### On Button Press + +```dart +ElevatedButton( + child: Text('Start Showcase'), + onPressed: () { + ShowcaseView.get().startShowCase([_one, _two, _three]); + }, +) +``` + +### On Screen Load + +To start showcase immediately after the screen loads: + +```dart +@override +void initState() { + super.initState(); + // Delayed execution to ensure the UI is fully rendered + WidgetsBinding.instance.addPostFrameCallback( + (_) => ShowcaseView.get().startShowCase([_one, _two, _three]), + ); +} +``` + +### After Animation + +If your UI has animations, you can start the showcase after they complete: + +```dart +WidgetsBinding.instance.addPostFrameCallback( + (_) => ShowcaseView.get().startShowCase( + [_one, _two, _three], + delay: Duration(milliseconds: 500), + ), +); +``` + +### Dispose ShowcaseView + +When you no longer need the showcase view, unregister it: + +```dart +ShowcaseView.get().unregister(); +``` + +## Example + +Here's a complete basic example: + +```dart +import 'package:flutter/material.dart'; +import 'package:showcaseview/showcaseview.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'ShowCase Example', + theme: ThemeData(primarySwatch: Colors.blue), + home: const MyHomePage(), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage(); + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + final GlobalKey _one = GlobalKey(); + final GlobalKey _two = GlobalKey(); + + @override + void initState() { + super.initState(); + // Register the showcase view + ShowcaseView.register(); + + // Start showcase after the screen is rendered to ensure internal initialization. + WidgetsBinding.instance.addPostFrameCallback( + (_) => ShowcaseView.get().startShowCase([_one, _two]), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('ShowCase Example'), + leading: Showcase( + key: _one, + title: 'Menu', + description: 'Click here to see menu options', + child: Icon(Icons.menu), + ), + ), + floatingActionButton: Showcase( + key: _two, + title: 'Add', + description: 'Click here to add new items', + child: FloatingActionButton( + onPressed: () {}, + child: Icon(Icons.add), + ), + ), + body: Center( + child: Text('ShowCase Example'), + ), + ); + } + + @override + void dispose() { + // Unregister the showcase view + ShowcaseView.get().unregister(); + super.dispose(); + } +} +``` + +# Advanced Usage + +This guide covers more advance features and customizations of the ShowCaseView package. + +## Auto Play + +Enable auto play to automatically advance through showcases: + +```dart +ShowcaseView.register( + autoPlay: true, + autoPlayDelay: Duration(milliseconds: 3000), + enableAutoPlayLock: true, +) +``` + +## Auto Scrolling + +Enable auto scrolling to automatically bring off-screen showcase widgets into view: + +```dart +ShowcaseView.register( + enableAutoScroll: true, + scrollDuration: Duration(milliseconds: 500), +) +``` + +> **Note:** Auto-scroll does not work with multi-showcase, and in order to scroll to a widget it +> needs to be attached with widget tree. +> +> If you are using a scrollview that renders widgets on demand like ListView.builder, it is +> possible that the widget to be showcased is not attached to the widget tree leaving flutter +> unable to scroll to that widget. +> +> In such cases, you can assign a ScrollController to that scrollview and manually scroll to +> the position where showcase widget gets rendered. You can add code for that in the onStart +> parameter of the ShowcaseView.register as shown below. + +Example: +```dart +final _controller = ScrollController(); + +ShowcaseView.register( + onStart: (index, key) { + if(index == 0) { + WidgetsBinding.instance.addPostFrameCallback((_) { + // Scroll to approximate position of the showcase widget + _controller.jumpTo(1000); + }); + } + }, +), + +// In your ListView: +ListView.builder( + controller: _controller, + itemCount: 100, + itemBuilder: (context, index) { + // Your list items + }, +) +``` + +## Multi-Showcase View + +To show multiple showcases simultaneously, use the same key for multiple showcase widgets: + +```dart +// Both will be displayed at the same time +Showcase( + key: _multiKey, + title: 'First Widget', + description: 'This is the first widget', + child: Icon(Icons.star), +), + +Showcase( + key: _multiKey, + title: 'Second Widget', + description: 'This is the second widget', + child: Icon(Icons.favorite), +), +``` + +> **Note:** Auto-scroll does not work with multi-showcase, and properties of the first +> initialized showcase are used for common settings like barrier tap and colors. + + +## Custom Tooltip Widget + +Use `Showcase.withWidget` to create a completely custom tooltip: + +```dart +Showcase.withWidget( + key: _customKey, + height: 80, + width: 140, + targetShapeBorder: CircleBorder(), + container: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Custom Tooltip', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + SizedBox(height: 5), + Text('This is a completely custom tooltip widget', style: TextStyle(color: Colors.white)), + ], + ), + child: Icon(Icons.star), +) +``` + +## Tooltip Actions + +Add action buttons to tooltips: + +```dart +Showcase( + key: _actionKey, + title: 'With Actions', + description: 'This showcase has action buttons', + tooltipActions: [ + TooltipActionButton( + type: TooltipActionButtonType.previous, + backgroundColor: Colors.blue, + textStyle: TextStyle(color: Colors.white), + name: 'Previous', + ), + TooltipActionButton( + type: TooltipActionButtonType.next, + backgroundColor: Colors.green, + textStyle: TextStyle(color: Colors.white), + name: 'Next', + ), + TooltipActionButton( + type: TooltipActionButtonType.skip, + backgroundColor: Colors.red, + textStyle: TextStyle(color: Colors.white), + name: 'Skip', + ), + ], + tooltipActionConfig: TooltipActionConfig( + alignment: MainAxisAlignment.spaceEvenly, + position: TooltipActionPosition.outside, + ), + child: MyWidget(), +) +``` + +## Custom Floating Action Widget + +Add a floating action widget that appears during showcases: + +```dart +Showcase( + key: _floatingKey, + title: 'With Floating Widget', + description: 'This showcase has a floating widget', + floatingActionWidget: (_) => Positioned( + bottom: 20, + right: 20, + child: ElevatedButton( + onPressed: () { + // Custom action + }, + child: Text('Custom Action'), + ), + ), + child: MyWidget(), +) +``` + +## Advanced Styling + +Customize the appearance of showcases: + +```dart +Showcase( + key: _styleKey, + title: 'Styled Showcase', + description: 'This showcase has custom styling', + titleTextStyle: TextStyle( + color: Colors.red, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + descTextStyle: TextStyle( + color: Colors.green, + fontSize: 16, + fontStyle: FontStyle.italic, + ), + tooltipBackgroundColor: Colors.black87, + targetPadding: EdgeInsets.all(8), + targetBorderRadius: BorderRadius.circular(8), + tooltipBorderRadius: BorderRadius.circular(16), + child: MyWidget(), +) +``` + +## Showcase Control Methods + +Programmatically control the showcase flow: + +```dart +// Navigate to next showcase +ShowcaseView.get().next(); + +// Navigate to previous showcase +ShowcaseView.get().previous(); + +// Dismiss all showcases +ShowcaseView.get().dismiss(); +``` + +## Event Callbacks + +Handle showcase events: + +```dart +ShowcaseView.register( + onStart: (index, key) { + print('Started showcase $index'); + }, + onComplete: (index, key) { + print('Completed showcase $index'); + }, + onFinish: () { + print('All showcases completed'); + }, + onDismiss: (reason) { + print('Showcase dismissed because: $reason'); + }, +) +``` + +## Overriding Showcase View Configuration + +You can set global configurations for all showcases in your app by using ShowcaseView.register() +and when you want to override that configuration then you can register a new set of +configurations by giving an unique scope name while registering. + +Let's say you want a specific configuration for your entire app so you register it as follow: + +```dart +ShowcaseView.register( + // appropriate configurations +) +``` +Here, when you don't specify a scope name, a default scope name will be used internally. Now, if +you would prefer an another set of configuration just for the profile module, then you can +utilise the scope parameter of ShowcaseView.register() and register another set of configurations +when user navigates to profile screen and unregister it when you want the other configuration set to +be used. An example would be as follow: + +```dart +ShowcaseView.register( + scope: 'profile', + // other configurations +) +``` + +When a scope name is provided, all the operations like startShowCase, dismiss, etc. should be +performed using that scope name, i.e. + +```dart + ShowcaseView.get(scope: 'profile').startShowCase([_one, _two, _three]); +``` + +> If multiple scopes are registered with same name then the last registering scope would be +> consider valid and the rest would be overrode by the last one. + +# Migration Guides + +This document provides guidance for migrating between different versions of the ShowCaseView package. + +## Migration guide for release 4.0.0 + +The 4.0.0 release includes changes to parameter names to better reflect their purpose and behavior. + +### Parameter Renaming + +The parameters `titleAlignment` and `descriptionAlignment` have been renamed to `titleTextAlign` +and `descriptionTextAlign` to correspond more accurately with the TextAlign property. The +original parameter names `titleAlignment` and `descriptionAlignment` are now reserved for widget +alignment. + +#### Before (Pre-4.0.0): + +```dart +Showcase( + titleAlignment: TextAlign.center, + descriptionAlignment: TextAlign.center, +), +``` + +#### After (4.0.0+): + +```dart +Showcase( + titleTextAlign: TextAlign.center, + descriptionTextAlign: TextAlign.center, +), +``` + +## Migration guide for release 3.0.0 + +The 3.0.0 release simplified the API by removing the need for a Builder widget in the ShowCaseWidget. + +### Builder Widget Removal + +The `ShowCaseWidget` no longer requires a `Builder` widget and instead accepts a builder +function directly. + +#### Before (Pre-3.0.0): + +```dart +ShowCaseWidget( + builder: Builder( + builder: (context) => SomeWidget() + ), +), +``` + +#### After (3.0.0+): + +```dart +ShowCaseWidget( + builder: (context) => SomeWidget(), +), +``` + +## Breaking Changes History + +### 4.0.0 +- Renamed `titleAlignment` to `titleTextAlign` +- Renamed `descriptionAlignment` to `descriptionTextAlign` + +### 3.0.0 +- Removed Builder widget from `ShowCaseWidget` +- Changed builder property to accept a function directly + +For a complete list of changes and new features in each version, please refer to the [release +notes](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/releases) on GitHub. + +# Contributors + +These are the main contributors who have helped shape the ShowCaseView package. + +## Main Contributors + +| ![img](https://avatars.githubusercontent.com/u/25323183?v=4&s=200) | ![img](https://avatars.githubusercontent.com/u/81063988?v=4&s=200) | ![img](https://avatars.githubusercontent.com/u/41247722?v=4&s=200) | +|:------------------------------------------------------------------:|:------------------------------------------------------------------:|:------------------------------------------------------------------:| +| [Vatsal Tanna](https://github.com/vatsaltanna) | [Sahil Totala](https://github.com/Flamingloon) | [Aditya Chavda](https://github.com/aditya-chavda) | + +| ![img](https://avatars.githubusercontent.com/u/20923896?v=4&s=200) | ![img](https://avatars.githubusercontent.com/u/56400956?v=4&s=200) | ![img](https://avatars.githubusercontent.com/u/97177197?v=4&s=200) | +|:------------------------------------------------------------------:|:------------------------------------------------------------------:|:------------------------------------------------------------------:| +| [Sanket Kachchela](https://github.com/SanketKachhela) | [Ujas Majithiya](https://github.com/Ujas-Majithiya) | [Happy Makadiya](https://github.com/HappyMakadiyaS) | + + +## How to Contribute + +Contributions to the ShowCaseView package are welcome! Here's how you can contribute: + +1. Fork the repository +2. Create your feature branch (`git checkout -b feature/amazing-feature`) +3. Commit your changes (`git commit -m 'Add some amazing feature'`) +4. Push to the branch (`git push origin feature/amazing-feature`) +5. Open a Pull Request + +## Guidelines for Contributing + +- Follow the coding style and conventions used in the project +- Write clear, concise commit messages +- Add tests for new features or bug fixes +- Update documentation as needed +- Make sure all tests pass before submitting a pull request + +For more information about contributing, please check the [GitHub repository](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview). + +# License + +``` +MIT License + +Copyright (c) 2021 Simform Solutions + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` diff --git a/example/lib/main.dart b/example/lib/main.dart index 0163511b..0df39d41 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -120,7 +120,8 @@ class _MailPageState extends State { //Start showcase view after current widget frames are drawn. WidgetsBinding.instance.addPostFrameCallback( (_) => ShowcaseView.get().startShowCase( - [_firstShowcaseWidget, _two, _three, _four, _lastShowcaseWidget]), + [_firstShowcaseWidget, _two, _three, _four, _lastShowcaseWidget], + ), ); mails = [ Mail( @@ -192,6 +193,8 @@ class _MailPageState extends State { @override void dispose() { scrollController.dispose(); + // Unregister the showcase view when the widget is disposed + ShowcaseView.get().unregister(); super.dispose(); } diff --git a/lib/src/showcase/showcase.dart b/lib/src/showcase/showcase.dart index ef52d51d..c1304c53 100644 --- a/lib/src/showcase/showcase.dart +++ b/lib/src/showcase/showcase.dart @@ -22,14 +22,10 @@ import 'package:flutter/material.dart'; +import '../../showcaseview.dart'; import '../models/showcase_scope.dart'; -import '../models/tooltip_action_button.dart'; -import '../models/tooltip_action_config.dart'; -import '../showcase_widget.dart'; import '../utils/constants.dart'; -import '../utils/enum.dart'; import '../utils/overlay_manager.dart'; -import '../widget/floating_action_widget.dart'; import 'showcase_controller.dart'; import 'showcase_service.dart'; diff --git a/lib/src/showcase/showcase_view.dart b/lib/src/showcase/showcase_view.dart index f394ab83..d7b568c1 100644 --- a/lib/src/showcase/showcase_view.dart +++ b/lib/src/showcase/showcase_view.dart @@ -22,11 +22,11 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:showcaseview/src/utils/enum.dart'; import '../models/tooltip_action_button.dart'; import '../models/tooltip_action_config.dart'; import '../utils/constants.dart'; +import '../utils/enum.dart'; import '../utils/overlay_manager.dart'; import '../widget/floating_action_widget.dart'; import 'showcase_controller.dart'; @@ -61,20 +61,20 @@ class ShowcaseView { /// options like auto-play, animation, and many more. ShowcaseView.register({ this.scope = Constants.defaultScope, - this.onFinish, this.onStart, + this.onFinish, this.onComplete, this.onDismiss, + this.enableShowcase = true, this.autoPlay = false, this.autoPlayDelay = Constants.defaultAutoPlayDelay, this.enableAutoPlayLock = false, - this.blurValue = 0, - this.scrollDuration = Constants.defaultScrollDuration, - this.disableMovingAnimation = false, - this.disableScaleAnimation = false, this.enableAutoScroll = false, + this.scrollDuration = Constants.defaultScrollDuration, this.disableBarrierInteraction = false, - this.enableShowcase = true, + this.disableScaleAnimation = false, + this.disableMovingAnimation = false, + this.blurValue = 0, this.globalTooltipActionConfig, this.globalTooltipActions, this.globalFloatingActionWidget, diff --git a/lib/src/widget/tooltip_action_button_widget.dart b/lib/src/widget/tooltip_action_button_widget.dart index a2ee5e88..a482a4fe 100644 --- a/lib/src/widget/tooltip_action_button_widget.dart +++ b/lib/src/widget/tooltip_action_button_widget.dart @@ -40,11 +40,10 @@ class TooltipActionButtonWidget extends StatelessWidget { super.key, }); - /// This will provide the configuration for the action buttons + /// This will provide the configuration for the action buttons. final TooltipActionButton config; - /// This is used for [TooltipActionButton] to close, next and previous - /// showcase navigation + /// This is used for close, next and previous showcase navigation. final ShowcaseView showCaseState; @override