@@ -4,8 +4,18 @@ import 'package:collection/collection.dart';
44import 'package:flutter/material.dart' hide Step;
55import 'package:survey_kit/survey_kit.dart' ;
66
7- /// StatefulWidget that manages the survey state
7+ /// A [StatefulWidget] that manages the mutable state for the survey.
8+ ///
9+ /// This widget holds the survey's state, results, and handles all state transitions
10+ /// through the [onEvent] method. It creates an immutable [SurveyStateProvider]
11+ /// on each rebuild to expose the state to descendant widgets.
12+ ///
13+ /// This follows the recommended Flutter pattern of separating mutable state
14+ /// (StatefulWidget) from the immutable state exposure (InheritedWidget).
815class SurveyStateProviderWidget extends StatefulWidget {
16+ /// Creates a [SurveyStateProviderWidget] .
17+ ///
18+ /// All parameters are required except [stepShell] .
919 const SurveyStateProviderWidget ({
1020 super .key,
1121 required this .taskNavigator,
@@ -15,10 +25,19 @@ class SurveyStateProviderWidget extends StatefulWidget {
1525 this .stepShell,
1626 });
1727
28+ /// The navigator that manages the task flow and step transitions.
1829 final TaskNavigator taskNavigator;
19- final Function (SurveyResult ) onResult;
30+
31+ /// Callback invoked when the survey is completed or closed.
32+ final void Function (SurveyResult ) onResult;
33+
34+ /// Optional custom shell widget builder for wrapping steps.
2035 final StepShell ? stepShell;
36+
37+ /// Global key for managing the Navigator state.
2138 final GlobalKey <NavigatorState > navigatorKey;
39+
40+ /// The widget below this widget in the tree.
2241 final Widget child;
2342
2443 @override
@@ -54,6 +73,13 @@ class _SurveyStateProviderWidgetState extends State<SurveyStateProviderWidget> {
5473 _surveyStateStream.add (_state);
5574 }
5675
76+ /// Handles survey events and triggers appropriate state transitions.
77+ ///
78+ /// Supported events:
79+ /// - [StartSurvey] : Initializes the survey with the first step
80+ /// - [NextStep] : Advances to the next step
81+ /// - [StepBack] : Returns to the previous step
82+ /// - [CloseSurvey] : Closes the survey and reports results
5783 void onEvent (SurveyEvent event) {
5884 if (event is StartSurvey ) {
5985 final newState = _handleInitialStep ();
@@ -101,7 +127,7 @@ class _SurveyStateProviderWidgetState extends State<SurveyStateProviderWidget> {
101127 );
102128 }
103129
104- //If not steps are provided we finish the survey
130+ // If no steps are provided we finish the survey
105131 final taskResult = SurveyResult (
106132 id: widget.taskNavigator.task.id,
107133 startTime: _startDate,
@@ -151,8 +177,7 @@ class _SurveyStateProviderWidgetState extends State<SurveyStateProviderWidget> {
151177 final previousStep =
152178 widget.taskNavigator.previousInList (currentState.currentStep);
153179
154- //If theres no previous step we can't go back further
155-
180+ // If there's no previous step we can't go back further
156181 if (previousStep != null ) {
157182 final questionResult = _getResultByStepIdentifier (previousStep.id);
158183
@@ -182,7 +207,7 @@ class _SurveyStateProviderWidgetState extends State<SurveyStateProviderWidget> {
182207 ) {
183208 _addResult (event.questionResult);
184209
185- final stepResults = _results.map ((e) => e). toList ();
210+ final stepResults = _results.toList ();
186211
187212 final taskResult = SurveyResult (
188213 id: widget.taskNavigator.task.id,
@@ -199,9 +224,9 @@ class _SurveyStateProviderWidgetState extends State<SurveyStateProviderWidget> {
199224 );
200225 }
201226
202- //Currently we are only handling one question per step
227+ // Currently we are only handling one question per step
203228 SurveyState _handleSurveyFinished (PresentingSurveyState currentState) {
204- final stepResults = _results.map ((e) => e). toList ();
229+ final stepResults = _results.toList ();
205230 final taskResult = SurveyResult (
206231 id: widget.taskNavigator.task.id,
207232 startTime: _startDate,
@@ -235,6 +260,9 @@ class _SurveyStateProviderWidgetState extends State<SurveyStateProviderWidget> {
235260 return widget.taskNavigator.currentStepIndex (step);
236261 }
237262
263+ /// Retrieves a step result by its identifier.
264+ ///
265+ /// Returns `null` if no result is found with the given [id] .
238266 StepResult ? getStepResultById (String id) {
239267 return _results.firstWhereOrNull ((element) => element.id == id);
240268 }
@@ -257,8 +285,18 @@ class _SurveyStateProviderWidgetState extends State<SurveyStateProviderWidget> {
257285 }
258286}
259287
260- /// InheritedWidget that provides survey state to descendants (immutable)
288+ /// An [InheritedWidget] that provides immutable access to survey state.
289+ ///
290+ /// This widget exposes the current survey state, results, and event handling
291+ /// to descendant widgets. It should not be instantiated directly; instead,
292+ /// use [SurveyStateProviderWidget] which manages the mutable state and
293+ /// creates this widget on each rebuild.
294+ ///
295+ /// Access this provider using [SurveyStateProvider.of(context)] .
261296class SurveyStateProvider extends InheritedWidget {
297+ /// Creates a [SurveyStateProvider] .
298+ ///
299+ /// This constructor should only be called by [SurveyStateProviderWidget] .
262300 const SurveyStateProvider ({
263301 super .key,
264302 required this .state,
@@ -274,17 +312,48 @@ class SurveyStateProvider extends InheritedWidget {
274312 this .stepShell,
275313 });
276314
315+ /// The current state of the survey.
277316 final SurveyState state;
317+
318+ /// The results collected so far in the survey.
319+ ///
320+ /// Note: This exposes the internal set. For better encapsulation,
321+ /// consider using this as a read-only reference.
278322 final Set <StepResult > results;
323+
324+ /// The date and time when the survey was started.
279325 final DateTime startDate;
326+
327+ /// Stream controller for broadcasting survey state changes.
328+ ///
329+ /// Use `.stream` to listen to state changes:
330+ /// ```dart
331+ /// SurveyStateProvider.of(context).surveyStateStream.stream
332+ /// ```
280333 final StreamController <SurveyState > surveyStateStream;
334+
335+ /// The navigator that manages the task flow.
281336 final TaskNavigator taskNavigator;
282- final Function (SurveyResult ) onResult;
337+
338+ /// Callback invoked when the survey is completed or closed.
339+ final void Function (SurveyResult ) onResult;
340+
341+ /// Optional custom shell widget builder for wrapping steps.
283342 final StepShell ? stepShell;
343+
344+ /// Global key for managing the Navigator state.
284345 final GlobalKey <NavigatorState > navigatorKey;
346+
347+ /// Callback for handling survey events.
285348 final void Function (SurveyEvent ) onEvent;
349+
350+ /// Function to retrieve a step result by its identifier.
286351 final StepResult ? Function (String ) getStepResultById;
287352
353+ /// Retrieves the [SurveyStateProvider] from the widget tree.
354+ ///
355+ /// The [context] must have a [SurveyStateProvider] ancestor.
356+ /// Throws an assertion error if no provider is found.
288357 static SurveyStateProvider of (BuildContext context) {
289358 final result =
290359 context.dependOnInheritedWidgetOfExactType <SurveyStateProvider >();
@@ -294,10 +363,12 @@ class SurveyStateProvider extends InheritedWidget {
294363
295364 @override
296365 bool updateShouldNotify (SurveyStateProvider oldWidget) =>
297- state != oldWidget.state || results != oldWidget.results ;
366+ state != oldWidget.state;
298367
368+ /// Returns the total number of steps in the survey.
299369 int get countSteps => taskNavigator.countSteps;
300370
371+ /// Returns the index of the given [step] in the survey.
301372 int currentStepIndex (Step step) {
302373 return taskNavigator.currentStepIndex (step);
303374 }
0 commit comments