Pending
A utility component that disables interactions, maintains keyboard focus, and ensures proper accessibility for buttons, forms, links, switches, and any interactive element while they are pending.
Installation
pnpm dlx shadcn@latest add @diceui/pendingLayout
Import the utility and use it with your interactive elements.
import { usePending, Pending } from "@/components/pending";
import { Button } from "@/components/ui/button";
// Using the hook
function SubmitButton() {
const [isSubmitting, setIsSubmitting] = useState(false);
const { pendingProps, isPending } = usePending({ isPending: isSubmitting });
return <Button {...pendingProps}>Submit</Button>;
}
// Using the wrapper component
function SubmitButton() {
const [isSubmitting, setIsSubmitting] = useState(false);
return (
<Pending isPending={isSubmitting}>
<Button>Submit</Button>
</Pending>
);
}Examples
Wrapper Component
Use the Pending wrapper component to easily apply pending state to any interactive element.
Form with Pending State
Handle form submissions with proper pending state management and user feedback.
Navigation Links
Apply pending states to links during async navigation or route transitions.
Toggle Switches
Show pending states on switches that save settings to an API or perform async updates.
API Reference
usePending
A hook that manages pending state for interactive elements. Returns props to spread on your element and the current pending state.
Prop
Type
Returns
Prop
Type
Pending
A wrapper component that applies pending state behavior to its child.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-pending] | "true" |
[data-disabled] | "true" |
Accessibility
The Pending utility follows best practices for accessible pending states:
- Uses
aria-busy="true"to indicate loading/pending state to screen readers - Uses
aria-disabled="true"to indicate the element is not currently interactive - Maintains focus ability—users can still Tab to the element
- Prevents all interaction events (click, pointer, keyboard) when pending
- Screen readers announce the changed button content (e.g., "Submitting...")
- Provides
data-pendingattribute for custom styling
Use Cases
The Pending utility works with any interactive element, not just buttons:
- Buttons - Form submissions, actions
- Links - Navigation with async route transitions
- Cards - Clickable cards that load content
- Menu Items - Actions like export, sync, archive
- Switches/Toggles - Settings that save to an API
- Form Fields - Inputs with async validation
- Tabs - Tab switches that load content
- Select Options - Dropdowns with async actions
- Icon Buttons - Icon-only interactive elements
- List Items - Navigation items in sidebars
Notes
- Choose your API: Use the
usePendinghook for more control, or thePendingwrapper for convenience - Focus management: Elements remain focusable but don't respond to interactions when pending
- Event prevention: All pointer and keyboard events are prevented during pending state
- Styling: Use the
data-pendingattribute to style elements based on their pending state - Accessibility: Screen readers announce both
aria-busy(loading state) andaria-disabled(not interactive) - Hook usage: When using the hook directly, spread
pendingPropslast to ensure event prevention works correctly
Credits
- React Aria's Button component - For the pending state management patterns (Apache License 2.0).