Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Progress Stepper Laravel Package

batistackapp/progress-stepper

A Laravel package for building progress steppers with a clean API for defining steps, tracking current progress, and rendering consistent multi-step workflows in PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This is the first stable tagged release (1.0.0) of BatistackApp/progress-stepper. The release notes are effectively just a changelog link, so treat this as "API is now declared stable" rather than a feature announcement — read CHANGELOG.md and the README in the 1.0.0 tag before you build on it.

Minimal setup:

composer require batistackapp/progress-stepper:^1.0
php artisan vendor:publish --provider="BatistackApp\ProgressStepper\ProgressStepperServiceProvider"

Then look at, in this order:

  1. config/progress-stepper.php — the published config is the fastest way to learn what the package considers tunable (variants, colours, orientation, default step rendering).
  2. resources/views/ (published via --tag=progress-stepper-views) — the Blade markup tells you exactly which slots and attributes exist, which is usually faster than reading the readme.
  3. The service provider's boot()/register() — confirms the component namespace and whether anything is registered globally (Blade component, Livewire component, view namespace).

First use case: drop a stepper into a multi-step form or onboarding flow where the step state already lives somewhere (a controller session key, a Livewire property, or a ?step= query param) and you just need the visual indicator.

<x-progress-stepper
    :steps="['Account', 'Company', 'Billing', 'Review']"
    :current="3"
/>

If the component name above doesn't resolve, check the provider for the registered alias prefix (<x-progress-stepper::stepper /> is common for namespaced packages) before assuming the install failed.

Implementation Patterns

Keep step definitions in one place. Define the ordered steps once — a config array, an enum, or a dedicated Step value object — and derive labels from it everywhere. Duplicating the label array between the stepper and the form sections is the most common source of drift when steps get reordered.

// config/onboarding.php
return [
    'steps' => [
        ['key' => 'account',  'label' => 'Account',  'route' => 'onboarding.account'],
        ['key' => 'company',  'label' => 'Company',  'route' => 'onboarding.company'],
        ['key' => 'billing',  'label' => 'Billing',  'route' => 'onboarding.billing'],
        ['key' => 'review',   'label' => 'Review',   'route' => 'onboarding.review'],
    ],
];

Controller-driven (server-rendered wizard). Store the current step in the session or derive it from the route, then pass an index into the component. Compute "completed" server-side from real model state rather than assuming every step before the current one is done — users skip backwards, and a stepper that shows Billing as complete because they're on Review is a bug report waiting to happen.

$completed = collect(config('onboarding.steps'))
    ->filter(fn ($step) => $user->hasCompletedStep($step['key']))
    ->pluck('key')
    ->all();

return view('onboarding.billing', [
    'steps' => config('onboarding.steps'),
    'current' => 'billing',
    'completed' => $completed,
]);

Livewire-driven. Bind the current step to a public property and let Livewire re-render the stepper; this is the least code and usually the best fit for anything with validation per step. Add wire:key on the stepper wrapper if you swap step content in and out, otherwise Alpine/JS state inside the component can survive a step change it shouldn't.

Progress percentage. If the component exposes a progress mode, compute the percentage from the same step list rather than hardcoding it (round(($index + 1) / count($steps) * 100)) so it stays correct when steps are added.

Partial/embedded usage. For a compact "3 of 5" indicator in a header, pass the same source array to a second instance with a minimal variant instead of writing a separate partial — one source of truth, two presentations.

Integration tip: wrap the stepper in your own Blade component (<x-ui.stepper>) that maps your domain vocabulary (enum cases, model states) onto the package's props. That single wrapper is where you absorb any prop renaming in a 1.x release, instead of touching every view.

Gotchas and Tips

  • Pin the version while you evaluate. 1.0.0 is the first stable tag; semver applies from here, but expect prop/shape adjustments in early 1.x minors. Use ^1.0 with a committed composer.lock, and read the changelog before bumping.
  • Publish and commit the views if you need visual control. Editing vendor views directly is lost on composer update; published views are yours, but they also won't receive upstream fixes — check the changelog for view changes on each bump.
  • Tailwind purging. Package views containing classes not present in your scanned paths will silently lose styling. Add the vendor view path to content in tailwind.config.js, or ensure a safelist, then rebuild.
  • Off-by-one on step indices. Determine once whether current is 0-based or 1-based and write it into your wrapper component's docblock. This is the single most common integration mistake and produces a stepper that's eternally one step behind.
  • Caching. Published views are fine, but if you cache rendered fragments (@cache) or use response caching on the wizard pages, the stepper can show stale "current" state after a redirect. Keep the stepper out of cached fragments, or key the cache on the step.
  • Accessibility is your responsibility unless proven otherwise. Check the rendered markup for aria-current="step" and a sensible ordered list (<ol>). If the package emits plain <div>s, add the semantics in your wrapper — it's a small change with a large payoff.
  • Debugging a component that renders nothing: verify the alias with php artisan blade:list-style introspection or by grepping the provider, then check that current isn't landing outside the steps range (some implementations render nothing rather than throwing).
  • Extension points worth inspecting before you fork: whether step rendering is a slot, a per-step closure/callback, or an overridable view. If a per-step render callback exists, use it for badges/icons rather than duplicating the whole component. If it doesn't, the published views are the intended extension surface.
  • Testing: assert on rendered text and aria-current, not on class names — visual classes are the most likely thing to change across minor releases.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource