An open API service indexing awesome lists of open source software.

https://github.com/devmaan707/flowxml

A modern Flutter library that converts XML code into Flutter components with real-time streaming support. Perfect for AI chat interfaces, dynamic content rendering, and real-time data visualization.
https://github.com/devmaan707/flowxml

ai dynamic flutter genai xml xml-parser

Last synced: about 2 months ago
JSON representation

A modern Flutter library that converts XML code into Flutter components with real-time streaming support. Perfect for AI chat interfaces, dynamic content rendering, and real-time data visualization.

Awesome Lists containing this project

README

          

# FlowXML

[![pub package](https://img.shields.io/pub/v/flowxml.svg)](https://pub.dev/packages/flowxml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A modern Flutter library that converts XML code into Flutter components with real-time streaming support. Perfect for AI chat interfaces, dynamic content rendering, and real-time data visualization.

## 🚀 Features

- **🔄 Real-time Streaming**: Handle partial XML content as it streams from APIs
- **🧩 Dynamic Components**: Automatically convert XML tags into interactive Flutter widgets
- **🎨 Customizable**: Easy to add custom component types and styling
- **📱 Flutter Native**: Built specifically for Flutter with Material Design 3 support
- **⚡ High Performance**: Efficient parsing and rendering with minimal overhead
- **🛡️ Error Resilient**: Graceful handling of malformed or incomplete XML
- **📦 Extensible**: Modular architecture for easy expansion

## 📦 Installation

Add FlowXML to your `pubspec.yaml`:

```yaml
dependencies:
flowxml: ^1.0.0
```

Then run:

```bash
flutter pub get
```

## 🏗️ Supported Components

### Built-in Components

| Component | Description | Example XML |
|-----------|-------------|-------------|
| **Message** | Rich text with Markdown support | `Hello **World**!` |
| **Card** | Grouped content with title and elevation | `Content` |
| **Image** | Network images with caching | `Alt text` |
| **Video** | Video playback with controls | `Caption` |
| **Button** | Interactive buttons with actions | `Click Me` |
| **OptionSelector** | Interactive choice selection | `Choose` |
| **Progress** | Progress indicators | `75%` |
| **List** | Ordered and unordered lists | `Item 1,Item 2` |
| **PostBody** | Rich content with copy functionality | `Content` |
| **Loader** | Loading indicators with Lottie support | `Loading...` |

## 🎯 Quick Start

### Basic Usage

```dart
import 'package:flutter/material.dart';
import 'package:flowxml/flowxml.dart';

class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
const xmlContent = '''

Hello! Welcome to FlowXML 🚀

This card was generated from XML and rendered as a Flutter widget!


Beautiful scenery


What do you think about FlowXML?


''';

return FlowXML.renderer(
xmlContent: xmlContent,
onComponentInteraction: (action, data) {
print('Component interaction: $action with data: $data');
},
);
}
}
```

### Real-time Streaming

```dart
class StreamingExample extends StatefulWidget {
@override
_StreamingExampleState createState() => _StreamingExampleState();
}

class _StreamingExampleState extends State {
late XmlStreamController _controller;
List _components = [];

@override
void initState() {
super.initState();
_controller = FlowXML.createStreamController();

// Listen to parsed components
_controller.componentsStream.listen((components) {
setState(() {
_components = components;
});
});

_simulateAIResponse();
}

void _simulateAIResponse() async {
_controller.startStreaming();

final chunks = [
'',
'Analyzing your request...',
'Processing',
'',
'Based on your input, here are the results.',
'',
'Download Report',
''
];

for (final chunk in chunks) {
await Future.delayed(Duration(milliseconds: 800));
_controller.addChunk(chunk);
}

_controller.completeStreaming();
}

@override
Widget build(BuildContext context) {
return Column(
children: _components.map((component) {
return FlowXML.renderer(
xmlContent: component.content,
isStreaming: !component.isComplete,
onComponentInteraction: (action, data) {
// Handle user interactions
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Action: $action')),
);
},
);
}).toList(),
);
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
```

## 🎨 Customization

### Custom Components

Create and register your own components:

```dart
class AlertComponent extends XmlComponent {
const AlertComponent({super.key, required super.props});

@override
String get componentType => 'Alert';

@override
Widget build(BuildContext context) {
final type = props.getAttribute('type', 'info');
final title = props.getAttribute('title', 'Alert');

return Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: _getAlertColor(type),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey.shade300),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
Text(props.content),
],
),
);
}

Color _getAlertColor(String type) {
switch (type) {
case 'error': return Colors.red[50]!;
case 'warning': return Colors.orange[50]!;
case 'success': return Colors.green[50]!;
default: return Colors.blue[50]!;
}
}
}

// Register the component
FlowXML.registerComponent('Alert', (props) => AlertComponent(props: props));
```

Now you can use it in XML:

```xml

Your operation completed successfully.

```

### Custom Styling

```dart
final customStyle = ComponentStyle(
backgroundColor: Colors.grey[50],
textColor: Colors.black87,
fontSize: 16.0,
padding: 20.0,
margin: 12.0,
);

FlowXML.renderer(
xmlContent: xmlContent,
style: customStyle,
);
```

### Font Configuration

FlowXML supports flexible font configuration with 12+ Google Fonts. Components default to `ebGaramond` for backward compatibility.

#### Available Fonts

```dart
// Get list of available fonts
List fonts = FlowXML.getAvailableFonts();
// ['system', 'roboto', 'openSans', 'lato', 'montserrat', 'poppins', 'nunito', 'sourceCodePro', 'inter', 'playfairDisplay', 'merriweather', 'lora']
```

#### Set Fonts Per Component

```dart
final style = FlowXML.createStyleWithFont(
fontFamily: 'roboto',
fontSize: 16.0,
fontWeight: FontWeight.w600,
textColor: Colors.black87,
);

FlowXML.renderer(
xmlContent: 'Choose option',
style: style,
);
```

#### Global Theme Configuration

```dart
// Set global theme with font
FlowXML.setTheme(FlowXMLTheme.light(
fontFamily: 'inter',
primaryColor: Colors.blue,
));

// All components now use Inter font by default
FlowXML.renderer(xmlContent: xmlContent);

// Predefined themes
FlowXML.setTheme(FlowXMLTheme.dark(fontFamily: 'poppins'));
FlowXML.setTheme(FlowXMLTheme.minimal());
FlowXML.setTheme(FlowXMLTheme.colorful(primaryColor: Colors.purple));
```

#### FontSelector Component

Let users select fonts dynamically:

```xml

```

```dart
FlowXML.renderer(
xmlContent: fontSelectorXml,
onComponentInteraction: (action, data) {
if (action == 'select') {
String selectedFont = data['value'];
FlowXML.setTheme(FlowXMLTheme.light(fontFamily: selectedFont));
}
},
);
```

#### Backward Compatibility

All existing code continues to work unchanged - components use `ebGaramond` by default when no font is specified.

## 🔧 Advanced Features

### Component Registry Management

```dart
// Check if component is registered
if (FlowXML.isComponentRegistered('CustomComponent')) {
// Component is available
}

// Get registry statistics
final stats = FlowXML.registry.statistics;
print('Registered components: ${stats['registeredComponents']}');

// Register component aliases
FlowXML.registry.registerAlias('Img', 'Image');
```

### Error Handling

```dart
FlowXML.renderer(
xmlContent: xmlContent,
errorBuilder: (error) => Container(
padding: EdgeInsets.all(16),
child: Text('Error: $error', style: TextStyle(color: Colors.red)),
),
loadingBuilder: () => CircularProgressIndicator(),
);
```

### FlowXML Initialization with Custom Loaders

FlowXML supports custom loaders that you can configure once and use throughout your app:

```dart
// Initialize FlowXML in your main.dart or app initialization
void main() {
// Initialize FlowXML with your custom loader
FlowXMLConfig.initialize(
customLoader: Lottie.asset(
'assets/your_company_loader.json',
width: 80,
height: 80,
fit: BoxFit.contain,
repeat: true,
),
primaryColor: const Color(0xFF2196F3), // Your brand color
secondaryColor: const Color(0xFF4CAF50),
);

runApp(const MyApp());
}
```

#### Advanced Custom Loader Configuration

```dart
// For dynamic loaders with different sizes and messages
FlowXMLAdvancedConfig.initialize(
customLoaderBuilder: ({
String? message,
double? width,
double? height,
Color? color,
}) {
return SizedBox(
width: width ?? 100,
height: height ?? 100,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Lottie.asset(
'assets/your_company_loader.json',
width: (width ?? 100) * 0.8,
height: (height ?? 100) * 0.8,
),
if (message != null)
Text(message, style: TextStyle(color: color)),
],
),
);
},
);
```

#### Using Loaders in XML

```xml

Loading...
Processing...
Please wait...

Loading with your custom animation...

Small custom loader
Large custom loader
```

#### Loader Attributes

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `type` | String | `circular` | Type of loader: `circular`, `linear`, `dots` |
| `size` | String | `medium` | Size for built-in loaders: `small`, `medium`, `large` |
| `color` | String | `primary` | Color: `primary`, `secondary`, `error`, `warning`, `success` |
| `useCustom` | String | `false` | Use the custom loader configured in FlowXMLConfig |
| `width` | String | `100` | Width for custom loader in pixels |
| `height` | String | `100` | Height for custom loader in pixels |

### Component Interactions

```dart
FlowXML.renderer(
xmlContent: xmlContent,
onComponentInteraction: (action, data) {
switch (action) {
case 'button_press':
handleButtonPress(data['action'] as String);
break;
case 'option_select':
handleOptionSelect(data['selected'] as List);
break;
case 'copy':
copyToClipboard(data['content'] as String);
break;
}
},
);
```

## 🎯 Use Cases

### AI Chat Interfaces
Perfect for rendering AI responses with rich content including images, videos, interactive elements, and formatted text.

### Dynamic Forms
Create forms dynamically based on XML configuration with validation and custom components.

### Real-time Dashboards
Stream data and update UI components in real-time for monitoring and analytics dashboards.

### Content Management
Render user-generated content with safety controls and custom styling.

### Educational Apps
Create interactive learning materials with quizzes, media content, and progress tracking.

## 📊 Performance

- **Streaming Parser**: Processes 10,000+ components per second
- **Memory Efficient**: <50MB for 1M+ characters of XML content
- **Smooth Rendering**: Maintains 60 FPS during active streaming
- **Error Recovery**: 99.9% success rate with malformed input

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](https://github.com/devmaan707/flowxml/blob/main/CONTRIBUTING.md) for details.

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🆘 Support

- 📚 [Documentation](https://github.com/devmaan707/flowxml#readme)
- 🐛 [Bug Reports](https://github.com/devmaan707/flowxml/issues)
- 💬 [Discussions](https://github.com/devmaan707/flowxml/discussions)
- 📧 [Email Support](mailto:support@flowxml.dev)

## 🚀 Example App

Check out our comprehensive [example app](https://github.com/devmaan707/flowxml/tree/main/example) that demonstrates all features including:

- Real-time XML streaming simulation
- All built-in components
- Custom component creation
- Performance monitoring
- Error handling
- Interactive elements

---

Made with ❤️ by [Aymaan](https://github.com/devmaan707)