conversational_onboarding 0.1.0 copy "conversational_onboarding: ^0.1.0" to clipboard
conversational_onboarding: ^0.1.0 copied to clipboard

Declarative, conversational onboarding flows for Flutter. Build Cal AI / Duolingo-style onboarding with branching, animations, and a typed answers map.

conversational_onboarding #

Declarative, conversational onboarding flows for Flutter. Build Cal AI / Duolingo / Headspace-style onboarding with branching, animations, and a typed answers map — in ~30 lines.

pub package

Why #

Most onboarding packages stop at "swipe through some screens". Modern high-converting apps instead ask the user a handful of questions, show a tailored summary, then open the paywall. That pattern is repetitive to build by hand — state, branching, transitions, progress bars, the "analyzing your answers…" reveal. This package packages it up.

Install #

dependencies:
  conversational_onboarding: ^0.1.0

30-line example #

import 'package:conversational_onboarding/conversational_onboarding.dart';

OnboardingFlow(
  onComplete: (answers) => Navigator.of(context).pushReplacementNamed('/home'),
  steps: [
    SplashStep(title: 'Welcome', subtitle: 'A few quick questions…'),
    SingleChoiceStep<String>(
      id: 'experience',
      question: 'How experienced are you?',
      options: const [
        Choice('beginner', 'Beginner', emoji: '🌱'),
        Choice('intermediate', 'Intermediate', emoji: '🔥'),
        Choice('advanced', 'Advanced', emoji: '⚡'),
      ],
    ),
    BranchStep(
      condition: (a) => a.getString('experience') == 'beginner',
      ifTrue: const [SliderStep(id: 'goal_km', question: 'Weekly goal?', min: 1, max: 20)],
      ifFalse: const [SliderStep(id: 'goal_km', question: 'Weekly goal?', min: 10, max: 100)],
    ),
    TextInputStep(id: 'name', question: "What's your first name?"),
    const PersonalizingStep(
      messages: ['Analyzing…', 'Building your plan…', 'Ready!'],
      duration: Duration(seconds: 3),
    ),
    SummaryStep(
      title: 'Your plan',
      builder: (ctx, answers) => Text('Hi ${answers.getString('name')}!'),
    ),
  ],
)

Step catalogue #

Step Purpose
SplashStep Intro / welcome with optional animation
InfoStep Informational break between questions
SingleChoiceStep Pick one. Auto-advances. Card / grid / pill styles
MultiChoiceStep Pick several, with min / max constraints
SliderStep Numeric input
TextInputStep Free-form text, validator, keyboard type
DatePickerStep Date selection
RankingStep Drag to reorder by priority
PermissionPrimingStep Soft-ask before a system permission prompt
PersonalizingStep "Analyzing your answers…" theatrical reveal
SummaryStep Custom widget that renders the collected answers
BranchStep Structural; picks between two sub-lists
CustomStep Escape hatch — render any widget

Branching #

Two mechanisms, use whichever fits:

Per-choice follow-ups — a Choice can carry its own nextSteps, which are inserted after the choice step:

SingleChoiceStep<String>(
  id: 'goal',
  question: 'Primary goal?',
  options: const [
    Choice('lose',    'Lose weight',  nextSteps: weightFlow),
    Choice('muscle',  'Build muscle', nextSteps: muscleFlow),
    Choice('health',  'Stay healthy'),
  ],
)

Structural branches — for more complex conditions:

BranchStep(
  condition: (a) => a.getInt('age') != null && a.getInt('age')! < 18,
  ifTrue:  [...minorFlow],
  ifFalse: [...adultFlow],
)

The progress bar automatically recalculates when branches change.

Theming #

OnboardingFlow(
  theme: const OnboardingTheme(
    primaryColor: Colors.deepPurple,
    borderRadius: 20,
    optionStyle: OptionStyle.card,     // card / list / pill / grid
    transition: OnboardingTransition.sharedAxis,
    animationCurve: Curves.easeOutCubic,
    hapticEnabled: true,
    respectReduceMotion: true,         // honors OS accessibility setting
  ),
  localizations: OnboardingLocalizations.ja, // built-in EN + JA
  steps: [...],
  onComplete: (_) {},
)

Accessing answers later #

onComplete receives an OnboardingAnswers map with typed accessors:

onComplete: (answers) {
  final name = answers.getString('name');
  final goalKm = answers.getDouble('goal_km');
  final races = answers.getList<String>('race_types') ?? const [];
  // persist, or push to your home route.
},

Accessibility #

  • Transitions honor the OS "reduce motion" setting by default.
  • All option tiles use standard Material hit targets and HapticFeedback.selectionClick().
  • Text styles inherit from Theme.of(context) so font-size scaling works.

State management #

The package is intentionally free of external state management dependencies. Internally it uses an InheritedNotifier + ChangeNotifier — which means it never conflicts with your Riverpod / Bloc / Provider setup.

If you want to drive the flow from the outside (e.g. to skip to a specific step from a deep link), pass an OnboardingController yourself:

final controller = OnboardingController(steps: steps);
OnboardingFlow(controller: controller, steps: steps, onComplete: ...);
controller.jumpTo('goal'); // anywhere in your app

Example app #

The example/ folder contains three runnable templates: Cal AI, Duolingo and Headspace styles.

cd example
flutter run

License #

MIT.

1
likes
160
points
87
downloads

Documentation

API reference

Publisher

verified publisherwarashibetech.com

Weekly Downloads

Declarative, conversational onboarding flows for Flutter. Build Cal AI / Duolingo-style onboarding with branching, animations, and a typed answers map.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on conversational_onboarding