<!--
Source: https://www.theui.dev/docs/button
Part of the theui-svelte documentation. Index: https://www.theui.dev/llms.txt
-->

# Button

The Button component covers the sizes, colors and themes the library uses. Give it an href and it renders an anchor instead of a button.

## About

Give it an `href` and it renders an `<a>`; leave it out and you get a `<button>`. The look comes from two axes, `theme` and `color`, with `outline` as a third option that overrides `theme`. Anything you pass in `class` is merged last, so your own styling wins.

## Example

Import the `Button` component into your Svelte file. The following example shows how to use the button component!

```html
<script>
  import { Button } from "theui-svelte";
</script>

<Button>Button</Button>
```

## Link Button

You can turn the `Button` into a link by adding the href prop. This makes the button behave like a regular link. This will navigate to the home page when clicked.

```html
<Button href="/">Link button</Button>
```

### New Tab Icon

Sometimes, you may want to show an arrow icon to indicate that a link opens in a new tab. This is controlled by the `newTabIcon` prop. By default, it's `true`, so the icon is shown. Set it to `false` to hide the icon.

**Important:** The link must have a `target` attribute (like `target="_blank"`) for the icon to appear. If there's no `target`, the icon won't show - even if `newTabIcon` is `true`.

```html
<Button href="/" target="_blank" newTabIcon={true}>...</Button>
```

## Button Content

The `Button` component offers `beforeLabel` and `afterLabel` snippet blocks that let you add custom content before or after the button's label. This is useful for icons, badges, or other elements, giving you more control over the button's look and behavior. Although you can add elements manually with HTML and CSS, using these snippets keeps the structure cleaner and easier to maintain. It also simplifies layout and styling.

For better structure, flexibility, and consistency, `beforeLabel` and `afterLabel` are great options.

### Example Using Snippets

```html
<Button>
  {#snippet beforeLabel()}
    <Svg size={1.5}>
      <path d="M8 8a3 3 0 ... />
    </Svg>
  {/snippet}

  Button Text

  {#snippet afterLabel()}
    <Svg size={1.5}>
      <path fill-rule="evenodd" d="M1 8a.5.5 0 0 ... />
    </Svg>
  {/snippet}
</Button>
```

### Example Without Snippets

```html
<Button>
  <div class="CUSTOM CLASSES">
    <Svg size={1.5}>
      <path d="M8 8a3 3 0 ... />
    </Svg>

    Button Text

    <Svg size={1.5}>
      <path fill-rule="evenodd" d="M1 8a.5.5 0 0 ... />
    </Svg>
  </div>
</Button>
```

## Button Color

The `color` prop lets you style the button using predefined themes like `"brand"`, `"error"`, `"info"`, `"success"`, and `"warning"`. These match common statuses or actions to keep your app's design consistent. The default is `"brand"`.

```html
<Button color="brand">Brand</Button>
<Button color="error">Error</Button>
<Button color="info">Info</Button>
<Button color="success">Success</Button>
<Button color="warning">Warning</Button>
```

Each color carries a meaning, so a reader can tell a destructive action from a safe one. You can still pass your own classes, but the `color` prop keeps the whole app on one palette.

## Theme

The `theme` prop controls the button's overall style and background. It supports three values: `'default'`, `'soft'`, and `'gradient'`. The default theme gives the standard button look, the soft theme uses softer colors, and the gradient theme adds a vibrant background with gradient styling.

### Soft Theme

The soft theme is a softer variation of the default button colors, making it suitable for more subtle designs.

```html
<Button theme="soft" color="brand">Brand</Button>
<Button theme="soft" color="error">Error</Button>
<Button theme="soft" color="info">Info</Button>
<Button theme="soft" color="success">Success</Button>
<Button theme="soft" color="warning">Warning</Button>
```

### Gradient Theme

The gradient theme fills the button background with a two color gradient.

```html
<Button theme="gradient" gradientColor="brand">Brand</Button>
<Button theme="gradient" gradientColor="error">Error</Button>
<Button theme="gradient" gradientColor="info">Info</Button>
<Button theme="gradient" gradientColor="success">Success</Button>
<Button theme="gradient" gradientColor="warning">Warning</Button>
```

> **Note:** The color prop can still be used with each theme to specify the button's color, allowing flexibility while maintaining consistency across different button themes.

## Outline

The `outline` prop lets you create a button with a modern outline style. It gives the button a transparent background and a border, making it great for secondary actions or a minimalist look.

