flowboard_flutter 1.2.0 copy "flowboard_flutter: ^1.2.0" to clipboard
flowboard_flutter: ^1.2.0 copied to clipboard

A versatile suite of UI components and flow management tools for building dynamic onboarding and dashboards in Flutter.

Flowboard #

A generic, JSON-driven UI rendering engine for Flutter.

Features #

  • Dynamic layout engine (Column, Row, Container, etc.)
  • Advanced Layering (stack, positioned) for complex UI
  • Premium Styling (Gradients for buttons, containers, and text)
  • FontAwesome 6 Icon Support via Hex Codes
  • Form inputs, sliders, Lottie animations, and more.

Documentation #

Usage #

import 'package:flowboard_flutter/flowboard.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Flowboard.init(
    apiToken: 'YOUR_BEARER_TOKEN',
    debug: true,
  );
  runApp(const MyApp());
}

Launch a specific onboarding by ID:

await Flowboard.launchOnboardingById(
  context,
  onboardingId: 'FLOW_ID',
  locale: 'fr_FR',
  version: FlowboardFlowVersion.draft,
);

Custom Navigation #

Use jump_to when a widget should navigate directly to a specific screen by ID:

{
  "type": "button",
  "action": "jump_to",
  "actionData": {
    "screenId": "signup"
  },
  "properties": {
    "label": "Jump to Sign Up"
  }
}

Inside a custom screen, the same behavior is available through FlowboardContext.onJumpTo:

customScreenBuilder: (ctx) {
  return ElevatedButton(
    onPressed: () => ctx.onJumpTo('signup'),
    child: const Text('Jump to Sign Up'),
  );
},

Host Hooks & Action Interception #

Every launch accepts optional interceptors mirroring the Swift SDK's launch options. Each returns a FlowboardActionResolutionperformDefault lets the SDK proceed, handled/cancel short-circuit:

await Flowboard.launchOnboarding(
  context,
  onAction: (ctx) {
    // ctx.action, ctx.screenId, ctx.sourceComponentId, ctx.values, ctx.data
    return FlowboardActionResolution.performDefault;
  },
  onURLOpen: (ctx) => FlowboardActionResolution.handled, // open URLs yourself
  onPermissionRequest: (ctx) => FlowboardActionResolution.performDefault,
  onCustomAction: (ctx) {
    if (ctx.action == 'open_paywall') showPaywall();
    return FlowboardActionResolution.handled;
  },
);

customActionBuilder keeps precedence over onCustomAction for backward compatibility.

Injecting Values (FlowboardFlowController) #

Mirror of Swift's setValue(_:for:) / setValues(_:) — injected values feed conditional routes and {{expressions}}, clear invalid state, and persist into the resume snapshot:

final controller = FlowboardFlowController();
await Flowboard.launchOnboarding(context, controller: controller);
// later, e.g. after a purchase:
controller.setValue('app.plan', 'pro');
controller.setValues({'app.seats': 3, 'app.trial': true});

formId shares the flow's component-id namespace — prefix host keys (e.g. app.plan) to avoid collisions. Custom screens get the same via ctx.setValue / ctx.setValues.

Runtime Dependencies #

URL opening, permission requests, and app rating are injectable (FlowboardRuntimeDependencies), globally via Flowboard.init or per launch:

await Flowboard.init(
  apiToken: '...',
  runtimeDependencies: FlowboardRuntimeDependencies(
    urlOpener: (url, {preferExternalApp = false}) => myOpener(url),
  ),
);

Health Permission (opt-in) #

The core SDK bundles no health package (bundling one would force every consuming app through HealthKit review — the ITMS-90683 exposure the Swift SDK's opt-in FlowboardHealthKit product avoids). To support the health_data permission, register a handler backed by e.g. the health package:

FlowboardHealthPermission.handler = () async {
  final ok = await Health().requestAuthorization([HealthDataType.STEPS]);
  return ok
      ? FlowboardPermissionStatus.granted
      : FlowboardPermissionStatus.denied;
};

Without a handler, health_data resolves to unsupported and the flow shows a snackbar without advancing.

Icon System (Guide for SaaS Team) #

The icon component uses FontAwesome 6. To ensure 100% compatibility without code changes, we use Hex Codes.

⚠️ Tree-shaking on iOS
Apple requires IconData instances to be compile-time constants. Because Flowboard resolves icons dynamically from JSON, you might need to disable the icon handler temporarily (and show placeholders) when submitting an app. Pass enableFontAwesomeIcons: false to FlowboardRenderer to force every icon to render as a generic helper icon until the store review is complete.

JSON Structure #

{
  "type": "icon",
  "properties": {
    "icon": "HEX_CODE",   // e.g., "f004"
    "style": "STYLE",     // "solid", "regular", or "brands"
    "size": 24,           // Optional, default 24
    "color": "0xFF000000" // Optional, default black
  }
}

How to Find the Hex Code #

  1. Go to the FontAwesome Search.
  2. Find your icon (e.g., "Heart").
  3. Copy the Unicode/Hex value (e.g., f004).
  4. Choose your style (solid is usually default).

Examples #

Solid Heart (Red)

{
  "type": "icon",
  "properties": {
    "icon": "f004",
    "style": "solid",
    "color": "0xFFFF0000"
  }
}

Regular Heart (Outlined)

{
  "type": "icon",
  "properties": {
    "icon": "f004",
    "style": "regular",
    "color": "0xFF000000"
  }
}

Apple Logo (Brand)

{
  "type": "icon",
  "properties": {
    "icon": "f179",
    "style": "brands",
    "size": 32
  }
}