dynamic_popup 1.0.2 copy "dynamic_popup: ^1.0.2" to clipboard
dynamic_popup: ^1.0.2 copied to clipboard

A flexible and customizable dynamic popup system for Flutter with markdown support and interactive components.

Dynamic Popup #

A flexible and customizable dynamic popup system for Flutter with markdown support and interactive components.

Features #

  • Configurable popups from backend APIs
  • Markdown parser with support for dynamic component placeholders
  • Interactive components: RadioButton, Checkbox, TextArea, TextField, Dropdown
  • Automatic validation of required fields
  • Persistent state management (show once, completed/dismissed)
  • Blocking and non-blocking popup behaviors
  • Easy to customize and extend
  • No dependency on GetX - works with any Flutter app
  • Minimal API requirements - only two endpoints required

๐Ÿš€ Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  dynamic_popup: ^1.0.2

Then run:

flutter pub get

Note: The http package is only required if you use the example implementations. The core library does not depend on http.

๐Ÿ“ฑ Popup Types #

1. Non-blocking Popup #

  • User can close without completing
  • Ideal for information, optional surveys, feature discovery

2. Blocking Popup #

  • User must complete to continue
  • Ideal for terms of service, privacy policy, required data

๐Ÿ›  Supported Components #

RadioButton #

[RADIOBUTTON:required:component_id:Label:Option1,Option2,Option3]

Checkbox (single/multiple) #

[CHECKBOX:optional:component_id:Label:Option1,Option2,Option3]

TextArea #

[TEXTAREA:required:component_id:Label:Placeholder text]

TextField #

[TEXTFIELD:optional:component_id:Label:Placeholder text]
[DROPDOWN:required:component_id:Label:Option1,Option2,Option3]

๐Ÿ”ง Placeholder Syntax #

[COMPONENT_TYPE:required/optional:component_id:label:options/placeholder]

Parameters:

  • COMPONENT_TYPE: Component type (RADIOBUTTON, CHECKBOX, etc.)
  • required/optional: Whether the field is required
  • component_id: Unique component ID
  • label: Label shown to user
  • options/placeholder: Options (for radio/checkbox/dropdown) or placeholder (for text)

๐Ÿ’ป Usage #

Setup Service #

import 'package:dynamic_popup/dynamic_popup.dart';

// Create a repository that implements your API calls
class MyPopupRepository extends BaseDynamicPopupRepository {
  @override
  Future<PopupApiResponse?> checkForPopup({
    required String screenName,
    String? userId,
  }) async {
    // Implement your API call here
    // Only these two methods are required
  }

  @override
  Future<bool> submitPopupResponse({
    required PopupResponse popupResponse,
  }) async {
    // Implement your API call here
    // Only these two methods are required
  }
}

// In your app initialization (e.g., in initState of your main widget)
final popupService = DynamicPopupService(
  repository: MyPopupRepository(),
);
popupService.init(); // Initialize the service

Show Manual Popup #

// Show specific popup by ID
await popupService.showPopupById('privacy_update_2024', context: context);

// Check for and show popup for a screen
await popupService.checkAndShowPopup(
  screenName: 'home_screen',
  context: context,
);

// Reset state for testing
await popupService.resetPopupState('privacy_update_2024');

// Reset all states
popupService.resetAllPopupStates();

Using the Test Page #

import 'package:dynamic_popup/dynamic_popup.dart';

// Navigate to test page
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => const DynamicPopupTestPage()),
);

Manual Popup Display #

// Test specific component
final config = PopupConfig(
  id: 'test_popup',
  title: 'Test',
  markdownContent: '[RADIOBUTTON:required:test:Test?:Yes,No]',
  isBlocking: false,
);

showDialog(
  context: context,
  builder: (BuildContext context) {
    return DynamicPopupWidget(
      config: config,
      onCompleted: (response) => print('Response: ${response.responses}'),
    );
  },
);

๐Ÿ”Œ Custom API Integration #

The package is designed to work with any backend API with minimal requirements. Here's how to integrate with your custom API:

1. Minimal Implementation (Only 2 Required Methods) #

import 'package:dynamic_popup/dynamic_popup.dart';

class MySimplePopupRepository extends BaseDynamicPopupRepository {
  @override
  Future<PopupApiResponse?> checkForPopup({
    required String screenName,
    String? userId,
  }) async {
    // Only implement these two required methods
    // All other methods are optional
  }

  @override
  Future<bool> submitPopupResponse({
    required PopupResponse popupResponse,
  }) async {
    // Only implement these two required methods
    // All other methods are optional
  }
}

2. Direct Usage Without Service #

// Fetch popup config from your API directly
final popupConfig = await MyApiService.getPopupForScreen('home_screen');

if (popupConfig != null) {
  await showDialog(
    context: context,
    builder: (BuildContext context) {
      return DynamicPopupWidget(
        config: popupConfig,
        onCompleted: (response) async {
          // Submit response to your API directly
          await MyApiService.submitResponse(response);
          Navigator.of(context).pop();
        },
      );
    },
  );
}

๐Ÿงช Testing #

Test Page #

Run DynamicPopupTestPage to test all components:

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => const DynamicPopupTestPage()),
);

