promo_carousel 1.1.0 copy "promo_carousel: ^1.1.0" to clipboard
promo_carousel: ^1.1.0 copied to clipboard

A flexible, customizable promotional carousel package for Flutter.

A flexible, production-ready Flutter package for creating beautiful promotional carousels with support for user-specific widget injection. Perfect for onboarding flows, feature announcements, and personalized promotions.

pub package License: MIT

✨ Features #

Core Features #

  • 🎯 Modal Overlay - Beautiful dialog-style presentation with dimmed background
  • πŸ“± Swipeable Carousel - Smooth PageView-based navigation
  • 🎨 Built-in Visual Types - Images, animations, search bars, videos, and more
  • πŸ”§ Custom Widget Injection - Inject user-specific widgets without coupling
  • πŸ’Ύ Persistent State - Tracks "show once" slides using SharedPreferences
  • πŸŒ— Theme Support - Automatically adapts to light and dark themes

Enhanced Features (v1.1) #

  • ⏱️ Auto-Advance - Automatically progress through slides with configurable timing
  • πŸ“Š Analytics Callbacks - Track views, clicks, skips, and completions
  • ⚑ Skip All Button - Let users bypass the entire carousel
  • 🎭 Multiple Display Modes - Dialog, bottom sheet, or fullscreen
  • πŸ“ Progress Indicators - Linear progress bar or custom indicators
  • 🎬 Transition Types - Slide, fade, scale, or rotate animations
  • πŸ’¨ Backdrop Blur - Add frosted glass effect to overlay
  • πŸ“± Gesture Controls - Swipe or tap to advance
  • β™Ώ Haptic Feedback - Tactile response on page changes
  • 🌍 Remote Config Ready - Load slides from JSON
  • πŸ”’ Conditional Display - Advanced filtering rules (dates, versions, segments, devices)
  • πŸ§ͺ Preview Mode - Test all slides without rules
  • πŸ› Debug Mode - Detailed logging for development

πŸ“Έ Preview #

Promo Carousel Demo

πŸš€ Getting Started #

Installation #

Add to your pubspec.yaml:

dependencies:
  promo_carousel: ^1.1.0

Then run:

flutter pub get

Basic Usage #

import 'package:promo_carousel/promo_carousel.dart';

PromoCarousel.show(
  context: context,
  slides: [
    PromoSlide(
      id: 'welcome',
      title: 'Welcome to Our App',
      subtitle: 'Discover amazing features',
      visualType: PromoVisualType.featureHighlight,
      cta: PromoCTA(
        text: 'Get Started',
        action: PromoAction.close,
      ),
      rules: PromoRules(showOnce: true),
    ),
  ],
  onAction: (action, target) {
    print('Action: $action');
  },
);

πŸ“– Documentation #

PromoSlide #

The core model representing a single carousel slide:

PromoSlide(
  id: 'unique_id',                    // Unique identifier
  title: 'Main Title',                // Required title text
  subtitle: 'Optional description',   // Optional subtitle
  visualType: PromoVisualType.image,  // Built-in visual type
  cta: PromoCTA(                      // Call-to-action button
    text: 'Button Text',
    action: PromoAction.navigate,
    target: '/route-name',
  ),
  rules: PromoRules(                  // Display rules
    showOnce: true,
    minAppVersion: '1.2.0',
    maxAppVersion: '2.0.0',
    showAfterDate: DateTime(2025, 1, 1),
    showBeforeDate: DateTime(2025, 12, 31),
    userSegments: ['premium', 'beta'],
    deviceTypes: [DeviceType.mobile],
  ),
  customContentBuilder: (context) {   // Optional custom widget
    return YourCustomWidget();
  },
  semanticLabel: 'Welcome screen',    // Accessibility
  metadata: {'experiment_id': '001'}, // A/B testing
)

Visual Types #

Built-in visual types available:

  • PromoVisualType.image - Display an image asset
  • PromoVisualType.animation - Show an animated visual
  • PromoVisualType.searchBar - Search bar animation
  • PromoVisualType.featureHighlight - Gradient highlight
  • PromoVisualType.video - Video player (requires video asset)
  • PromoVisualType.custom - Use with customContentBuilder

Actions #

Available CTA actions:

  • PromoAction.navigate - Navigate to a route
  • PromoAction.openFeature - Open a specific feature
  • PromoAction.openPaywall - Show paywall/upgrade screen
  • PromoAction.close - Simply close the modal
  • PromoAction.custom - Custom action with callback

