Example 06 · Async button addon

Give a rejected request a clear retry.

A reporting form owns its simulated request lifecycle. When the server rejects the first attempt, the addon passes the first form error to an existing async-button-style instance.

SaaS control room

Keep request state and error recovery aligned.

The first attempt fails locally; the retry succeeds. No request leaves the browser.

Try it

  1. Submit the report and notice the pending state.
  2. Read the rejected response and the button's retry state.
  3. Try again to reach success.
  4. Reset and repeat with Tab and Space.
addon.async-buttonapplication-owned request

Generate accessibility report

The request is simulated. The first attempt is rejected and the second succeeds.

Ready to submit.

Implementation

Let each layer own one job.

Developer notes

  • The root selector is #async-button-demo; the bridge also recognizes its data attribute.
  • Import createAsyncButtonAddon from ../../dist/addons/async-button.js.
  • Pass an existing instance with error() and reset() methods.
  • useFirstFormError supplies the rejection text; resetOnClear restores the idle state.
  • The application still owns pending, retry timing, success, and the package CSS import.

Accessibility notes

  • Native buttons keep standard keyboard behavior and visible focus.
  • The pending button is disabled to prevent duplicate activation.
  • One polite status announces application-owned progress and success.
  • The focused bridge error region communicates rejection, so the live status is cleared instead of repeating it.
  • Persistent state text remains available through the button's description.
  • The demo adds no motion; shared styles cover reduced motion and forced colors.
  • The local object demonstrates the addon contract, not the complete optional peer.

Copy path

How to use it.

  1. Create the async-button instance for your form's submit button.
  2. Pass it to the bridge addon and choose the rejection message source.
  3. Keep pending and success state in your submit handler; the addon handles rejected bridge responses.

HTML

<link rel="stylesheet" href="../../dist/styles.css">

<form id="report-form" data-a11y-server-error-bridge>
  <div data-a11y-server-error-bridge-form-errors></div>
  <label for="report-url">Page URL</label>
  <input id="report-url" name="url" type="url">
  <button type="submit">Generate report</button>
</form>

JavaScript

import { createServerErrorBridge } from "../../dist/index.js";
import { createAsyncButtonAddon } from
  "../../dist/addons/async-button.js";
import { createAsyncButton } from "a11y-async-button";

const form = document.querySelector("#report-form");
const asyncButton = createAsyncButton(
  form.querySelector("[type='submit']")
);
const bridge = createServerErrorBridge(form, {
  addons: [createAsyncButtonAddon({
    instance: asyncButton,
    useFirstFormError: true,
    resetOnClear: true
  })]
});