Power-User Systems

Approval Flow

A step-by-step approval checklist for agent permissions — radio and checkbox groups, an "Other…" escape hatch that grows a field in place, and per-step validation that blocks the commit. Answering a step sends the chosen option flying into a running record of what you have already decided, so the screen accumulates a decision trail instead of replacing itself.

Install

bun add motion clsx tailwind-merge

Then copy 7 files into your project:

  • components/registry/approval-flow/approval-flow.tsx
  • components/registry/approval-flow/types.ts
  • components/registry/approval-flow/use-approval-flow.ts
  • components/registry/approval-flow/step-panel.tsx
  • components/registry/approval-flow/option-row.tsx
  • components/registry/approval-flow/decided-rail.tsx
  • lib/utils.ts

Props

PropTypeDefaultDescription
layout"rail" | "inline""rail"Where the record of decided steps sits. A rail parks it beside the live step on wide screens; inline stacks it above.
morphDurationnumber420Step change, option reveal and the escape hatch growing open. The flight into the record is a spring and ignores this — stiffness and damping own that one.
stiffnessnumber380How hard the chosen option is pulled toward its slot in the record.
dampingnumber34How fast that flight settles. Low values let the label overshoot its slot before landing.
density"comfortable" | "compact""comfortable"Row height, padding and glyph size throughout.
revealStaggernumber45Delay added per option as a step's list arrives. 0 lands the whole group at once.
shakeIntensitynumber6Travel of the shake when a step is rejected. 0 disables it — the message and the red border still fire, because a rejection with no signal at all is a dead end.
shakeCyclesnumber3Round trips in that shake. Each one decays, and the last always ends on centre.
showProgressbooleantrueCompletion bar and step count above the live step.
autoAdvancebooleanfalseCommit a single-choice step the moment it is answered. Never applies to the escape hatch, which needs a sentence first, and it is forced off under reduced motion.
accentColorstring (hex)"#a855f7"Selection, checked glyph, progress fill and the approve button.
dangerColorstring (hex)"#f87171"Invalid row border and the rejection message.

What It Demonstrates

Morph
One shape smoothly turns into another shape, e.g. Dynamic Island.
Shared element transition
An element travels and transforms from one position into another, like a thumbnail expanding into a card.
Layout animation
When an element's size or position changes, it animates to the new spot instead of snapping.
Stepped animation
An animation that is divided into discrete steps, like a countdown timer.
Direction-aware transition
Content slides one way going forward and the opposite way going back, so navigation has a sense of direction.
Shake / Wiggle
A quick side-to-side jitter signaling an error or rejected input.
Spatial consistency
Animating so an element keeps its identity and position across states, so users never lose track of where things went.

Related Components

Appears In