flutter_welcome_kit 2.0.0 copy "flutter_welcome_kit: ^2.0.0" to clipboard
flutter_welcome_kit: ^2.0.0 copied to clipboard

A beautiful, customizable onboarding/tour guide kit for Flutter apps with spotlight overlays, animations, and step-by-step tooltips.

example/lib/main.dart

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Task Manager Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        brightness: Brightness.dark,
        primaryColor: Colors.indigo,
        scaffoldBackgroundColor: const Color(0xFF0D1117),
        colorScheme: const ColorScheme.dark(
          primary: Colors.indigo,
          secondary: Color(0xFF21262D),
          surface: Color(0xFF161B22),
        ),
        appBarTheme: const AppBarTheme(
          backgroundColor: Color(0xFF161B22),
          elevation: 0,
        ),
        cardTheme: const CardThemeData(
          color: Color(0xFF21262D),
        ),
        elevatedButtonTheme: ElevatedButtonThemeData(
          style: ElevatedButton.styleFrom(
            backgroundColor: Colors.indigo,
            foregroundColor: Colors.white,
          ),
        ),
      ),
      home: const TaskManagerDemo(),
    );
  }
}

/// A practical demo showcasing the Flutter Welcome Kit in a real app context
class TaskManagerDemo extends StatefulWidget {
  const TaskManagerDemo({super.key});

  @override
  State<TaskManagerDemo> createState() => _TaskManagerDemoState();
}

class _TaskManagerDemoState extends State<TaskManagerDemo> {
  // Global keys for tour targets
  final GlobalKey _addTaskKey = GlobalKey();
  final GlobalKey _filterKey = GlobalKey();
  final GlobalKey _searchKey = GlobalKey();
  final GlobalKey _taskCardKey = GlobalKey();
  final GlobalKey _priorityBadgeKey = GlobalKey();
  final GlobalKey _checkboxKey = GlobalKey();
  final GlobalKey _statsCardKey = GlobalKey();

  late TourController _tourController;
  bool _showTour = true;

