claform_sdk_flutter 1.1.0
claform_sdk_flutter: ^1.1.0 copied to clipboard
Flutter SDK for Claform. Provides a complete survey-taking experience with 36 question types, display/content blocks, theming, offline support, quiz scoring, and full backend API integration.
example/lib/main.dart
// Example app for the Claform Flutter SDK.
//
// It shows the two things every integration needs:
// 1. A [SurveySDKConfig] pointing at your API and a public survey share ID.
// 2. A [SurveyScope] (which wires up the providers and loads the survey)
// wrapping the batteries-included [SurveyScreen] widget.
//
// Run it with `flutter run` from the `example/` directory, paste a real
// public survey share ID on the home screen, and tap "Start survey".
import 'package:claform_sdk_flutter/claform_sdk_flutter.dart';
import 'package:flutter/material.dart';
/// Default production API base URL. Point this at your own backend if you are
/// self-hosting.
const String kDefaultApiUrl = 'https://api.claform.com/api/v1';
void main() => runApp(const ClaformExampleApp());
class ClaformExampleApp extends StatelessWidget {
const ClaformExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Claform SDK Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: const Color(0xFF0C3B49),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
/// Collects an API URL + survey share ID, then launches the survey.
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _formKey = GlobalKey<FormState>();
final _apiUrlController = TextEditingController(text: kDefaultApiUrl);
final _shareIdController = TextEditingController();
@override
void dispose() {
_apiUrlController.dispose();
_shareIdController.dispose();
super.dispose();
}
void _startSurvey() {
if (!_formKey.currentState!.validate()) return;
final config = SurveySDKConfig(
apiUrl: _apiUrlController.text.trim(),
shareId: _shareIdController.text.trim(),
);
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (_) => SurveyPage(config: config),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Claform SDK Example')),
body: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 420),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Embed a survey',
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 8),
Text(
'Enter a public survey share ID to render it with the SDK.',
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 24),
TextFormField(
controller: _apiUrlController,
keyboardType: TextInputType.url,
decoration: const InputDecoration(
labelText: 'API URL',
border: OutlineInputBorder(),
),
validator: (value) =>
(value == null || value.trim().isEmpty)
? 'API URL is required'
: null,
),
const SizedBox(height: 16),
TextFormField(
controller: _shareIdController,
decoration: const InputDecoration(
labelText: 'Survey share ID',
hintText: 'e.g. abc123',
border: OutlineInputBorder(),
),
validator: (value) =>
(value == null || value.trim().isEmpty)
? 'Share ID is required'
: null,
onFieldSubmitted: (_) => _startSurvey(),
),
const SizedBox(height: 24),
FilledButton(
onPressed: _startSurvey,
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: Text('Start survey'),
),
),
],
),
),
),
),
),
);
}
}
/// Renders a survey full-screen. [SurveyScope] loads the survey (auto-load is
/// on by default) and provides the state that [SurveyScreen] consumes.
class SurveyPage extends StatelessWidget {
const SurveyPage({super.key, required this.config});
final SurveySDKConfig config;
void _showMessage(BuildContext context, String message) {
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(SnackBar(content: Text(message)));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Survey')),
body: SurveyScope(
config: config,
onError: (error) => _showMessage(context, 'Error: ${error.message}'),
child: SurveyScreen(
onComplete: (response) {
_showMessage(context, 'Response submitted (${response.id}).');
},
onDone: () => Navigator.of(context).maybePop(),
),
),
);
}
}