# Button

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

Source: https://ngwr.dev/reference/components/button  
Kind: Component, Standalone

## Installation

```angular-ts
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.

```html
<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.

```html
<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

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

## Outlined

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

## Sizes

```html
<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.

```html
<!-- 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.

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

## Disabled

```html
<wr-btn disabled>Disabled</wr-btn>
```

## Loading

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

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

## Block

Fills the parent's width.

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

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `color` | Color 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 \| null` | `null` |
| `size` | Size variant. Unset, it resolves through `provideWrConfig({ button: { size } })` and then to `md`. | `WrButtonSize \| null` | `'md'` |
| `shape` | Corner 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 \| null` | `null` |
| `icon` | Icon name to render alongside the label. The icon is hidden while `loading` is `true` so the spinner can take its place. | `WrIconName \| null` | `null` |
| `iconPosition` | Position of the icon relative to the label. | `WrButtonIconPosition` | `'start'` |
| `disabled` | Disable the button. | `boolean` | `false` |
| `outlined` | Outlined variant — colored text and border on a transparent background. | `boolean` | `false` |
| `block` | Stretch the button to fill its parent's width. | `boolean` | `false` |
| `loading` | Show a spinner overlaying the label. Layout is preserved. | `boolean` | `false` |
| `disabledWhenLoading` | When `loading` is `true` and this is also `true`, pointer events are suppressed and the button reports as disabled to assistive tech. | `boolean` | `true` |

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

| Variable | Default | Declared on |
| --- | --- | --- |
| `--wr-btn-bg` | `var(--wr-color-surface)` | `.wr-btn` +8 variant overrides |
| `--wr-btn-border` | `var(--wr-color-outline)` | `.wr-btn` +6 variant overrides |
| `--wr-btn-color` | `var(--wr-color-on-surface)` | `.wr-btn` +4 variant overrides |
| `--wr-btn-font-size` | `var(--wr-control-font-size-md)` | `.wr-btn` +2 variant overrides |
| `--wr-btn-font-weight` | `500` | `.wr-btn` |
| `--wr-btn-gap` | `0.375rem` | `.wr-btn` +2 variant overrides |
| `--wr-btn-icon-size` | `1rem` | `.wr-btn` +2 variant overrides |
| `--wr-btn-line-height` | `var(--wr-control-line-height-md)` | `.wr-btn` +2 variant overrides |
| `--wr-btn-padding-x` | `0.875rem` | `.wr-btn` +2 variant overrides |
| `--wr-btn-padding-y` | `var(--wr-control-padding-y-md)` | `.wr-btn` +2 variant overrides |
| `--wr-btn-radius` | `var(--wr-control-radius-md)` | `.wr-btn` +4 variant overrides |
