ai_ui_render 0.1.0 copy "ai_ui_render: ^0.1.0" to clipboard
ai_ui_render: ^0.1.0 copied to clipboard

AI-driven JSON to Flutter UI rendering framework. Safely generate Flutter UI from AI prompts with guardrailed component catalogs, streaming support, visibility conditions, and rich action handling.

ai_ui_render #

A Flutter framework for safely generating UI from AI prompts. Render Flutter widgets from JSON with guardrailed component catalogs, streaming support, and rich action handling.

pub package License: MIT

Features #

  • Guardrailed Components - AI can only use components you explicitly define in your catalog
  • JSON to Widget Rendering - Convert JSON tree structures into Flutter widgets
  • Streaming Support - Render UI progressively as AI generates it (JSONL format)
  • Visibility Conditions - Show/hide components based on data, auth state, or complex logic
  • Rich Actions - Handle user interactions with confirmation dialogs and callbacks
  • Data Binding - Dynamic values that resolve from your data model
  • Validation - Built-in validators for forms and custom validation support

Screenshots #

Components Gallery Data Binding Visibility Conditions Feedback Components

Installation #

Add to your pubspec.yaml:

dependencies:
  ai_ui_render: ^0.1.0

Then run:

flutter pub get

Quick Start #

1. Define a Component Catalog #

The catalog defines which components AI can generate - this is your safety guardrail:

import 'package:ai_ui_render/ai_ui_render.dart';
import 'package:flutter/material.dart';

final catalog = createCatalog('my-app')
  .component(
    'Text',
    builder: (props, children) => Text(
      props['text'] as String? ?? '',
      style: TextStyle(
        fontSize: (props['size'] as num?)?.toDouble() ?? 14,
        fontWeight: props['bold'] == true ? FontWeight.bold : FontWeight.normal,
      ),
    ),
    hasChildren: false,
    description: 'Display text content',
  )
  .component(
    'Button',
    builder: (props, children) => ElevatedButton(
      onPressed: () {
        // Handle action
      },
      child: Text(props['label'] as String? ?? 'Button'),
    ),
    hasChildren: false,
    description: 'Clickable button',
  )
  .component(
    'Card',
    builder: (props, children) => Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(children: children),
      ),
    ),
    description: 'Card container',
  )
  .build();

2. Create a Registry #

final registry = createRegistryFromCatalog(catalog);

3. Render a UI Tree #

// JSON structure (typically from AI)
final uiTree = UITree.fromJson({
  'root': 'main-card',
  'elements': {
    'main-card': {
      'key': 'main-card',
      'type': 'Card',
      'props': {},
      'children': ['greeting', 'action-btn'],
    },
    'greeting': {
      'key': 'greeting',
      'type': 'Text',
      'props': {'text': 'Hello, World!', 'size': 24, 'bold': true},
      'children': [],
    },
    'action-btn': {
      'key': 'action-btn',
      'type': 'Button',
      'props': {'label': 'Click Me'},
      'children': [],
    },
  },
});

// Render it
StandaloneJsonRenderer(
  tree: uiTree,
  registry: registry,
)

Streaming UI Generation #

For AI-powered streaming generation:

final streamController = UIStreamController(
  UIStreamOptions(
    api: 'https://your-api.com/generate',
    onComplete: (tree) => print('Generation complete!'),
    onError: (error) => print('Error: $error'),
  ),
);

// Send a prompt
await streamController.send('Create a dashboard with revenue metrics');

// Use in widget
ListenableBuilder(
  listenable: streamController,
  builder: (context, child) {
    return StandaloneJsonRenderer(
      tree: streamController.tree,
      registry: registry,
      loading: streamController.isStreaming,
    );
  },
)

Visibility Conditions #

Control component visibility based on data or auth state:

// In JSON
{
  'key': 'admin-panel',
  'type': 'Card',
  'props': {},
  'visible': {'auth': 'signedIn'},  // Only show when signed in
  'children': [],
}