  // Sample task data
  final List<Map<String, dynamic>> _tasks = [
    {'title': 'Review pull requests', 'priority': 'high', 'done': false},
    {'title': 'Update documentation', 'priority': 'medium', 'done': true},
    {'title': 'Fix login bug', 'priority': 'high', 'done': false},
    {'title': 'Team standup meeting', 'priority': 'low', 'done': true},
  ];

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _initTour();
      // Auto-start tour for demo purposes
      if (_showTour) {
        Future.delayed(const Duration(milliseconds: 500), () {
          _tourController.start();
        });
      }
    });
  }

  void _initTour() {
    _tourController = TourController(
      context: context,
      steps: [
        TourStep(
          key: _addTaskKey,
          title: '➕ Create Tasks',
          description: 'Tap here to add a new task to your list. You can set priority levels and due dates.',
          backgroundColor: Colors.indigo,
          animation: StepAnimation.fadeSlideUp,
          highlightShape: HighlightShape.circle,
          showPulse: true,
          duration: const Duration(seconds: 6),
        ),
        TourStep(
          key: _filterKey,
          title: '🔍 Filter Tasks',
          description: 'Filter your tasks by status, priority, or date to focus on what matters.',
          backgroundColor: Colors.teal,
          animation: StepAnimation.fadeSlideDown,
          highlightShape: HighlightShape.circle,
          duration: const Duration(seconds: 6),
        ),
        TourStep(
          key: _searchKey,
          title: '🔎 Quick Search',
          description: 'Instantly find any task by typing keywords. Works across all your projects.',
          backgroundColor: Colors.orange,
          animation: StepAnimation.scale,
          highlightShape: HighlightShape.circle,
          showPulse: true,
          duration: const Duration(seconds: 6),
        ),
        TourStep(
          key: _taskCardKey,
          title: '📋 Task Cards',
          description: 'Each task shows its title, priority, and completion status at a glance.',
          backgroundColor: Colors.purple,
          animation: StepAnimation.fadeSlideLeft,
          highlightShape: HighlightShape.rounded,
          spotlightPadding: 4,
          duration: const Duration(seconds: 6),
        ),
        TourStep(
          key: _priorityBadgeKey,
          title: '🏷️ Priority Badges',
          description: 'Color-coded badges help you identify urgent tasks quickly.',
          backgroundColor: Colors.red.shade700,
          animation: StepAnimation.bounce,
          highlightShape: HighlightShape.pill,
          showPulse: true,
          duration: const Duration(seconds: 6),
        ),
        TourStep(
          key: _checkboxKey,
          title: '✓ Complete Tasks',
          description: 'Tap the checkbox to mark a task as complete. Your progress is saved automatically.',
          backgroundColor: Colors.green,
          animation: StepAnimation.scale,
          highlightShape: HighlightShape.circle,
          duration: const Duration(seconds: 6),
        ),
        TourStep(
          key: _statsCardKey,
          title: '📊 Your Progress',
          description: 'Track your productivity with real-time statistics and insights.',
          backgroundColor: Colors.blue,
          animation: StepAnimation.fadeSlideUp,
          highlightShape: HighlightShape.rounded,
          isLast: true,
          buttonLabel: 'Get Started! 🚀',
          duration: const Duration(seconds: 8),
        ),
      ],
      startDelay: const Duration(milliseconds: 300),
      onComplete: () {
        setState(() => _showTour = false);
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('🎉 You\'re all set! Start managing your tasks.'),
            backgroundColor: Colors.green,
            behavior: SnackBarBehavior.floating,
          ),
        );
      },
      onSkip: () {
        setState(() => _showTour = false);
      },
      onStepChange: (index, step) {
        debugPrint('Tour step ${index + 1}: ${step.title}');
      },
    );
  }

  Color _getPriorityColor(String priority) {
    switch (priority) {
      case 'high':
        return Colors.red;
      case 'medium':
        return Colors.orange;
      default:
        return Colors.blue;
    }
  }

  @override
  Widget build(BuildContext context) {
    final completedCount = _tasks.where((t) => t['done'] == true).length;
    final totalCount = _tasks.length;

    return Scaffold(
      appBar: AppBar(
        title: const Text('Task Manager'),
        actions: [
          IconButton(
            key: _filterKey,
            icon: const Icon(Icons.filter_list),
            onPressed: () {},
            tooltip: 'Filter',
          ),
          IconButton(
            key: _searchKey,
            icon: const Icon(Icons.search),
            onPressed: () {},
            tooltip: 'Search',
          ),
          const SizedBox(width: 8),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            // Stats card
            Card(
              key: _statsCardKey,
              child: Padding(
                padding: const EdgeInsets.all(20),
                child: Row(
                  children: [
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            'Today\'s Progress',
                            style: TextStyle(
                              fontSize: 14,
                              color: Colors.grey[400],
                            ),
                          ),
                          const SizedBox(height: 8),
                          Text(
                            '$completedCount of $totalCount tasks',
                            style: const TextStyle(
                              fontSize: 24,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ],
                      ),
                    ),
                    SizedBox(
                      width: 60,
                      height: 60,
                      child: Stack(
                        children: [
                          CircularProgressIndicator(
                            value: completedCount / totalCount,
                            strokeWidth: 6,
                            backgroundColor: Colors.grey[800],
                            valueColor: const AlwaysStoppedAnimation(Colors.green),
                          ),
                          Center(
                            child: Text(
                              '${((completedCount / totalCount) * 100).round()}%',
                              style: const TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 12,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // Task list header
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  'Tasks',
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                TextButton.icon(
                  onPressed: () {
                    // Restart tour
                    _initTour();
                    _tourController.start();
                  },
                  icon: const Icon(Icons.replay, size: 18),
                  label: const Text('Replay Tour'),
                ),
              ],
            ),
            const SizedBox(height: 8),

            // Task list
            Expanded(
              child: ListView.builder(
                itemCount: _tasks.length,
                itemBuilder: (context, index) {
                  final task = _tasks[index];
                  final isFirstTask = index == 0;
                  
                  return Card(
                    key: isFirstTask ? _taskCardKey : null,
                    margin: const EdgeInsets.only(bottom: 8),
                    child: ListTile(
                      leading: Checkbox(
                        key: isFirstTask ? _checkboxKey : null,
                        value: task['done'],
                        onChanged: (value) {
                          setState(() {
                            _tasks[index]['done'] = value;
                          });
                        },
                        activeColor: Colors.green,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(4),
                        ),
                      ),
                      title: Text(
                        task['title'],
                        style: TextStyle(
                          decoration: task['done'] 
                              ? TextDecoration.lineThrough 
                              : null,
                          color: task['done'] 
                              ? Colors.grey 
                              : Colors.white,
                        ),
                      ),
                      trailing: Container(
                        key: isFirstTask ? _priorityBadgeKey : null,
                        padding: const EdgeInsets.symmetric(
                          horizontal: 12,
                          vertical: 4,
                        ),
                        decoration: BoxDecoration(
                          color: _getPriorityColor(task['priority'])
                              .withValues(alpha: 0.2),
                          borderRadius: BorderRadius.circular(12),
                          border: Border.all(
                            color: _getPriorityColor(task['priority']),
                          ),
                        ),
                        child: Text(
                          task['priority'].toUpperCase(),
                          style: TextStyle(
                            fontSize: 10,
                            fontWeight: FontWeight.bold,
                            color: _getPriorityColor(task['priority']),
                          ),
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        key: _addTaskKey,
        onPressed: () {},
        backgroundColor: Colors.indigo,
        child: const Icon(Icons.add),
      ),
    );
  }
}
5
likes
140
points
196
downloads

Publisher

unverified uploader

Weekly Downloads

A beautiful, customizable onboarding/tour guide kit for Flutter apps with spotlight overlays, animations, and step-by-step tooltips.

Repository (GitHub)
View/report issues

Topics

#onboarding #tutorial #tooltip #walkthrough #ui

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_welcome_kit