react-confirm-alert

What's new

What 3.1, 3.2 and 3.3 add. Code written for 3.0 keeps working.

Every release since 3.0 is a minor or patch release. Upgrade and your 3.0 code keeps working: confirmAlert, its options, the CSS path, the class names and the timing. The newest release comes first.

3.3

Plain HTML gets the default look

Inside a dialog, plain h1 to h3, p, label, input, textarea, select and button are styled with no class names. Any class you add wins. Tailwind v4 preflight does not remove them.

plain-html.tsx
'use client'
import { DialogLayout, openDialog } from 'react-confirm-alert'

export const pickTopic = () =>
  openDialog<string>({
    render: ({ close }) => (
      <form
        onSubmit={(e) => {
          e.preventDefault()
          close(new FormData(e.currentTarget).get('topic') as string)
        }}
      >
        <DialogLayout
          title="Send feedback"
          actions={[{ label: 'Send', variant: 'primary', type: 'submit' }]}
        >
          <label htmlFor="topic">Topic</label>
          <select id="topic" name="topic">
            <option>Bug</option>
            <option>Idea</option>
          </select>
        </DialogLayout>
      </form>
    ),
  }).result

DialogLayout

Lays out a title, a message, your content and a row of buttons. An action that returns a Promise is busy until it settles.

<DialogLayout
  title="Rename workspace"
  message="Everyone in it sees the new name."
  actions={[{ label: 'Save', variant: 'primary', onClick: save }]}
>
  <input aria-label="Name" defaultValue="Acme" />
</DialogLayout>

content under the message

confirm, alert and prompt take content, your JSX between the message and the buttons. message can be JSX too.

content.tsx
'use client'
import { confirm } from 'react-confirm-alert'

export const archiveBoard = () =>
  confirm({
    title: 'Archive “Launch” board?',
    content: <p>12 cards move to the archive with it.</p>,
    confirmLabel: 'Archive',
  })

skin for confirmAlert

skin: true gives confirmAlert the new look, customUI included. Without it, confirmAlert keeps the 3.0 look.

configureDialogs({ confirmAlert: { skin: true } })

Fixed in 3.3

  • A textarea with data-slot="input" fills the width and resizes vertically.
  • In dark mode, a select's option list is dark too.

3.2

A new default look

confirm, alert, prompt and <Dialog> use your app's font. Cancel is secondary, the action is primary, and tone: 'danger' is red. On narrow screens the buttons go full width. Opening, closing and a waiting button are animated, except under reduced motion.

confirmAlert keeps the 3.0 look. Every colour is a --rca-* variable. Styling lists them.

Dark mode, when you turn it on

Put .dark or data-theme="dark" on an ancestor. The library does not follow the OS on its own.

<html class="dark">

Hover colours you can set

From 3.2.1, the main and danger buttons get 15% darker on hover. Set your own with two variables:

:root {
  --rca-button-bg-hover: #4338ca;
  --rca-danger-hover: #b91c1c;
}

Fixed in 3.2

  • Closing a dialog with Enter no longer opens it again in Chromium (#84).
  • confirmAlert({ message: 'a\nb' }) keeps the line break (#38).
  • From 3.2.1, a disabled button keeps readable text.

3.1

Promise API

confirm, alert, prompt and openDialog return a Promise, so the code reads top to bottom.

if (await confirm('Delete this file?')) await moveToTrash(file)

Dialogs in your tree

<DialogHost /> renders dialogs inside your providers. <Dialog open> and <ConfirmDialog open> render in place and read your state.

<ConfirmDialog
  kind="confirm"
  open={open}
  onOpenChange={setOpen}
  title="Leave without saving?"
/>

Queue and stack

A dialog opened from another stacks on top, the default. strategy: 'queue' waits for the one before to close.

alert({ title: 'Two', strategy: 'queue' })

Defaults and class names

configureDialogs() sets defaults for every dialog. classNames adds a class per slot, and unstyled: true drops the default CSS. --rca-width sets the width.

configureDialogs({ classNames: { button: 'rounded-full' } })

3.1.1: a shorter CSS path

import 'react-confirm-alert/style.css'

The 3.0 path, react-confirm-alert/src/react-confirm-alert.css, still works.

Fixed in 3.1

  • The blur shows on every open (#77).
  • A press that starts inside and ends outside no longer closes the dialog (#92).
  • Focus moves into the dialog and back (#29).
  • Opening a dialog while one is open no longer logs a createRoot error (#82).
  • modal: true sits above any z-index (#31).
  • Vite no longer needs prop-types (#85).

On this page