---
title: Button
description: Initiates an action, such as completing a task or submitting information.
---

# Button

Initiates an action, such as completing a task or submitting information.

```tsx
import { Button } from "@ngrok/mantle/button";

<Button type="button">Outlined</Button>
<Button type="button" appearance="filled">Filled</Button>
<Button type="button" appearance="ghost">Ghost</Button>
<Button type="button" appearance="link">Link</Button>

<Button type="button" priority="neutral">Outlined</Button>
<Button type="button" priority="neutral" appearance="filled">Filled</Button>
<Button type="button" priority="neutral" appearance="ghost">Ghost</Button>
<Button type="button" priority="neutral" appearance="link">Link</Button>

<Button type="button" priority="danger">Outlined</Button>
<Button type="button" priority="danger" appearance="filled">Filled</Button>
<Button type="button" priority="danger" appearance="ghost">Ghost</Button>
<Button type="button" priority="danger" appearance="link">Link</Button>
```

## Icon and Positioning

Use the `icon` prop to add an icon to the button. By default, it will render on the logical start side of the button. Use the `iconPlacement` prop to change the side the icon is rendered on.

```tsx
import { Button } from "@ngrok/mantle/button";
import { FireIcon } from "@phosphor-icons/react/Fire";

<Button type="button" icon={<FireIcon weight="fill" />}>Icon Start</Button>
<Button type="button" icon={<FireIcon weight="fill" />} iconPlacement="end">
	Icon End
</Button>
```

## isLoading

`isLoading` determines whether or not the button is in a loading state, default `false`. Setting `isLoading` will replace any `icon` with a spinner, or add one if an icon wasn't given. It will also disable user interaction with the button and set `aria-disabled`.

```tsx
import { Button } from "@ngrok/mantle/button";
import { FireIcon } from "@phosphor-icons/react/Fire";

<Button type="button">No Icon + Idle</Button>
<Button type="button" icon={<FireIcon weight="fill" />}>Icon Start + Idle</Button>
<Button type="button" icon={<FireIcon weight="fill" />} iconPlacement="end">
	Icon End + Idle
</Button>
<Button type="button" isLoading>No Icon + isLoading</Button>
<Button type="button" icon={<FireIcon weight="fill" />} isLoading>
	Icon Start + isLoading
</Button>
<Button type="button" icon={<FireIcon weight="fill" />} iconPlacement="end" isLoading>
	Icon End + isLoading
</Button>
```

## Polymorphism

When you want to render *something else* as a `Button`, you can use the `asChild` prop to compose. This is useful when you want to splat the `Button` styling onto a `react-router` `Link`. Keep in mind that when you use `asChild` the `type` prop will **NOT** be passed to the child component.

```tsx
import { Button } from "@ngrok/mantle/button";
import { FireIcon } from "@phosphor-icons/react/Fire";
import { Link, href } from "react-router";

<Button appearance="filled" icon={<FireIcon weight="fill" />} asChild>
	<Link to={href("/base/colors")}>See our colors!</Link>
</Button>;
```

## API Reference

### Button

All props from [button](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes), plus:

| Prop             | Type                                                | Default      | Description                                                                                                                                                                                                                                                                      |
| ---------------- | --------------------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `appearance?`    | `"ghost"` \| `"filled"` \| `"outlined"` \| `"link"` | `"outlined"` | Defines the visual style of the `Button`.                                                                                                                                                                                                                                        |
| `asChild?`       | `boolean`                                           | `false`      | Use the `asChild` prop to compose the `Button` styling onto alternative element types or your own React components.                                                                                                                                                              |
| `icon?`          | `ReactNode`                                         |              | An icon to render inside the button. When `isLoading` is `true`, the icon will automatically be replaced with a spinner.                                                                                                                                                         |
| `iconPlacement?` | `"start"` \| `"end"`                                | `"start"`    | The side that the icon will render on, if one is present. When `isLoading` is `true`, the loading spinner will also render on this side.                                                                                                                                         |
| `isLoading?`     | `boolean`                                           | `false`      | Determines whether or not the button is in a loading state. Setting `isLoading` will replace any `icon` with a spinner, or add one if an icon wasn't given. It will also disable user interaction with the button and set `aria-disabled`.                                       |
| `priority?`      | `"default"` \| `"danger"` \| `"neutral"`            | `"default"`  | Indicates the importance or impact level of the button, affecting its color and styling to communicate its purpose to the user.                                                                                                                                                  |
| `type`           | `"button"` \| `"reset"` \| `"submit"`               |              | The default behavior of the `Button`. Unlike the native `button` element, unless you use the `asChild` prop, **this prop is required and has no default value**. See [the MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type) for more information. |