// Complex conditions
{
  'visible': {
    'and': [
      {'auth': 'signedIn'},
      {'path': '/user/isAdmin'},
      {'gt': [{'path': '/user/level'}, 5]}
    ]
  }
}

Available conditions:

  • true / false - Always visible/hidden
  • {'path': '/data/path'} - Visible when path is truthy
  • {'auth': 'signedIn'} / {'auth': 'signedOut'} - Auth-based
  • {'and': [...]} - All conditions must be true
  • {'or': [...]} - Any condition must be true
  • {'not': {...}} - Negates a condition
  • {'eq': [a, b]}, {'neq': [a, b]} - Equality checks
  • {'gt': [a, b]}, {'gte': [a, b]}, {'lt': [a, b]}, {'lte': [a, b]} - Comparisons

Data Binding #

Use dynamic values that resolve from your data model:

// In JSON props
{
  'type': 'Text',
  'props': {
    'text': {'path': '/user/name'}  // Resolves from data model
  }
}

// Provide data when rendering
StandaloneJsonRenderer(
  tree: uiTree,
  registry: registry,
  dataModel: {
    'user': {'name': 'John Doe', 'level': 10},
  },
)

Actions #

Define and handle user actions:

final catalog = createCatalog('my-app')
  .action('deleteItem', description: 'Delete an item')
  .action('saveForm', description: 'Save form data')
  .build();

// In JSON
{
  'type': 'Button',
  'props': {
    'label': 'Delete',
    'action': {
      'name': 'deleteItem',
      'params': {'id': {'path': '/selectedItem/id'}},
      'confirm': {
        'title': 'Confirm Delete',
        'message': 'Are you sure you want to delete this item?',
        'variant': 'danger'
      }
    }
  }
}

Validation #

Built-in validators for form fields:

final validators = Validators.compose([
  Validators.required('Email is required'),
  Validators.email('Invalid email format'),
]);

final result = validators('[email protected]');
print(result.isValid); // true

Available validators:

  • required - Value must not be null or empty
  • email - Valid email format
  • minLength(n) / maxLength(n) - String length constraints
  • min(n) / max(n) - Numeric constraints
  • pattern(regex) - Regex pattern matching
  • url - Valid URL format

With Providers #

For full state management integration:

JsonUIProvider(
  registry: registry,
  initialData: {'user': {'name': 'John'}},
  authState: AuthState(isSignedIn: true),
  actionHandlers: {
    'deleteItem': (params) async {
      // Handle delete
    },
  },
  child: JsonRenderer(
    tree: uiTree,
    registry: registry,
  ),
)

JSON Tree Structure #

The UI tree uses a flat structure optimized for LLM generation:

{
  "root": "main-element-key",
  "elements": {
    "main-element-key": {
      "key": "main-element-key",
      "type": "ComponentType",
      "props": { "prop1": "value1" },
      "children": ["child-key-1", "child-key-2"],
      "visible": true
    },
    "child-key-1": {
      "key": "child-key-1",
      "type": "Text",
      "props": { "text": "Hello" },
      "children": []
    }
  }
}

Generate AI Prompts #

Generate a prompt describing your catalog for AI:

final prompt = generateCatalogPrompt(catalog);
// Use this prompt to instruct AI about available components

Example App #

The example directory contains a comprehensive demo application with 5 interactive pages:

Showcases all 25+ built-in components organized by category:

  • Layout: Card, Row, Column, Container, Center, Expanded, Wrap, Spacer, Divider
  • Text: Text, Heading, RichText
  • Buttons: Button, IconButton
  • Display: Icon, Badge, Avatar, Image, ProgressBar, Chip
  • Input: TextField, Checkbox, Switch
  • Feedback: Alert, Loading

2. Data Binding #

Demonstrates dynamic values that resolve from your data model with live updates.

3. Visibility Conditions #

