Button v0.1.0 Forms

Action button with variants, sizes, and a loading state that preserves width and sets aria-busy.

import { Button } from "latticeui-react";

Examples

Variants

Four visual variants cover most intents; danger is reserved for destructive actions.

Show code
<Button>Solid</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="danger">Danger</Button>

Sizes

Show code
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>

Loading state

loading disables the button and swaps in a spinner while preserving width.

Show code
const [loading, setLoading] = useState(false);

<Button
  loading={loading}
  onClick={() => {
    setLoading(true);
    setTimeout(() => setLoading(false), 1500);
  }}
>
  {loading ? "Saving..." : "Save changes"}
</Button>

Anatomy

These data-part attributes are a versioned public API - style and test against them; they will not change in a minor release.

PartElementStable selector
rootbutton[data-scope="button"][data-part="root"]
spinneronly while loadingspan[data-scope="button"][data-part="spinner"]
labelspan[data-scope="button"][data-part="label"]

Props

PropTypeDefaultDescription
variant"solid" | "outline" | "ghost" | "danger""solid"
size"sm" | "md" | "lg""md"
loadingbooleanfalseShows spinner, disables interaction, sets aria-busy.
...restReact.ButtonHTMLAttributes<HTMLButtonElement>

Accessibility

Roles: button (native)

KeyAction
Enter / Spaceactivates

Styling

Override styles by targeting the stable selectors below from any unlayered CSS - it always beats the library's @layer latticeui styles, no !important needed.

[data-scope="button"][data-part="root"] {
  /* your overrides */
}

Component tokens: --button-bg--button-fg--button-border--button-bg-hover

State attributes: data-variantdata-sizedata-loading