Skip to content

Overview

AuraWelcomeWidget is an abstract Filament widget you extend to get an onboarding checklist with a primary-themed SVG progress ring. Steps are configured through the fluent OnboardingStep DTO — each one carries a title, description, icon, optional CTA, and a completion closure.

Because completion is derived from live closures (typically a Model::exists() or a property check on the authed user), the widget is stateless — no new DB column, no sync issues, no "reset onboarding" button.


Minimal example

namespace App\Filament\Widgets;

use App\Models\Project;
use BlueStarSystem\AuraFilament\Support\OnboardingStep;
use BlueStarSystem\AuraFilament\Widgets\AuraWelcomeWidget;

class OnboardingChecklist extends AuraWelcomeWidget
{
    protected ?string $heading = 'Welcome to Acme';

    protected ?string $subheading = 'Five quick steps to get going.';

    protected function getSteps(): array
    {
        return [
            OnboardingStep::make('profile')
                ->title('Complete your profile')
                ->description('Add your name and avatar so teammates recognize you.')
                ->icon('heroicon-o-user-circle')
                ->completed(fn () => filled(auth()->user()?->avatar_path))
                ->action('Go to profile', url('/admin/profile')),

            OnboardingStep::make('first_project')
                ->title('Create your first project')
                ->description('Test the full flow end-to-end.')
                ->icon('heroicon-o-briefcase')
                ->completed(fn () => Project::where('user_id', auth()->id())->exists())
                ->action('New project', url('/admin/projects/create')),

            // ... more steps
        ];
    }
}

Filament auto-discovers widgets under app/Filament/Widgets/, so no panel-provider registration is needed.


OnboardingStep API

OnboardingStep::make(string $key)
    ->title(string $title)
    ->description(?string $description)
    ->icon(?string $icon)                           // heroicon / phosphor name
    ->completed(Closure $callback)                  // returns bool
    ->action(string $label, string $url, bool $newTab = false);
  • ->completed() — called every render. Keep it cheap: ->exists(), ->where(...)->count(), or a property check. Exceptions are swallowed (broken closure → step treated as not-done, never crashes the widget).
  • ->action() — optional. Not rendered when the step is already done; cleans up the UI once a user completes a step.

Widget options

Override these properties on your subclass:

Property Default Effect
$heading 'Welcome' Section heading
$subheading null One-line greeting under the heading
$completedMessage 'All set — you\'re good to go.' Pill shown when 100% done
$hideWhenComplete false If true, canView() returns false once every step is done — the widget hides itself
$columnSpan 'full' Filament grid span

Visual behavior

  • Progress ring: SVG 80×80px with a track + primary arc. stroke-dashoffset animates between percentages, and a drop-shadow keeps the glow on-theme even after the user changes the primary.
  • Step marker — not done: subtle primary-tinted circle with the step's icon (or its number if no icon)
  • Step marker — done: solid success-green circle, white check, scaled up 5% with a soft success-colored ring
  • Step title — done: line-through with a success-green underline color
  • Action pill: primary-tinted pill with a chevron → on the right; hover brightens the background and slides the chevron 2px
  • Hover on the row: light primary tint, primary-tinted border, translateX(2px)

Everything re-tints when the end user changes the primary via the theme configurator.


Live showcase

The dashboard of demo.aura-ui.com/admin runs an OnboardingChecklist with 5 steps derived from real data (auth, saved theme prefs, visited showcase, order exists, second user registered).