Logo

Component Blueprint

X: 1280 · Y: 720 · Grid: 8px

Button

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

01 Hero Preview

Grid: 8px · Scale: 1:1

02 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>

03 Examples

Basic

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

Component Sheet

Grid: 8px · Scale: 1:1

Appearances

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

Component Sheet

Grid: 8px · Scale: 1:1

Sizes

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

Component Sheet

Grid: 8px · Scale: 1:1

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.

Component Sheet

Grid: 8px · Scale: 1:1

Icon buttons

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

Component Sheet

Grid: 8px · Scale: 1:1

04 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 markup and behavior.

Component Sheet

Grid: 8px · Scale: 1:1

05 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.

06 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;