ComponentStandalone

Button

Trigger an action. Renders as <wr-btn>, button[wr-btn], or a[wr-btn].

Installation

import { WrButton } from 'ngwr/button';

@Component({ imports: [WrButton] })
export class MyComponent {}

Basic usage

The same selector matches a custom element, a native button, and an anchor.

DefaultAnchor
<wr-btn>Default</wr-btn>
<button wr-btn>Native button</button>
<a wr-btn>Anchor</a>

Inside a form

<wr-btn> is a custom element with a button role, and no custom element submits a form — the platform submits for <button>, <input type=submit> and <input type=image> and nothing else. So it takes no type input, and Enter in a text field will not reach it either. A submit or reset button has to be the native form: <button wr-btn type=submit>. Where the element form is what you want, bind the click and call the handler yourself.

<form (ngSubmit)="save()">
  <!-- Submits: a real <button>, with the type the platform reads. -->
  <button wr-btn type="submit" color="primary">Save</button>

  <!-- Does NOT submit: <wr-btn> is a custom element. Bind the click. -->
  <wr-btn (click)="save()" color="primary">Save</wr-btn>
</form>

Colors

primarysecondarysuccesswarningdangerinfolightmediumdark
<wr-btn color="primary">Primary</wr-btn>
<wr-btn color="success">Success</wr-btn>

Outlined

primarysecondarysuccesswarningdangerinfolightmediumdark
<wr-btn color="primary" outlined>Outlined</wr-btn>

Sizes

SmallMediumLarge
<wr-btn size="sm">Small</wr-btn>
<wr-btn size="md">Medium</wr-btn>
<wr-btn size="lg">Large</wr-btn>

Shape

shape is rounded (default, small radius), pill (fully rounded ends) or squircle. Every button already asks for corner-shape: squircle where the browser supports it, so squircle mostly picks a larger anchor radius to make those smooth corners read — and pill deliberately opts back to a round arc, since squircle maths draws a different shape at pill radii rather than degenerating into one. Where corner-shape is unsupported the corners are ordinary arcs; [wrSquircle] is the clip-path route that works regardless — see the Squircle docs.

rounded
PrimaryOutlinedDefault
pill
PrimaryOutlinedDefault
squircle
PrimaryOutlinedDefault
roundedprimarysecondarysuccesswarningdangerinfolightmediumdark
pillprimarysecondarysuccesswarningdangerinfolightmediumdark
squircleprimarysecondarysuccesswarningdangerinfolightmediumdark
<!-- Three shapes -->
<wr-btn color="primary">Rounded (default)</wr-btn>
<wr-btn color="primary" shape="pill">Pill</wr-btn>
<wr-btn color="primary" shape="squircle">Squircle</wr-btn>

<!-- No corner-shape support? [wrSquircle] clips the same look everywhere.
     Its own entry point: import { WrSquircle } from 'ngwr/squircle' and add
     WrSquircle to imports — the attribute is inert without it. -->
<wr-btn color="primary" wrSquircle [radius]="14">Squircle</wr-btn>

With icon

Pass any icon registered via provideWrIcons. iconPosition switches between start/end.

AddConfirmDeleteDownload
<wr-btn icon="add" color="primary">Add</wr-btn>
<wr-btn icon="download" iconPosition="end" color="success">Download</wr-btn>

Disabled

DisabledDisabledDisabled
<wr-btn disabled>Disabled</wr-btn>

Loading

The spinner overlays the label so layout stays put. By default pointer events are blocked while loading.

Click to toggleSavingWith icon
<wr-btn [loading]="loading()" color="primary" (click)="loading.set(!loading())">
  Click to toggle
</wr-btn>

Block

Fills the parent's width.

Full width
<wr-btn color="primary" block>Full width</wr-btn>

API

NameDescriptionTypeDefault
colorColor variant. Omit for the neutral default style. Deliberately NOT configurable app-wide: the library's own chrome binds [color]="isCurrent ? 'primary' : null", where null means neutral, and a configured intent would repaint every one of those buttons. See WrConfig.WrColor | nullnull
sizeSize variant. Unset, it resolves through provideWrConfig({ button: { size } }) and then to md.WrButtonSize | null'md'
shapeCorner treatment — rounded, pill or squircle. null (default) falls back to rounded. Inside a <wr-btn-group shape="…">, the group's shape ALWAYS wins over this input — the group enforces a consistent corner treatment across its members.WrButtonShape | nullnull
iconIcon name to render alongside the label. The icon is hidden while loading is true so the spinner can take its place.WrIconName | nullnull
iconPositionPosition of the icon relative to the label.WrButtonIconPosition'start'
disabledDisable the button.booleanfalse
outlinedOutlined variant — colored text and border on a transparent background.booleanfalse
blockStretch the button to fill its parent's width.booleanfalse
loadingShow a spinner overlaying the label. Layout is preserved.booleanfalse
disabledWhenLoadingWhen loading is true and this is also true, pointer events are suppressed and the button reports as disabled to assistive tech.booleantrue

CSS variables

Custom properties ngwr/button publishes. Each default below is declared on the component's own selector, so a :root override is shadowed by it — set them on that selector, on a wrapper you scope yourself, or inline on the element. Unlike the BEM class names, these are the supported way to restyle the component.

VariableDefaultDeclared on
--wr-btn-bgvar(--wr-color-surface).wr-btn +8 variant overrides
--wr-btn-bordervar(--wr-color-outline).wr-btn +6 variant overrides
--wr-btn-colorvar(--wr-color-on-surface).wr-btn +4 variant overrides
--wr-btn-font-sizevar(--wr-control-font-size-md).wr-btn +2 variant overrides
--wr-btn-font-weight500.wr-btn
--wr-btn-gap0.375rem.wr-btn +2 variant overrides
--wr-btn-icon-size1rem.wr-btn +2 variant overrides
--wr-btn-line-heightvar(--wr-control-line-height-md).wr-btn +2 variant overrides
--wr-btn-padding-x0.875rem.wr-btn +2 variant overrides
--wr-btn-padding-yvar(--wr-control-padding-y-md).wr-btn +2 variant overrides
--wr-btn-radiusvar(--wr-control-radius-md).wr-btn +4 variant overrides