<!-- Generated by tools/docs.php from docs/src/busy.html - edit the source, not this file. -->

# Busy

`REDZ.ui.busy(element, promise)` marks a button or a region busy until the promise settles: a button shows a spinner and ignores clicks, a region turns inert under an overlay.

## Examples

A region - a card, its body, a dialog's or a drawer's body, any `region` - keeps its old content under a dimmed overlay while the new comes. The overlay shows only after 400 ms, so a quick answer does not flash; once shown it stays at least 400 ms. A focus the region dropped comes back to the same element, to the element with its id in the new content, or to the region.

```html
<section class="card" id="busy-region-card" aria-labelledby="busy-region-title">
	<div class="card-header"><h2 id="busy-region-title">Bookings this week</h2><button class="btn btn-sm ms-auto" type="button" data-docs-run="busy-region" aria-controls="busy-region-card"><i class="bi bi-arrow-repeat" aria-hidden="true"></i>Reload for 2 seconds</button></div>
	<div class="card-body vstack gap-8">
		<p class="fs-24 fw-600 tabular-nums">128</p>
		<p class="text-muted">bookings, 312,400 THB</p>
	</div>
</section>
```

```js
await REDZ.ui.busy(card, fetch(url).then((answer) => answer.text()).then((html) => { body.innerHTML = html; }));
```

### A button

The button keeps its focus, ignores clicks until the promise settles and shows a spinner: in place of its leading icon, or over its words when it has none - then it keeps its size too. `data-busy` on the button gives the words it shows while it waits, said politely once the wait passes 400 ms; set it again before each call when the wait has steps.

```html
<button class="btn btn-primary" type="button" data-docs-run="busy-button">Save for 2 seconds</button>
<button class="btn btn-primary" type="button" data-busy="Signing in…" data-docs-run="busy-button"><i class="bi bi-box-arrow-in-right" aria-hidden="true"></i>Sign in for 2 seconds</button>
```

A button that starts a [cooldown](btn.md#btn-cooldown) while it waits - "Send the code again" with `data-cooldown` set as the code goes - stays disabled until the count ends: the cooldown holds `aria-disabled` while it counts, `busy()` leaves it alone, and the state from before both comes back when the last of them ends.

## States

What `busy()` sets, written by hand - the overlay appears 400 ms after the page draws it.

## Accessibility

- Screen readers mostly ignore `aria-busy`, and on a live region it breaks the region in some of them: here it is a styling hook, and `busy()` refuses a live region in the console.
- The region is `inert` while busy: no focus, no clicks, out of the accessibility tree. When the overlay shows, one polite message says so - the page's text `busy`, “Loading…”.
- For a first load, where there is nothing to cover yet, use [placeholders](placeholder.md).

## Tokens

From [`css/components/busy.css`](https://github.com/redz-tech/REDZ.UI/blob/main/css/components/busy.css), which declares no custom property of its own.

It reads the theme's `--redz-bg`, `--redz-primary`.
