Showcase Coach

Modern, design-forward showcase coach overlays for Flutter with smooth motion, glassmorphism, and sensible validation so you can guide users through product tours with confidence.

Pub Version License

Preview

Showcase Coach Preview

Try it live: Interactive Demo

Why use Showcase Coach?

  • Design-first: Glassmorphism, elevated cards, and balanced typography that fit Material 3.
  • Safe by default: Duplicate key detection, visibility checks, and user-friendly error dialogs.
  • Flexible logic: Per-step and global conditions (shouldShow / showIf) plus smart scrolling.
  • Motion-aware: Reduced-motion mode to turn off blur and heavy effects, plus customizable transition animations.
  • Accessible: Built-in accessibility support with semantic labels and proper tap targets.
  • Well-documented: Comprehensive API documentation with examples and best practices.
  • Drop-in: Simple API that works with any widget that has a GlobalKey.

Installation

Add to pubspec.yaml:

dependencies:
  save_points_showcaseview: ^1.0.3

Then install:

flutter pub get

Quick start (3 steps)

  1. Create keys:
final _buttonKey = GlobalKey();
final _cardKey = GlobalKey();
  1. Attach keys:
FilledButton(key: _buttonKey, onPressed: () {}, child: const Text('Click me'));
Card(key: _cardKey, child: const Text('Important card'));
  1. Show the coach:
await ShowcaseCoach.show(
  context,
  steps: [
    CoachStep(
      targetKey: _buttonKey,
      title: 'Welcome!',
      description: ['This is your first step.'],
    ),
    CoachStep(
      targetKey: _cardKey,
      title: 'Feature Card',
      description: [
        'This card contains important information.',
        'Swipe to see more tips.',
      ],
    ),
  ],
);

Full example

import 'package:flutter/material.dart';
import 'package:save_points_showcaseview/save_points_showcaseview.dart';

class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final _buttonKey = GlobalKey();
  final _cardKey = GlobalKey();

  Future<void> _startTour() async {
    await ShowcaseCoach.show(
      context,
      steps: [
        CoachStep(
          targetKey: _buttonKey,
          title: 'Action Button',
          description: ['Tap this button to perform an action.'],
        ),
        CoachStep(
          targetKey: _cardKey,
          title: 'Information Card',
          description: ['This card displays important information.'],
        ),
      ],
      onSkip: () => debugPrint('Tour skipped'),
      onDone: () => debugPrint('Tour completed'),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          FilledButton(
            key: _buttonKey,
            onPressed: _startTour,
            child: const Text('Start Tour'),
          ),
          Card(
            key: _cardKey,
            child: const Padding(
              padding: EdgeInsets.all(12),
              child: Text('Card content'),
            ),
          ),
        ],
      ),
    );
  }
}

Configuration highlights

  • ShowcaseCoachConfig lets you tune:
    • primaryColor, buttonColor, fontFamily
    • cardStyle: glass (default) or normal
    • overlayTintOpacity
    • reduceMotion: disables blur/heavy effects
    • Transition animations (new):
      • enableTransitions: enable/disable transition animations (defaults based on reduceMotion)
      • transitionDuration: global duration for all transitions
      • transitionCurve: global curve for all transitions
      • Individual transition durations:
        • backdropTransitionDuration: backdrop hole transitions (default: 450ms)
        • gradientTransitionDuration: gradient overlay transitions (default: 500ms)
        • highlightTransitionDuration: highlight position transitions (default: 700ms)
        • cardTransitionDuration: tooltip card transitions (default: 600ms)
  • Per-step logic:
    • shouldShow: function returning bool (priority)
    • showIf: simple bool (defaults to true)

Customizing transition animations

ShowcaseCoachConfig(
  // Enable/disable transitions (defaults to true unless reduceMotion is true)
  enableTransitions: true,
  
  // Set global duration for all transitions
  transitionDuration: Duration(milliseconds: 300),
  
  // Set global curve for all transitions
  transitionCurve: Curves.easeInOut,
  
  // Or customize individual transitions
  backdropTransitionDuration: Duration(milliseconds: 400),
  cardTransitionDuration: Duration(milliseconds: 500),
  
  // Disable transitions entirely
  // enableTransitions: false,
  
  // Or let reduceMotion handle it automatically
  // reduceMotion: true,  // This will disable transitions
)

Validation and safety

  • Duplicate GlobalKey detection before showing.
  • Visibility checks ensure targets are attached and scroll into view.
  • Friendly dialogs instead of silent failures or crashes.
  • Comprehensive error messages with actionable guidance.

Accessibility

  • Semantic labels for screen readers.
  • Minimum tap target sizes (48x48) for better touch accessibility.
  • Proper button semantics for assistive technologies.
  • Full keyboard navigation support.

Tips & best practices

  1. Wait for layout before showing:
WidgetsBinding.instance.addPostFrameCallback((_) {
  ShowcaseCoach.show(context, steps: steps);
});
  1. Unique keys: every step needs its own GlobalKey.
  2. Concise copy: short titles and descriptions improve completion.
  3. Respect motion: use reduceMotion: true where needed, or customize transition animations with enableTransitions and duration/curve options.
  4. Accessibility: The library includes built-in accessibility support, but ensure your target widgets are also accessible.

Troubleshooting

  • Nothing shows: confirm Overlay.of(context) is available (e.g., use inside a MaterialApp), and run after the first frame.
  • Step skipped: check shouldShow / showIf for that step.
  • Target not found: ensure the widget has a unique GlobalKey and is mounted.

Contributing

Issues and PRs are welcome! Open one at: https://github.com/m7hamed-dev/save-points-showcaseview/issues

License

MIT License. See LICENSE for details.

Libraries

main
Main library entry point for the showcase coach package.
models/phase
save_points_showcaseview
A beautiful, modern showcase coach overlay for Flutter.
showcase_coach
Deprecated entry point. Use package:save_points_showcaseview/save_points_showcaseview.dart.
widgets/coach_step
widgets/explainable_action