Skip to content
Pinky UI

Async Action Control

Give one action control a complete idle, pending, success, failure and retry lifecycle while preserving intent.

Live example

Try the interaction before reading the recipe.

real component · keyboard-safe

Ready to publish.

Purpose

Give one action control a complete idle, pending, success, failure and retry lifecycle while preserving intent.

Use when

Publish, invite, submit or retry has a meaningful short asynchronous result that belongs to the initiating control.

Avoid

A button that only swaps in a spinner, a disabled control with no recovery path, or a full task that should become a Background Task Row.

Accessibility

Expose aria-busy while pending, keep success and error text available, and never rely on icon or color alone to communicate the result.

Keyboard and touch

Use a native button with stable dimensions. Enter and Space share the pointer path, repeated activation is guarded while pending, and retry stays reachable.

Reduced motion and performance

Use immediate state swaps when motion is reduced. Ignore late callbacks after unmount and prevent duplicate requests while pending.

Composition and anti-patterns

Let the control own a concise lifecycle; add Inline Save State when detailed field persistence or validation needs to remain beside an editor.

Source: packages/skills/feedback/async-action-control.md