Configuration #

Customize appearance and behavior:

PromoCarousel.show(
  context: context,
  slides: slides,
  config: PromoCarouselConfig(
    // Appearance
    borderRadius: 24.0,
    elevation: 8.0,
    barrierColor: Color(0x80000000),
    backdropBlur: 10.0,
    displayMode: DisplayMode.dialog,

    // Behavior
    barrierDismissible: true,
    showCloseButton: true,
    showDontShowAgain: false,
    showSkipButton: true,
    enableSwipeGestures: true,
    enableTapToAdvance: true,

    // Auto-advance
    autoAdvance: true,
    autoAdvanceDuration: Duration(seconds: 5),
    pauseOnInteraction: true,

    // Progress
    showProgressBar: true,
    progressBarPosition: ProgressPosition.top,

    // Accessibility
    enableHaptics: true,
    hapticFeedbackType: HapticType.light,
    respectReducedMotion: true,
  ),
);

Pre-built Configs #

Use factory constructors for common scenarios:

// Onboarding flow
config: PromoCarouselConfig.onboarding()

// Feature announcement
config: PromoCarouselConfig.announcement()

// Marketing promotion
config: PromoCarouselConfig.marketing()

🎯 Advanced Usage #

Custom User-Specific Widgets #

The key feature - inject personalized content without coupling the package to your data models:

PromoSlide(
  id: 'zodiac_preview',
  title: 'Your Personal Insights',
  subtitle: 'Based on your zodiac sign',
  visualType: PromoVisualType.custom,
  cta: PromoCTA(
    text: 'Reveal',
    action: PromoAction.openFeature,
    target: 'zodiac_detail',
  ),
  rules: PromoRules(showOnce: true),
  customContentBuilder: (context) {
    // Access your app's user data here
    final user = Provider.of<User>(context);

    return ZodiacPreviewCard(
      sign: user.zodiacSign,
      topSearch: user.topSearch,
    );
  },
)

Analytics Tracking #

Track user interactions with comprehensive callbacks:

PromoCarousel.show(
  context: context,
  slides: slides,
  analytics: PromoCarouselAnalytics(
    onSlideViewed: (slideId, index) {
      print('Viewed: $slideId at index $index');
      analytics.logEvent('promo_slide_viewed', {'slide_id': slideId});
    },
    onSlideSkipped: (slideId, index) {
      analytics.logEvent('promo_slide_skipped');
    },
    onCTAClicked: (slideId, action, target) {
      analytics.logEvent('promo_cta_clicked', {
        'slide_id': slideId,
        'action': action.name,
        'target': target,
      });
    },
    onCarouselCompleted: (viewedSlides) {
      analytics.logEvent('promo_completed', {
        'slides_viewed': viewedSlides.length,
      });
    },
    onCarouselDismissed: (lastIndex, viewedSlides) {
      analytics.logEvent('promo_dismissed', {
        'last_index': lastIndex,
        'completion_rate': viewedSlides.length / slides.length,
      });
    },
    onSkipAll: () {
      analytics.logEvent('promo_skipped_all');
    },
  ),
);

Auto-Advance with Pause #

Automatically progress through slides:

PromoCarousel.show(
  context: context,
  slides: slides,
  config: PromoCarouselConfig(
    autoAdvance: true,
    autoAdvanceDuration: Duration(seconds: 5),
    pauseOnInteraction: true, // Pause when user interacts
    showProgressBar: true,
  ),
);

Display Modes #

Choose how to present the carousel:

// Dialog (default)
PromoCarousel.show(context: context, slides: slides);

// Bottom sheet
PromoCarousel.showBottomSheet(context: context, slides: slides);

// Fullscreen
PromoCarousel.showFullscreen(context: context, slides: slides);

Remote Config Integration #

Load slides from JSON:

// From your Firebase Remote Config, API, etc.
final jsonData = await remoteConfig.getJson('promo_slides');

// Parse to slides
final slides = PromoCarousel.fromJson(jsonData);

// Show carousel
PromoCarousel.show(context: context, slides: slides);

Conditional Display Rules #

Advanced filtering based on multiple criteria:

