2024-11-26 11:59:11 +00:00
< script setup lang = "ts" >
import { ref, watchEffect } from 'vue'
2024-12-04 15:06:34 +00:00
import Alert from '~/components/ui/Alert.vue'
import Button from '~/components/ui/Button.vue'
import Modal from '~/components/ui/Modal.vue'
2024-12-08 22:35:34 +00:00
import Layout from '~/components/ui/Layout.vue'
2024-12-04 15:06:34 +00:00
2024-12-08 19:34:52 +00:00
const isOpen = ref(false)
const isOpen2 = ref(false)
const isOpen3 = ref(false)
2024-12-08 22:35:34 +00:00
2024-11-26 11:59:11 +00:00
const alertOpen = ref(true)
watchEffect(() => {
2024-12-08 19:34:52 +00:00
if (isOpen3.value === false) {
2024-11-26 11:59:11 +00:00
alertOpen.value = true
}
})
2024-12-08 19:34:52 +00:00
const isOpen4 = ref(false)
const isOpen5 = ref(false)
2024-12-08 22:35:34 +00:00
const isOpen6 = ref(false)
2024-11-26 11:59:11 +00:00
< / script >
# Modal
2024-12-08 19:34:52 +00:00
| Prop | Data type | Required? | Default | Description |
| --------- | ----------------- | --------- | ------- | ---------------------------------- |
| `title` | `string` | Yes | | The modal title |
2024-12-12 09:41:43 +00:00
| `v-model` | `true` \| `false` | No | | Whether the modal is isOpen or not |
2024-11-26 11:59:11 +00:00
2024-12-08 22:35:34 +00:00
< Layout flex >
2024-11-26 11:59:11 +00:00
```vue-html
2024-12-08 19:34:52 +00:00
< Button @click =" isOpen = true" >
2024-11-26 11:59:11 +00:00
Open modal
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
2024-12-08 19:34:52 +00:00
< Modal v-model = "isOpen" title = "My modal" >
2024-11-26 11:59:11 +00:00
Modal content
2024-12-04 15:06:34 +00:00
< / Modal >
2024-12-09 09:49:11 +00:00
```
< div class = "preview" >
2024-12-08 19:34:52 +00:00
< Button @click =" isOpen = true" >
2024-11-26 11:59:11 +00:00
Open modal
2024-12-04 15:06:34 +00:00
< / Button >
2024-12-09 09:49:11 +00:00
< Modal v-model = "isOpen" title = "My modal" >
Modal content
< / Modal >
2024-12-08 22:35:34 +00:00
< / div >
< / Layout >
2024-11-26 11:59:11 +00:00
## Modal actions
2024-12-04 15:06:34 +00:00
Use the `#actions` slot to add actions to a modal. Actions typically take the form of [buttons ](./button ).
2024-11-26 11:59:11 +00:00
2024-12-08 22:35:34 +00:00
Make sure to add `autofocus` to the preferred button.
< Layout flex >
2024-11-26 11:59:11 +00:00
```vue-html
2024-12-09 09:49:11 +00:00
< Button @click =" isOpen = true" >
Open modal
< / Button >
2024-12-08 19:34:52 +00:00
< Modal v-model = "isOpen" title = "My modal" >
2024-11-26 11:59:11 +00:00
Modal content
< template #actions >
2024-12-15 23:07:09 +00:00
< Button @click =" isOpen = false" >
2024-11-26 11:59:11 +00:00
Cancel
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
2024-12-08 22:35:34 +00:00
< Button autofocus @click = "isOpen = false" >
2024-11-26 11:59:11 +00:00
Ok
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
< / template >
2024-12-04 15:06:34 +00:00
< / Modal >
2024-11-26 11:59:11 +00:00
```
2024-12-08 22:35:34 +00:00
< div class = "preview" >
2024-12-09 09:49:11 +00:00
< Button @click =" isOpen2 = true" >
Open modal
< / Button >
2024-12-08 19:34:52 +00:00
< Modal v-model = "isOpen2" title = "My modal" >
2024-11-26 11:59:11 +00:00
Modal content
< template #actions >
2024-12-15 23:07:09 +00:00
< Button @click =" isOpen2 = false" >
2024-11-26 11:59:11 +00:00
Cancel
2024-12-04 15:06:34 +00:00
< / Button >
2024-12-08 22:35:34 +00:00
< Button autofocus @click = "isOpen2 = false" >
2024-11-26 11:59:11 +00:00
Ok
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
< / template >
2024-12-04 15:06:34 +00:00
< / Modal >
2024-12-08 22:35:34 +00:00
< / div >
< / Layout >
### Confirm a dangerous action
Note that confirmation dialogs interrupt the user's workflow. Consider adding a recovery functionality such as "undo" instead.
::: tip Read more about designing user experiences around dangerous actions:
- [How to use visual signals and spacing to differentiate between benign and dangerous options ](https://www.nngroup.com/articles/proximity-consequential-options/ )
2024-12-09 09:49:11 +00:00
> If you need to implement dangerous actions, make sure to place them apart from other actions to prevent accidental clicks. Add contextual hints and information so that the user understands the consequences of the action.
2024-12-08 22:35:34 +00:00
- [How to design a confirmation dialog ](https://www.nngroup.com/articles/confirmation-dialog/ )
2024-12-09 09:49:11 +00:00
> 1. Let the user confirm potentially destructive actions
> 2. Do not use confirmation dialogs for routine tasks
> 3. Be specific about the action and its potential consequences
> 4. Label the response buttons with their result: "Delete my account" instead of "Yes"
> 5. Make sure to give the user all information they need to decide
2024-12-08 22:35:34 +00:00
:::
```vue-html
2024-12-15 23:07:09 +00:00
< Button @click =" isOpen = true" destructive >
2024-12-09 09:49:11 +00:00
Delete my account ...
< / Button >
2024-12-08 22:35:34 +00:00
< Modal v-model = "isOpen" title = "Delete account?" >
< template #alert >
2024-12-15 23:07:09 +00:00
< Alert red >
2024-12-08 22:35:34 +00:00
1 082 music files that you uploaded will be deleted.< br / >
7 879 items in your collections will be unlinked.
< / Alert >
< / template >
Do you want to delete your account forever?
You will not be able to restore your account.
< template #actions >
2024-12-15 23:07:09 +00:00
< Button autofocus @click = "isOpen = false" >
2024-12-08 22:35:34 +00:00
Keep my account
< / Button >
2024-12-15 23:07:09 +00:00
< Button destructive @click = "isOpen = false" >
2024-12-08 22:35:34 +00:00
I understand. Delete my account now!
< / Button >
< / template >
< / Modal >
```
2024-12-15 23:07:09 +00:00
< Button @click =" isOpen6 = true" destructive >
2024-12-09 09:49:11 +00:00
Delete my account ...
< / Button >
2024-12-08 22:35:34 +00:00
< Modal v-model = "isOpen6" title = "Delete account?" >
2024-12-12 09:41:43 +00:00
< template #alert >
2024-12-15 23:07:09 +00:00
< Alert red >
2024-12-08 22:35:34 +00:00
1 082 music files that you uploaded will be deleted.< br / >
7 879 items in your collections will be unlinked.
2024-12-12 09:41:43 +00:00
< / Alert >
< / template >
2024-12-08 22:35:34 +00:00
Do you want to delete your account forever?
You will not be able to restore your account.
2024-12-09 09:49:11 +00:00
< template #actions >
2024-12-15 23:07:09 +00:00
< Button autofocus @click = "isOpen6 = false" >
2024-12-09 09:49:11 +00:00
Keep my account
< / Button >
2024-12-15 23:07:09 +00:00
< Button destructive @click = "isOpen6 = false" >
2024-12-09 09:49:11 +00:00
I understand. Delete my account now!
2024-12-08 22:35:34 +00:00
< / Button >
2024-12-09 09:49:11 +00:00
< / template >
< / Modal >
2024-11-26 11:59:11 +00:00
## Nested modals
2024-12-08 19:34:52 +00:00
You can nest modals to allow users to isOpen a modal from inside another modal. This can be useful when creating a multi-step workflow.
2024-11-26 11:59:11 +00:00
2024-12-08 22:35:34 +00:00
< Layout flex >
2024-11-26 11:59:11 +00:00
```vue-html
2024-12-09 09:49:11 +00:00
< Button @click =" isOpen = true" >
Open modal
< / Button >
2024-12-08 19:34:52 +00:00
< Modal v-model = "isOpen" title = "My modal" >
< Modal v-model = "isOpenNested" title = "My modal" >
2024-11-26 11:59:11 +00:00
Nested modal content
2024-12-04 15:06:34 +00:00
< / Modal >
2024-11-26 11:59:11 +00:00
2024-12-08 22:35:34 +00:00
< Button autofocus @click = "isOpenNested = true" >
2024-11-26 11:59:11 +00:00
Open nested modal
2024-12-04 15:06:34 +00:00
< / Button >
< / Modal >
2024-11-26 11:59:11 +00:00
```
2024-12-08 22:35:34 +00:00
< div class = "preview" >
2024-12-09 09:49:11 +00:00
< Button @click =" isOpen4 = true" >
Open modal
< / Button >
2024-12-08 19:34:52 +00:00
< Modal v-model = "isOpen4" title = "My modal" >
< Modal v-model = "isOpen5" title = "My modal" >
2024-11-26 11:59:11 +00:00
Nested modal content
2024-12-04 15:06:34 +00:00
< / Modal >
2024-12-08 22:35:34 +00:00
< Button autofocus @click = "isOpen5 = true" >
2024-11-26 11:59:11 +00:00
Open nested modal
2024-12-04 15:06:34 +00:00
< / Button >
< / Modal >
2024-12-08 22:35:34 +00:00
< / div >
< / Layout >
2024-11-26 11:59:11 +00:00
## Alert inside modal
2024-12-04 15:06:34 +00:00
You can nest [Funkwhale alerts ](./alert ) to visually highlight content within the modal.
2024-11-26 11:59:11 +00:00
2024-12-08 22:35:34 +00:00
< Layout flex >
2024-11-26 11:59:11 +00:00
```vue-html
2024-12-09 09:49:11 +00:00
< Button @click =" isOpen = true" >
Open modal
< / Button >
2024-12-08 19:34:52 +00:00
< Modal v-model = "isOpen" title = "My modal" >
2024-11-26 11:59:11 +00:00
Modal content
< template #alert v-if = "alertOpen" >
< fw-alert >
Alert content
< template #actions >
2024-12-08 22:35:34 +00:00
< Button autofocus @click = "alertOpen = false" > Close alert</ Button >
2024-11-26 11:59:11 +00:00
< / template >
< / fw-alert >
< / template >
2024-12-04 15:06:34 +00:00
< / Modal >
2024-11-26 11:59:11 +00:00
```
2024-12-08 22:35:34 +00:00
< div class = "preview" >
2024-12-09 09:49:11 +00:00
< Button @click =" isOpen3 = true" >
Open modal
< / Button >
2024-12-08 19:34:52 +00:00
< Modal v-model = "isOpen3" title = "My modal" >
2024-11-26 11:59:11 +00:00
Modal content
< template #alert v-if = "alertOpen" >
2024-12-15 23:07:09 +00:00
< Alert blue >
2024-11-26 11:59:11 +00:00
Alert content
< template #actions >
2024-12-08 22:35:34 +00:00
< Button autofocus @click = "alertOpen = false" > Close alert</ Button >
2024-11-26 11:59:11 +00:00
< / template >
2024-12-04 15:06:34 +00:00
< / Alert >
2024-11-26 11:59:11 +00:00
< / template >
< template #actions >
2024-12-08 19:34:52 +00:00
< Button @click =" isOpen3 = false" color = "secondary" >
2024-11-26 11:59:11 +00:00
Cancel
2024-12-04 15:06:34 +00:00
< / Button >
2024-12-15 23:07:09 +00:00
< Button primary @click = "isOpen3 = false" >
2024-11-26 11:59:11 +00:00
Ok
2024-12-04 15:06:34 +00:00
< / Button >
2024-11-26 11:59:11 +00:00
< / template >
2024-12-04 15:06:34 +00:00
< / Modal >
2024-12-08 22:35:34 +00:00
< / div >
< / Layout >