# Button

A button, or a component that looks like one.

Source: [button.tsx](https://github.com/jakejarvis/jarvis-ui/blob/main/src/components/ui/button.tsx)

```tsx
import { Button } from "@/components/ui/button";

export default function ButtonVariants() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button variant="primary">Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="destructive">Destructive</Button>
      <Button variant="link">Link</Button>
    </div>
  );
}
```

## Installation

Add the registry, once per project:

```bash
npx shadcn@latest registry add @jarvis=https://ui.jarv.is/r/{name}.json
```

Then add the component:

```bash
npx shadcn@latest add @jarvis/button
```

## Usage

```tsx
import { Button } from "@/components/ui/button";

export function SaveButton() {
  return <Button variant="primary">Save changes</Button>;
}
```

To render a link that looks like a button, pass `buttonVariants` to its class name rather than
nesting an anchor in a button.

```tsx
import { buttonVariants } from "@/components/ui/button";

export function PricingLink() {
  return (
    <a href="/pricing" className={buttonVariants({ variant: "outline" })}>
      See pricing
    </a>
  );
}
```

## Examples

### Sizes

`size` sets the height and padding.

```tsx
import { Button } from "@/components/ui/button";

export default function ButtonSizes() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button size="xs">Extra small</Button>
      <Button size="sm">Small</Button>
      <Button>Default</Button>
      <Button size="lg">Large</Button>
    </div>
  );
}
```

### With icons

```tsx
import { ArrowRightIcon, CopyIcon, DownloadIcon, PlusIcon, Trash2Icon } from "lucide-react";

import { Button } from "@/components/ui/button";

export default function ButtonWithIcons() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button variant="primary">
        <PlusIcon />
        New project
      </Button>
      <Button variant="secondary">
        <DownloadIcon />
        Export CSV
      </Button>
      <Button variant="outline">
        Next step
        <ArrowRightIcon />
      </Button>
      <Button variant="ghost" size="sm">
        <CopyIcon />
        Copy link
      </Button>
      <Button variant="destructive">
        <Trash2Icon />
        Delete
      </Button>
    </div>
  );
}
```

### Icon only

The `icon` sizes make a square button. Give it an `aria-label`.

```tsx
import { EllipsisIcon, RefreshCwIcon } from "lucide-react";

import { Button } from "@/components/ui/button";

export default function ButtonIconOnly() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button size="icon-xs" aria-label="Refresh">
        <RefreshCwIcon />
      </Button>
      <Button size="icon-sm" aria-label="Refresh">
        <RefreshCwIcon />
      </Button>
      <Button size="icon" aria-label="Refresh">
        <RefreshCwIcon />
      </Button>
      <Button size="icon-lg" aria-label="Refresh">
        <RefreshCwIcon />
      </Button>
      <Button variant="ghost" size="icon-xs" aria-label="More options">
        <EllipsisIcon />
      </Button>
      <Button variant="ghost" size="icon-sm" aria-label="More options">
        <EllipsisIcon />
      </Button>
      <Button variant="ghost" size="icon" aria-label="More options">
        <EllipsisIcon />
      </Button>
      <Button variant="ghost" size="icon-lg" aria-label="More options">
        <EllipsisIcon />
      </Button>
    </div>
  );
}
```

### Disabled

```tsx
import { Button } from "@/components/ui/button";

export default function ButtonDisabled() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button variant="primary" disabled>
        Primary
      </Button>
      <Button variant="secondary" disabled>
        Secondary
      </Button>
      <Button variant="outline" disabled>
        Outline
      </Button>
      <Button variant="ghost" disabled>
        Ghost
      </Button>
      <Button variant="destructive" disabled>
        Destructive
      </Button>
      <Button variant="link" disabled>
        Link
      </Button>
    </div>
  );
}
```

### Invalid

Set `aria-invalid` to mark the button as invalid.

```tsx
import { Button } from "@/components/ui/button";

export default function ButtonInvalid() {
  return <Button aria-invalid>Choose a file</Button>;
}
```

## Props

| Part | Extends |
| --- | --- |
| `Button` | [`Button`](https://base-ui.com/react/components/button#api-reference) |

The tables leave out `className`, `style` and `render`. Parts built on Base UI take them as its [styling](https://base-ui.com/react/handbook/styling) and [composition](https://base-ui.com/react/handbook/composition) guides describe.

### Button

| Prop                     | Type                                                                                 | Description                                                                                                                                                                                       |
| ------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `focusableWhenDisabled?` | `boolean`                                                                            | Whether the button should be focusable when disabled. Default: `false`                                                                                                                            |
| `nativeButton?`          | `boolean`                                                                            | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). Default: `true` |
| `variant?`               | `"destructive" \| "ghost" \| "link" \| "outline" \| "primary" \| "secondary"`        | Default: `"secondary"`                                                                                                                                                                            |
| `size?`                  | `"default" \| "icon" \| "icon-lg" \| "icon-sm" \| "icon-xs" \| "lg" \| "sm" \| "xs"` | Default: `"default"`                                                                                                                                                                              |