To use an outline button, set the `outline` prop to `true` like this: `outline={"{true}"}`

```html
<Button color="brand" outline={true}>Brand</Button>
<Button color="error" outline={true}>Error</Button>
<Button color="info" outline={true}>Info</Button>
<Button color="success" outline={true}>Success</Button>
<Button color="warning" outline={true}>Warning</Button>
```

## Size

The `size` prop sets the padding and the font size of the button. It takes one of the preset values below.

Available values are `"xs"`, `"sm"`, `"md"` (default), `"lg"`, `"xl"`, and `"auto"`, allowing flexibility while maintaining consistency.

```html
<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra large</Button>
<Button size="auto">Auto</Button>
```

Each size option adjusts the button's padding and font size, providing a cohesive look across different screen sizes and use cases. The `auto` size adapts to the content, has no padding, making it flexible for various layouts.

## Square Button

The `square` prop makes the button's height and width equal, which is what you want for an icon button.

```html
<Button square={true}>m</Button>
```

You can combine the `square` prop with the `size` prop to create square buttons of varying dimensions. This flexibility lets you choose the appropriate size for different UI elements while maintaining the square shape.

```html
<Button square={true} size="xs"> ... </Button>
<Button square={true} size="sm"> ... </Button>
<Button square={true} size="md"> ... </Button>
<Button square={true} size="lg"> ... </Button>
<Button square={true} size="xl"> ... </Button>
```

Square buttons follow the same size scale, so an icon button lines up with the text buttons beside it.

## Rounded Corner Button

The `rounded` prop sets the corner radius of the button. Available values are: `none`, `sm`, `md`, `lg`, `xl`, `2xl`, and `full`. Default value `md`.

```html
<Button rounded="none">None</Button>
<Button rounded="sm">Small</Button>
<Button rounded="md">Medium</Button>
<Button rounded="lg">Large</Button>
<Button rounded="xl">Extra large</Button>
<Button rounded="full">Full</Button>
```

## Button Shadow

The `shadow` prop controls the button's shadow. Available values are `"none"`, `"xs"`, `"sm"`, `"md"` (default), `"lg"`, `"xl"`, `"2xl"` and `"inner"`. Buttons inside a `ButtonGroup` don't use it.

```html
<Button shadow="none">No shadow</Button>
<Button shadow="sm">Small</Button>
<Button shadow="lg">Large</Button>
<Button shadow="2xl">2xl</Button>
```

## Button Animation Speed

The `animationSpeed` determines the speed of the button's animation, with options including `"none"`, `"slower"`, `"slow"`, `"normal"`, `"fast"`, and `"faster"`.

```html
<Button animationSpeed="slower">Slower animation</Button>
<Button animationSpeed="slow">Slow animation</Button>
<Button animationSpeed="normal">Normal animation</Button>
<Button animationSpeed="fast">Fast animation</Button>
<Button animationSpeed="faster">Faster animation</Button>
<Button animationSpeed="none">No Animation animation</Button>
```

Each value sets a different transition duration.

## Loading State

Set the `loading` prop to `true` to show a spinner in the button, for example while a form is being submitted. While loading, the button can't be clicked. The `loadingText` prop sets the text shown after the button label; the default is `"Loading..."`. Set it to an empty string to show only the spinner.

```html
<script>
  let saving = $state(false);
</script>

<Button loading={saving} onclick={() => saving = true}>Save</Button>

<!-- Spinner only -->
<Button loading={true} loadingText="">Save</Button>
```

## Active State

Use the `isActive` prop to show a button in its pressed style, for example the selected option in a group of buttons or a toggle that is on. The default is `false`. On a button (not a link), `isActive` also sets `aria-pressed="true"` so screen readers announce it as pressed.

```html
<Button>Inactive</Button>
<Button isActive={true}>Active</Button>
<Button outline={true} isActive={true}>Active outline</Button>
```

## Disabled Button

Add the `disabled` attribute to disable a button. A disabled button is dimmed, can't be clicked and gets `aria-disabled="true"`. On a link button, the link is also removed, so it can't be opened with the mouse or the keyboard.

```html
<Button disabled>Disabled button</Button>
<Button href="/" disabled>Disabled link</Button>
```

## Actions

