SwitchForm
A Switch that saves itself: optimistic with JavaScript, a plain form POST without.
Examples
Row switch
The thumb flips at once and a spinner shows while the request is in flight; clicks are ignored until it answers. An error flips it back and shows a toast.
<SwitchForm
action={routes.dashboard.servers.toggle.href({ id })}
name="enabled"
checked={server.enabled === 1}
fields={{ return_to: serversHref }}
aria-label={`Route ${server.display_name}`}
subject={server.display_name}
/>Usage
import { SwitchForm } from '@switchboard/ui'
// The action answers JSON to Accept: application/json: { checked } (2xx) or { message } (error).
// Without JavaScript the same form posts and the action redirects (to return_to).
<SwitchForm action={toggleHref} name="enabled" checked={on} fields={{ return_to: listHref }} aria-label="Route Linear" />Props
Every component also takes mix, for css() and mixins applied after its own style.
SwitchForm
| Prop | Type | Default | Description |
|---|---|---|---|
| action* | string | – | Where the form posts. |
| name* | string | – | Field name. Posts "off", then "on" when on. |
| checked* | boolean | – | Server state. Adopted when it changes and nothing is in flight. |
| fields | Record<string, string> | – | Hidden fields, e.g. { return_to } for the no-JS redirect. |
| label | string | – | Inline label. |
| aria-label | string | – | Name when there is no label. |
| size | 'sm' | 'md' | 'sm' | Switch size. |
| subject | string | – | Named in the error toast: "Couldn't switch off Linear". |
| submitLabel | string | 'Save' | The button shown only without JavaScript. |
Accessibility
- In flight the input is read-only, not disabled, so focus stays on it; the label gets aria-busy.
- Errors are announced by the toast region, since focus stays on the switch.
- Without JavaScript a Save button appears (noscript) and the form posts normally.
Guidance
Do
- Use for reversible, predictable settings.
- Answer the JSON request without a redirect or flash.
Don’t
- Use for destructive changes; use a ConfirmDialog.
- Navigate after the toggle; the page reloads its data quietly.