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

8.5 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>
Open modal Modal content

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>
Open modal Modal content Ok

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.

Customize the title bar

Use the icon prop and/or the #topleft slot for indicators such as the user's photo or a search input. You can hide the title by setting it to "".

<Button primary @click="isOpen10 = true"> Open modal <template #topleft> No information pages found for {{ input }}

Add a main alert

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>
Open modal Modal content Alert content Close alert Ok

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

    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

:::

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 using <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>
Open modal Nested modal content Open nested modal

Auto-focus the close button

If there are no action slots and no cancel button, the close button is auto-focused.

The autofocus prop, when set to off, overrides this behavior.

Responsivity

Designing for small screens

On slim phones, with the default 32px paddings, the content may only be 260px wide (Galaxy S5). Make sure the content wraps accordingly.