RRezi UI

Button

Pill-shaped button with gradient emphasis variants, a loading state and asChild support.

Installation

npx shadcn@latest add @reziui/button

Installs the theme tokens too if they are missing. Run npx shadcn@latest add @reziui/theme first to apply the full Rezi UI palette — see Installation.

Usage

app/page.tsx
import { Button } from "@/components/ui/button";

export function Example() {
  return <Button>Save changes</Button>;
}

Examples

Variants

VariantUse for
defaultThe primary action on a screen. Blue gradient, white label.
secondaryMost other actions. Surface fill with a 1px ring.
outlineActions on tinted or busy backgrounds. Transparent fill.
ghostLow-emphasis actions in toolbars and menus.
destructiveIrreversible actions such as delete. Red gradient.
destructive-secondaryLess prominent destructive actions. Red label on a surface.
linkInline navigation styled as text.

Sizes

SizeHeightNotes
xs20pxDense tables and tags.
sm26pxCompact toolbars.
default36pxStandard forms and dialogs.
lg40pxHero and page-level calls to action.
icon-xs · icon-sm · icon · icon-lg20 · 26 · 36 · 40pxIcon-only, always circular.

Icon-only buttons have no visible text — always pass aria-label.

Loading

loading disables the button, sets aria-busy and shows a spinner before the label. With asChild, no spinner is injected (Slot needs exactly one child); only aria-busy and data-loading are set, so style the loading state yourself.

Success

Pass success (controlled) to cross-fade the label to a check and successLabel ("Saved" by default) after an async action, then reset it yourself. The button always hugs what it shows: while loading it shrinks to an icon-only circle with the spinner, then grows to fit the success label (200ms; instant under reduced motion). The button keeps its name while loading and the success label is announced to screen readers.

Keep the button's container from depending on its width (e.g. not centered among siblings that would shift), since it changes size during the morph.

code
<Button asChild variant="secondary">
  <a href="/pricing">See pricing</a>
</Button>

API reference

PropTypeDefault
variant"default" | "secondary" | "outline" | "ghost" | "destructive" | "destructive-secondary" | "link""default"
size"xs" | "sm" | "default" | "lg" | "icon-xs" | "icon-sm" | "icon" | "icon-lg""default"
loadingbooleanfalse
asChildbooleanfalse
staticbooleanfalse
successboolean—
successLabelReactNode"Saved"

All native <button> props are forwarded.

Buttons scale to 96% while pressed; static turns that off where movement would distract. Both the press scale and the loading spinner stay still under prefers-reduced-motion — the label and aria-busy still carry the state.