Functional Weave
Code in Python

react.form.button@1.0.1

README.md

3,159 bytes · view raw

# react.form.button

The GOV.UK Design System button as a React component: a `<button>` that
submits its form unless told otherwise, in three styles, with a loading state
that stops a double submission without taking the button away from keyboard
and screen reader users.

```tsx
"use client";
import { Button } from "#fune/react.form.button@^1";

<Button>Save and continue</Button>
<Button variant="secondary" type="button" onClick={findAddress}>Find address</Button>
<Button variant="warning" name="action" value="delete">Delete account</Button>
<Button loading={saving} loadingText="Saving">Save and continue</Button>
```

- **variant**: `primary` (the default, the page's main action), `secondary`
  (other actions) or `warning`, GOV.UK's red button for an action that
  destroys something. Other kits call that "danger"; it is `warning` here, as
  in GOV.UK, and `danger` is not accepted. GOV.UK asks for one primary button
  per page and very few warning buttons.
- **type** is `submit` unless you say `button` or `reset`. It is always
  written out, so a button inside a form never submits it by surprise.
- **name** and **value** are sent with the form when this button submits it,
  for a form with more than one submit button ("Save" and "Add another").
  React writes `value` before `name` in its HTML; the browser does not care.
- **disabled** is the real attribute plus `aria-disabled="true"`, as GOV.UK
  renders it. GOV.UK advises against disabled buttons: they have poor
  contrast and give no reason.
- **loading** is this component's answer to GOV.UK's "Stop users from
  accidentally sending information more than once". GOV.UK ignores a second
  click within a second (`data-prevent-double-click`); here the app says when
  the work is under way. The button stays enabled, so it keeps focus and is
  still announced, but carries `aria-disabled="true"` and
  `fune-button--loading`, and a press does nothing: `onClick` is not called
  and the event's default (submitting the form) is prevented. `loadingText`
  replaces the children meanwhile.
- **onClick** is called with no arguments, never the event. A disabled button
  never fires it.
- **id** is rendered only when you give one: nothing refers to a button by
  id, so unlike the fields it does not fall back to `useId()`.

It listens for clicks, so it is a client component (`"use client"`). What a
press does cannot be rendered on a server; the vectors pin the markup of every
state, and the rule for a press (ignored while `loading`) is the four lines in
`press`.

Classes: `fune-button`, `fune-button--secondary`, `fune-button--warning`,
`fune-button--loading`.

Sources: GOV.UK Design System, "Button"
https://design-system.service.gov.uk/components/button/ (default, secondary,
warning and disabled buttons, and "Stop users from accidentally sending
information more than once").

## Notices

Portions derived from GOV.UK Frontend (https://github.com/alphagov/govuk-frontend), Copyright (c) 2017 Crown Copyright (Government Digital Service), under the MIT License; the full notice is in NOTICE.

1.0.1 adds its attribution notices (NOTICE). The code and the tests are unchanged.