---
type: doc
title: Button
description: Displays a button or a component that looks like a button.
---

> Fulldev UI for Astro. The `@fulldev` registry in `components.json` points at `https://ui.full.dev/r/styles/{style}/{name}.json`; see [installation](/astro/docs/installation.md).

```astro title="src/components/examples/button/button-demo.astro"
---
import ArrowUpIcon from "@lucide/astro/icons/arrow-up"

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

<div class="flex flex-wrap items-center gap-2 md:flex-row">
  <Button variant="outline">Button</Button>
  <Button variant="outline" size="icon" aria-label="Submit">
    <ArrowUpIcon />
  </Button>
</div>
```

## Installation

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

## Usage

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

```astro
<Button variant="outline">Button</Button>
```

`Button` renders a `button` with `type="button"`, or an `a` when you pass
`href`. Pass `as` to render another element, such as `as="label"`. Use
`type="submit"` explicitly for form submission. `buttonVariants` gives the same
classes to a custom element.

## Size

Use the `size` prop to change the size of the button.

```astro title="src/components/examples/button/button-size.astro"
---
import ArrowUpRightIcon from "@lucide/astro/icons/arrow-up-right"

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

<div class="flex flex-col items-start gap-8 sm:flex-row">
  <div class="flex items-start gap-2">
    <Button size="xs" variant="outline">
      Extra Small
    </Button>
    <Button size="icon-xs" aria-label="Submit" variant="outline">
      <ArrowUpRightIcon />
    </Button>
  </div>
  <div class="flex items-start gap-2">
    <Button size="sm" variant="outline">
      Small
    </Button>
    <Button size="icon-sm" aria-label="Submit" variant="outline">
      <ArrowUpRightIcon />
    </Button>
  </div>
  <div class="flex items-start gap-2">
    <Button variant="outline">Default</Button>
    <Button size="icon" aria-label="Submit" variant="outline">
      <ArrowUpRightIcon />
    </Button>
  </div>
  <div class="flex items-start gap-2">
    <Button variant="outline" size="lg">
      Large
    </Button>
    <Button size="icon-lg" aria-label="Submit" variant="outline">
      <ArrowUpRightIcon />
    </Button>
  </div>
</div>
```

## Default

```astro title="src/components/examples/button/button-default.astro"
---
import { Button } from "@/components/ui/button"
---

<Button>Button</Button>
```

## Outline

```astro title="src/components/examples/button/button-outline.astro"
---
import { Button } from "@/components/ui/button"
---

<Button variant="outline">Outline</Button>
```

## Secondary

```astro title="src/components/examples/button/button-secondary.astro"
---
import { Button } from "@/components/ui/button"
---

<Button variant="secondary">Secondary</Button>
```

## Ghost

```astro title="src/components/examples/button/button-ghost.astro"
---
import { Button } from "@/components/ui/button"
---

<Button variant="ghost">Ghost</Button>
```

## Destructive

```astro title="src/components/examples/button/button-destructive.astro"
---
import { Button } from "@/components/ui/button"
---

<Button variant="destructive">Destructive</Button>
```

## Link

```astro title="src/components/examples/button/button-link.astro"
---
import { Button } from "@/components/ui/button"
---

<Button variant="link">Link</Button>
```

## Icon

```astro title="src/components/examples/button/button-icon.astro"
---
import CircleFadingArrowUpIcon from "@lucide/astro/icons/circle-fading-arrow-up"

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

<Button variant="outline" size="icon">
  <CircleFadingArrowUpIcon />
</Button>
```

## With Icon

Add `data-icon="inline-start"` or `data-icon="inline-end"` to the icon for the
correct spacing.

