9.2 KiB
import Modal from "~/components/ui/Modal.vue";
Modal
Prop | Data type | Required? | Default | Description |
---|---|---|---|---|
title |
string |
Yes | The modal title | |
v-model |
true | false |
No | Whether the modal is isOpen or not |
<Button @click="isOpen = true">
Open modal
</Button>
<Modal v-model="isOpen" title="My modal">
Modal content
</Modal>
Add actions
Use the #actions
slot to add actions to a modal. Actions typically take the form of buttons.
Make sure to add autofocus
to the preferred button.
<Button @click="isOpen = true">
Open modal
</Button>
<Modal v-model="isOpen" title="My modal">
Modal content
<template #actions>
<Button secondary @click="isOpen2 = false" icon="bi-arrow-left"/>
<Button autofocus @click="isOpen = false">
Ok
</Button>
</template>
</Modal>
Add a cancel button
All modals can be closed so it makes sense to add a cancel
button. Note that Modal
also implements the ESC
shortcut by default.
The cancel
prop accepts a string and will add a cancel button.
Note that the Cancel button has autofocus
. If you want another button to auto-focus, implement the Cancel button manually inside the #action
slot.
Add elements to the top left corner
Use this slot for indicators such as the user's photo.
<Button primary @click="isOpen10 = true"> Open modal Modal content <template #topleft> <template #actions> <Button autofocus @click="isOpen10 = false"> Ok
Alert inside modal
You can nest Funkwhale alerts to visually highlight content within the modal.
<Button @click="isOpen = true">
Open modal
</Button>
<Modal v-model="isOpen8" title="My modal" cancel="Cancel">
Modal content
<template #alert v-if="alertOpen">
<Alert>
Alert content
<template #actions>
<Button autofocus @click="alertOpen = false">Close alert</Button>
</template>
</Alert>
</template>
</Modal>
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
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.
-
How to design a confirmation dialog
- Let the user confirm potentially destructive actions
- Do not use confirmation dialogs for routine tasks
- Be specific about the action and its potential consequences
- Label the response buttons with their result: "Delete my account" instead of "Yes"
- Make sure to give the user all information they need to decide
:::
Destructive Modal
The destructive
prop is used to visually indicate a potentially dangerous or irreversible action. When set to true
, the modal will have a distinctive red styling to draw the user's attention and highlight the critical nature of the action.
Prop | Data type | Required? | Default | Description |
---|---|---|---|---|
destructive |
true |
No | false |
Applies a red styling to emphasize dangerous actions |
Styling Effects
When the destructive
prop is set to true
, the modal will:
- Add a red border
- Style the title in red
To visually distinguish the modal from standard modals
Best Practices
- Use the
destructive
prop sparingly - Clearly explain the consequences of the action unsing
<Alert red>
- Provide a clear way to cancel the action. If you use the
cancel
prop, the Cancel button will have autofocus, preventing accidental confirmation. - Use descriptive action button labels
The example in the "Confirm a dangerous action" section demonstrates the recommended usage of the destructive modal.
<Button
@click="isOpen4 = true"
destructive
>
Delete my account
</Button>
<Modal
v-model="isOpen4"
title="Delete Account?"
destructive
cancel="Cancel"
>
<template #alert>
<Alert red>
Detailed consequences of the action
</Alert>
</template>
<template #actions>
<Button
destructive
@click="isOpen4 = false"
>
Confirm Deletion
</Button>
</template>
</Modal>
<Button @click="isOpen4 = true" destructive
Delete my account <Modal v-model="isOpen4" title="Delete Account?" destructive cancel="Cancel"
<template #alert> Detailed consequences of the action <template #actions> <Button destructive @click="isOpen4 = false" > Confirm Deletion
Nested modals
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.
<Button @click="isOpen = true">
Open modal
</Button>
<Modal v-model="isOpen" title="My modal">
<Modal v-model="isOpenNested" title="My modal">
Nested modal content
</Modal>
<Button autofocus @click="isOpenNested = true">
Open nested modal
</Button>
</Modal>
Responsivity
Designing for small screens
On slim phones, the content may only be 260px wide (Galaxy S5). Make sure the content wraps accordingly.
Long, scrolling content
Consider using an indicator such as a line or a shadow to convey that there is content below the fold.
<Button primary @click="isOpen9 = true">
Open modal
</Button>
<Modal v-model="isOpen9" title="Long content">
Nested modal content
<section v-for="index in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]">
<h2>{{ index }}</h2>
<p>
<span v-for="_ in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]">Lorem ipsum dolor sit amet.</span>
</p>
</section>
<template #actions>
<div style="background: currentcolor; opacity: .2; width: 100%; height: 1px;" > </div>
</template>
</Modal>
<Button primary @click="isOpen9 = true"> Open modal Nested modal content
{{ index }}
Lorem ipsum dolor sit amet.