Form Phoenix 🔥
Advanced Form State Time-Travel & Secure Persistence for Flutter.
Form Phoenix is a powerful, dependency-light form state management engine that gives your Flutter forms "Superpowers". It tracks every change, allowing users to Undo, Redo, and Recover their form data seamlessly, even after a full app restart.
✨ Features
- 🔄 Undo / Redo / Replay: Standard time-travel mechanics for any form field.
- 🔒 Secure Persistence: Automatically save form drafts to
flutter_secure_storage. - 🛡️ AES Encryption: Encrypt sensitive form data before storing it on disk.
- 🔗 Auto-Binding: Bidirectional sync with
TextEditingController. - ⏱️ Debounced Updates: Intelligent snapshotting to prevent history bloating while typing.
- 🏢 Multi-Step Support: Perfect for complex wizards and multi-page onboarding flows.
- 🚀 Zero Global State: No Bloc, No Provider, No Redux required. Just a clean Controller.
📦 Installation
Add this to your pubspec.yaml:
dependencies:
form_phoenix: ^1.0.0
🚀 Quick Start
1. Initialize the Controller
Create and initialize the controller in your StatefulWidget.
late final FormPhoenixController formController;
@override
void initState() {
super.initState();
formController = FormPhoenixController(
persistKey: 'user_profile_form', // Required for persistence
syncOnRestart: true, // Auto-load drafts on restart
enableDataEncryption: true, // Encrypt stored data
);
// Initialize to load persisted data
formController.init();
}
2. Bind your Fields
For TextFields, use bindTextController to sync automatically.
final nameController = TextEditingController();
@override
void initState() {
// ...
formController.bindTextController(
field: 'full_name',
controller: nameController,
);
}
For other inputs (Selectors, Sliders, Checkboxes), use updateField:
Checkbox(
value: formController.getValue<bool>('agreed') ?? false,
onChanged: (val) => formController.updateFieldImmediate('agreed', val),
)
3. Implement Undo/Redo
Hook up your UI buttons to the controller's time-travel methods.
ListenableBuilder(
listenable: formController,
builder: (context, _) {
return Row(
children: [
IconButton(
icon: Icon(Icons.undo),
onPressed: formController.canUndo ? formController.undo : null,
),
IconButton(
icon: Icon(Icons.redo),
onPressed: formController.canRedo ? formController.redo : null,
),
],
);
},
)
🛠 Advanced Usage
Persistent Storage & Encryption
If syncOnRestart is enabled, Form Phoenix will save a snapshot of the currentData to Secure Storage on every change. If enableDataEncryption is true, the data is encrypted using AES-256 with a key derived from your persistKey.
Clearing State
To wipe all history and delete the saved draft from the device:
await formController.clearHistory();
Handling Files
You can store file paths in the controller just like strings. Form Phoenix will persist the path, and you can reload the file on restart:
void pickImage() async {
final image = await picker.pickImage(source: ImageSource.gallery);
if (image != null) {
formController.updateFieldImmediate('profile_image', image.path);
}
}
📄 License
MIT License - see LICENSE for details.
🙏 Support
If you like this package, ⭐ Star it on GitHub!
For issues or feature requests, open an issue on GitHub.