Button
An interactive element used to trigger actions, submit forms, or navigate between views.
Playground
Section controls
<script setup>
import { Button } from 'frappe-ui'
</script>
<template>
<div class="flex w-full max-w-[1100px] items-center gap-8">
<div class="flex flex-1 items-center gap-1.5">
<Button>Lead owner</Button>
<Button icon-right="lucide-chevron-down">Status</Button>
<Button icon-right="lucide-chevron-down">Organisation</Button>
</div>
<div class="flex items-center gap-2">
<Button icon-left="lucide-eye-off">Columns</Button>
<Button icon-left="lucide-list-filter">
Filter
<template #suffix>
<span
class="inline-flex h-4.5 items-center justify-center rounded-1 bg-surface-base px-1.5 text-xs text-ink-gray-7 shadow-sm ring-1 ring-black/5"
>
1
</span>
</template>
</Button>
<Button icon-left="lucide-arrow-up-down">Sort</Button>
<Button icon="lucide-ellipsis" />
</div>
</div>
</template>Section action
<script setup>
import { Button } from 'frappe-ui'
</script>
<template>
<div class="flex w-full max-w-[352px] items-center gap-2 p-3">
<Button
variant="ghost"
icon-left="lucide-chevron-down"
class="-ml-2 font-medium"
>
Contacts
</Button>
<div class="flex-1" />
<Button icon-left="lucide-plus">Add contact</Button>
</div>
</template>Selection toolbar
<script setup>
import { Button } from 'frappe-ui'
</script>
<template>
<div
class="inline-flex items-center gap-3.5 rounded-6 bg-surface-base p-1.5 shadow-[0px_0px_1.5px_rgba(0,0,0,0.16),0px_2px_5px_rgba(0,0,0,0.14)]"
>
<Button variant="ghost" icon-left="lucide-x">2 selected</Button>
<div class="h-5 w-px bg-outline-gray-1" />
<div class="flex items-center gap-1">
<Button variant="ghost" icon-left="lucide-download">Download</Button>
<Button variant="ghost" icon-left="lucide-corner-up-right">Move</Button>
<Button variant="ghost" icon-left="lucide-share-2">Share</Button>
<Button variant="ghost" theme="red" icon-left="lucide-trash-2">
Delete
</Button>
</div>
</div>
</template>Inline actions
<script setup>
import { Button } from 'frappe-ui'
</script>
<template>
<div class="flex items-center gap-2">
<Button>Join</Button>
<Button variant="solid">Reschedule</Button>
</div>
</template>Stacked actions
<script setup>
import { Button } from 'frappe-ui'
</script>
<template>
<div class="flex w-58 flex-col items-stretch gap-2">
<Button class="w-full">Join</Button>
<Button variant="solid" class="w-full">Reschedule</Button>
</div>
</template>Card actions
<script setup>
import { Button } from 'frappe-ui'
</script>
<template>
<div
class="flex w-96 flex-col gap-6 rounded-6 bg-surface-base p-4 shadow-[0px_0px_0.75px_rgba(0,0,0,0.16),0px_2px_2.5px_rgba(0,0,0,0.14)]"
>
<div class="flex flex-col gap-5">
<div class="flex flex-col gap-3">
<p class="text-md-semibold text-ink-gray-7">Frappe january - 2023</p>
<div class="flex flex-col gap-3">
<div class="flex items-center gap-2 text-base text-ink-gray-7">
<span class="lucide-calendar size-4" aria-hidden="true" />
<span>Wed, Dec 27, 2023</span>
</div>
<div class="flex items-center gap-2 text-base text-ink-gray-7">
<span class="lucide-clock size-4" aria-hidden="true" />
<span>03:45 PM - 04:15 PM (30 min)</span>
</div>
</div>
</div>
<p class="text-base leading-normal text-ink-gray-7">
Digital products are more abstract and complex than any product we’v…
</p>
</div>
<div class="flex items-center gap-2">
<Button class="flex-1">Start</Button>
<Button variant="solid" class="flex-1" icon-left="lucide-video">
Join
</Button>
</div>
</div>
</template>API Reference
Show types
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}`Visual color theme of the button
Visual style of the button
Native button type
Text label displayed inside the button
Shows a loading state and disables interaction
Controls the button size
Icon shown when no left or right icon is specified
Icon shown before the label
Icon shown after the label
Tooltip text shown on hover
Text shown while the button is loading
Disables the button
Router destination when used as a link
External link URL
| Slot | Payload |
|---|---|
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) |
Content shown before the button label (left icon / custom content)
Icon-only content for icon buttons
Main button content (overrides `label`)
Content shown after the button label (right icon / custom content)