funkwhale/front/ui-docs/components/ui/button.md

447 wiersze
8.3 KiB
Markdown
Czysty Zwykły widok Historia

2024-12-22 23:35:56 +00:00
<script setup lang="ts">
import Button from '~/components/ui/Button.vue'
import Layout from '~/components/ui/Layout.vue'
2024-12-22 23:35:56 +00:00
const click = ():Promise<void> => new Promise(resolve => setTimeout(resolve, 1000))
</script>
# Button
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.
```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
& AlignmentProps
```
## Button colors
Buttons come in different types depending on the type of action they represent.
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">
```vue-html
<Button>
Default button
</Button>
```
2024-12-22 20:22:55 +00:00
</div>
<Button>
Default button
</Button>
</Layout>
### 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">
```vue-html
<Button primary>
Primary button
</Button>
```
2024-12-22 20:22:55 +00:00
</div>
<Button primary>
Primary button
</Button>
2024-12-22 20:22:55 +00:00
</Layout>
### 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">
```vue-html
2024-12-22 20:22:55 +00:00
<Button secondary raised>
Secondary button
</Button>
```
2024-12-22 20:22:55 +00:00
</div>
<Button secondary raised>
Secondary button
</Button>
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.
### 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">
```vue-html
<Button destructive>
Destructive button
</Button>
```
2024-12-22 20:22:55 +00:00
</div>
<Button destructive>
Destructive button
</Button>
2024-12-22 20:22:55 +00:00
</Layout>
## 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
<Button>
Filled button
</Button>
<Button solid>
Also filled button
</Button>
```
<Button>
Filled button
</Button>
<Button solid>
Also filled button
</Button>
### Outline
Outline buttons have a transparent background. Use these to deemphasize the action the button performs.
```vue-html
<Button outline secondary>
Outline button
</Button>
```
<Button outline secondary>
Outline button
</Button>
### Ghost
Ghost buttons have a transparent background and border. Use these to deemphasize the action the button performs.
```vue-html
<Button ghost secondary>
Ghost button
</Button>
```
<Button ghost secondary>
Ghost button
</Button>
## Button styles
### Shadow
You can give a button a shadow to add depth.
```vue-html
<Button shadow>
Shadow button
</Button>
```
<Button shadow>
Shadow button
</Button>
## 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
<Button>
Normal button
</Button>
```
<Button>
Normal button
</Button>
### Round
Round buttons have fully rounded edges.
```vue-html
<Button round>
Round button
</Button>
```
<Button round>
Round button
</Button>
## Button states
### On/Off
You can force an active state by passing an `aria-pressed` prop.
::: 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
:::
```vue-html
<Button>
Off
</Button>
<Button aria-pressed>
On
</Button>
```
2024-12-22 20:22:55 +00:00
**Default:**
<Button>
Off
</Button>
<Button aria-pressed>
On
</Button>
---
2024-12-22 20:22:55 +00:00
**Secondary:**
<Button secondary>
Off
2024-12-22 20:22:55 +00:00
</Button>
<Button secondary aria-pressed>
On
2024-12-22 20:22:55 +00:00
</Button>
---
**Primary:**
<Button primary>
Off
</Button>
<Button primary aria-pressed>
On
</Button>
### Disabled
Disabled buttons are non-interactive and inherit a less bold color than the one provided.
::: tip When do I use `disabled`?
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.
:::
```vue-html
<Button disabled>
Disabled button
</Button>
```
<Button disabled>
Disabled button
</Button>
### 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
<Button is-loading>
Loading button
</Button>
```
<Button is-loading>
Loading button
</Button>
### 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
There is no promise rejection mechanism implemented in the `<Button>` component. Make sure the `@click` handler never rejects.
:::
```vue
<script setup lang="ts">
const click = () => new Promise((resolve) => setTimeout(resolve, 1000));
</script>
<template>
<Button @click="click"> Click me </Button>
</template>
```
<Button @click="click">
Click me
</Button>
You can override the promise state by passing a false `is-loading` prop.
```vue-html
<Button :is-loading="false">
Click me
</Button>
```
<Button :is-loading="false">
Click me
</Button>
## Add an icon
You can use [Bootstrap Icons](https://icons.getbootstrap.com/) in your button component
::: info
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`
:::
```vue-html
<Button icon="bi-three-dots-vertical" />
2024-12-22 23:35:56 +00:00
<Button round icon="bi-x large" />
<Button primary icon="bi-save" buttonWidth/>
<Button destructive icon="bi-trash">
Delete
</Button>
```
<Layout flex>
<Button icon="bi-three-dots-vertical" />
<Button round secondary icon="bi-x large" />
<Button primary icon="bi-save" buttonWidth/>
<Button destructive icon="bi-trash">
Delete
</Button>
</Layout>
## Set width and alignment
See [Using width](/using-width) and [Using alignment](/using-alignment)
<Layout flex>
```vue-html
<Button min-content>🐌</Button>
<Button tiny>🐌</Button>
<Button buttonWidth>🐌</Button>
<Button small>🐌</Button>
<Button auto>🐌</Button>
<hr />
<Button alignSelf="start">🐌</Button>
<Button alignSelf="center">🐌</Button>
<Button alignSelf="end">🐌</Button>
<hr />
<Button alignText="left">🐌</Button>
<Button alignText="center">🐌</Button>
<Button alignText="right">🐌</Button>
```
<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>
<hr />
2024-12-22 23:35:56 +00:00
<Button alignSelf="start">🐌</Button>
<Button alignSelf="center">🐌</Button>
<Button alignSelf="end">🐌</Button>
<hr />
2024-12-22 23:35:56 +00:00
<Button alignText="left">🐌</Button>
<Button alignText="center">🐌</Button>
<Button alignText="right">🐌</Button>
</Layout>
</Layout>