Skip to content

Claform/sdk-flutter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

claform_sdk_flutter

Flutter SDK for Claform. Provides a complete survey-taking experience with 36 question types, 6 content blocks, Material 3 theming, offline support, quiz scoring, and full backend API integration.

Pure Dart + Flutter implementation -- no TypeScript bridge or WebView. All engines (logic, validation, piping, quiz, randomization, theming, conflict resolution, A/B testing) are re-implemented natively in Dart.

Features

  • 36 question type widgets -- native Flutter implementations with Material 3 design
  • 6 content blocks -- headings, text, images, video embeds, dividers, and spacers
  • Provider-based state management -- SurveyNotifier (ChangeNotifier) wrapping SurveySDK
  • SurveyScreen -- drop-in widget for a complete survey experience
  • Swipe navigation -- gesture-based page transitions
  • Animated transitions -- page transitions, validation shake animations
  • Material 3 theming -- full theme resolution from survey config with Material 3 mapping
  • Offline mode -- queue responses, sync when online, conflict resolution
  • Quiz mode -- timer, hints, instant feedback, results screen
  • Accessibility -- semantics labels, screen reader support
  • Platform adapters -- SharedPreferences storage, Dio HTTP client, connectivity
  • i18n -- multi-language surveys, RTL support
  • Backend API integration -- full API client with retry and backoff

Requirements

  • Flutter >= 3.10.0
  • Dart >= 3.0.0

Installation

Add to your pubspec.yaml:

dependencies:
  claform_sdk_flutter: ^1.0.0

Then run:

flutter pub get

Dependencies

The SDK depends on:

Package Version Purpose
provider ^6.1.1 State management
dio ^5.4.0 HTTP client
shared_preferences ^2.2.2 Persistent storage
uuid ^4.2.1 Session ID generation
intl ^0.19.0 i18n and formatting
collection ^1.18.0 Collection utilities
file_picker ^6.1.1 File upload questions
image_picker ^1.0.7 Photo upload questions
signature ^5.4.1 Signature questions
confetti ^0.7.0 Quiz celebration effects

Quick Start

import 'package:flutter/material.dart';
import 'package:claform_sdk_flutter/survey_sdk.dart';

class SurveyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SurveyScreen(
        config: SurveySDKConfig(
          apiUrl: 'https://api.example.com/api/v1',
          shareId: 'abc123',
        ),
        onComplete: (response) => print('Done! $response'),
        onError: (error) => print('Error: $error'),
      ),
    );
  }
}

With Provider (Custom Layout)

import 'package:provider/provider.dart';
import 'package:claform_sdk_flutter/survey_sdk.dart';

class CustomSurveyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => SurveyNotifier(
        config: SurveySDKConfig(
          apiUrl: 'https://api.example.com/api/v1',
          shareId: 'abc123',
          offlineEnabled: true,
          storageAdapter: SharedPrefsStorageAdapter(),
        ),
      ),
      child: Consumer<SurveyNotifier>(
        builder: (context, notifier, _) {
          if (notifier.phase == SurveyPhase.loading) {
            return const LoadingScreen();
          }
          if (notifier.phase == SurveyPhase.error) {
            return ErrorScreen(error: notifier.error);
          }
          if (notifier.phase == SurveyPhase.completed) {
            return const ThankYouScreen();
          }
          return Column(
            children: [
              ProgressBar(progress: notifier.progress),
              Expanded(
                child: SurveyPageRenderer(
                  page: notifier.currentPage!,
                  answers: notifier.answers,
                  onAnswer: notifier.setAnswer,
                ),
              ),
              NavigationButtons(
                canGoNext: notifier.canGoNext,
                canGoPrevious: notifier.canGoPrevious,
                isLastPage: notifier.isLastPage,
                onNext: notifier.nextPage,
                onPrevious: notifier.previousPage,
                onSubmit: notifier.submit,
              ),
            ],
          );
        },
      ),
    );
  }
}

State Management

The SDK uses the Provider pattern with SurveyNotifier, a ChangeNotifier that wraps the core SurveySDK and subscribes to 12 EventBus events for reactive state updates.

SurveyNotifier

Property Type Description
survey Survey? The loaded survey
phase SurveyPhase Current lifecycle phase
currentPage Page? Current page
currentPageIndex int Current page index
progress ProgressInfo Progress information
answers Map<String, ResponseValue> All current answers
validationErrors Map<String, List<String>> Validation errors
visibleQuestionIds Set<String> IDs of visible questions
isOnline bool Network status
error SDKError? Current error
canGoNext bool Whether next page is available
canGoPrevious bool Whether previous page is available
isLastPage bool Whether on last page
Method Description
loadSurvey() Load survey from API
setAnswer(questionId, value) Set an answer
clearAnswer(questionId) Clear an answer
nextPage() Navigate forward
previousPage() Navigate backward
goToPage(index) Jump to page
validateCurrentPage() Validate current page
submit() Submit the response
resume([sessionId]) Resume a saved session

Widget Catalog

Screens

Widget Description
SurveyScreen Full survey experience with all lifecycle phases
LoadingScreen Loading state with indicator
ErrorScreen Error state with retry
ThankYouScreen Completion screen
QuizResultScreen Quiz results display

Navigation

Widget Description
SurveyPageRenderer Renders the current page with questions
NavigationButtons Next/Previous/Submit buttons
ProgressBar Survey progress indicator
SwipeNavigator Gesture-based page navigation
PageTransition Animated page transitions