```astro title="src/components/examples/button/button-with-icon.astro"
---
import GitBranchIcon from "@lucide/astro/icons/git-branch"
import GitForkIcon from "@lucide/astro/icons/git-fork"

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

<div class="flex gap-2">
  <Button variant="outline">
    <GitBranchIcon data-icon="inline-start" /> New Branch
  </Button>
  <Button variant="outline">
    Fork
    <GitForkIcon data-icon="inline-end" />
  </Button>
</div>
```

## Rounded

Use the `rounded-full` class to make the button rounded.

```astro title="src/components/examples/button/button-rounded.astro"
---
import ArrowUpIcon from "@lucide/astro/icons/arrow-up"

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

<div class="flex gap-2">
  <Button class="rounded-full">Get Started</Button>
  <Button variant="outline" size="icon" class="rounded-full">
    <ArrowUpIcon />
  </Button>
</div>
```

## Spinner

Render a `Spinner` inside the button to show a loading state, with
`data-icon="inline-start"` or `data-icon="inline-end"`.

```astro title="src/components/examples/button/button-spinner.astro"
---
import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"
---

<div class="flex gap-2">
  <Button variant="outline" disabled>
    <Spinner data-icon="inline-start" />
    Generating
  </Button>
  <Button variant="secondary" disabled>
    Downloading
    <Spinner data-icon="inline-start" />
  </Button>
</div>
```

## Button Group

Use `ButtonGroup` to group related buttons. See [Button Group](/astro/components/button-group/). The official example on this page uses a dropdown submenu, so it is in the [React Button](/react/components/button/) docs only.

## As Link

With `href`, `Button` renders a real `a` element, so the link keeps its link
role.

```astro title="src/components/examples/button/button-render.astro"
---
import { Button } from "@/components/ui/button"
---

<Button as="a" href="#" variant="secondary" size="sm">
  Login
</Button>
```

## RTL

```astro title="src/components/examples/button/button-rtl.astro"
---
import ArrowRightIcon from "@lucide/astro/icons/arrow-right"
import PlusIcon from "@lucide/astro/icons/plus"

import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"

const translations = {
  en: {
    dir: "ltr",
    values: {
      button: "Button",
      submit: "Submit",
      delete: "Delete",
      loading: "Loading",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      button: "زر",
      submit: "إرسال",
      delete: "حذف",
      loading: "جاري التحميل",
    },
  },
  he: {
    dir: "rtl",
    values: {
      button: "כפתור",
      submit: "שלח",
      delete: "מחק",
      loading: "טוען",
    },
  },
}

const { dir, values: t } = translations.ar
---

<div class="flex flex-wrap items-center gap-2 md:flex-row" dir={dir}>
  <Button variant="outline">{t.button}</Button>
  <Button variant="destructive">{t.delete}</Button>
  <Button variant="outline">
    {t.submit} <ArrowRightIcon class="rtl:rotate-180" data-icon="inline-end" />
  </Button>
  <Button variant="outline" size="icon" aria-label="Add">
    <PlusIcon />
  </Button>
  <Button variant="secondary" disabled>
    <Spinner data-icon="inline-start" />
    {t.loading}
  </Button>
</div>
```

## API Reference

Source: [`src/components/ui/button`](https://github.com/fulldotdev/ui/tree/main/src/components/ui/button)

| Prop      | Type                                                                                 | Default                          |
| --------- | ------------------------------------------------------------------------------------ | -------------------------------- |
| `variant` | `"default" \| "outline" \| "ghost" \| "destructive" \| "secondary" \| "link"`        | `"default"`                      |
| `size`    | `"default" \| "xs" \| "sm" \| "lg" \| "icon" \| "icon-xs" \| "icon-sm" \| "icon-lg"` | `"default"`                      |
| `as`      | HTML tag                                                                             | `"a"` with `href`, else `button` |

`Button` writes its variant and size to `data-variant` and `data-size`, as
shadcn/ui does, so a parent can style it, such as
`has-data-[variant=outline]:gap-2`.

## Install what this page shows

```bash
npx shadcn@latest add @fulldev/button-examples
```
