pilot_ui 0.0.4
pilot_ui: ^0.0.4 copied to clipboard
A dynamic, theme-aware JSON UI rendering engine for Flutter with extensible parsers, action handlers, and ready-to-use smart dispatch & RTS action components.
Pilot UI 🚀 #
A powerful, dynamic, theme-aware JSON UI compilation and rendering engine for Flutter. Build interactive, responsive widget trees directly from JSON schemas or server-driven definitions, complete with state management, expression evaluation, extensible registries, and specialized UI components.
✨ Features #
- 🧱 Server-Driven UI (SDUI): Render complete Flutter widget trees directly from JSON payloads.
- ⚡ Extensible Registry: Register your own custom widget parsers and action handlers seamlessly via
PilotRegistry. - 🔄 Reactive State Management: Built-in state context (
PilotStateContext) and expression evaluator (${state.myValue}) for interactive UI flows. - 🎨 Theme-Aware & Responsive: Dynamic theme resolution (colors, typography, elevation) and responsive props adapting to device screen sizes and breakpoints.
- 📦 Rich Widget Parser Suite:
- Layout:
Container,Column,Row,Flex,Stack,ListView,Expanded,Wrap,SafeArea - Display:
Text,Icon,CachedImage,Card,Avatar,Badge,ProgressIndicator,GlassContainer - Inputs & Buttons:
TextField,Checkbox,ElevatedButton,TextButton - Structure & Nav:
AppBar,BottomNavigationBar,FloatingActionButton,PageView,TabView
- Layout:
- 🎯 Action Routing: Declarative action handling for
showDialog,showBottomSheet,setState, and custom event emission (emitEvent). - 🚚 Specialized Dispatch Components:
RtsActionCard: Ready-to-use, interactive Return-to-Station request cards featuring expandable/collapsible animation, severity badges, AI diagnosis/reasons, dialogs, and dynamic action buttons.DynamicActionButtons: Configurable action trigger buttons with icon matching and customizable color palettes.
📦 Installation #
Add pilot_ui to your pubspec.yaml dependencies:
dependencies:
flutter:
sdk: flutter
pilot_ui: ^0.0.4
Or run:
flutter pub add pilot_ui
🚀 Quick Start #
1. Basic JSON Widget Rendering #
Use PilotBuilder to compile a JSON UI specification into live Flutter widgets:
import 'package:flutter/material.dart';
import 'package:pilot_ui/pilot_ui.dart';
class DynamicScreen extends StatelessWidget {
const DynamicScreen({super.key});
final Map<String, dynamic> jsonUi = const {
"type": "container",
"children": [
{
"type": "column",
"children": [
{
"type": "text",
"properties": {
"text": "Hello, Pilot UI!",
"style": {
"fontSize": 22.0,
"fontWeight": "bold",
"color": "#7C4DFF"
}
}
},
{
"type": "elevated_button",
"properties": {
"label": "Click Me"
},
"actions": {
"onTap": {
"action": "showDialog",
"params": {
"title": "Welcome",
"message": "Rendered dynamically from JSON!"
}
}
}
}
]
}
]
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Dynamic UI')),
body: PilotBuilder(
json: jsonUi,
initialState: const {
'user': 'Driver #42',
},
onEvent: (eventName, payload) {
debugPrint('Event emitted: $eventName -> $payload');
},
),
);
}
}
🚚 Specialized Components: RtsActionCard #
pilot_ui includes high-fidelity operational components for logistics and dispatch feeds.
import 'package:flutter/material.dart';
import 'package:pilot_ui/pilot_ui.dart';
Widget buildEventCard(Map<String, dynamic> eventJson, BuildContext context) {
return RtsActionCard(
data: eventJson,
initiallyExpanded: false, // Collapsed by default; tap to expand
onButtonTap: (action) {
debugPrint('Triggered: ${action?.actionType} with payload: ${action?.actionPayload}');
},
);
}
You can also render RtsActionCard dynamically inside your JSON definitions:
// Register specialized components before building
PilotComponents.registerAll();
{
"type": "rts_action_card",
"title": "Driver RTS Request - 50 Undeliverables",
"severity": "warning",
"description": "Driver requested early return to station.",
"ai_diagnosis": "High volume of remaining packages. Recommend review.",
"actions": [
{
"action_type": "APPROVE_RTS",
"action_label": "⚡ Approve Return to Station",
"action_payload": {"status": "approved"}
},
{
"action_type": "REJECT_RTS",
"action_label": "❌ Reject Return",
"action_payload": {"status": "rejected"}
}
]
}
🛠️ Extending Pilot UI #
Registering Custom Widget Parsers #
Implement BaseWidgetParser and register it with PilotRegistry:
import 'package:flutter/material.dart';
import 'package:pilot_ui/pilot_ui.dart';
class CustomHeaderParser extends BaseWidgetParser {
@override
Widget parse(JsonWidgetData data, BuildContext context) {
final title = data.props['title'] ?? '';
return Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.deepPurple.shade50,
borderRadius: BorderRadius.circular(8),
),
child: Text(
title,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
);
}
}
// In your app initialization:
PilotRegistry.registerWidget('custom_header', CustomHeaderParser());
Registering Custom Action Handlers #
Implement BaseActionHandler and register it with PilotRegistry:
import 'package:flutter/material.dart';
import 'package:pilot_ui/pilot_ui.dart';
class AnalyticsActionHandler extends BaseActionHandler {
@override
void handle(ActionModel action, BuildContext context) {
final eventName = action.params['event_name'];
debugPrint('Analytics tracked: $eventName');
}
}
// In your app initialization:
PilotRegistry.registerAction('trackAnalytics', AnalyticsActionHandler());
📂 Example App #
An interactive dashboard example is available in the example/ directory.
To run the example:
cd example
flutter run
📄 License #
This project is licensed under the MIT License.