dynamic_ui_renderer 0.2.1 copy "dynamic_ui_renderer: ^0.2.1" to clipboard
dynamic_ui_renderer: ^0.2.1 copied to clipboard

A Flutter package for rendering UI from JSON responses. Build dynamic forms, screens, and components from server-driven JSON.

example/lib/main.dart

import 'package:example_dynamic_ui_renderer_app/details_screen.dart';
import 'package:example_dynamic_ui_renderer_app/second_screen.dart';
import 'package:flutter/material.dart';

import 'package:dynamic_ui_renderer/dynamic_ui_renderer.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dynamic UI Renderer - Complete Demo',
      theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
      home: const HomePage(),
      routes: {
        '/second': (context) => const SecondScreen(),
        '/details': (context) => const DetailsScreen(),
      },
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0;

  // State for multi-form section
  Map<String, dynamic>? _registrationFormData;
  Map<String, dynamic>? _contactFormData;
  Map<String, dynamic>? _layoutFormData;
  bool _useAlternateOrder = false;

  final List<DemoSection> _sections = [
    DemoSection(
      title: '🎯 Button Actions',
      description: 'Test all button action types',
      json: _buildButtonActionsJson(),
    ),
    DemoSection(
      title: '📱 Core Widgets',
      description: 'Basic widgets: Text, Container, Button, Column, Row',
      json: _buildCoreWidgetsJson(),
    ),
    DemoSection(
      title: '🎨 Styling Properties',
      description: 'Colors, padding, margins, font styles',
      json: _buildStylingJson(),
    ),
    DemoSection(
      title: '📐 Layout Examples',
      description: 'Different alignments and arrangements',
      json: _buildLayoutJson(),
    ),
    DemoSection(
      title: '📝 Multi-Form Demo',
      description: 'Multiple forms with real-time data display',
      isMultiForm: true,
    ),
    DemoSection(
      title: '⚠️ Error Handling',
      description: 'Unsupported widget types',
      json: _buildErrorHandlingJson(),
    ),
  ];

  @override
  void initState() {
    super.initState();

    // Register form callbacks
    DynamicUIRenderer.registerFormCallback('registration_form', (
      formId,
      formData,
    ) {
      debugPrint('📝 Registration Form Submitted: $formData');
      setState(() {
        _registrationFormData = formData;
      });
    });

    DynamicUIRenderer.registerFormCallback('contact_form', (formId, formData) {
      debugPrint('📧 Contact Form Submitted: $formData');
      setState(() {
        _contactFormData = formData;
      });
    });

    DynamicUIRenderer.registerFormCallback('dynamic_layout_form', (
      formId,
      formData,
    ) {
      debugPrint('🎨 Dynamic Layout Form Submitted: $formData');
      setState(() {
        _layoutFormData = formData;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Dynamic UI Renderer v0.2.0'),
        backgroundColor: Colors.blue,
        foregroundColor: Colors.white,
        elevation: 2,
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: () {
              setState(() {}); // Refresh to rebuild UI
            },
            tooltip: 'Refresh',
          ),
          if (_sections[_selectedIndex].json != null)
            IconButton(
              icon: const Icon(Icons.code),
              onPressed: () {
                _showJsonDialog(context, _sections[_selectedIndex].json!);
              },
              tooltip: 'View JSON',
            ),
        ],
      ),
      body: Row(
        children: [
          // Left Sidebar - Navigation
          _buildSidebar(),
          // Right Side - Content
          Expanded(
            child: Container(
              color: Colors.white,
              child: SingleChildScrollView(
                padding: const EdgeInsets.all(24),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    _buildSectionHeader(),
                    _buildSectionContent(context),
                    const SizedBox(height: 24),
                    _buildFeatureStatus(),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSidebar() {
    return Container(
      width: 280,
      color: Colors.grey.shade50,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            padding: const EdgeInsets.all(16),
            color: Colors.blue,
            child: const Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '📦 dynamic_ui_renderer',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(height: 4),
                Text(
                  'Complete Feature Demo',
                  style: TextStyle(color: Colors.white70, fontSize: 14),
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              padding: const EdgeInsets.symmetric(vertical: 8),
              itemCount: _sections.length,
              itemBuilder: (context, index) {
                final isSelected = _selectedIndex == index;
                return Container(
                  margin: const EdgeInsets.symmetric(
                    horizontal: 8,
                    vertical: 2,
                  ),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(8),
                    color: isSelected ? Colors.blue.shade50 : null,
                  ),
                  child: ListTile(
                    leading: Text(
                      _sections[index].title.split(' ')[0],
                      style: TextStyle(
                        fontSize: 20,
                        color: isSelected ? Colors.blue : Colors.grey,
                      ),
                    ),
                    title: Text(
                      _sections[index].title,
                      style: TextStyle(
                        fontWeight: isSelected
                            ? FontWeight.bold
                            : FontWeight.normal,
                        color: isSelected ? Colors.blue : Colors.black87,
                      ),
                    ),
                    subtitle: Text(
                      _sections[index].description,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: TextStyle(
                        fontSize: 12,
                        color: isSelected
                            ? Colors.blue.shade300
                            : Colors.grey.shade600,
                      ),
                    ),
                    selected: isSelected,
                    onTap: () {
                      setState(() {
                        _selectedIndex = index;
                      });
                    },
                  ),
                );
              },
            ),
          ),
          _buildFooter(),
        ],
      ),
    );
  }

  Widget _buildFooter() {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        border: Border(top: BorderSide(color: Colors.grey.shade300)),
      ),
      child: Row(
        children: [
          Container(
            padding: const EdgeInsets.all(8),
            decoration: const BoxDecoration(
              color: Colors.green,
              shape: BoxShape.circle,
            ),
            child: const Text(
              '✓',
              style: TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
          const SizedBox(width: 12),
          const Expanded(
            child: Text(
              'All features working in v0.2.0',
              style: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSectionHeader() {
    return Container(
      margin: const EdgeInsets.only(bottom: 24),
      child: Row(
        children: [
          Container(
            padding: const EdgeInsets.all(12),
            decoration: BoxDecoration(
              color: Colors.blue.shade50,
              borderRadius: BorderRadius.circular(12),
            ),
            child: Text(
              _sections[_selectedIndex].title.split(' ')[0],
              style: const TextStyle(fontSize: 24),
            ),
          ),
          const SizedBox(width: 16),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  _sections[_selectedIndex].title,
                  style: const TextStyle(
                    fontSize: 24,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                const SizedBox(height: 4),
                Text(
                  _sections[_selectedIndex].description,
                  style: TextStyle(fontSize: 14, color: Colors.grey.shade600),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSectionContent(BuildContext context) {
    if (_sections[_selectedIndex].isMultiForm) {
      return _buildMultiFormContent(context);
    } else {
      return Container(
        width: double.infinity,
        padding: const EdgeInsets.all(24),
        decoration: BoxDecoration(
          color: Colors.grey.shade50,
          borderRadius: BorderRadius.circular(16),
          border: Border.all(color: Colors.grey.shade300),
        ),
        child: DynamicUIRenderer.fromJsonString(
          _sections[_selectedIndex].json!,
          context,
        ),
      );
    }
  }

  Widget _buildFeatureStatus() {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.blue.shade50,
        borderRadius: BorderRadius.circular(12),
      ),
      child: Row(
        children: [
          const Icon(Icons.info, color: Colors.blue),
          const SizedBox(width: 12),
          Expanded(
            child: Text(
              'This section demonstrates ${_sections[_selectedIndex].description.toLowerCase()}. '
              'All widgets are rendered dynamically from JSON.',
              style: TextStyle(color: Colors.blue.shade900),
            ),
          ),
        ],
      ),
    );
  }

  // ============= MULTI-FORM SECTION =============
  Widget _buildMultiFormContent(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Toggle Order Button for Dynamic Layout
        Container(
          margin: const EdgeInsets.only(bottom: 16),
          child: Row(
            children: [
              Expanded(
                child: ElevatedButton.icon(
                  onPressed: () {
                    setState(() {
                      _useAlternateOrder = !_useAlternateOrder;
                    });
                  },
                  icon: Icon(
                    _useAlternateOrder ? Icons.swap_vert : Icons.swap_horiz,
                  ),
                  label: Text(
                    _useAlternateOrder
                        ? 'Switch to Default Order'
                        : 'Switch to Alternate Order',
                  ),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.purple,
                    foregroundColor: Colors.white,
                    padding: const EdgeInsets.symmetric(vertical: 12),
                  ),
                ),
              ),
            ],
          ),
        ),

        // Registration Form
        _buildFormCard(
          title: 'Form 1: User Registration',
          icon: Icons.app_registration,
          color: Colors.green,
          formJson: _buildRegistrationFormJson(),
          formId: 'registration_form',
          formData: _registrationFormData,
          context: context,
        ),

        // Contact Form
        _buildFormCard(
          title: 'Form 2: Contact Us',
          icon: Icons.contact_mail,
          color: Colors.blue,
          formJson: _buildContactFormJson(),
          formId: 'contact_form',
          formData: _contactFormData,
          context: context,
        ),

        // Dynamic Layout Form
        _buildFormCard(
          title: 'Form 3: Dynamic Layout',
          subtitle: _useAlternateOrder ? 'Alternate Order' : 'Default Order',
          icon: Icons.swap_vert,
          color: Colors.purple,
          formJson: _buildDynamicLayoutFormJson(),
          formId: 'dynamic_layout_form',
          formData: _layoutFormData,
          context: context,
        ),
      ],
    );
  }

  Widget _buildFormCard({
    required String title,
    String? subtitle,
    required IconData icon,
    required MaterialColor color,
    required String formJson,
    required String formId,
    required Map<String, dynamic>? formData,
    required BuildContext context,
  }) {
    return Container(
      margin: const EdgeInsets.only(bottom: 32),
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        color: Colors.grey.shade50,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: Colors.grey.shade300),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Container(
                padding: const EdgeInsets.all(8),
                decoration: BoxDecoration(
                  color: color.shade100,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Icon(icon, color: color),
              ),
              const SizedBox(width: 12),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    title,
                    style: const TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  if (subtitle != null)
                    Text(
                      subtitle,
                      style: TextStyle(
                        fontSize: 12,
                        color: color.shade700,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                ],
              ),
            ],
          ),
          const SizedBox(height: 16),
          DynamicUIRenderer.fromJsonString(formJson, context, formId: formId),
          if (formData != null) ...[
            const SizedBox(height: 16),
            _buildDataDisplayCard('Submitted Data', formData, color),
          ],
        ],
      ),
    );
  }

  Widget _buildDataDisplayCard(
    String title,
    Map<String, dynamic> data,
    MaterialColor color,
  ) {
    return Container(
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: color.shade50,
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: color.shade200),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Icon(Icons.check_circle, color: color.shade700, size: 20),
              const SizedBox(width: 8),
              Text(
                title,
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  color: color.shade700,
                ),
              ),
            ],
          ),
          const SizedBox(height: 8),
          ...data.entries.map(
            (e) => Padding(
              padding: const EdgeInsets.symmetric(vertical: 2),
              child: Row(
                children: [
                  SizedBox(
                    width: 100,
                    child: Text(
                      '${e.key}:',
                      style: const TextStyle(fontWeight: FontWeight.w500),
                    ),
                  ),
                  Expanded(
                    child: Text(
                      e.value?.toString() ?? 'null',
                      style: TextStyle(color: Colors.grey.shade700),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  void _showJsonDialog(BuildContext context, String json) {
    showDialog(
      context: context,
      builder: (context) => Dialog(
        insetPadding: const EdgeInsets.all(24),
        child: Container(
          width: 600,
          padding: const EdgeInsets.all(16),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  const Icon(Icons.code, color: Colors.blue),
                  const SizedBox(width: 8),
                  const Text(
                    'JSON Source',
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  const Spacer(),
                  IconButton(
                    icon: const Icon(Icons.close),
                    onPressed: () => Navigator.pop(context),
                  ),
                ],
              ),
              const SizedBox(height: 16),
              Container(
                constraints: const BoxConstraints(maxHeight: 400),
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: Colors.grey.shade900,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: SingleChildScrollView(
                  child: SelectableText(
                    json,
                    style: const TextStyle(
                      fontFamily: 'monospace',
                      color: Colors.white,
                      fontSize: 12,
                    ),
                  ),
                ),
              ),
              const SizedBox(height: 16),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  TextButton(
                    onPressed: () => Navigator.pop(context),
                    child: const Text('Close'),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

  //   // ============= FORM JSON BUILDERS =============
  //   String _buildRegistrationFormJson() {
  //     return '''
  // {
  //   "type": "form",
  //   "properties": {
  //     "title": "Create Account",
  //     "titleFontSize": 16,
  //     "titleColor": "#4CAF50",
  //     "backgroundColor": "#FFFFFF",
  //     "padding": 16,
  //     "borderRadius": 8,
  //     "elevation": 2,
  //     "submitText": "Register",
  //     "submitButtonColor": "#4CAF50",
  //     "submitButtonTextColor": "#FFFFFF",
  //     "submitButtonRadius": 8,
  //     "submitButtonHeight": 44,
  //     "showValidationMessage": true
  //   },
  //   "fields": [
  //     {
  //       "name": "username",
  //       "type": "text",
  //       "label": "Username",
  //       "hint": "Choose a username",
  //       "required": true,
  //       "order": 1,
  //       "validations": [
  //         {
  //           "type": "minLength",
  //           "value": 3,
  //           "message": "Username must be at least 3 characters"
  //         }
  //       ]
  //     },
  //     {
  //       "name": "email",
  //       "type": "email",
  //       "label": "Email",
  //       "hint": "Enter your email",
  //       "required": true,
  //       "order": 2,
  //       "validations": [
  //         {
  //           "type": "email",
  //           "message": "Enter a valid email"
  //         }
  //       ]
  //     },
  //     {
  //       "name": "password",
  //       "type": "password",
  //       "label": "Password",
  //       "hint": "Create a password",
  //       "required": true,
  //       "order": 3,
  //       "validations": [
  //         {
  //           "type": "minLength",
  //           "value": 6,
  //           "message": "Password must be at least 6 characters"
  //         }
  //       ]
  //     },
  //     {
  //       "name": "newsletter",
  //       "type": "checkbox",
  //       "label": "Subscribe to newsletter",
  //       "order": 4
  //     }
  //   ],
  //   "actions": {
  //     "onSubmit": {
  //       "type": "print",
  //       "parameters": {
  //         "message": "Registration submitted"
  //       }
  //     }
  //   }
  // }
  // ''';
  //   }

  // ============= NEW: Forms JSON Builder =============
  static String _buildRegistrationFormJson() {
    return '''
{
  "type": "column",
  "properties": {
    "crossAxisAlignment": "stretch"
  },
  "children": [
    {
      "type": "text",
      "properties": {
        "text": "📝 Dynamic Forms Demo",
        "fontSize": 20,
        "fontWeight": "bold",
        "color": "#1976D2"
      }
    },
    {
      "type": "text",
      "properties": {
        "text": "Complete form with validation and all field types",
        "fontSize": 14,
        "color": "#757575",
        "margin": [0, 8, 0, 16]
      }
    },
    {
      "type": "form",
      "properties": {
       "formId": "registration_form",
        "title": "📝 User Registration",
        "titleFontSize": 18,
        "titleColor": "#1976D2",
        "backgroundColor": "#FFFFFF",
        "padding": 20,
        "borderRadius": 12,
        "elevation": 4,
        "submitText": "Create Account",
        "submitButtonColor": "#4CAF50",
        "submitButtonTextColor": "#FFFFFF",
        "submitButtonRadius": 8,
        "submitButtonHeight": 48,
        "showValidationMessage": true,
        "validationMessage": "Please fix the errors and try again"
      },
      "fields": [
        {
          "name": "fullName",
          "type": "text",
          "label": "Full Name",
          "hint": "Enter your full name",
          "placeholder": "John Doe",
          "required": true,
          "requiredMessage": "Name is required",
          "order": 1,
          "validations": [
            {
              "type": "minLength",
              "value": 3,
              "message": "Name must be at least 3 characters"
            },
            {
              "type": "maxLength",
              "value": 50,
              "message": "Name cannot exceed 50 characters"
            }
          ],
          "uiProperties": {
            "borderRadius": 8,
            "filled": true,
            "fillColor": "#F5F5F5",
            "fontSize": 16,
            "prefixIcon": "person"
          }
        },
        {
          "name": "email",
          "type": "email",
          "label": "Email Address",
          "hint": "Enter your email",
          "placeholder": "john@example.com",
          "required": true,
          "requiredMessage": "Email is required",
          "order": 2,
          "validations": [
            {
              "type": "email",
              "message": "Please enter a valid email address"
            }
          ],
          "uiProperties": {
            "borderRadius": 8,
            "filled": true,
            "fillColor": "#F5F5F5",
            "prefixIcon": "email"
          }
        },
        {
          "name": "password",
          "type": "password",
          "label": "Password",
          "hint": "Create a strong password",
          "required": true,
          "requiredMessage": "Password is required",
          "order": 3,
          "validations": [
            {
              "type": "minLength",
              "value": 8,
              "message": "Password must be at least 8 characters"
            },
            {
              "type": "pattern",
              "pattern": "^[A-Za-z0-9.@!-]{8,}",
              "message": "Password must be at least 8 characters and can include letters, numbers, and special characters (. @ ! -)"
            }
          ],
          "uiProperties": {
            "borderRadius": 8,
            "filled": true,
            "fillColor": "#F5F5F5",
            "prefixIcon": "lock"
          }
        },
        {
          "name": "confirmPassword",
          "type": "password",
          "label": "Confirm Password",
          "hint": "Re-enter your password",
          "required": true,
          "requiredMessage": "Please confirm your password",
          "order": 4,
          "validations": [
            {
              "type": "match",
              "value": "password",
              "message": "Passwords do not match"
            }
          ],
          "uiProperties": {
            "borderRadius": 8,
            "filled": true,
            "fillColor": "#F5F5F5",
            "prefixIcon": "lock"
          }
        },
        {
          "name": "phone",
          "type": "phone",
          "label": "Phone Number",
          "hint": "Enter your phone number",
          "placeholder": "+1 234 567 8900",

          "order": 5,
          "validations": [
            {
              "type": "phone",
              "message": "Please enter a valid phone number"
            }
          ],
          "uiProperties": {
            "borderRadius": 8,
            "filled": true,
            "fillColor": "#F5F5F5",
            "prefixIcon": "phone"
          }
        },
        {
          "name": "age",
          "type": "number",
          "label": "Age",
          "hint": "Enter your age",
          "required": false,
          "order": 6,
          "validations": [
            {
              "type": "minValue",
              "value": 18,
              "message": "You must be at least 18 years old"
            },
            {
              "type": "maxValue",
              "value": 120,
              "message": "Please enter a valid age"
            }
          ],
          "uiProperties": {
            "borderRadius": 8,
            "filled": true,
            "fillColor": "#F5F5F5"
          }
        },
        {
          "name": "country",
          "type": "dropdown",
          "label": "Country",
          "hint": "Select your country",
          "required": true,
          "requiredMessage": "Please select a country",
          "order": 7,
          "options": [
            {
              "label": "United States",
              "value": "us",
              "icon": {"name": "home"}
            },
            {
              "label": "United Kingdom",
              "value": "uk",
              "icon": {"name": "home"}
            },
            {
              "label": "Canada",
              "value": "ca",
              "icon": {"name": "home"}
            },
            {
              "label": "Australia",
              "value": "au",
              "icon": {"name": "home"}
            },
            {
              "label": "India",
              "value": "in",
              "icon": {"name": "home"}
            }
          ],
          "uiProperties": {
            "borderRadius": 8,
            "filled": true,
            "fillColor": "#F5F5F5"
          }
        },
        {
          "name": "birthDate",
          "type": "date",
          "label": "Birth Date",
          "hint": "Select your birth date",
          "required": false,
          "order": 8,
          "uiProperties": {
            "borderRadius": 8,
            "filled": true,
            "fillColor": "#F5F5F5",
            "format": "dd/MM/yyyy",
            "iconColor": "#1976D2"
          }
        },
        {
          "name": "termsAccepted",
          "type": "checkbox",
          "label": "I accept the Terms and Conditions*",
          "required": true,
          "requiredMessage": "You must accept the terms to continue",
          "order": 9,
          "uiProperties": {
            "activeColor": "#4CAF50",
            "checkColor": "#FFFFFF"
          }
        }
      ],
      "actions": {
        "onSubmit": {
          "type": "showDialog",
          "parameters": {
            "title": "Registration Successful! 🎉",
            "message": "Your account has been created successfully.\\n\\nCheck the console for form data.",
            "buttonText": "OK"
          }
        }
      }
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 24, 0, 0],
        "color": "#E3F2FD",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "📋 Form Features Demonstrated:",
                "fontWeight": "bold",
                "color": "#1565C0"
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Text field with min/max length validation",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Email field with email format validation",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Password with pattern validation (letter + number)",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Password match validation",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Phone number validation",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Number field with min/max value validation",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Dropdown with options",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Date picker with custom format",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Checkbox with required validation",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Real-time validation",
                "color": "#1565C0",
                "fontSize": 13
              }
            },
            {
              "type": "text",
              "properties": {
                "text": "• Error messages below fields",
                "color": "#1565C0",
                "fontSize": 13
              }
            }
          ]
        }
      ]
    }
  ]
}
''';
  }

  String _buildContactFormJson() {
    return '''
{
  "type": "form",
  "properties": {
    "title": "Get in Touch",
    "titleFontSize": 16,
    "titleColor": "#2196F3",
    "backgroundColor": "#FFFFFF",
    "padding": 16,
    "borderRadius": 8,
    "elevation": 2,
    "submitText": "Send Message",
    "submitButtonColor": "#2196F3",
    "submitButtonTextColor": "#FFFFFF",
    "submitButtonRadius": 8,
    "submitButtonHeight": 44,
    "showValidationMessage": true
  },
  "fields": [
    {
      "name": "name",
      "type": "text",
      "label": "Your Name",
      "hint": "Enter your full name",
      "required": true,
      "order": 1,
      "uiProperties": {
        "prefixIcon": "person"
      }
    },
    {
      "name": "email",
      "type": "email",
      "label": "Email",
      "hint": "Enter your email",
      "required": true,
      "order": 2,
      "uiProperties": {
        "prefixIcon": "email"
      }
    },
    {
      "name": "subject",
      "type": "dropdown",
      "label": "Subject",
      "required": true,
      "order": 3,
      "options": [
        {"label": "General Inquiry", "value": "general"},
        {"label": "Technical Support", "value": "support"},
        {"label": "Feedback", "value": "feedback"},
        {"label": "Business", "value": "business"}
      ]
    },
    {
      "name": "message",
      "type": "textarea",
      "label": "Message",
      "hint": "Type your message here",
      "required": true,
      "order": 4,
      "uiProperties": {
        "minLines": 3,
        "maxLines": 5
      }
    },
    {
      "name": "priority",
      "type": "radio",
      "label": "Priority",
      "order": 5,
      "options": [
        {"label": "Low", "value": "low"},
        {"label": "Medium", "value": "medium"},
        {"label": "High", "value": "high"}
      ]
    }
  ],
  "actions": {
    "onSubmit": {
      "type": "print",
      "parameters": {
        "message": "Contact form submitted"
      }
    }
  }
}
''';
  }

  String _buildDynamicLayoutFormJson() {
    if (_useAlternateOrder) {
      return '''
{
  "type": "form",
  "properties": {
    "title": "Dynamic Layout (Alternate Order)",
    "titleFontSize": 16,
    "titleColor": "#9C27B0",
    "backgroundColor": "#FFFFFF",
    "padding": 16,
    "borderRadius": 8,
    "elevation": 2,
    "submitText": "Submit",
    "submitButtonColor": "#9C27B0",
    "submitButtonTextColor": "#FFFFFF",
    "submitButtonRadius": 8,
    "submitButtonHeight": 44,
    "showValidationMessage": true
  },
  "fields": [
    {
      "name": "feedback",
      "type": "textarea",
      "label": "Your Feedback",
      "hint": "Tell us what you think",
      "required": true,
      "order": 4,
      "uiProperties": {
        "minLines": 2,
        "maxLines": 4
      }
    },
    {
      "name": "country",
      "type": "dropdown",
      "label": "Country",
      "required": true,
      "order": 2,
      "options": [
        {"label": "USA", "value": "us"},
        {"label": "UK", "value": "uk"},
        {"label": "Canada", "value": "ca"},
        {"label": "Australia", "value": "au"}
      ]
    },
    {
      "name": "rating",
      "type": "dropdown",
      "label": "Rating",
      "required": true,
      "order": 3,
      "options": [
        {"label": "⭐⭐⭐⭐⭐ Excellent", "value": "5"},
        {"label": "⭐⭐⭐⭐ Very Good", "value": "4"},
        {"label": "⭐⭐⭐ Good", "value": "3"},
        {"label": "⭐⭐ Fair", "value": "2"},
        {"label": "⭐ Poor", "value": "1"}
      ]
    },
    {
      "name": "fullName",
      "type": "text",
      "label": "Full Name",
      "hint": "Enter your name",
      "required": true,
      "order": 1
    },
    {
      "name": "subscribe",
      "type": "checkbox",
      "label": "Subscribe to updates",
      "order": 5
    }
  ],
  "actions": {
    "onSubmit": {
      "type": "print",
      "parameters": {
        "message": "Dynamic layout form submitted"
      }
    }
  }
}
''';
    } else {
      return '''
{
  "type": "form",
  "properties": {
    "title": "Dynamic Layout (Default Order)",
    "titleFontSize": 16,
    "titleColor": "#9C27B0",
    "backgroundColor": "#FFFFFF",
    "padding": 16,
    "borderRadius": 8,
    "elevation": 2,
    "submitText": "Submit",
    "submitButtonColor": "#9C27B0",
    "submitButtonTextColor": "#FFFFFF",
    "submitButtonRadius": 8,
    "submitButtonHeight": 44,
    "showValidationMessage": true
  },
  "fields": [
    {
      "name": "fullName",
      "type": "text",
      "label": "Full Name",
      "hint": "Enter your name",
      "required": true,
      "order": 1
    },
    {
      "name": "country",
      "type": "dropdown",
      "label": "Country",
      "required": true,
      "order": 2,
      "options": [
        {"label": "USA", "value": "us"},
        {"label": "UK", "value": "uk"},
        {"label": "Canada", "value": "ca"},
        {"label": "Australia", "value": "au"}
      ]
    },
    {
      "name": "rating",
      "type": "dropdown",
      "label": "Rating",
      "required": true,
      "order": 3,
      "options": [
        {"label": "⭐⭐⭐⭐⭐ Excellent", "value": "5"},
        {"label": "⭐⭐⭐⭐ Very Good", "value": "4"},
        {"label": "⭐⭐⭐ Good", "value": "3"},
        {"label": "⭐⭐ Fair", "value": "2"},
        {"label": "⭐ Poor", "value": "1"}
      ]
    },
    {
      "name": "feedback",
      "type": "textarea",
      "label": "Your Feedback",
      "hint": "Tell us what you think",
      "required": true,
      "order": 4,
      "uiProperties": {
        "minLines": 2,
        "maxLines": 4
      }
    },
    {
      "name": "subscribe",
      "type": "checkbox",
      "label": "Subscribe to updates",
      "order": 5
    }
  ],
  "actions": {
    "onSubmit": {
      "type": "print",
      "parameters": {
        "message": "Dynamic layout form submitted"
      }
    }
  }
}
''';
    }
  }

  // ============= EXISTING JSON BUILDERS =============
  static String _buildButtonActionsJson() {
    return '''
{
  "type": "column",
  "properties": {
    "crossAxisAlignment": "stretch"
  },
  "children": [
    {
      "type": "text",
      "properties": {
        "text": "🎯 Button Actions",
        "fontSize": 20,
        "fontWeight": "bold",
        "color": "#1976D2"
      }
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 16, 0, 0],
        "color": "#FFFFFF",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Print Action",
                "fontSize": 16,
                "fontWeight": "bold"
              }
            },
            {
              "type": "button",
              "properties": {
                "text": "Print to Console",
                "backgroundColor": "#4CAF50",
                "foregroundColor": "#FFFFFF",
                "borderRadius": 8
              },
              "actions": {
                "type": "print",
                "parameters": {
                  "message": "Hello from dynamic button!",
                  "level": "info"
                }
              }
            }
          ]
        }
      ]
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 8, 0, 0],
        "color": "#FFFFFF",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Dialog Action",
                "fontSize": 16,
                "fontWeight": "bold"
              }
            },
            {
              "type": "button",
              "properties": {
                "text": "Show Dialog",
                "backgroundColor": "#FF9800",
                "foregroundColor": "#FFFFFF",
                "borderRadius": 8
              },
              "actions": {
                "type": "showDialog",
                "parameters": {
                  "title": "Welcome!",
                  "message": "This dialog was created dynamically from JSON.",
                  "buttonText": "Got it"
                }
              }
            }
          ]
        }
      ]
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 8, 0, 0],
        "color": "#FFFFFF",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Snackbar Action",
                "fontSize": 16,
                "fontWeight": "bold"
              }
            },
            {
              "type": "button",
              "properties": {
                "text": "Show Snackbar",
                "backgroundColor": "#2196F3",
                "foregroundColor": "#FFFFFF",
                "borderRadius": 8
              },
              "actions": {
                "type": "showSnackbar",
                "parameters": {
                  "message": "This is a snackbar message!",
                  "duration": 3,
                  "actionLabel": "UNDO"
                }
              }
            }
          ]
        }
      ]
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 8, 0, 0],
        "color": "#FFFFFF",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "URL Launch Action",
                "fontSize": 16,
                "fontWeight": "bold"
              }
            },
            {
              "type": "button",
              "properties": {
                "text": "Open Flutter Website",
                "backgroundColor": "#9C27B0",
                "foregroundColor": "#FFFFFF",
                "borderRadius": 8
              },
              "actions": {
                "type": "launchUrl",
                "parameters": {
                  "url": "https://flutter.dev",
                  "mode": "external"
                }
              }
            }
          ]
        }
      ]
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 8, 0, 0],
        "color": "#FFFFFF",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Bottom Sheet Action",
                "fontSize": 16,
                "fontWeight": "bold"
              }
            },
            {
              "type": "button",
              "properties": {
                "text": "Show Bottom Sheet",
                "backgroundColor": "#E91E63",
                "foregroundColor": "#FFFFFF",
                "borderRadius": 8
              },
              "actions": {
                "type": "showBottomSheet",
                "parameters": {
                  "title": "Dynamic Bottom Sheet",
                  "message": "This bottom sheet was created from JSON!",
                  "buttonText": "Close"
                }
              }
            }
          ]
        }
      ]
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 8, 0, 0],
        "color": "#FFFFFF",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Navigation Action",
                "fontSize": 16,
                "fontWeight": "bold"
              }
            },
            {
              "type": "button",
              "properties": {
                "text": "Go to Second Screen",
                "backgroundColor": "#3F51B5",
                "foregroundColor": "#FFFFFF",
                "borderRadius": 8
              },
              "actions": {
                "type": "navigate",
                "parameters": {
                  "route": "/second",
                  "type": "push",
                  "arguments": {
                    "message": "From Dynamic Button!"
                  }
                }
              }
            }
          ]
        }
      ]
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 8, 0, 0],
        "color": "#FFFFFF",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Navigation Action",
                "fontSize": 16,
                "fontWeight": "bold"
              }
            },
            {
              "type": "button",
              "properties": {
                "text": "Go to Details Screen",
                "backgroundColor": "#3F51B5",
                "foregroundColor": "#FFFFFF",
                "borderRadius": 8
              },
              "actions": {
                "type": "navigate",
                "parameters": {
                  "route": "/details",
                  "type": "push",
                  "arguments": {
                    "message": "From Dynamic Button!"
                  }
                }
              }
            }
          ]
        }
      ]
    }
  ]
}
''';
  }

  static String _buildCoreWidgetsJson() {
    return '''
{
  "type": "column",
  "properties": {
    "crossAxisAlignment": "stretch"
  },
  "children": [
    {
      "type": "text",
      "properties": {
        "text": "📱 Core Widgets",
        "fontSize": 20,
        "fontWeight": "bold",
        "color": "#1976D2"
      }
    },
    {
      "type": "text",
      "properties": {
        "text": "This is a Text widget rendered from JSON",
        "fontSize": 14,
        "color": "#757575"
      }
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "margin": [0, 16, 0, 0],
        "color": "#E3F2FD",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "text",
          "properties": {
            "text": "This is a Container with Text inside",
            "color": "#1565C0"
          }
        }
      ]
    },
    {
      "type": "button",
      "properties": {
        "text": "Click Me - I'm a Button",
        "backgroundColor": "#4CAF50",
        "foregroundColor": "#FFFFFF",
        "borderRadius": 8,
        "margin": [0, 16, 0, 0]
      },
      "actions": {
        "type": "print",
        "parameters": {
          "message": "Button clicked!",
          "level": "info"
        }
      }
    },
    {
      "type": "row",
      "properties": {
        "mainAxisAlignment": "spaceEvenly",
        "margin": [0, 16, 0, 0]
      },
      "children": [
        {
          "type": "container",
          "properties": {
            "padding": 12,
            "color": "#FF5252",
            "borderRadius": 4
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Left",
                "color": "#FFFFFF"
              }
            }
          ]
        },
        {
          "type": "container",
          "properties": {
            "padding": 12,
            "color": "#4CAF50",
            "borderRadius": 4
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Center",
                "color": "#FFFFFF"
              }
            }
          ]
        },
        {
          "type": "container",
          "properties": {
            "padding": 12,
            "color": "#2196F3",
            "borderRadius": 4
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Right",
                "color": "#FFFFFF"
              }
            }
          ]
        }
      ]
    }
  ]
}
''';
  }

  static String _buildStylingJson() {
    return '''
{
  "type": "column",
  "properties": {
    "crossAxisAlignment": "stretch"
  },
  "children": [
    {
      "type": "text",
      "properties": {
        "text": "🎨 Styling Properties",
        "fontSize": 20,
        "fontWeight": "bold",
        "color": "#1976D2"
      }
    },
    {
      "type": "text",
      "properties": {
        "text": "Font Sizes",
        "fontSize": 16,
        "fontWeight": "bold",
        "margin": [0, 16, 0, 4]
      }
    },
    {
      "type": "row",
      "properties": {
        "mainAxisAlignment": "spaceEvenly"
      },
      "children": [
        {
          "type": "text",
          "properties": {
            "text": "Small",
            "fontSize": 12
          }
        },
        {
          "type": "text",
          "properties": {
            "text": "Medium",
            "fontSize": 16
          }
        },
        {
          "type": "text",
          "properties": {
            "text": "Large",
            "fontSize": 20
          }
        }
      ]
    },
    {
      "type": "text",
      "properties": {
        "text": "Font Weights",
        "fontSize": 16,
        "fontWeight": "bold",
        "margin": [0, 16, 0, 4]
      }
    },
    {
      "type": "column",
      "children": [
        {
          "type": "text",
          "properties": {
            "text": "Normal weight",
            "fontWeight": "normal"
          }
        },
        {
          "type": "text",
          "properties": {
            "text": "Bold weight",
            "fontWeight": "bold"
          }
        },
        {
          "type": "text",
          "properties": {
            "text": "W500 weight",
            "fontWeight": "w500"
          }
        }
      ]
    },
    {
      "type": "text",
      "properties": {
        "text": "Colors",
        "fontSize": 16,
        "fontWeight": "bold",
        "margin": [0, 16, 0, 4]
      }
    },
    {
      "type": "row",
      "properties": {
        "mainAxisAlignment": "spaceEvenly"
      },
      "children": [
        {
          "type": "container",
          "properties": {
            "padding": 12,
            "color": "#FF5252",
            "borderRadius": 8
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Red",
                "color": "#FFFFFF"
              }
            }
          ]
        },
        {
          "type": "container",
          "properties": {
            "padding": 12,
            "color": "#4CAF50",
            "borderRadius": 8
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Green",
                "color": "#FFFFFF"
              }
            }
          ]
        },
        {
          "type": "container",
          "properties": {
            "padding": 12,
            "color": "#2196F3",
            "borderRadius": 8
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Blue",
                "color": "#FFFFFF"
              }
            }
          ]
        }
      ]
    },
    {
      "type": "text",
      "properties": {
        "text": "Padding & Margin",
        "fontSize": 16,
        "fontWeight": "bold",
        "margin": [0, 16, 0, 4]
      }
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "color": "#E0E0E0",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "container",
          "properties": {
            "padding": [8, 4, 8, 4],
            "color": "#2196F3",
            "borderRadius": 4
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Container with 16 padding",
                "color": "#FFFFFF"
              }
            }
          ]
        }
      ]
    }
  ]
}
''';
  }

  static String _buildLayoutJson() {
    return '''
{
  "type": "column",
  "properties": {
    "crossAxisAlignment": "stretch"
  },
  "children": [
    {
      "type": "text",
      "properties": {
        "text": "📐 Layout Examples",
        "fontSize": 20,
        "fontWeight": "bold",
        "color": "#1976D2"
      }
    },
    {
      "type": "text",
      "properties": {
        "text": "Column with different alignments",
        "fontSize": 16,
        "fontWeight": "bold",
        "margin": [0, 16, 0, 8]
      }
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "color": "#F5F5F5",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "properties": {
            "crossAxisAlignment": "start"
          },
          "children": [
            {
              "type": "container",
              "properties": {
                "padding": 8,
                "color": "#FF5252",
                "borderRadius": 4
              },
              "children": [
                {
                  "type": "text",
                  "properties": {
                    "text": "Start",
                    "color": "#FFFFFF"
                  }
                }
              ]
            },
            {
              "type": "container",
              "properties": {
                "padding": 8,
                "color": "#4CAF50",
                "borderRadius": 4
              },
              "children": [
                {
                  "type": "text",
                  "properties": {
                    "text": "Center",
                    "color": "#FFFFFF"
                  }
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "type": "text",
      "properties": {
        "text": "Row with space between",
        "fontSize": 16,
        "fontWeight": "bold",
        "margin": [0, 16, 0, 8]
      }
    },
    {
      "type": "row",
      "properties": {
        "mainAxisAlignment": "spaceBetween"
      },
      "children": [
        {
          "type": "container",
          "properties": {
            "padding": 12,
            "color": "#2196F3",
            "borderRadius": 4
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Left",
                "color": "#FFFFFF"
              }
            }
          ]
        },
        {
          "type": "container",
          "properties": {
            "padding": 12,
            "color": "#9C27B0",
            "borderRadius": 4
          },
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Right",
                "color": "#FFFFFF"
              }
            }
          ]
        }
      ]
    },
    {
      "type": "text",
      "properties": {
        "text": "Nested Layouts",
        "fontSize": 16,
        "fontWeight": "bold",
        "margin": [0, 16, 0, 8]
      }
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "color": "#FFE0B2",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "column",
          "children": [
            {
              "type": "text",
              "properties": {
                "text": "Parent Container",
                "fontWeight": "bold"
              }
            },
            {
              "type": "row",
              "properties": {
                "mainAxisAlignment": "spaceEvenly",
                "margin": [0, 8, 0, 0]
              },
              "children": [
                {
                  "type": "container",
                  "properties": {
                    "padding": 8,
                    "color": "#FF7043",
                    "borderRadius": 4
                  },
                  "children": [
                    {
                      "type": "text",
                      "properties": {
                        "text": "Child 1",
                        "color": "#FFFFFF"
                      }
                    }
                  ]
                },
                {
                  "type": "container",
                  "properties": {
                    "padding": 8,
                    "color": "#7E57C2",
                    "borderRadius": 4
                  },
                  "children": [
                    {
                      "type": "text",
                      "properties": {
                        "text": "Child 2",
                        "color": "#FFFFFF"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
''';
  }

  static String _buildErrorHandlingJson() {
    return '''
{
  "type": "column",
  "properties": {
    "crossAxisAlignment": "stretch"
  },
  "children": [
    {
      "type": "text",
      "properties": {
        "text": "⚠️ Error Handling",
        "fontSize": 20,
        "fontWeight": "bold",
        "color": "#F44336"
      }
    },
    {
      "type": "text",
      "properties": {
        "text": "Supported widgets work normally:",
        "margin": [0, 16, 0, 8]
      }
    },
    {
      "type": "button",
      "properties": {
        "text": "Working Button",
        "backgroundColor": "#4CAF50",
        "foregroundColor": "#FFFFFF"
      },
      "actions": {
        "type": "print",
        "parameters": {
          "message": "This button works!"
        }
      }
    },
    {
      "type": "text",
      "properties": {
        "text": "Unsupported widget shows fallback:",
        "margin": [0, 16, 0, 8]
      }
    },
    {
      "type": "unsupportedWidget",
      "properties": {
        "text": "This will not render"
      }
    },
    {
      "type": "anotherUnsupported",
      "properties": {
        "text": "This will also show error"
      }
    },
    {
      "type": "text",
      "properties": {
        "text": "Invalid JSON handling:",
        "margin": [0, 16, 0, 8]
      }
    },
    {
      "type": "container",
      "properties": {
        "padding": 16,
        "color": "#FFCDD2",
        "borderRadius": 8
      },
      "children": [
        {
          "type": "text",
          "properties": {
            "text": "If you pass invalid JSON, the package shows a friendly error message",
            "color": "#B71C1C"
          }
        }
      ]
    }
  ]
}
''';
  }
}

class DemoSection {
  final String title;
  final String description;
  final String? json;
  final bool isMultiForm;

  DemoSection({
    required this.title,
    required this.description,
    this.json,
    this.isMultiForm = false,
  });
}
2
likes
160
points
284
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package for rendering UI from JSON responses. Build dynamic forms, screens, and components from server-driven JSON.

Repository (GitHub)
View/report issues

Topics

#server-driven-ui #dynamic-ui #form #json-ui

Documentation

API reference

License

MIT (license)

Dependencies

flutter, url_launcher

More

Packages that depend on dynamic_ui_renderer