sdui 0.1.201 copy "sdui: ^0.1.201" to clipboard
sdui: ^0.1.201 copied to clipboard

SDUI make it easy to implement Server Driven UI pattern on flutter.

pub package

SDUI #

SDUI make it easy to implement Server Driven UI pattern on flutter.

  • The server decides what to render by describing in a JSON the widgets to render.
  • The Flutter screen parse the JSON and build the widgets

Kind like HTML... but not really.

Example #

The Server #

Here is an example of JSON returned by the URL POST http://myapp.herokuapp.com/screens/profile:

{
    "type": "Screen",
    "appBar": {
        "type": "AppBar",
        "attributes": {
            "title": "Profile"
        }
    },
    "child": {
        "type": "Form",
        "attributes": {
            "padding": 10
        },
        "children": [
            {
                "type": "Input",
                "attributes": {
                    "name": "first_name",
                    "value": "Ray",
                    "caption": "First Name",
                    "maxLength": 30
                }
            },
            {
                "type": "Input",
                "attributes": {
                    "name": "last_name",
                    "value": "Sponsible",
                    "caption": "Last Name",
                    "maxLength": 30
                }
            },
            {
                "type": "Input",
                "attributes": {
                    "name": "email",
                    "value": "ray.sponsible@gmail.com",
                    "caption": "Email *",
                    "required": true
                }
            },
            {
                "type": "Input",
                "attributes": {
                    "type": "date",
                    "name": "birth_date",
                    "caption": "Date of Birth"
                }
            },
            {
                "type": "Input",
                "attributes": {
                    "type": "Submit",
                    "name": "submit",
                    "caption": "Create Profile"
                },
                "action": {
                    "type": "Command",
                    "url": "https://myapp.herokuapp.com/commands/save-profile",
                    "prompt": {
                        "type": "Dialog",
                        "attributes": {
                            "type": "confirm",
                            "title": "Confirmation",
                            "message": "Are you sure you want to change your profile?"
                        }
                    }
                }
            }
        ]
    }
}

The UI in Flutter #

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: 'Demo', initialRoute: '/', routes: _routes());
  }

  Map<String, WidgetBuilder> _routes() =>
      {
        '/': (context) =>
        const DynamicRoute(
            provider: HttpRouteContentProvider(
                'http://www.myapp.com/screens/profile'))
      };
}

Screenshots #

Screen Date Picker Alert Dialog

Widgets #

In Flutter, UI is composed of a hierarchy of Widgets. A widget is a visual element on a screen.

SDUI described widgets with the following json structure:

{
    "type": "...",
    "attributes": {
      "padding": 12,
      "color": "#ff0000",
      ...
    },
    "children": [
      ...
    ]
}
  • type: indicates the type of widget
  • attributes: key/value pair of the attributes of the widget. Ex: caption, color, padding, spacing etc.
  • children: The list of children widgets

Widget Library #

Global Variables #

  • sduiErrorState: Function for building the error state.
  • sduiLoadingState: Function for building the loading state.
  • sduiProgressIndicator: Function for building the progress indicator.
  • sduiRouteObserver: Route observer that reload each page on navigation.
  • sduiAnalytics: Analytics class. See SDUIAnalytics
  • sduiCameras: List of available cameras. Empty by default, must be initialized the application

Actions #

With actions, you can:

  • Execute a command on a server (Ex: Saver User Profile, Delete User Account etc.)
  • Navigate to another screen.
  • Prompt a message to user.

SDUI described actions with the following json structure:

{
    "type": "...",
    "attributes": {
      ...
    },
    ...
    "action": {
      "type": "...",
      "url": "...",
      "prompt": {
        "type": "...",
        "title": "Confirmation",
        "message": "Are you sure you want to change your profile?"
      }
    }

}
  • type: Defines the type of action:
    • Route: To redirect to another route
    • Page: To redirect to another page, in the context of [PageView]
    • Command: Remote action to execute. The screen is associated with a URL that will execute the command, and redirect the user to the next screen
    • Share: Share a message to user via email/messenger/whatsapp etc.
    • Navigate: Navigate user to a web page
  • url: is the URL associated with the action
    • route:/..: redirect users to previous route
    • route:/~: redirect users to 1st route
    • URL starting with route:/<ROUTE_NAME> redirect user the a named route. (Ex: route:/checkout)
    • URL starting with http:// or https redirect user to a server driven page
    • page:/<PAGE_NUMBER>: redirect users to a given page. <PAGE_NUMBER> is the page index (starting with 0).
  • replacement: For type=Route, this indicate if we replace the current view or navigate.
  • parameters: Parameters to add to the URL where to redirect to
  • message: Message to share
  • prompt: Shows a Dialog before execute the action
    • type: The type of prompt (Exemple: Confirm, Error, Warning, Information)
    • title: Title of the alert box to open
    • message: Message to display to the user

Build your own Widget #

You can integrate your own widget into sdui.

Step 1: Create your instance of SDUIWidget #

This is an example of widget that render a text with a margin and padding. The widget has the following attributes

  • text: The text to display
  • padding: The padding value
  • margin: The margin value
    class MyWidget extends SDUIWidget {
  String text = '';
  double padding = 10.0;
  double margin = 10.0;

  /// This method will be called by [SDUIParser] to read the widget attributes from the JSON data
  @override
  SDUIWidget fromJson(Map<String, dynamic>? json) {
    text = json?['caption'] ?? '';
    margin = json?['margin'] ?? 10.0;
    padding = json?['padding'] ?? 10.0;
    return this;
  }

  /// This method will be called when rendering the page to create the Flutter widget
  @override
  Widget toWidget(BuildContext context) =>
      Container(
        padding: EdgeInsets.all(padding),
        margin: EdgeInsets.all(margin),
        child: Text(
          text,
          style:
          const TextStyle(fontWeight: FontWeight.bold, color: Colors.red),
        ),
      );
}

Step 2: Register the widget #

The Widget is registered into SDUI and associated with the type MyWidget

void main() async {
  // Register 3rd party widget
  SDUIWidgetRegistry.getInstance().register('MyWidget', () => MyWidget());

  runApp(constMyApp());
}

class MyApp extends StatelessWidget {
  // ...
}

Step 3: Add the widget into the JSONs #

Here is an example of JSON with our 3rd party widget

{
    "type": "Screen",
    "appBar": {
        "type": "AppBar",
        "attributes": {
            "title": "Home"
        }
    },
    "child": {
        "type": "Center",
        "children": [
            {
                "type": "MyWidget",
                "attributes": {
                    "caption": "3rd Party Widget",
                    "padding": 5.0,
                    "margin": 5.0
                }
            }
        ]
    }
}