๐Ÿ“‹ Complete Examples #

Privacy Policy Popup #

# Privacy Policy Update

Our privacy policy has been updated. Please review and confirm your preferences.

## Required Consent
[RADIOBUTTON:required:privacy_accept:Do you accept the new privacy policy?:Accept,Decline]

## Data Usage (Optional)
[CHECKBOX:optional:data_usage:What data can we use?:Analytics,Marketing,Performance,Crash Reports]

## Feedback
[TEXTAREA:optional:feedback:Comments or questions?:Share your thoughts...]

**Thank you for your attention.**

Complete Survey #

# Satisfaction Survey

Help us improve the app by completing this brief survey.

[TEXTFIELD:required:name:Full Name:Enter your name]

[DROPDOWN:required:frequency:Usage Frequency:Daily,Weekly,Monthly,Occasional]

[CHECKBOX:required:features:Which features do you use?:Restaurant,Special Sales,PCM,Snack Bar]

[TEXTAREA:required:suggestions:Improvement suggestions:Describe your ideas...]

[RADIOBUTTON:required:recommend:Would you recommend the app?:Definitely,Probably,Not Sure,Probably Not,Definitely Not]

๐Ÿ— Architecture #

File Structure #

lib/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ data/
โ”‚   โ”‚   โ”œโ”€โ”€ model/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ popup_config.dart
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dynamic_component.dart
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ popup_models.dart
โ”‚   โ”‚   โ””โ”€โ”€ repository/
โ”‚   โ”‚       โ”œโ”€โ”€ dynamic_popup_repository.dart
โ”‚   โ”‚       โ””โ”€โ”€ base_dynamic_popup_repository.dart
โ”‚   โ”œโ”€โ”€ parser/
โ”‚   โ”‚   โ””โ”€โ”€ markdown_dynamic_parser.dart
โ”‚   โ”œโ”€โ”€ service/
โ”‚   โ”‚   โ””โ”€โ”€ dynamic_popup_service.dart
โ”‚   โ”œโ”€โ”€ ui/
โ”‚   โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dynamic_radio_button.dart
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dynamic_checkbox.dart
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dynamic_text_area.dart
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dynamic_text_field.dart
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dynamic_dropdown.dart
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ dynamic_component_factory.dart
โ”‚   โ”‚   โ””โ”€โ”€ dynamic_popup_widget.dart
โ”‚   โ””โ”€โ”€ test/
โ”‚       โ””โ”€โ”€ dynamic_popup_test_page.dart
โ””โ”€โ”€ dynamic_popup.dart

๐Ÿ”’ Security and Privacy #

  • All data is validated client-side
  • Responses are sent in secure JSON format
  • Local storage is encrypted for popup states
  • No sensitive data stored permanently

๐ŸŽจ Customization #

Themes and Styles #

The system uses the current app theme. To customize:

// In dynamic_popup_widget.dart, modify colors:
primaryColor: Theme.of(context).primaryColor,
errorColor: Colors.red.shade600,
backgroundColor: Colors.grey.shade50,

Custom Components #

Add new components by extending DynamicComponentFactory:

case DynamicComponentType.newType:
  return NewCustomWidget(/* ... */);

๐Ÿšจ Troubleshooting #

  • Verify service is initialized
  • Check API logs for errors
  • Verify target screen is correct

Parsing errors #

  • Check placeholder markdown syntax
  • Verify all components have unique IDs
  • Ensure options don't contain special characters

Validation issues #

  • Check that required fields have values
  • Verify data types are correct
  • Test with simple popups first

๐Ÿ“ Changelog #

v1.0.2 #

  • Removed http dependency from core library (moved to example project only)
  • Removed unused DefaultDynamicPopupRepository from core library
  • Added .pubignore file to prevent publishing unnecessary files
  • Updated documentation to clarify dependency requirements
  • Improved package structure for pub.dev publishing

v1.0.1 #

  • Simplified repository pattern by reducing required methods from 7 to 3
  • Removed complex optional methods (markPopupAsShown, markPopupAsDismissed) for easier implementation
  • Streamlined example code by removing redundant buttons and simplifying demonstrations
  • Improved documentation with clearer, more concise instructions
  • Added JSON logging in example apps for better debugging of popup responses
  • Enhanced snackbar colors in examples for better readability and user experience
  • Fixed undefined variable error in API integration example
  • Removed unnecessary http dependency from core library (now only in example)
  • Removed unused DefaultDynamicPopupRepository from core library
  • Maintained all core functionality while reducing complexity

v1.0.0 #

  • โœ… Base dynamic popup system
  • โœ… Markdown parser with placeholders
  • โœ… Interactive UI components
  • โœ… API repository and service
  • โœ… Controller integration
  • โœ… Testing system
  • โœ… Removed GetX dependency for better compatibility
  • โœ… Simplified API requirements (only 2 endpoints required)

๐Ÿ“ž Support #

For questions or issues with the dynamic popup system, please open an issue on GitHub.

0
likes
0
points
12
downloads

Publisher

unverified uploader

Weekly Downloads

A flexible and customizable dynamic popup system for Flutter with markdown support and interactive components.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_html, shared_preferences

More

Packages that depend on dynamic_popup