--- title: Button description: Buttons trigger actions in the interface. Choose a variant that reflects importance. category: Actions --- import { meta as ButtonMeta, Default, Destructive, Ghost, Link } from '@/content/stories/button'; import Canvas from '@/components/component-docs/canvas'; import Demo from '@/components/component-docs/demo'; export const config = { dependencies: { components: [Canvas, Demo], scripts: [ '../../components/component-docs/demo.script.tsx', '../../components/component-docs/canvas.script.tsx', '../../components/component-docs/controls.script.tsx', ], }, }; # 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. ```tsx import { RuiButton } from '@ecopages/radiant-ui/button'; Save changes ``` ## 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. Use the `square` modifier for an icon-only action. It keeps the selected control size on both axes; provide an `aria-label` because it has no visible text. ```tsx ```

## Theming Button variants map to **semantic action roles** from the active theme, not Tailwind palette steps (`blue-500`, `red-500`, …): | `variant` | Semantic role | Typical utilities on `.rui-button--*` | | --- | --- | --- | | `filled` | `primary` | `bg-primary`, `text-on-primary` | | `outline` | surface + `border` | `bg-transparent`, `text-on-background`, `border-border` | | `ghost` | surface-container | `bg-transparent`, `text-on-surface`, hover `bg-surface-container-low` | | `destructive` | `error` (destructive) | `bg-error`, `text-on-error` | | `link` | `link` | `text-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 `