2024-12-22 23:35:56 +00:00
< script setup lang = "ts" >
2024-12-04 15:06:34 +00:00
import Button from '~/components/ui/Button.vue'
2024-12-17 22:09:10 +00:00
import Layout from '~/components/ui/Layout.vue'
2024-12-04 15:06:34 +00:00
2024-12-22 23:35:56 +00:00
const click = ():Promise< void > => new Promise(resolve => setTimeout(resolve, 1000))
2024-11-26 11:59:11 +00:00
< / script >
# Button
2025-01-01 23:31:20 +00:00
Buttons are UI elements that users can interact with to perform actions and manipulate objects. They are distinct from [Links ](link ) and will not change the user's position.
2024-11-26 11:59:11 +00:00
2024-12-22 20:19:49 +00:00
```ts
{
thin?: true
isActive?: boolean
isLoading?: boolean
shadow?: boolean
round?: boolean
icon?: string
onClick?: (...args: any[]) => void | Promise< void >
autofocus? : boolean
ariaPressed? : true
} & (ColorProps | DefaultProps)
& VariantProps
& RaisedProps
& WidthProps
2025-01-01 23:31:20 +00:00
& AlignmentProps
2024-12-22 20:19:49 +00:00
```
2024-11-26 11:59:11 +00:00
## Button colors
Buttons come in different types depending on the type of action they represent.
2024-12-18 15:58:27 +00:00
Find [a complete overview of recommended styles on the color page ](../../using-color#links-and-buttons ).
### Default
2024-12-22 20:22:55 +00:00
< Layout grid class = "preview transparent" >
< div style = "grid-column: span 3" >
2024-12-18 15:58:27 +00:00
```vue-html
< Button >
Default button
< / Button >
```
2024-12-22 20:22:55 +00:00
< / div >
< Button >
Default button
< / Button >
2024-12-18 15:58:27 +00:00
< / Layout >
2024-11-26 11:59:11 +00:00
### Primary
2024-12-22 20:22:55 +00:00
The primary button represents the **single positive** action on a page or modal, such as uploading, confirming, and accepting changes.
< Layout grid class = "preview" >
< div style = "grid-column: span 3" >
2024-11-26 11:59:11 +00:00
```vue-html
2024-12-15 23:07:09 +00:00
< Button primary >
2024-11-26 11:59:11 +00:00
Primary button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-22 20:22:55 +00:00
< / div >
2024-12-15 23:07:09 +00:00
< Button primary >
2024-11-26 11:59:11 +00:00
Primary button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
2024-12-22 20:22:55 +00:00
< / Layout >
2024-11-26 11:59:11 +00:00
### Secondary
Secondary buttons represent **neutral** actions such as cancelling a change or dismissing a notification.
2024-12-22 20:22:55 +00:00
< Layout grid class = "preview secondary" >
< div style = "grid-column: span 3" >
2024-11-26 11:59:11 +00:00
```vue-html
2024-12-22 20:22:55 +00:00
< Button secondary raised >
2024-11-26 11:59:11 +00:00
Secondary button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-22 20:22:55 +00:00
< / div >
< Button secondary raised >
2024-11-26 11:59:11 +00:00
Secondary button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
2024-12-22 20:22:55 +00:00
< / Layout >
Note that on a secondary background, the button needs to be `raised` to make it stand out.
2024-11-26 11:59:11 +00:00
### Destructive
Desctrutive buttons represent **dangerous** actions including deleting items or purging domain information.
2024-12-22 20:22:55 +00:00
< Layout grid class = "preview" >
< div style = "grid-column: span 3" >
2024-11-26 11:59:11 +00:00
```vue-html
2024-12-15 23:07:09 +00:00
< Button destructive >
2024-11-26 11:59:11 +00:00
Destructive button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-22 20:22:55 +00:00
< / div >
2024-12-15 23:07:09 +00:00
< Button destructive >
2024-11-26 11:59:11 +00:00
Destructive button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
2024-12-22 20:22:55 +00:00
< / Layout >
2024-11-26 11:59:11 +00:00
## Button variants
Buttons come in different styles that you can use depending on the location of the button.
### Solid
Solid buttons have a filled background. Use these to emphasize the action the button performs.
::: info
This is the default style. If you don't specify a style, a solid button is rendered.
:::
```vue-html
2024-12-04 15:06:34 +00:00
< Button >
2024-11-26 11:59:11 +00:00
Filled button
2024-12-04 15:06:34 +00:00
< / Button >
2024-12-15 23:07:09 +00:00
< Button solid >
Also filled button
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-04 15:06:34 +00:00
< Button >
2024-11-26 11:59:11 +00:00
Filled button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
2024-12-15 23:07:09 +00:00
< Button solid >
Also filled button
< / Button >
2024-11-26 11:59:11 +00:00
### Outline
Outline buttons have a transparent background. Use these to deemphasize the action the button performs.
```vue-html
2024-12-15 23:07:09 +00:00
< Button outline secondary >
2024-11-26 11:59:11 +00:00
Outline button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-15 23:07:09 +00:00
< Button outline secondary >
2024-11-26 11:59:11 +00:00
Outline button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
### Ghost
Ghost buttons have a transparent background and border. Use these to deemphasize the action the button performs.
```vue-html
2024-12-15 23:07:09 +00:00
< Button ghost secondary >
2024-11-26 11:59:11 +00:00
Ghost button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-15 23:07:09 +00:00
< Button ghost secondary >
2024-11-26 11:59:11 +00:00
Ghost button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
## Button styles
### Shadow
You can give a button a shadow to add depth.
```vue-html
2024-12-04 15:06:34 +00:00
< Button shadow >
2024-11-26 11:59:11 +00:00
Shadow button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-04 15:06:34 +00:00
< Button shadow >
2024-11-26 11:59:11 +00:00
Shadow button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
## Button shapes
You can choose different shapes for buttons depending on their location and use.
### Normal
Normal buttons are slightly rounded rectangles.
::: info
This is the default shape. If you don't specify a type, a normal button is rendered.
:::
```vue-html
2024-12-04 15:06:34 +00:00
< Button >
2024-11-26 11:59:11 +00:00
Normal button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-04 15:06:34 +00:00
< Button >
2024-11-26 11:59:11 +00:00
Normal button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
### Round
Round buttons have fully rounded edges.
```vue-html
2024-12-04 15:06:34 +00:00
< Button round >
2024-11-26 11:59:11 +00:00
Round button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-04 15:06:34 +00:00
< Button round >
2024-11-26 11:59:11 +00:00
Round button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
## Button states
2025-01-01 23:31:20 +00:00
### On/Off
2024-11-26 11:59:11 +00:00
2024-12-15 23:07:09 +00:00
You can force an active state by passing an `aria-pressed` prop.
2025-01-06 19:56:03 +00:00
::: tip When do I use a Toggle vs. a Button?
**Use a Button with an `aria-pressed` prop**
- if the semantics of the option change depending whether it's on or off
- to perform asynchronous, stateful and fallible actions
**Examples:**
- Toggle a remote property
- Open/close a section in the Ui
- Toolbar buttons that toggle through many options such as "Paragraph/Heading/List"
**Use the [Toggle component ](toggle ) (a.k.a. switch)**
- for options that don't cause side-effects and never change the Toggle label content based on the Toggle state (think of the traditional checkbox).
- for options that don't have any intermediary state besides "on" and "off"
**Examples:**
- A checkbox in the User settings
- A checkbox in a form that the user submits later
:::
2024-11-26 11:59:11 +00:00
```vue-html
2025-01-01 23:31:20 +00:00
< Button >
Off
< / Button >
2024-12-15 23:07:09 +00:00
< Button aria-pressed >
2025-01-01 23:31:20 +00:00
On
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-22 20:22:55 +00:00
**Default:**
2024-12-15 23:07:09 +00:00
< Button >
2025-01-01 23:31:20 +00:00
Off
2024-12-15 23:07:09 +00:00
< / Button >
< Button aria-pressed >
2025-01-01 23:31:20 +00:00
On
2024-12-15 23:07:09 +00:00
< / Button >
---
2024-12-22 20:22:55 +00:00
**Secondary:**
< Button secondary >
2025-01-01 23:31:20 +00:00
Off
2024-12-22 20:22:55 +00:00
< / Button >
< Button secondary aria-pressed >
2025-01-01 23:31:20 +00:00
On
2024-12-22 20:22:55 +00:00
< / Button >
---
2024-12-15 23:07:09 +00:00
**Primary:**
< Button primary >
2025-01-01 23:31:20 +00:00
Off
2024-12-15 23:07:09 +00:00
< / Button >
< Button primary aria-pressed >
2025-01-01 23:31:20 +00:00
On
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
### Disabled
2025-01-06 19:56:03 +00:00
Disabled buttons are non-interactive and inherit a less bold color than the one provided.
2024-11-26 11:59:11 +00:00
2025-01-06 19:56:03 +00:00
::: tip When do I use `disabled` ?
2025-01-01 23:31:20 +00:00
Use the `disabled` property for buttons that the user expects at a certain position, for example in a toolbar or in a row of action buttons.
If there is just one button in a form and its action is disabled, you may instead just remove it.
:::
2024-11-26 11:59:11 +00:00
```vue-html
2024-12-04 15:06:34 +00:00
< Button disabled >
2024-11-26 11:59:11 +00:00
Disabled button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-04 15:06:34 +00:00
< Button disabled >
2024-11-26 11:59:11 +00:00
Disabled button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
### Loading
If a user can't interact with a button until something has finished loading, you can add a spinner by passing the `is-loading` prop.
```vue-html
2024-12-04 15:06:34 +00:00
< Button is-loading >
2024-11-26 11:59:11 +00:00
Loading button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-04 15:06:34 +00:00
< Button is-loading >
2024-11-26 11:59:11 +00:00
Loading button
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
### Promise handling in `@click`
When a function passed to `@click` returns a promise, the button automatically toggles a loading state on click. When the promise resolves or is rejected, the loading state turns off.
::: danger
2024-12-04 15:06:34 +00:00
There is no promise rejection mechanism implemented in the `<Button>` component. Make sure the `@click` handler never rejects.
2024-11-26 11:59:11 +00:00
:::
```vue
< script setup lang = "ts" >
const click = () => new Promise((resolve) => setTimeout(resolve, 1000));
< / script >
< template >
2024-12-04 15:06:34 +00:00
< Button @click =" click " > Click me </ Button >
2024-11-26 11:59:11 +00:00
< / template >
```
2024-12-04 15:06:34 +00:00
< Button @click =" click " >
2024-11-26 11:59:11 +00:00
Click me
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
You can override the promise state by passing a false `is-loading` prop.
```vue-html
2024-12-04 15:06:34 +00:00
< Button :is-loading = "false" >
2024-11-26 11:59:11 +00:00
Click me
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-04 15:06:34 +00:00
< Button :is-loading = "false" >
2024-11-26 11:59:11 +00:00
Click me
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
2025-01-01 23:31:20 +00:00
## Add an icon
2024-11-26 11:59:11 +00:00
You can use [Bootstrap Icons ](https://icons.getbootstrap.com/ ) in your button component
::: info
2024-12-19 13:57:04 +00:00
Icon buttons shrink down to the icon size if you don't pass any content. If you want to keep the button at full width with just an icon, add `width=standard`
2024-11-26 11:59:11 +00:00
:::
```vue-html
2024-12-19 13:57:04 +00:00
< Button icon = "bi-three-dots-vertical" / >
2024-12-22 23:35:56 +00:00
< Button round icon = "bi-x large" / >
2024-12-22 20:19:49 +00:00
< Button primary icon = "bi-save" buttonWidth / >
2024-12-19 13:57:04 +00:00
< Button destructive icon = "bi-trash" >
2024-11-26 11:59:11 +00:00
Delete
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
```
2024-12-22 20:19:49 +00:00
< Layout flex >
2024-12-15 23:07:09 +00:00
< Button icon = "bi-three-dots-vertical" / >
2024-12-22 20:19:49 +00:00
< Button round secondary icon = "bi-x large" / >
< Button primary icon = "bi-save" buttonWidth / >
2024-12-15 23:07:09 +00:00
< Button destructive icon = "bi-trash" >
2024-11-26 11:59:11 +00:00
Delete
2024-12-04 15:06:34 +00:00
< / Button >
2024-12-22 20:19:49 +00:00
< / Layout >
2024-12-17 22:09:10 +00:00
2025-01-01 23:31:20 +00:00
## Set width and alignment
See [Using width ](/using-width ) and [Using alignment ](/using-alignment )
2024-12-17 22:09:10 +00:00
< Layout flex >
```vue-html
2024-12-30 12:18:28 +00:00
< Button min-content > 🐌< / Button >
< Button tiny > 🐌< / Button >
< Button buttonWidth > 🐌< / Button >
< Button small > 🐌< / Button >
< Button auto > 🐌< / Button >
2024-12-17 22:09:10 +00:00
< hr / >
2024-12-30 12:18:28 +00:00
< Button alignSelf = "start" > 🐌< / Button >
< Button alignSelf = "center" > 🐌< / Button >
< Button alignSelf = "end" > 🐌< / Button >
2024-12-17 22:09:10 +00:00
< hr / >
2024-12-30 12:18:28 +00:00
< Button alignText = "left" > 🐌< / Button >
< Button alignText = "center" > 🐌< / Button >
< Button alignText = "right" > 🐌< / Button >
2024-12-17 22:09:10 +00:00
```
2024-12-22 20:19:49 +00:00
< Layout class = "preview solid primary" stack no-gap >
2024-12-22 23:35:56 +00:00
< Button min-content > 🐌< / Button >
< Button tiny > 🐌< / Button >
< Button buttonWidth > 🐌< / Button >
< Button small > 🐌< / Button >
< Button auto > 🐌< / Button >
2024-12-17 22:09:10 +00:00
< hr / >
2024-12-22 23:35:56 +00:00
< Button alignSelf = "start" > 🐌< / Button >
< Button alignSelf = "center" > 🐌< / Button >
< Button alignSelf = "end" > 🐌< / Button >
2024-12-17 22:09:10 +00:00
< hr / >
2024-12-22 23:35:56 +00:00
< Button alignText = "left" > 🐌< / Button >
< Button alignText = "center" > 🐌< / Button >
< Button alignText = "right" > 🐌< / Button >
2024-12-17 22:09:10 +00:00
< / Layout >
< / Layout >