Interactive demo of all visibility condition types with toggles to see real-time effects.

4. Actions #

Shows the action system with confirmation dialogs, parameters, and success/error handlers.

5. Streaming #

Simulates AI streaming UI generation with progressive rendering.

Running the Example #

cd example
flutter run

API Reference #

Core Classes #

Class Description
UITree Flat tree structure containing all UI elements
UIElement Single UI element with type, props, and children
AiUiCatalog Registry of allowed components (safety guardrail)
ComponentRegistry Maps component types to widget builders
DynamicValue<T> Value that can be literal or path reference
VisibilityCondition Condition for showing/hiding elements
Action User action with params, confirm, callbacks

Widgets #

Widget Description
JsonRenderer Main renderer with Provider integration
StandaloneJsonRenderer Standalone renderer without Provider
JsonUIProvider Combined provider for data, visibility, actions
UIStreamProvider Provider for streaming UI generation

Functions #

Function Description
createCatalog(name) Create a catalog builder
createRegistryFromCatalog(catalog) Create registry from catalog
generateCatalogPrompt(catalog) Generate AI prompt from catalog
evaluateVisibility(condition, ctx) Evaluate visibility condition
resolveAction(action, dataModel) Resolve dynamic values in action
validateForm(data, validations) Validate form data

Validators #

Validators.required([message])      // Not null or empty
Validators.email([message])         // Valid email format
Validators.minLength(n, [message])  // Min string length
Validators.maxLength(n, [message])  // Max string length
Validators.min(n, [message])        // Min numeric value
Validators.max(n, [message])        // Max numeric value
Validators.pattern(regex, [message]) // Regex pattern
Validators.url([message])           // Valid URL
Validators.compose([...])           // Combine validators

Architecture #

┌─────────────────────────────────────────────────────────┐
│                      Your App                           │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐  │
│  │   Catalog   │  │  Registry   │  │  Data Model     │  │
│  │ (Components)│  │ (Builders)  │  │  (State)        │  │
│  └──────┬──────┘  └──────┬──────┘  └────────┬────────┘  │
│         │                │                   │          │
│         ▼                ▼                   ▼          │
│  ┌─────────────────────────────────────────────────────┐│
│  │              JsonRenderer / StandaloneJsonRenderer  ││
│  │  ┌─────────────────────────────────────────────┐   ││
│  │  │              ElementBuilder                  │   ││
│  │  │  - Resolves dynamic values                   │   ││
│  │  │  - Evaluates visibility                      │   ││
│  │  │  - Builds widgets recursively                │   ││
│  │  └─────────────────────────────────────────────┘   ││
│  └─────────────────────────────────────────────────────┘│
│                          │                              │
│                          ▼                              │
│  ┌─────────────────────────────────────────────────────┐│
│  │                  Flutter Widgets                    ││
│  └─────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────┘

         ┌──────────────────────────────────┐
         │         AI / LLM                 │
         │  ┌────────────────────────────┐  │
         │  │  Catalog Prompt            │  │
         │  │  (Generated from catalog)  │  │
         │  └────────────────────────────┘  │
         │              │                   │
         │              ▼                   │
         │  ┌────────────────────────────┐  │
         │  │  JSON UI Tree              │  │
         │  │  (Streamed via JSONL)      │  │
         │  └────────────────────────────┘  │
         └──────────────────────────────────┘

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

MIT License - see LICENSE for details.

2
likes
140
points
48
downloads

Publisher

verified publisherhoneymeta.com

Weekly Downloads

AI-driven JSON to Flutter UI rendering framework. Safely generate Flutter UI from AI prompts with guardrailed component catalogs, streaming support, visibility conditions, and rich action handling.

Repository (GitHub)
View/report issues

Topics

#ai #json #ui #widget #llm

Documentation

API reference

License

MIT (license)

Dependencies

flutter, http, provider

More

Packages that depend on ai_ui_render