Loading

One glyph, four places. The shadcn/ui spinner is the same Lucide loader Button spins for its loading prop, stroked in the action gradient; it sits inline, at the end of a field while it validates, and in a dialog that cannot be dismissed while work runs. Long jobs list their steps and tick each one off. Inside a Button the loader stays on the label colour, since a gradient on a gradient fill would vanish. For content that has not arrived yet, use Skeleton; for a measurable job, Progress.

<Button loading={busy} loadingText="Publishing">Publish lot</Button>

<LoadingDialog open={busy} status={done ? "done" : "running"} title="Publishing the lot">
  <LoadingSteps>
    <LoadingStep state="done">Matching 340 EANs</LoadingStep>
    <LoadingStep state="active">Pricing the lot</LoadingStep>
    <LoadingStep state="pending">Publishing to the marketplace</LoadingStep>
  </LoadingSteps>
</LoadingDialog>

Inline

Button's loading prop at sm, default and lg; the width is reserved so nothing shifts. Beside text, the bare Spinner.

Pricing agent is comparing lots

After a text field

Input group with the Spinner as the trailing addon while the value validates on blur; a check when it passes.

Checked when you leave the field.

Modal

Cannot be closed by Escape, the overlay or a corner button. It closes itself when the job ends, or through Cancel when one is offered.

Modal with steps

Each finished step draws its check; the active one spins; the rest wait. After the last, the tile draws the check too, one stroke heavier, and the dialog holds for a second before it closes. A step can end in a warning and the job goes on; the tile ends on the warning triangle and the dialog stays open with Close, since there is something to read. A failed step stops it, the tile draws the cross, and Close is the way out.