Button

Buttons trigger actions. Use the primary style for the main action, others for lower-emphasis actions.

Overview

The Button component is the primary interactive element for triggering actions. It supports multiple variants for different emphasis levels, five sizes, icons, loading states, and accessibility features out of the box.

tsx
import { Button } from "@rogo-technologies/ui/button"

<Button variant="brand" size="md">Click me</Button>

Variants

Use the variant prop to change button emphasis. The default variant is brand.

VariantPurpose
brandPrimary actions—the main call to action on a page or section.
outlineSecondary actions—bordered style with subtle background.
mutedSecondary actions—subtle filled background, lower emphasis than outline.
ghostTertiary actions—transparent background, appears on hover.
destructiveDangerous actions—delete, remove, or irreversible operations.
textMinimal styling—inline actions without visual weight.
linkLink-style—underlines on hover, for navigation-like actions.
tsx
// Primary action
<Button variant="brand">Save changes</Button>

// Secondary actions
<Button variant="outline">Cancel</Button>
<Button variant="muted">Edit</Button>

// Tertiary action
<Button variant="ghost">More options</Button>

// Dangerous action
<Button variant="destructive">Delete</Button>

// Minimal actions
<Button variant="text">Learn more</Button>
<Button variant="link">View documentation</Button>

Sizes

Use the size prop to control button dimensions. The default size is md.

SizeHeightUse Case
xxs20px (h-5)Compact UI, tags, tight spaces
xs24px (h-6)Secondary actions in dense layouts
sm28px (h-7)Toolbars, inline actions
md32px (h-8)Default—most buttons in the interface
lg36px (h-9)Primary CTAs, hero sections
tsx
// Compact button for tight spaces
<Button size="xxs">Tag</Button>

// Default size for most use cases
<Button size="md">Submit</Button>

// Large button for primary CTAs
<Button size="lg">Get started</Button>

With Icons

Use prefix to add an icon before the label or suffix to add one after. Icons automatically scale to match the button size.

tsx
import { IconPlus, IconArrowRight } from "@rogo-technologies/ui/icons"

// Icon before label (common for "Add" actions)
<Button prefix={<IconPlus />}>Add item</Button>

// Icon after label (common for "Next" actions)
<Button suffix={<IconArrowRight />}>Continue</Button>

// Both icons (use sparingly)
<Button prefix={<IconPlus />} suffix={<IconArrowRight />}>
  Add and continue
</Button>

Loading

Use the loading prop to show a spinner and disable interaction during async operations. The button remains the same width to prevent layout shift.

tsx
const [isLoading, setIsLoading] = useState(false)

async function handleSubmit() {
  setIsLoading(true)
  await saveData()
  setIsLoading(false)
}

<Button loading={isLoading} onClick={handleSubmit}>
  Save changes
</Button>

When loading is true:

  • A spinner replaces the prefix icon
  • The button becomes disabled
  • aria-busy is set for screen readers

Disabled

Use the disabled prop to prevent interaction when the action is unavailable.

tsx
// Disable until form is valid
<Button disabled={!isFormValid}>Submit</Button>

// Disable during loading (automatic when loading={true})
<Button disabled={isLoading}>Save</Button>

Icon Only

Use the iconOnly prop to create square buttons containing only an icon. The button becomes a perfect square based on the size. Always provide an aria-label for accessibility.

SizeDimensions
xxs20×20px
xs24×24px
sm28×28px
md32×32px
lg36×36px
tsx
// Icon-only button with accessibility label
<Button iconOnly aria-label="Open settings">
  <IconSettingsGear3 />
</Button>

// Different variants work with iconOnly
<Button variant="ghost" iconOnly aria-label="More options">
  <IconMoreHorizontal />
</Button>

Rounded

Use the rounded prop to create pill-shaped buttons with fully rounded corners. Works with all sizes and variants.

tsx
// Pill-shaped button
<Button rounded>Subscribe</Button>

// Rounded icon-only button (circular)
<Button rounded iconOnly aria-label="Add">
  <IconPlus />
</Button>

As Link

Use the render prop to render the button as a different element, such as a Next.js Link for navigation.

tsx
import Link from "next/link"

// Render as Next.js Link
<Button render={<Link href="/dashboard" />}>
  Go to Dashboard
</Button>

// With an anchor tag
<Button render={<a href="https://example.com" target="_blank" />}>
  External Link
</Button>

Props

PropTypeDefaultDescription
variant"brand" | "outline" | "muted" | "ghost" | "destructive" | "text" | "link""brand"Visual style of the button.
size"xxs" | "xs" | "sm" | "md" | "lg""md"Size of the button.
iconOnlybooleanfalseRenders a square button for icon-only use.
roundedbooleanfalseApplies fully rounded corners (pill shape).
prefixReactNodeElement to render before the label.
suffixReactNodeElement to render after the label.
loadingbooleanfalseShows a spinner and disables the button.
disabledbooleanfalseDisables the button.
renderReactElementRenders as a different element (e.g., Link).

Additionally, the Button accepts all standard HTML button attributes.

Usage Guidelines

Do

  • Use brand for the primary action on a page or in a modal
  • Use outline or muted for secondary actions alongside a primary button
  • Use ghost for tertiary or contextual actions (e.g., in toolbars)
  • Use destructive only for irreversible or dangerous actions
  • Provide aria-label for icon-only buttons
  • Use loading state for async operations to provide feedback
  • Keep button labels concise and action-oriented ("Save", "Delete", "Continue")

Don't

  • Don't use multiple brand buttons in the same context—there should be one clear primary action
  • Don't use destructive for non-dangerous actions just for visual emphasis
  • Don't disable buttons without explaining why (consider a tooltip or helper text)
  • Don't use icon-only buttons without aria-label—they're inaccessible to screen readers
  • Don't mix too many button variants in one area—it creates visual noise
  • Don't use text or link variants for important actions—they lack visual prominence
PreviousAvatar
© 2026 Rogo Technologies Inc.