Logo

Button

Action primitives with variants, loading, icon support, and sizing options.

Preview

Usage

TS

import { FrButtonModule } from '@frame-ui-ng/components/button';
import { FrSpinnerModule } from '@frame-ui-ng/components/spinner';

HTML

<button frButton type="button">
  <span frButtonIcon>
    <ng-icon name="tablerPlus" size="16" />
  </span>
  <span frButtonLabel>Save changes</span>
</button>

Examples

Basic

Use the primary button for the main action in a section or flow.

Appearances

Switch appearances to control emphasis, from the filled primary action to lighter outline and ghost affordances.

Sizes

Use `sm`, `md`, and `lg` to match dense toolbars, default forms, or more prominent page-level actions.

Radius options

Use radius presets when a button should feel more squared, softly rounded, or fully pill-shaped.

Loading states

Buttons can replace their content with a shared Spinner primitive or keep the label visible and show loading inline, depending on how much continuity the action needs.

Icon buttons

Use `FrIconButton` for compact icon-only actions and always provide an accessible label because there is no visible text label.

Custom Styling

Override button tokens on a local wrapper when a product area needs a different height, radius, or visual density while keeping the same button API and behavior.

Token Inspector

Hover the button shell, icon, label, or loading indicator to inspect the tokens that control spacing, height, radius, icon sizing, and loading treatment. Click a region to pin the inspector while you review the current values.

Design Tokens

Use these CSS custom properties to tune button height, spacing, icon sizing, loading indicators, and interaction states without changing the markup structure.

SCSS


  --frame-button-root-gap: 0.5rem;
  --frame-button-root-height: 2.25rem;
  --frame-button-root-padding-x: 1rem;
  --frame-button-root-radius: var(--frame-radius-md);
  --frame-button-root-shadow: var(--frame-shadow-sm);
  --frame-button-root-font-size: 0.875rem;
  --frame-button-root-font-weight: 600;
  --frame-button-root-ring-color: var(--frame-ring);
  --frame-button-root-focus-shadow: var(--frame-button-root-shadow), 0 0 0 3px color-mix(in srgb, var(--frame-button-root-ring-color) 35%, transparent);
  --frame-button-root-hover-filter: brightness(0.98);
  --frame-button-root-active-filter: brightness(0.96);
  --frame-button-root-disabled-opacity: 0.55;
  --frame-button-root-disabled-shadow: none;
  --frame-button-loading-size: 1rem;
  --frame-button-loading-stroke: 2px;
  --frame-button-loading-track: color-mix(in srgb, currentColor 24%, transparent);
  --frame-spinner-size: 1rem;
  --frame-spinner-stroke: 2px;
  --frame-spinner-track-color: color-mix(in srgb, currentColor 24%, transparent);
  --frame-spinner-indicator-color: currentColor;
  --frame-button-icon-size: 1rem;
  --frame-button-label-weight: inherit;