Loading Button
A button that displays a loading indicator and prevents interaction while an asynchronous action is in progress.JSX
<LoadingButton loadingText="Saving…">Save</LoadingButton>
Installation
Package
CLI (copy source)
pnpm
pnpm add @advui/corenpm
npm install @advui/coreUsage
import { LoadingButton } from '@advui/core'
const [saving, setSaving] = useState(false)
const save = async () => {
setSaving(true)
try {
await saveData()
} finally {
setSaving(false)
}
}
<LoadingButton loading={saving} loadingText="Saving…" onPress={save}>
Save
</LoadingButton>Examples
Basic
Normal and loading.Preview
Code
Loading text
Say what is happening while the action runs.Preview
Code
Custom spinner
Preview
Code
Spinner position
The spinner replaces the icon on its side: the leading icon on the left, `iconAfter` on the right.Preview
Code
Async operation
The parent sets `loading` around the request. Press it several times: presses while saving are ignored.Preview
Code
Not saved yet.
API reference
LoadingButton
Takes every Button prop (`variant`, `size`, `icon`, `iconAfter`, `fullWidth`, `disabled`, `onPress`, `theme`, style props…). Your app owns `loading`; the button only shows it and blocks presses.| Prop | Type | Default | Description |
|---|---|---|---|
loading | boolean | false | Shows the spinner, sets `aria-busy` and ignores presses, clicks and keys. When false it is a plain Button. |
loadingText | ReactNode | — | Replaces the label while loading, e.g. "Saving…". Without it the label stays next to the spinner. |
spinner | ReactNode | `<Spinner size="sm" />` in the label color | A custom indicator element. Icons take the button’s icon size and color. |
spinnerPosition | 'left' | 'right' | 'left' | Side of the spinner. It takes the place of the icon on that side. With only `iconAfter`, it defaults to `'right'`. |
disabled | boolean | false | Works as on Button. While loading the button is disabled either way. |
Accessibility
- It is a Button: a native
<button>on web and abuttonrole on iOS and Android, named by its visible label. - While loading it is disabled and has
aria-busy="true", so screen readers report it as busy and unavailable, and Enter, Space, clicks and taps do nothing. - The spinner is hidden from assistive technology so it does not change the button’s name. The name is the label, or
loadingTextwhile loading: useloadingTextwhen the change should be heard. - Like any disabled
<button>, it loses keyboard focus while loading on web. Announce the result (for example in a polite live region, as in the Async example) when the action finishes.
| Key | Action |
|---|---|
| Enter / Space | Activates the button; ignored while loading. |
| Tab | Moves focus; a loading button is skipped. |
Responsive behavior
Height, padding and radius come from size, so they do not change while loading. A longer loadingText widens the button; keep it about as long as the label.
Platform notes
Web
Uses the browser spinner SVG from Spinner.
iOS
The default spinner is the platform ActivityIndicator.
Android
Same as iOS; the ripple is off while loading.