# Button

Triggers an action, such as submitting a form or sending a payment.

[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Button.tsx)

## Overview

A button is a native `<button>` for actions. It scales slightly while pressed and shows a blue outline on keyboard focus.

Use `Button` for actions and `Button.Link` for navigation. Keep one `primary` button per view or section.

## Examples

### Basic

```tsx
import { Button } from '@tempoxyz/ds'

export function Demo() {
  return <Button>Continue</Button>
}
```

[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Button/Basic.tsx)

### Variant

Set `variant` to `primary`, `secondary`, `negative`, or `text`. It defaults to `primary`.

```tsx
import { Button, style } from '@tempoxyz/ds'

export function Demo() {
  return (
    <div {...styles.row()}>
      {(['primary', 'secondary', 'negative', 'text'] as const).map((variant) => (
        <Button key={variant} variant={variant}>
          {variant}
        </Button>
      ))}
    </div>
  )
}

namespace styles {
  export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '3' })
}
```

[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Button/Variant.tsx)

### Size

Set `size` to `small`, `medium`, or `large`. It defaults to `medium` and matches the height of an `Input` of the same size.

```tsx
import { Button, Input, style } from '@tempoxyz/ds'

export function Demo() {
  return (
    <>
      <div {...styles.row()}>
        {(['small', 'medium', 'large'] as const).map((size) => (
          <Button key={size} size={size}>
            {size}
          </Button>
        ))}
      </div>
      {(['small', 'medium', 'large'] as const).map((size) => (
        <div key={size} {...styles.field()}>
          <Input.Group size={size} {...styles.input()}>
            <Input.Control aria-label="Amount" placeholder="Amount" />
          </Input.Group>
          <Button size={size}>Send</Button>
        </div>
      ))}
    </>
  )
}

namespace styles {
  export const field = style({
    alignItems: 'center',
    display: 'flex',
    gap: '3',
    maxWidth: '24rem !custom',
  })

  export const input = style({ flex: '1 !custom', minWidth: '0 !custom' })

  export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '3' })
}
```

[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Button/Size.tsx)

### Shape

Set `shape="icon"` for a square button that holds only an icon. Give it an `aria-label`.

```tsx
import { Button, style } from '@tempoxyz/ds'
import { Plus as Add } from '@tempoxyz/ds/icons'

export function Demo() {
  return (
    <div {...styles.row()}>
      <Button>
        <Add />
        With icon
      </Button>
      {(['primary', 'secondary', 'negative', 'text'] as const).map((variant) => (
        <Button aria-label="Add" key={variant} shape="icon" variant={variant}>
          <Add />
        </Button>
      ))}
    </div>
  )
}

namespace styles {
  export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '3' })
}
```

[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Button/Shape.tsx)

### Loading

Set `loading` to disable the button and replace its label with a spinner, keeping its width.

```tsx
import { Button, style } from '@tempoxyz/ds'

export function Demo() {
  return (
    <div {...styles.row()}>
      {(['primary', 'secondary', 'negative', 'text'] as const).map((variant) => (
        <Button key={variant} loading variant={variant}>
          Loading
        </Button>
      ))}
    </div>
  )
}

namespace styles {
  export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '3' })
}
```

[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Button/Loading.tsx)

### Disabled

```tsx
import { Button, style } from '@tempoxyz/ds'

export function Demo() {
  return (
    <div {...styles.row()}>
      {(['primary', 'secondary', 'negative', 'text'] as const).map((variant) => (
        <Button disabled key={variant} variant={variant}>
          Disabled
        </Button>
      ))}
    </div>
  )
}

namespace styles {
  export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '3' })
}
```

[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Button/Disabled.tsx)

## Guidelines

TODO: Write guidelines for Button.
