FSAI Design System
Components

Button

Triggers an action or navigates to a new page.

Overview

Buttons communicate actions users can take. Use primary for the main action, secondary for alternatives, and destructive for irreversible actions. The Button component supports both button and link roles.

Variants

Six visual variants are available:

VariantUsage
primaryMain call-to-action (dark background, white text)
secondaryAlternative actions (outlined, subtle background)
secondary-altAlternative with subtle fill instead of border
ghostText-only, minimal footprint
destructiveIrreversible or dangerous actions (red tinted)
linkInline link-style button (brand color)
import { Button } from '@fsai/shared-ui';

<Button role="button" variant="primary">Submit</Button>
<Button role="button" variant="secondary">Cancel</Button>
<Button role="button" variant="secondary-alt">Alternative</Button>
<Button role="button" variant="ghost">Ghost</Button>
<Button role="button" variant="destructive">Delete</Button>
<Button role="button" variant="link">Learn more</Button>

Sizes

Four sizes are available. Default is md.

SizeHeightUsage
lg48pxHero sections, prominent CTAs
md36pxStandard actions (default)
sm32pxCompact toolbars, table rows
xs28pxInline actions, tight spaces
<Button role="button" size="lg">Large</Button>
<Button role="button" size="md">Medium</Button>
<Button role="button" size="sm">Small</Button>
<Button role="button" size="xs">Extra Small</Button>

With Icons

Use leftAdornment or rightAdornment to add icons from @fsai/icons:

<Button role="button" leftAdornment="Plus">Add Item</Button>
<Button role="button" rightAdornment="ChevronRightSmall">Next</Button>

Loading State

Set isLoading to show a spinner and disable interaction:

<Button role="button" isLoading>Saving...</Button>

Use role="link" to render as a navigation link (uses react-router-dom Link):

<Button role="link" href="/settings">Go to Settings</Button>
<Button role="link" href="https://example.com" external>External Link</Button>

Props

PropTypeDefaultDescription
variant'primary' | 'secondary' | 'secondary-alt' | 'ghost' | 'destructive' | 'link''primary'Visual style
size'lg' | 'md' | 'sm' | 'xs''md'Size of the button
role'button' | 'link'Required. Determines behavior
isLoadingbooleanfalseShows spinner, disables interaction
isActivebooleanfalseShows active/pressed visual state
leftAdornmentIconNameIcon before the label
rightAdornmentIconNameIcon after the label
disabledbooleanfalseDisables the button (button role only)
onClick(event: MouseEvent) => voidClick handler (button role only)
hrefstringNavigation target (link role only)
externalbooleanfalseOpens in new tab (link role only)

Guidelines

  • Do use a single primary button per section for the main action
  • Do use descriptive labels ("Save changes" not "OK")
  • Do use isLoading during async operations to prevent double-clicks
  • Don't use destructive variant for non-destructive actions
  • Don't disable buttons without explaining why (use a Tooltip)
  • Don't use the ghost variant for primary actions — it's too subtle

On this page