Przejdź do treści

Alert Dialog

Stabilny

Modalne okno potwierdzenia, które zatrzymuje użytkownika przed akcją o poważnych lub nieodwracalnych skutkach. Zamknąć je można tylko, dokonując wyboru.

Instalacja

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/alert-dialog.json

Użycie

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogMedia,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
const [open, setOpen] = React.useState(false)

<AlertDialog open={open} onOpenChange={setOpen}>
  <AlertDialogTrigger render={<Button variant="outline" />}>Delete project</AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Delete “Atlas”?</AlertDialogTitle>
      <AlertDialogDescription>This can’t be undone.</AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Keep project</AlertDialogCancel>
      <AlertDialogAction variant="destructive" onClick={deleteProject}>
        Delete project
      </AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>
Przycisk akcji nie zamyka okna
AlertDialogCancel zamyka okno. AlertDialogAction to celowo zwykły Button: potwierdzona operacja często jest asynchroniczna, a okno powinno pozostać otwarte — z akcją w stanie loading — aż do jej powodzenia lub błędu. Kontroluj open i zamknij okno samodzielnie, gdy operacja się zakończy.

Przykłady

Podstawowy

Często wystarczą tytuł i opis. Opis mówi, co zostanie utracone, a przyciski — co robi każdy z wyborów.

Grafika

AlertDialogMedia dodaje ikonę, która nadaje ton, zanim ktokolwiek przeczyta tytuł. Dopasuj jej variant do skutków — destructive przy utracie danych, warning przy zakłóceniach, success przy potwierdzaniu czegoś dobrego, czego nie da się cofnąć, brand przy ważnych, ale bezpiecznych akcjach, default w pozostałych przypadkach — i nadaj przyciskowi akcji ten sam stopień wyróżnienia.

Mały

size="sm" wyśrodkowuje treść i dzieli stopkę na dwa równe przyciski. Używaj go do krótkich pytań z dwiema możliwymi odpowiedziami — o uprawnienia czy szybkie zgody — zwłaszcza na urządzeniach mobilnych.

Potwierdzenie przez wpisanie

Przy akcjach, które za jednym razem niszczą dużo pracy, poproś o wpisanie nazwy tego, co ma zostać usunięte. Przycisk akcji pozostaje wyłączony, dopóki tekst się nie zgadza, co zapobiega potwierdzaniu z przyzwyczajenia.

Akcja asynchroniczna

Nie zamykaj okna, gdy trwa żądanie: przełącz akcję w stan loading, wyłącz anulowanie i ignoruj próby zamknięcia, dopóki operacja się nie zakończy. Potem zamknij okno i potwierdź wynik powiadomieniem Toast.

<AlertDialog open={open} onOpenChange={(next) => !pending && setOpen(next)}>
  {/* … */}
  <AlertDialogCancel disabled={pending}>Cancel</AlertDialogCancel>
  <AlertDialogAction variant="destructive" loading={pending} onClick={revoke}>
    Revoke key
  </AlertDialogAction>
</AlertDialog>

Wytyczne

Kiedy używać

  • Przed akcjami nieodwracalnymi: usuwaniem, unieważnianiem, trwałym usuwaniem osób.
  • Przed akcjami o szerokim zasięgu skutków: wdrożeniem na produkcję, odłączeniem integracji, wylogowaniem ze wszystkich urządzeń.
  • Gdy wyjście oznaczałoby utratę pracy, której nie da się odzyskać.

Kiedy nie używać

  • Przy akcjach, które da się cofnąć — wykonaj je od razu i zaproponuj Cofnij w powiadomieniu Toast. Możliwość cofnięcia jest zawsze życzliwsza niż potwierdzenie.
  • Do zbierania danych lub wyświetlania informacji — użyj komponentu Dialog.
  • Do informowania, że coś poszło nie tak — użyj komponentu Alert w treści strony albo powiadomienia.

Potwierdzaj rzadko

Każde potwierdzenie uczy ludzi odruchowo przeklikiwać kolejne. Zachowaj okna potwierdzenia na nieliczne momenty, które na to zasługują, i mów w nich konkretnie: podaj nazwę, liczbę i skutek.

Nazwij wybory

Tytuł zadaje jedno pytanie. Przycisk akcji powtarza czasownik z tytułu, a przycisk anulowania mówi, co pozostanie bez zmian. Nigdy nie używaj Tak, Nie ani OK.

