# Confirmations and undo

> When to ask before doing something, when to offer undo instead, and how Home Assistant keeps people from losing unsaved changes.

Source: https://contributors.home-assistant.io/design/patterns/confirmations/

Some actions can't be taken back. Deleting a dashboard, deleting a backup, discarding an hour of work on an automation. For those, Home Assistant asks first. For actions that can be reverted, it gets out of the way and offers undo.

## When to use

- **The action can't be undone**, like deleting something: ask with a confirmation dialog.
- **The action can be undone right away**: do it, and offer **Undo** in a toast. The automation editor does this when you delete a building block.
- **People are about to lose changes they did not save**: ask whether to save or discard them.

The words help here too. **Delete** means it is gone for good, **remove** means it can come back. See [Remove, delete, add, or create](https://contributors.home-assistant.io/design/ui-text/remove-delete/).

## How it works

### Confirmation dialogs

A confirmation dialog is a [dialog](https://contributors.home-assistant.io/design/components/dialog/) with a title, a short description, and two buttons.

- **Title**: people mostly read the title and the buttons, so put what matters there. Without a title, the dialog falls back to "Are you sure?", which says nothing about what happens.
- **Description**: for people who are unsure, explain what will happen.
- **Buttons**: **Cancel**, and a main button that says what it does: **Delete**, not **OK**. A destructive action uses the danger variant, so it is red.
- **No way around it**: a confirmation dialog has no close button, and does not close when you select outside of it. People choose one of the two buttons.

The example from the dialog guidelines:

> **Delete dashboard?**
>
> Dashboard Kitchen will be permanently deleted from Home Assistant.
>
> **Cancel** / **Delete**

Do and don't, as live demos.

**Do:** The button says what happens, in red because it can't be undone.

```html
<ha-button appearance="plain">Cancel</ha-button>
<ha-button variant="danger">Delete</ha-button>
```

**Don't:** A generic OK. People have to read the text to know what it does.

```html
<ha-button appearance="plain">Cancel</ha-button>
<ha-button>OK</ha-button>
```

When the action is destructive, focus starts on **Cancel**, so pressing <kbd>Enter</kbd> by reflex does not delete anything. For other confirmations, focus starts on the main button. While the action runs, the main button shows that it is busy.

### Undo

With undo, people do what they meant to do in one step, and can still change their mind. The [toast](https://contributors.home-assistant.io/design/patterns/errors/#toasts) with **Undo** stays for at least four seconds.

### Unsaved changes

Editors keep track of whether something changed since the last save. When it did:

- Leaving the editor asks first. The automation editor, for example, asks **Save changes?**: "You have made some changes in this automation. You can save these changes, or discard them and leave. You can't undo this action."
- Closing or reloading the browser tab shows the warning of the browser.
- A dialog with a changed form does not close with Escape or by selecting outside of it. It gives a little shake instead.

## Accessibility

- A confirmation dialog is announced as a dialog, with its title as its name, and its description linked to it.
- Focus moves into the dialog when it opens, and the safe choice gets focus for destructive actions.
- The red of a danger button is not the only signal. The label says **Delete**.

## Components

- [Dialog](https://contributors.home-assistant.io/design/components/dialog/)
- [Button](https://contributors.home-assistant.io/design/components/button/), with the danger variant
- [Errors and messages](https://contributors.home-assistant.io/design/patterns/errors/), for the toast with undo

## In code

```ts
const confirmed = await showConfirmationDialog(this, {
  title: this.hass.localize("ui.example.delete_title"),
  text: this.hass.localize("ui.example.delete_text"),
  confirmText: this.hass.localize("ui.common.delete"),
  destructive: true,
});
```

`showConfirmationDialog()` and `showAlertDialog()` live in [`src/dialogs/generic/show-dialog-box.ts`](https://github.com/home-assistant/frontend/blob/dev/src/dialogs/generic/show-dialog-box.ts). Pass `action` instead of waiting for the result when the main button should show progress while the work runs. For unsaved changes, editors use `DirtyStateProviderMixin` together with `PreventUnsavedMixin` from [`src/mixins/`](https://github.com/home-assistant/frontend/tree/dev/src/mixins).
