Button
The action a person takes on a view.
Overview
An action that changes something in place: save, cancel, delete, retry.
One primary
import { Button, ButtonGroup } from "@hackcove/ui";
<ButtonGroup>
<Button>Save</Button>
<Button variant="outline">Cancel</Button>
</ButtonGroup>import { Button, ButtonGroup } from "@hackcove/ui";
<ButtonGroup>
<Button>Save</Button>
<Button>Save and close</Button>
</ButtonGroup>Disabled reason
import { Button } from "@hackcove/ui";
<Button disabledReason="Pick a shop first">Save</Button>
disabledReason greys the button and shows the reason on hover.import { Button } from "@hackcove/ui";
<Button disabled>Save</Button>
disabled leaves the user guessing why nothing happens.Navigate
import { ButtonLink } from "@hackcove/ui";
<ButtonLink href="#quotes" variant="outline">
Open quotes
</ButtonLink>ButtonLink keeps the anchor, middle-click and the URL.import { Button } from "@hackcove/ui";
<Button variant="outline" onClick={() => location.assign("#quotes")}>
Open quotes
</Button>location loses middle-click, the status-bar URL and crawlability.Destructive
import { Button, ButtonGroup } from "@hackcove/ui";
<ButtonGroup>
<Button tone="danger">Delete quote</Button>
<Button variant="outline">Cancel</Button>
</ButtonGroup>tone="danger", so the red says what the button does before it is read.import { Button, ButtonGroup } from "@hackcove/ui";
<ButtonGroup>
<Button>Delete quote</Button>
<Button variant="outline">Cancel</Button>
</ButtonGroup>Row
import { Button, ButtonGroup, ButtonLink } from "@hackcove/ui";
<ButtonGroup
label="Quote actions"
end={
<ButtonLink href="#quotes" variant="ghost">
Back
</ButtonLink>
}
>
<Button>Save</Button>
<Button variant="outline">Preview</Button>
</ButtonGroup>ButtonGroup spaces and wraps its buttons, and end pushes one item to the far side.import { Button, ButtonLink } from "@hackcove/ui";
<div>
<Button>Save</Button>
<Button variant="outline">Preview</Button>
<ButtonLink href="#quotes" variant="ghost">
Back
</ButtonLink>
</div>Usage
- Put one primary Button in a view. The other actions use
variant="outline","ghost"or"link";variant="dashed"is the full-width "add another" row at the foot of a list. - Group the actions in a
ButtonGroup, so the row spaces and wraps the same everywhere;endpushes one item, such as a Back link, to the far side, andlabelnames the group. - Say why a button cannot be pressed with
disabledReason; usebusywhile the work is in flight. - Going to another page is a
ButtonLink, not a Button. - A destructive action is
tone="danger", an accept istone="positive";size="sm"is for a button inside a row or a card header. pressedmakes a toggle;busyLabelreplaces the label whilebusy.- An icon-only action is an
IconButton, not a Button holding a glyph.
Accessibility
- A Button is a native
<button>and defaults totype="button", so it never submits a form by accident. disabledReasondisables the button and sets the reason as itstitle, so a pointer user sees why.busysetsaria-busyand disables the button until the work is done.- Every Button has a focus ring from the component, so the keyboard focus is always visible.
API
Button
A button in the primary, outline, ghost, link or dashed style (the link has no box: text with an underline on hover, for an in-line action; dashed is the full-width "add" row, a dashed outline with muted text that fills its container, with an optional leading icon in the children). size="sm" is compact; tone="positive" is green and tone="danger" is red; pressed makes it a toggle with a selected look. Defaults to type="button". disabledReason and busy are the two disabled states that say more than a plain disabled, which keeps its half-opacity look.
busyThe work is in flight: disabled, aria-busy, keeps its colour. Wins over disabledReason.
- Type
boolean- Default
false
busyLabelThe label while busy, in place of the children.
- Type
string
disabledReasonWhy the button cannot be pressed: disables it, sets it as the title, and greys it flat.
- Type
string
pressedA toggle: sets aria-pressed, and when true draws the selected look (the tone's border and
tint) on the outline and ghost variants. Left out, the button is not a toggle and has no
aria-pressed.
- Type
boolean
sizesm is compact, for table rows and toolbars.
- Type
"sm" | "md"- Default
md
tonepositive is green, for accept and approve; danger is red, for delete and clear. Not for
dashed, which has the one look.
- Type
"default" | "positive" | "danger"- Default
default
variant- Type
"link" | "primary" | "outline" | "ghost" | "dashed"- Default
primary
ButtonLink
A link that looks like a Button. A plain <a href> by default; with render it draws the app's own router <Link> instead (render={(p) => <Link to="/quotes" {...p} />}), already carrying the button classes. variant, size and tone are the Button's.
externalOpens in a new tab: adds target="_blank" and rel="noreferrer".
- Type
boolean- Default
false
href- Type
string
render- Type
LinkRender
sizesm is compact, for table rows and toolbars.
- Type
"sm" | "md"- Default
md
tonepositive is green, for accept and approve; danger is red, for delete and clear. Not for
dashed, which has the one look.
- Type
"default" | "positive" | "danger"- Default
default
variant- Type
"link" | "primary" | "outline" | "ghost" | "dashed"- Default
primary
ButtonGroup
A wrapping row of buttons with one optional item pushed to the far end (a Back link, say). On a narrow viewport the row wraps and end stays at the end of the last line. label makes it a named role="group". Directly in a Card footer it spans the footer, so end reaches the far edge.
endOne item, pushed to the end of the row.
- Type
ReactNode
labelThe accessible name of the group: sets role="group" and aria-label.
- Type
string
Functions
buttonClassThe Button's look as a class string, for a router link that has to look like a Button whenButtonLink'srendercannot draw it.