Alert
Trwały komunikat osadzony w treści, który informuje o czymś ważnym dla bieżącej strony lub zadania.
import { InfoIcon } from "lucide-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
export default function AlertDemo() {
return (
<Alert variant="info" className="max-w-sm">
<InfoIcon />
<AlertTitle>Planowana przerwa techniczna</AlertTitle>
<AlertDescription>
W niedzielę od 02:00 do 03:00 UTC pulpit będzie dostępny tylko do odczytu.
</AlertDescription>
</Alert>
)
}Anatomia
- 1IkonaPozwala od razu rozpoznać rodzaj komunikatu. Przyjmuje kolor wariantu, ale nigdy nie niesie znaczenia sama.
- 2KontenerObramowana, lekko zabarwiona powierzchnia. Wariant ustala jej kolory i rolę: status w większości przypadków, alert przy ostrzeżeniach i błędach.
- 3TytułJeden wiersz, który mówi, co się stało lub co trzeba wiedzieć.
- 4OpisSzczegóły i, jeśli jest, następny krok. Neutralny tekst.
Instalacja
$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/alert.jsonUżycie
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"<Alert variant="warning">
<TriangleAlertIcon />
<AlertTitle>Your trial ends in 3 days</AlertTitle>
<AlertDescription>Add a payment method to keep your projects running.</AlertDescription>
</Alert>Przykłady
Warianty
Pięć wariantów: default jest neutralny, a pozostałe cztery odpowiadają skalom statusów. Wariant statusu barwi tło stopniem 2, rysuje obramowanie stopniem 6, ikonie nadaje stopień 11, a tytułowi stopień 12; default używa powierzchni karty i standardowego obramowania. Opis pozostaje neutralny w każdym wariancie, więc status widać od razu, a szczegóły czyta się wygodnie, z kontrastem co najmniej 4,5:1 w obu trybach.
import {
CircleAlertIcon,
CircleCheckIcon,
InfoIcon,
TerminalIcon,
TriangleAlertIcon,
} from "lucide-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
export default function AlertVariants() {
return (
<div className="flex w-full max-w-lg flex-col gap-3">
<Alert>
<TerminalIcon />
<AlertTitle>Nowa wersja CLI</AlertTitle>
<AlertDescription>
Wersja 4.2 wprowadza przestrzenie nazw w rejestrze i szybszą instalację.
</AlertDescription>
</Alert>
<Alert variant="info">
<InfoIcon />
<AlertTitle>Zaproszenia wygasają po 7 dniach</AlertTitle>
<AlertDescription>
Zaproszenie możesz w każdej chwili wysłać ponownie z listy członków.
</AlertDescription>
</Alert>
<Alert variant="success">
<CircleCheckIcon />
<AlertTitle>Domena zweryfikowana</AlertTitle>
<AlertDescription>
Domena acme.com jest gotowa. Certyfikaty odnawiają się automatycznie.
</AlertDescription>
</Alert>
<Alert variant="warning">
<TriangleAlertIcon />
<AlertTitle>Wykorzystano 90% minut kompilacji</AlertTitle>
<AlertDescription>
Gdy 31 maja osiągniesz limit, kompilacje zaczną trafiać do kolejki.
</AlertDescription>
</Alert>
<Alert variant="destructive">
<CircleAlertIcon />
<AlertTitle>Płatność nie powiodła się</AlertTitle>
<AlertDescription>
Nie udało się obciążyć karty kończącej się na 4242. Zaktualizuj ją, aby twoja przestrzeń robocza pozostała aktywna.
</AlertDescription>
</Alert>
</div>
)
}Z akcją
Umieść jedną akcję uzupełniającą w AlertAction. Znajduje się po prawej stronie, wyśrodkowana w pionie, we własnej kolumnie: tekst zawija się obok niej niezależnie od jej szerokości. Ogranicz się do jednego małego przycisku; alert z paskiem narzędzi to już karta.
import { SparklesIcon } from "lucide-react"
import {
Alert,
AlertAction,
AlertDescription,
AlertTitle,
} from "@/components/ui/alert"
import { Button } from "@/components/ui/button"
export default function AlertWithAction() {
return (
<Alert variant="info" className="max-w-lg">
<SparklesIcon />
<AlertTitle>Środowiska podglądowe są już dostępne</AlertTitle>
<AlertDescription>
Każdy pull request dostaje teraz własny adres URL.
</AlertDescription>
<AlertAction>
<Button size="xs" variant="outline">
Włącz
</Button>
</AlertAction>
</Alert>
)
}Z linkiem
Linki w AlertDescription są podkreślone, mają średnią grubość pisma i dziedziczą neutralny kolor tekstu opisu, więc pozostają czytelne na każdym zabarwionym tle.
import { TriangleAlertIcon } from "lucide-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
export default function AlertWithLink() {
return (
<Alert variant="warning" className="max-w-lg">
<TriangleAlertIcon />
<AlertTitle>Wsparcie dla Node.js 20 kończy się w kwietniu</AlertTitle>
<AlertDescription>
Trzy projekty nadal kompilują się na Node.js 20.{" "}
<a href="#">Przejrzyj te projekty</a> już teraz, zanim kompilacje zaczną kończyć się błędem.
</AlertDescription>
</Alert>
)
}Z listą
Gdy trzeba poprawić kilka rzeczy, wypunktuj je. Listę się przegląda, akapit — tylko przebiega wzrokiem.
Popraw te błędy i spróbuj ponownie:
- Tytuł strony jest pusty.
- Dwa obrazy nie mają tekstu alternatywnego.
- Kanoniczny adres URL wskazuje na usuniętą stronę.
import { CircleAlertIcon } from "lucide-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
export default function AlertWithList() {
return (
<Alert variant="destructive" className="max-w-lg">
<CircleAlertIcon />
<AlertTitle>Nie udało się opublikować zmian</AlertTitle>
<AlertDescription>
<p>Popraw te błędy i spróbuj ponownie:</p>
<ul className="list-disc pl-5 [&>li]:mt-1">
<li>Tytuł strony jest pusty.</li>
<li>Dwa obrazy nie mają tekstu alternatywnego.</li>
<li>Kanoniczny adres URL wskazuje na usuniętą stronę.</li>
</ul>
</AlertDescription>
</Alert>
)
}Tylko tytuł
Krótki komunikat nie potrzebuje opisu. Ikona jest opcjonalna — pomiń ją w neutralnych notkach, które nie powinny przyciągać wzroku.
import { CircleCheckIcon } from "lucide-react"
import { Alert, AlertTitle } from "@/components/ui/alert"
export default function AlertMinimal() {
return (
<div className="flex w-full max-w-md flex-col gap-3">
<Alert variant="success">
<CircleCheckIcon />
<AlertTitle>Zmiany zostały zapisane.</AlertTitle>
</Alert>
<Alert>
<AlertTitle>
Szkice widzisz tylko Ty i Twoi redaktorzy.
</AlertTitle>
</Alert>
</div>
)
}Wytyczne
Kiedy używać
- Aby wyjaśnić sytuację, która dotyczy całej strony lub sekcji: awarię, limit, oczekującą weryfikację.
- Aby podsumować błędy formularza nad formularzem — jako uzupełnienie komunikatów o błędach przy poszczególnych polach.
- Aby wyeksponować informację, która musi pozostać widoczna, dopóki sytuacja się nie zmieni.
Kiedy nie używać
- Do potwierdzania czegoś, co ktoś właśnie zrobił — użyj komponentu Toast. Powiadomienie pojawia się tam, gdzie już skupia się uwaga, i samo znika.
- Do błędów pojedynczego pola — użyj
FieldErrorwewnątrz komponentu Field, tuż przy polu. - Do decyzji, które blokują dalsze działanie — użyj komponentu Alert Dialog.
- Do treści marketingowych. Alert pożycza pilność od kolorów statusów; marnowanie jej na promocje uczy ludzi, że można go ignorować.
Wybieraj najłagodniejszy wariant, który oddaje sytuację
Kolory statusów to ograniczony budżet. Jeśli nic złego się nie dzieje, alert ma wariant default lub info — nawet gdy komunikat wydaje się ważny. Zachowaj warning dla rzeczy, które przestaną działać, a destructive dla tych, które już nie działają.
Treść
- Zaczynaj od skutku, nie od przyczyny: Po osiągnięciu limitu kompilacje trafią do kolejki, a nie Wykorzystano 90% minut kompilacji.
- Powiedz, co dalej. Każde ostrzeżenie i każdy błąd powinny wskazywać akcję albo prowadzić do niej linkiem.
- Ogranicz tytuł do jednego wiersza, a opis do dwóch zdań. Dłuższa treść powinna trafić na osobną stronę.
- Nie piętrz alertów. Dwa lub więcej alertów w jednym miejscu konkurują ze sobą; połącz je albo pokaż najpoważniejszy.
Dostępność
Alerty są regionami na żywo (live regions), więc ich treść jest ogłaszana w chwili pojawienia się, bez przenoszenia fokusu.
- Pilność ogłoszenia zależy od wagi.
destructiveiwarningrenderująrole="alert"i są ogłaszane natychmiast, przerywając to, co czytnik ekranu właśnie czytał. Pozostałe warianty renderująrole="status"i czekają na przerwę. Przekażrole, aby to nadpisać — na przykładrole="note"dla treści statycznej, która w ogóle nie powinna być ogłaszana. - Wstawiaj, nie odsłaniaj. Regiony na żywo ogłaszają zmiany. Alert obecny od załadowania strony jest odczytywany w kolejności dokumentu; alert dodany później — powiedzmy po nieudanym wysłaniu formularza — jest ogłaszany w chwili pojawienia się.
- Kolor nigdy nie jest jedynym sygnałem. Łącz każdy wariant statusu z ikoną i tytułem, który nazywa status słowami.
- Akcje pozostają w kolejności tabulacji. Przyciski i linki w alercie są osiągalne klawiszem Tab i nigdy nie przejmują fokusu, gdy alert się pojawia.
Dokumentacja API
Alert
Kontener. Renderuje <div> z data-slot="alert" i atrybutem data-variant.
AlertTitle
Pojedynczy wiersz, który wyraża sedno komunikatu. Renderuje <div>; gdy alert ma ikonę, tytuł zaczyna się w drugiej kolumnie.
AlertDescription
Tekst uzupełniający, linki i listy. W każdym wariancie ma neutralny kolor muted-foreground, więc kolor statusu niosą tylko ikona i tytuł.
AlertAction
Slot na jedną akcję uzupełniającą. Zajmuje własną kolumnę przy prawej krawędzi, wyśrodkowany w pionie, więc tekst zawija się obok niego.