Question Types (36)

All question widgets accept QuestionInputProps and are rendered automatically by QuestionRenderer.

Text: TextShortInput, TextLongInput

Choice: SingleChoiceInput, MultiChoiceInput, DropdownInput, ImageChoiceInput, ChoiceOption

Rating: RatingScaleInput, StarRatingInput, NPSInput, SliderInput, EmojiRatingInput, SemanticDifferentialInput, OpinionScaleInput

Boolean: YesNoInput

Date/Time: DateInput, DateTimeInput, TimeInput

Contact: EmailInput, PhoneInput, NumberInput, WebsiteUrlInput

Location: LocationInput

Advanced: RankingInput, MatrixSingleInput, MatrixMultiInput, FileUploadInput, PhotoUploadInput, SignatureInput, AddressInput, NameInput, ImageHeatmapInput, RepeatingGroupInput

Special: ConstantSumInput, MaxDiffInput, CardSortInput, PriceSensitivityInput

Content Blocks (6)

Non-input display elements, rendered inline in page order and skipped by validation, progress, and answers.

Widget Description
HeadingBlock Section heading (h1/h2/h3)
TextBlock Rich text / paragraph content
ImageBlock Image with caption and optional link
VideoEmbedBlock Video (YouTube/Vimeo/Loom/custom)
DividerBlock Horizontal rule
SpacerBlock Vertical spacing

Action elements (redirect, email, webhook, calculate, score display, payment, integration) are recognized by the SDK but execute server-side and are not rendered.

Quiz

Widget Description
QuizTimer Countdown timer display
QuizHint Hint display for quiz questions
QuizFeedback Immediate answer feedback

Validation

Widget Description
ValidationError Error message display
ShakeAnimation Shake effect for invalid fields
ScrollToError Auto-scroll to first error

Engines

All engines are re-implemented in pure Dart:

Engine Description
LogicEngine Conditional logic evaluation (17 operators)
ValidationEngine Answer validation for all question types
PipingEngine Answer piping into question text
QuizEngine Quiz scoring (8 strategies)
RandomizationEngine Deterministic option shuffling (Mulberry32 PRNG)
ThemeEngine Theme resolution with Material 3 mapping
ConflictEngine Offline sync conflict resolution
ABTestingEngine A/B test variant assignment

Services

Service Description
ApiClient HTTP client (Dio-based) with retry and backoff
SessionManager Local session persistence and auto-save
OfflineManager Response queuing and sync orchestration
I18nManager Locale management and RTL detection
DeepLinkParser Parse survey deep links
PackageManager Offline survey package management
MediaCache Media asset caching
AnalyticsTracker Event tracking
PaymentHandler Payment question processing

Adapters

Adapter Interface Implementation Description
Storage StorageAdapter SharedPrefsStorageAdapter Persistent key-value storage
Network NetworkAdapter DioNetworkAdapter HTTP client
Connectivity ConnectivityAdapter -- Network monitoring
Background Sync BackgroundSyncAdapter -- Background task scheduling
Encryption EncryptionAdapter -- Data encryption
Geolocation GeolocationAdapter -- GPS location
Biometric BiometricAdapter -- Biometric auth
Push Notifications PushNotificationAdapter -- Push delivery
Payment PaymentAdapter -- Payment processing
Analytics AnalyticsAdapter -- Analytics output

Theming

The SDK maps survey theme settings to Material 3 automatically. Override via config:

SurveyScreen(
  config: SurveySDKConfig(
    apiUrl: 'https://api.example.com/api/v1',
    shareId: 'abc123',
    themeOverrides: ThemeSettings(
      colors: ThemeColors(
        primary: '#6200EE',
        background: '#FFFFFF',
        text: '#212121',
      ),
      typography: ThemeTypography(
        fontFamily: 'Roboto',
      ),
    ),
  ),
)

Access theme values in custom widgets:

final theme = SurveyTheme.of(context);
Container(
  color: theme.colors.background,
  padding: EdgeInsets.all(theme.spacing.md),
  child: Text(
    'Content',
    style: TextStyle(
      color: theme.colors.text,
      fontFamily: theme.fonts.body,
    ),
  ),
)

Theme Utilities

import 'package:claform_sdk_flutter/survey_sdk.dart';

final color = ColorUtils.fromHex('#6200EE');
final lighter = ColorUtils.lighten(color, 0.2);
final darker = ColorUtils.darken(color, 0.1);

Offline Mode

SurveyScreen(
  config: SurveySDKConfig(
    apiUrl: 'https://api.example.com/api/v1',
    surveyId: 'survey-123',
    offlineEnabled: true,
    storageAdapter: SharedPrefsStorageAdapter(),
    conflictStrategy: ConflictStrategy.clientWins,
  ),
)

The SDK automatically:

  1. Caches the survey definition for offline access
  2. Queues responses when offline
  3. Syncs queued responses when connectivity is restored
  4. Detects and resolves conflicts using the configured strategy

Platform-Specific Setup

iOS

Add to ios/Runner/Info.plist if using location questions:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This survey requires your location.</string>

Add for camera/photo access:

<key>NSCameraUsageDescription</key>
<string>This survey requires camera access for photo questions.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This survey requires photo library access.</string>

Android

Add to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

License

MIT

About

Flutter SDK (pure Dart) for embedding Claform surveys — 36 question types, content blocks, theming, offline support, and quiz scoring.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages