Przejdź do treści

Alert

Trwały komunikat osadzony w treści, który informuje o czymś ważnym dla bieżącej strony lub zadania.

Kod źródłowyRejestr
Planowana przerwa techniczna
W niedzielę od 02:00 do 03:00 UTC pulpit będzie dostępny tylko do odczytu.
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

Zaplanowane prace serwisowe
W niedzielę od 02:00 do 03:00 UTC pulpit będzie dostępny tylko do odczytu.
  1. 1IkonaPozwala od razu rozpoznać rodzaj komunikatu. Przyjmuje kolor wariantu, ale nigdy nie niesie znaczenia sama.
  2. 2KontenerObramowana, lekko zabarwiona powierzchnia. Wariant ustala jej kolory i rolę: status w większości przypadków, alert przy ostrzeżeniach i błędach.
  3. 3TytułJeden wiersz, który mówi, co się stało lub co trzeba wiedzieć.
  4. 4OpisSzczegóły i, jeśli jest, następny krok. Neutralny tekst.

Instalacja

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

Uż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.

Nowa wersja CLI
Wersja 4.2 wprowadza przestrzenie nazw w rejestrze i szybszą instalację.
Zaproszenia wygasają po 7 dniach
Zaproszenie możesz w każdej chwili wysłać ponownie z listy członków.
Domena zweryfikowana
Domena acme.com jest gotowa. Certyfikaty odnawiają się automatycznie.
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>
  )
}
WariantZastosowanie
defaultNeutralny kontekst, który nie sugeruje żadnego statusu: ogłoszenia, wskazówki, informacje o wersji.
infoPrzydatne informacje, które wpływają na to, jak korzysta się ze strony.
successPomyślnie zakończony stan, który pozostaje istotny także po fakcie.
warningCoś, co stanie się problemem, jeśli nikt nie zareaguje: limity, wycofywane funkcje, wygasający dostęp.
destructiveCoś właśnie teraz nie działa lub jest zablokowane i wymaga uwagi.

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.

Środowiska podglądowe są już dostępne
Każdy pull request dostaje teraz własny adres URL.
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>
  )
}

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.

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.

Zmiany zostały zapisane.
Szkice widzisz tylko Ty i Twoi redaktorzy.
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 FieldError wewną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ą.

Tryb ciemny jest już dostępny
Motyw zmienisz w menu profilu.
DobrzeNeutralna wiadomość, neutralny alert. Kolor zachowuje znaczenie na wypadek prawdziwych problemów.
ŹleOgłaszanie nowej funkcji ostrzeżeniem uczy ludzi ignorować ostrzeżenia.

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. destructive i warning renderują 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ład role="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.

PropTypDomyślnie
variant

Barwi powierzchnię, obramowanie, tytuł i ikonę odpowiednią skalą statusu.

"default" | "info" | "success" | "warning" | "destructive""default"
role

Domyślnie alert dla destructive i warning, w pozostałych przypadkach status. Nadpisz go dla statycznych notek.

string"alert" | "status"
className

Scalany z klasami wariantu. Używaj go do układu, nie do koloru.

stringBrak wartości domyślnej

AlertTitle

Pojedynczy wiersz, który wyraża sedno komunikatu. Renderuje <div>; gdy alert ma ikonę, tytuł zaczyna się w drugiej kolumnie.

PropTypDomyślnie
className

Dodatkowe klasy.

stringBrak wartości domyślnej

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ł.

PropTypDomyślnie
className

Dodatkowe klasy. Akapity wewnątrz otrzymują odstępy automatycznie.

stringBrak wartości domyślnej

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.

PropTypDomyślnie
className

Dodatkowe klasy, np. aby w wysokich alertach wyrównać akcję do góry.

stringBrak wartości domyślnej