Button
When to use
Section titled “When to use”- Submitting a form, saving or deleting
- Opening a Dialog, a Menu or a Popover
- Any action that changes something on this page
Not to go to another page — use a Link, so it can be opened in a new tab and is announced as a link.
Choosing between actions and navigation:
| Component | Use it for | For example |
|---|---|---|
| Button | Does something on this page: saves, deletes, opens a dialog | “Save”, “Delete”, “Add to cart” |
| Link | Goes somewhere: another page, a section, a file | “View invoice”, “Read the docs” |
| Toggle | Turns a state on or off and stays pressed | “Bold”, “Mute” |
Choosing between rows of controls:
| Component | Use it for | For example |
|---|---|---|
| Toolbar | Several controls acting on one thing, reached with one Tab stop and the arrow keys | An editor’s formatting bar |
| ToggleGroup | A set of Toggles sharing one value | Text alignment, bold / italic / underline |
| Buttons in a row | A few independent actions, each its own Tab stop | Cancel / Save at the end of a form |
import { Button } from '@arun-dev/ui';
export default function ButtonVariants() { return ( <> <Button>Ghost</Button> <Button variant="primary">Primary</Button> <Button variant="danger">Delete</Button> <Button variant="danger-ghost">Delete</Button> <Button disabled>Disabled</Button> </> );}Choosing a variant:
| Variant | Use it for | For example |
|---|---|---|
primary | The one main action of a form or dialog | “Save”, “Create account” |
ghost | Every other action | “Cancel”, “Edit” |
danger | The last step of deleting, which cannot be undone | “Delete” in the confirmation Dialog |
danger-ghost | Starting a deletion, before a confirmation asks | “Delete” in a form footer or on a row |
Pending
Section titled “Pending”While a save is in flight, set pending. The button is disabled — a second press, or Enter in a
field, cannot submit again — and a Spinner turns over the label, which keeps its place so the
button does not change width. Clear it when the request settles, whether it succeeded or failed.
import { useState } from 'react';import { Button } from '@arun-dev/ui';
// A save that takes a moment, as an API call does: pending from the submit until it settles.export default function ButtonPending() { const [pending, setPending] = useState(false); return ( <form onSubmit={(event) => { event.preventDefault(); setPending(true); setTimeout(() => setPending(false), 2000); }} > <Button type="submit" variant="primary" pending={pending}> Save changes </Button> </form> );}With react-hook-form, pass formState.isSubmitting: <Button type="submit" pending={isSubmitting}>.
Playground
Section titled “Playground”<Button variant="ghost">Click me</Button>| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'ghost' | 'primary' | 'danger' | 'danger-ghost' | 'ghost' | Visual weight. primary is the filled call to action; danger and danger-ghost delete or discard. |
type | 'button' | 'submit' | 'reset' | 'button' | Defaults to button so it never submits a form by accident. |
disabled | boolean | false | Prevents activation, using the platform rather than synthesising it. |
pending | boolean | false | Busy with the action it started. Disabled while it lasts, with a Spinner over the label. |
className | string | Concatenated with the component's own classes, never replacing them. | |
render | ReactElement | Element or component to render instead of the default. Props, className, event handlers and ref are merged onto it. | |
ref | Ref<HTMLElement> | Ref to the rendered element. Merged with any ref on the render element. | |
…rest | HTMLAttributes | Anything else is spread onto the rendered element, so id, aria-*, data-* and event handlers all reach the DOM. |
- A bare
Buttonrenders<button type="button">— the explicit type means it never submits a form by accident. typeis not forwarded to a component supplied throughrender— pass it on the element there.Buttondoes not navigate. A link is a separateLinkcomponent.pendingdisables the button natively, so focus leaves it and assistive technology skips it while it lasts. Announce the outcome — a Toast saying “Saved”, or the error — rather than the wait.