0.1.0-rc.2

Button

Buttons trigger actions in the interface. Choose a variant that reflects importance, and write labels that describe the outcome, not the control type.

Try it

Usage

Import RuiButton from the focused module. The default filled variant suits the primary action in a small context.

import { RuiButton } from '@ecopages/radiant-ui/button';
 
<RuiButton variant="filled" size="md">
	Save changes
</RuiButton>

Choose a tone

Use filled for the main action, outline for a supporting action, and ghost when the action should recede until needed. link looks like inline navigation copy and underlines on hover and focus; pair it with size="none" in running text. destructive is for irreversible operations.

Pass href when the control should navigate; variant only changes appearance.



Theming

Button variants map to semantic action roles from the active theme, not Tailwind palette steps (blue-500, red-500, …):

variantSemantic roleTypical utilities on .rui-button--*
filledprimarybg-primary, text-on-primary
outlinesurface + borderbg-transparent, text-on-background, border-border
ghostsurface-containerbg-transparent, text-on-surface, hover bg-surface-container-low
destructiveerror (destructive)bg-error, text-on-error
linklinktext-link, underline on hover/focus

Pressed (toggle) states keep the same role family with a stronger fill (bg-primary-dark, bg-error-dark) and a focus ring. Brand color packs remap all roles for light and dark mode.

Override at the theme layer (tokens/presets/colors/*.css), not in component CSS. destructive reuses the error status family, matching alerts and toasts.

Accessibility

  • Write labels that describe the resulting action, such as "Save changes".
  • Keep disabled buttons explainable with nearby supporting text when needed.
  • Do not use color as the only way to communicate action priority or status.
  • Set aria-label when a button has no visible text (icon-only buttons).
  • Toggle buttons set aria-pressed when toggle / pressed are used.

API

RuiButton is a presentational JSX view over a native <button> or <a>, no custom element. RuiButtonProps is a union: pass href to render a link, otherwise a button.

Shared props

PropTypeDefaultDescription
variantfilled · outline · destructive · ghost · linkfilledVisual tone.
sizenone · sm · md · lgmdControl size; none for inline link chrome.
aria-labelstringAccessible name when there is no visible text.

Button branch props

PropTypeDefaultDescription
typebutton · submit · resetbuttonNative button type.
disabledbooleanfalseDisabled state.
pressedbooleanControlled aria-pressed (toggle buttons).
defaultPressedbooleanfalseInitial pressed state for uncontrolled toggles.
togglebooleanfalseToggle aria-pressed on click when pressed is uncontrolled.

Link branch props

PropTypeDefaultDescription
hrefstringDestination; renders <a> instead of <button>.
target_self · _blank · _parent · _topLink target.
relstringLink relationship.
downloadboolean | stringNative download attribute.
aria-currentstringCurrent-page indicator for nav links.

CSS classes

Public BEM classes on the rendered element (documented via @cssclass on RuiButton):

ClassDescription
.rui-buttonButton / button-styled link root.
.rui-button--filledPrimary filled action.
.rui-button--outlineBordered secondary action.
.rui-button--destructiveDestructive action.
.rui-button--ghostSubtle, borderless action.
.rui-button--linkInline link-styled action.
.rui-button--noneNo fixed size (inline link chrome).
.rui-button--sm · .rui-button--md · .rui-button--lgControl sizes.

Theme roles (per variant)

VariantCSS variables consumed
filled--primary, --on-primary, --primary-dark
outline--on-background, --border, --surface
ghost--on-surface, --surface-container-low, --surface-container
destructive--error, --on-error, --error-dark
link--link