The `actions` prop lets you apply [Svelte actions](https://svelte.dev/docs/svelte/use) to the button element. Pass an array of `[action, params]` pairs; `params` is optional. Each action runs when the button is mounted, and its `destroy` function runs when the button is removed.

```html
<script>
  const tooltip = (node, text) => {
    node.title = text;
    return { destroy: () => node.removeAttribute("title") };
  };
</script>

<Button actions={[[tooltip, "Save your changes"]]}>Save</Button>
```

## Accessibility

The Button carries the ARIA attributes it needs and answers to the keyboard out of the box.

- **Keyboard Navigation**: Use tab to navigate between buttons, and Enter or Space to activate a button.

- **ARIA Attributes**: By default, screen readers use the button's visible text as its name. The `ariaLabel` prop sets `aria-label`, which replaces that text, so use it when the button's text or icon alone may not be clear (e.g., icon-only buttons).

```html
<Button square={true} ariaLabel="Open profile">
  <Svg>...</Svg>
</Button>
```

A disabled button gets `aria-disabled="true"`, and an active button (`isActive`) gets `aria-pressed="true"`.

- **Focus Management**: focus styles use `focus-visible` or `focus-within`, so the ring shows for keyboard users without appearing on every mouse click.

- **State Indications**: Visual cues (hover, focus, active, and disabled states) are provided to communicate the button's interactive state clearly.

## Configuration

### Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `beforeLabel` | Snippet | `undefined` | Custom content to display before the button label. |
| `afterLabel` | Snippet | `undefined` | Custom content to display after the button label. |
| `animationSpeed` | [ANIMATE_SPEED](https://www.theui.dev/docs/types#animation-speed-type) | `normal` | Controls the animation speed of the button. Inherited from ButtonGroup if available. |
| `actions` | [action, params?][] | `undefined` | A list of Svelte actions applied to the button element, each as an `[action, params]` pair. |
| `ariaLabel` | string | `undefined` | Accessible label for the button. When not set, screen readers use the visible button text. Use it for buttons without visible text, like icon-only buttons. |
| `newTabIcon` | boolean | `true` | Display an arrow that indicates the link will open a new tab. It will only be visible if the button has an href with a "target" attribute. |
| `href` | string \| undefined | `undefined` | URL to navigate to when the button is clicked, converting the button into a link. |
| `isActive` | boolean | `false` | Shows the button in its active (pressed) style. On a button (not a link) it also sets `aria-pressed="true"`. |
| `loading` | boolean | `false` | Shows a spinner and the `loadingText`, and blocks clicks while loading. |
| `loadingText` | string | `Loading...` | Text shown next to the spinner when `loading` is true. Set it to an empty string to show only the spinner. |
| `outline` | boolean | `false` | Whether the button should have an outline style. Inherited from ButtonGroup if available. |
| `rounded` | [ROUNDED](https://www.theui.dev/docs/types#rounded-type) | `md` | Specifies the rounded corners of the button. Inherited from ButtonGroup if available. |
| `shadow` | [SHADOW](https://www.theui.dev/docs/types#shadow-types) | `md` | Controls the shadow of the button. |
| `size` | [BUTTON_SIZE](https://www.theui.dev/docs/types#button-size-type) | `md` | Specifies the size of the button. Inherited from ButtonGroup if available. |
| `square` | boolean | `false` | Whether the button should be a square. Inherited from ButtonGroup if available. |
| `theme` | 'default' \| 'soft' \| 'gradient' | `default` | Theme of the button, determining its overall style. Inherited from ButtonGroup if available. |
| `gradientColor` | 'brand' \| 'error' \| 'info' \| 'success' \| 'warning' | `brand` | Defines the base color of the gradient theme. Inherited from ButtonGroup if available. |
| `color` | 'brand' \| 'error' \| 'info' \| 'success' \| 'warning' | `brand` | The color of the button, indicating its purpose. Inherited from ButtonGroup if available. |
| `type` | 'button' \| 'submit' \| 'reset' | `button` | Specifies the type of button, such as button, submit, or reset. |

### Dynamic props

| Name | Description |
| --- | --- |
| `disabled` | Disables the button: dims it, blocks clicks and sets `aria-disabled="true"`. On a button the native `disabled` attribute is set too; on a link the `href` is removed. |

### Snippets

| Name | Description |
| --- | --- |
| `beforeLabel` | Custom content to display before the button label. |
| `afterLabel` | Custom content to display after the button label. |

---

Category: Components
Keywords: button, buttons, clickable, interactive, component, svelte, svelte-5, theui-svelte, component-library, ui, tailwindcss
Full documentation set: https://www.theui.dev/llms-full.txt
