Group steps for larger journeys and read per-section progress. Steps with no group fall into the reserved general section (Flow::UNGROUPED_SECTION):
$flow = Onboarding::flow('default')->title('Account setup');
$flow->add('Upload photo')->group('profile')->completeWhenFilled('avatar_path');
$flow->add('Add card')->group('billing')->completeWhenFilled('card_last4');
$flow->add('Accept terms')->completeWhenFilled('terms_accepted_at'); // no group: "general"$flow = Onboarding::for($user);
$flow?->sections(); // Collection<int, SectionData>
$flow?->groups(); // alias of sections()
$flow?->section('billing')?->percentage; // float
$flow?->section('billing')?->isCompleted; // bool — required steps in the group completeSections follow the order in which each group first appears in the ordered step list. A section’s percentage covers all its visible steps; its isCompleted is true once its required steps are complete.
SectionData
Each section is a final readonly SectionData DTO — key, title (currently the group key), percentage, isCompleted and steps (a list of StepData) — implementing Arrayable and JsonSerializable. Serialized steps also carry their group key:
[
'key' => 'billing',
'title' => 'billing',
'percentage' => 0.0,
'is_completed' => false,
'steps' => [ /* list of StepData shapes */ ],
]A multi-part wizard
@foreach ($user->onboarding()?->sections() ?? [] as $section)
<h3>{{ $section->title }} — {{ $section->percentage }}%</h3>
<ul>
@foreach ($section->steps as $step)
<li @class(['is-done' => $step->isCompleted])>{{ $step->title }}</li>
@endforeach
</ul>
@endforeachShow your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.