# Button

The Button component is used for any action or to trigger something. Ideally
a button would fire a function or complete an action, rather than be used as a link.

## Import

```js
import { Button } from "@blockstack/ui";
```

## Usage

```jsx
<Button>This is a Button!</Button>
```

### Button Sizes

Use the `size` prop to change the size of the button. You can set the value to `sm`, `md`, or `lg`. Default value is `lg`.

```jsx
<ButtonGroup spacing={4}>
  <Button size="sm">Button</Button>
  <Button size="md">Button</Button>
  <Button size="lg">Button</Button>
</ButtonGroup>
```

### Button Variant

Use the `variant` prop to change the visual style of the Button. You can set the
value to `solid`, `link`, or `unstyled`.

```jsx
<ButtonGroup spacing={4}>
  <Button variant="solid">Button</Button>
  <Button variant="link">Button</Button>
  <Button variant="unstyled">Button</Button>
</ButtonGroup>
```

### Button loading state

Pass `isLoading` prop to the Button component to show it's loading state. You
can optionally pass `loadingText` prop, if you do, the button will show a
spinner and the loading text. Otherwise, the button will take the width of the
text label and show only the spinner

```jsx
<ButtonGroup spacing={4}>
  <Button isLoading variant="solid">
    Email
  </Button>
  <Button isLoading loadingText="Submitting">
    Submit
  </Button>
</ButtonGroup>
```

## Accessibility

- Button has `role` button.
- When Button has focus, <kbd>Space</kbd> and <kbd>Enter</kbd> activates it.

## Composition

Button composes [PseudoBox](/pseudobox) and all props you pass (variant,
bg, color, etc.) are converted to style props. This means you can override
any style of the Button via props.

```jsx
// The size prop affects the height of the button
// but I can still override it by passing a custom height
<Button size="md" height="48px" width="200px" border="2px" borderColor="green">
  Button
</Button>
```

---

## Custom Button

In event you need to make your own custom button, you can leverage the
`PseudoBox` component. It provides the `hover`, `focus`, `active` and `disabled`
style props to style the button.

```jsx
// Button from facebook.com
<PseudoBox
  as="button"
  height="24px"
  lineHeight="1.2"
  transition="all 0.2s cubic-bezier(.08,.52,.52,1)"
  border="1px"
  px="8px"
  rounded="2px"
  fontSize="14px"
  fontWeight="semibold"
  bg="#f5f6f7"
  borderColor="#ccd0d5"
  color="#4b4f56"
  _hover={{ bg: "#ebedf0" }}
  _active={{
    bg: "#dddfe2",
    transform: "scale(0.98)",
    borderColor: "#bec3c9"
  }}
  _focus={{
    boxShadow:
      "0 0 1px 2px rgba(88, 144, 255, .75), 0 1px 1px rgba(0, 0, 0, .15)"
  }}
>
  Join Group
</PseudoBox>
```

## Props

The Button composes the `PseudoBox` component so you can pass props for
`PseudoBox`. These are props related to the Button component.

| Name          | Type                          | Default | Description                                                                                               |
| ------------- | ----------------------------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `aria-label`  | `string`                      |         | The label of the button                                                                                   |
| `variant`     | `unstyled` , `link` , `solid` | `solid` | The variant of the button style to use.                                                                   |
| `isDisabled`  | `boolean`                     |         | If `true`, the button will be disabled.                                                                   |
| `isLoading`   | `boolean`                     |         | If `true`, the button will show a spinner.                                                                |
| `loadingText` | `string`                      |         | The label to show in the button when `isLoading` is true. If no text is passed, it only shows the spinner |
| `size`        | `sm`, `md`, `lg`              | `md`    | The size of the button.                                                                                   |
