Button

An interactive element used to trigger actions, submit forms, or navigate between views.

Variants

vue
<script setup>
import { Button } from 'frappe-ui'
</script>

<template>
  <Button variant="solid">Solid</Button>
  <Button variant="subtle">Subtle</Button>
  <Button variant="outline">Outline</Button>
  <Button variant="ghost">Ghost</Button>
</template>

Themes

vue
<script setup>
import { Button } from 'frappe-ui'
</script>

<template>
  <Button theme="gray">Gray</Button>
  <Button theme="red">Red</Button>
</template>

Sizes

vue
<script setup>
import { Button } from 'frappe-ui'
</script>

<template>
  <Button size="xs">Button</Button>
  <Button size="sm">Button</Button>
  <Button size="md">Button</Button>
  <Button size="lg">Button</Button>
</template>

Icons

vue
<script setup>
import { Button, KeyboardShortcut } from 'frappe-ui'
</script>

<template>
  <Button>
    <template #icon>
      <LucideBolt class="size-4" />
    </template>
  </Button>

  <Button>
    <template #prefix>
      <LucideDownload class="size-4" />
    </template>
    Download
  </Button>

  <Button>
    <template #suffix>
      <LucideArrowRight class="size-4" />
    </template>
    Get Started
  </Button>

  <Button>
    Discover
    <template #suffix>
      <KeyboardShortcut combo="Mod+K" :show-plus="false" />
    </template>
  </Button>

  <Button :loading="true"> Fetching </Button>
</template>

API Reference

Show types
typescript
import { type RouterLinkProps } from 'vue-router'
import { type Component, type ExtractPublicPropTypes, type PropType } from 'vue'

export type Theme = 'gray' | 'blue' | 'green' | 'red'
export type Size = 'xs' | 'sm' | 'md' | 'lg'
export type Variant = 'solid' | 'subtle' | 'outline' | 'ghost'

const iconProp = {
  type: [String, Object, Function] as PropType<string | Component>,
  default: undefined,
}

/**
 * Runtime prop definitions — the single source of truth for the button's props.
 * `Button.vue` spreads these into `defineComponent`, and the public `ButtonProps`
 * type is derived from them, so the runtime and the type can never drift apart.
 */
export const buttonProps = {
  /** Visual color theme of the button */
  theme: { type: String as PropType<Theme>, default: 'gray' },
  /** Controls the button size */
  size: { type: String as PropType<Size>, default: 'sm' },
  /** Visual style of the button */
  variant: { type: String as PropType<Variant>, default: 'subtle' },
  /** Text label displayed inside the button */
  label: { type: String, default: undefined },
  /** Icon shown when no left or right icon is specified */
  icon: iconProp,
  /** Icon shown before the label */
  iconLeft: iconProp,
  /** Icon shown after the label */
  iconRight: iconProp,
  /** Tooltip text shown on hover */
  tooltip: { type: String, default: undefined },
  /** Shows a loading state and disables interaction */
  loading: { type: Boolean, default: false },
  /** Text shown while the button is loading */
  loadingText: { type: String, default: undefined },
  /** Disables the button */
  disabled: { type: Boolean, default: false },
  /** Router destination when used as a link */
  route: {
    type: [String, Object] as PropType<RouterLinkProps['to']>,
    default: undefined,
  },
  /** External link URL */
  link: { type: String, default: undefined },
  /** Native button type */
  type: {
    type: String as PropType<'button' | 'submit' | 'reset'>,
    default: 'button',
  },
}

/** Public prop types for `<Button>`. Derived from {@link buttonProps}. */
export type ButtonProps = ExtractPublicPropTypes<typeof buttonProps>

/** Combined theme and variant key */
export type ThemeVariant = `${Theme}-${Variant}`
theme
= 'gray'
Theme

Visual color theme of the button

variant
= 'subtle'
Variant

Visual style of the button

type
= 'button'
"button" | "submit" | "reset"

Native button type

label
= undefined
string

Text label displayed inside the button

loading
= false
boolean

Shows a loading state and disables interaction

size
= 'sm'
Size

Controls the button size

icon
string | Component

Icon shown when no left or right icon is specified

iconLeft
string | Component

Icon shown before the label

iconRight
string | Component

Icon shown after the label

tooltip
= undefined
string

Tooltip text shown on hover

loadingText
= undefined
string

Text shown while the button is loading

disabled
= false
boolean

Disables the button

route
= undefined
string | kt | Tt

Router destination when used as a link

link
= undefined
string

External link URL

prefix
[void]

Content shown before the button label (left icon / custom content)

icon
[void]

Icon-only content for icon buttons

default
[void]

Main button content (overrides `label`)

suffix
[void]

Content shown after the button label (right icon / custom content)