PromoSlide(
  id: 'premium_offer',
  title: 'Upgrade to Premium',
  rules: PromoRules(
    showOnce: true,
    minAppVersion: '1.5.0',
    maxAppVersion: '2.0.0',
    showAfterDate: DateTime(2025, 1, 1),
    showBeforeDate: DateTime(2025, 12, 31),
    userSegments: ['free_tier', 'trial'],
    deviceTypes: [DeviceType.mobile, DeviceType.tablet],
    customCondition: () {
      // Custom logic
      return user.hasUsedAppForDays(7);
    },
  ),
  // ...
)

Custom Page Indicators #

Replace the default page counter:

PromoCarousel.show(
  context: context,
  slides: slides,
  config: PromoCarouselConfig(
    indicatorBuilder: (context, currentPage, totalPages) {
      return Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: List.generate(totalPages, (index) {
          return Container(
            margin: EdgeInsets.symmetric(horizontal: 4),
            width: index == currentPage ? 12 : 8,
            height: 8,
            decoration: BoxDecoration(
              color: index == currentPage ? Colors.blue : Colors.grey,
              borderRadius: BorderRadius.circular(4),
            ),
          );
        }),
      );
    },
  ),
);

Preview Mode #

Test all slides regardless of rules:

PromoCarousel.showPreview(
  context: context,
  slides: slides,
  // Ignores showOnce, date ranges, version checks, etc.
);

Manual State Management #

Control slide visibility programmatically:

// Check if slide was seen
final seen = await PromoCarousel.hasSeenSlide('welcome');

// Reset a specific slide
await PromoCarousel.resetSlide('welcome');

// Reset multiple slides
await PromoCarousel.resetSlides(['slide1', 'slide2']);

// Reset all slides
await PromoCarousel.resetAll();

// Get all seen slides
final seenSlides = await PromoCarousel.getSeenSlides();

// Export analytics
final analytics = await PromoCarousel.exportAnalytics();

Debug Mode #

Enable detailed logging during development:

void main() {
  PromoCarousel.debugMode = true;
  runApp(MyApp());
}

🎨 Theming #

The carousel automatically adapts to your app's theme:

MaterialApp(
  theme: ThemeData.light(),
  darkTheme: ThemeData.dark(),
  // Carousel will adapt to both themes
)

πŸ“± Use Cases #

Perfect for:

  • βœ… Onboarding flows - Welcome new users
  • βœ… Feature announcements - Showcase new capabilities
  • βœ… Personalized promotions - Zodiac insights, user stats, achievements
  • βœ… Contextual tips - Show relevant guidance
  • βœ… Marketing campaigns - Promote offers and upgrades
  • βœ… Product tours - Guide users through features
  • βœ… A/B testing - Test different messaging with metadata tracking
  • βœ… Seasonal campaigns - Date-based promotions

πŸ—οΈ Architecture #

The package follows clean architecture principles:

lib/
β”œβ”€β”€ models/
β”‚   β”œβ”€β”€ promo_slide.dart              # Core data models
β”‚   └── promo_carousel_config.dart    # Configuration classes
β”œβ”€β”€ controllers/
β”‚   └── promo_carousel_controller.dart # State management
β”œβ”€β”€ widgets/
β”‚   β”œβ”€β”€ promo_carousel_modal.dart     # Main modal widget
β”‚   └── promo_slide_content.dart      # Content renderer
└── promo_carousel.dart               # Public API

🚫 What This Package Does NOT Do #

To keep the package generic and reusable:

  • ❌ No Firebase or remote config integration (but provides JSON parsing)
  • ❌ No analytics tracking implementation (but provides callbacks)
  • ❌ No app-specific navigation logic
  • ❌ No user data models or assumptions
  • ❌ No network requests

These features should be implemented in your app layer using the provided callbacks and hooks.

🀝 Contributing #

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.

πŸ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ“ Changelog #

See CHANGELOG.md for release history.

πŸ™ Acknowledgments #

Built with ❀️ for the Flutter community.

πŸ“ž Support #


Made with Flutter πŸ’™

1
likes
160
points
63
downloads
screenshot

Publisher

verified publisherkyawzayartun.com

Weekly Downloads

A flexible, customizable promotional carousel package for Flutter.

Repository (GitHub)
View/report issues

Topics

#onboarding #promo-content #promo-carousel #utility

Documentation

API reference

License

MIT (license)

Dependencies

flutter, shared_preferences, video_player

More

Packages that depend on promo_carousel