Usunąć 3 pliki?Znikną dla wszystkich.
Dobrze.Pytanie i przyciski używają tego samego czasownika.
Czy na pewno?Tej akcji nie można cofnąć.
Źle.„Tak” i „Nie” zmuszają do ponownego czytania pytania pod presją.

Kolejność i wyróżnienie

Umieść akcję na końcu — po prawej od sm wzwyż, na górze, gdy na urządzeniach mobilnych przyciski w stopce układają się jeden pod drugim — a anulowanie przed nią. Przycisku destructive używaj tylko do akcji nieodwracalnych: czerwień oznacza zaraz coś stracisz.

Dostępność

Alert Dialog realizuje wzorzec WAI-ARIA Alert Dialog. Base UI renderuje go z role="alertdialog"; tytuł staje się jego nazwą dostępną, a opis — opisem dostępnym. Dzięki temu czytnik ekranu ogłasza skutki od razu po otwarciu okna.

KlawiszDziałanie
EnterSpacja
Na wyzwalaczu: otwiera okno potwierdzenia.
Tab
Przechodzi między wyborami. Fokus nie może opuścić okna.
ShiftTab
Przenosi fokus wstecz; z pierwszego elementu przechodzi na ostatni.
Esc
Zamyka okno — tak samo jak wybór Anuluj — i przywraca fokus na wyzwalacz.
  • Bez zamykania kliknięciem obok. Kliknięcie przyciemnionego tła nie zamyka okna potwierdzenia: trzeba dokonać wyboru. Esc nadal działa jak Anuluj.
  • Tytuł i opis są wymagane. Tylko z nich użytkownik czytnika ekranu dowie się, co potwierdza.
  • Fokus. Fokus trafia na pierwszy element, który może go przyjąć — zwykle przycisk anulowania, czyli bezpieczny wybór — a po zamknięciu wraca na wyzwalacz.
  • Kolor nigdy nie jest jedynym sygnałem. Akcja nieodwracalna jest czerwona, a jej etykieta dodatkowo mówi Usuń.

Dokumentacja API

AlertDialog

Komponent główny. Nie renderuje żadnego elementu. Przyjmuje wszystkie propsy AlertDialog.Root z Base UI — te same co Dialog, bez modaldisablePointerDismissal, które są zawsze włączone.

PropTypDomyślnie
open

Czy okno jest otwarte. Steruj nim, gdy akcja jest asynchroniczna.

booleanBrak wartości domyślnej
defaultOpen

Czy okno jest początkowo otwarte (w trybie niekontrolowanym).

booleanfalse
onOpenChange

Wywoływana, gdy okno się otwiera lub zamyka.

(open: boolean, details) => voidBrak wartości domyślnej
onOpenChangeComplete

Wywoływana po zakończeniu animacji otwierania lub zamykania.

(open: boolean) => voidBrak wartości domyślnej
actionsRef

Imperatywny uchwyt do zamknięcia lub odmontowania okna.

RefObject<{ close, unmount }>Brak wartości domyślnej

AlertDialogContent

Renderuje portal, przyciemnione tło i samo okno.

PropTypDomyślnie
size

sm wyśrodkowuje treść, zwęża okno i dzieli stopkę na dwa równe przyciski.

"default" | "sm""default"
initialFocus

Element, który otrzymuje fokus po otwarciu.

boolean | RefObject | (interaction) => HTMLElement | booleanBrak wartości domyślnej
finalFocus

Element, który otrzymuje fokus po zamknięciu.

boolean | RefObject | (interaction) => HTMLElement | booleanBrak wartości domyślnej

AlertDialogMedia

Ikona w kolorowym kółku, wyświetlana obok tytułu (albo nad nim w małych oknach).

PropTypDomyślnie
variant

Kolor kółka z ikoną. Dopasuj go do skutków akcji.

"default" | "destructive" | "warning" | "success" | "brand""default"

AlertDialogAction

Button z prfct. Przyjmuje wszystkie propsy Button — variant, loading, disabled — i nie zamyka okna.

AlertDialogCancel

Zamyka okno. Renderuje Button z prfct.

PropTypDomyślnie
variant

Stopień wyróżnienia przycisku.

Button variant"outline"
size

Rozmiar przycisku.

Button size"default"

AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter

Części układu. AlertDialogTitle renderuje <h2> i nadaje oknu nazwę; AlertDialogDescription renderuje <p> i je opisuje. AlertDialogFooter na małych ekranach układa wybory jeden pod drugim, a od sm wzwyż wyrównuje je do prawej.