İçeriğe atla

Uyarı iletişim kutusu

Silme, oturumu kapatma, iptal etme gibi geri dönüşü olmayan işlemler sırasında akışı durduran ve neobrütalist tarzda kenarlık ve gölge efektlerine sahip bir modal.

import {
  AlertDialog,
  AlertDialogAction,

Uyarı diyaloğu, kullanıcıyı açık bir seçim yapmaya zorlayan kalıcı (modal) bir pencereyle akışı durdurur — dışarıya tıklamak pencereyi kapatmaz. Base UI Alert Dialog bileşeni üzerine kuruludur ve neobrütalist reçeteye göre biçimlendirilmiştir: kalın kenarlıklar, sert gölgeler ve koyu tipografi.

Şu durumlarda tercih edin:

  • Yıkıcı işlem onayları — hesabı silme, ekip üyesini çıkarma, projeyi tamamen kaldırma.
  • Geri alınamayan işlemler — yayımlama, gönderme, teslim etme; geri alması olmayan her şey.
  • Kaydedilmemiş değişiklik korumaları — doldurulmuş bir formdan ayrılmadan önce kullanıcıyı uyarın.

Kurulum

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/alert-dialog.json
npx shadcn@latest add https://neobrutalism.com/r/base/alert-dialog.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/alert-dialog.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/alert-dialog.json

Şu bağımlılıkları kurun:

pnpm add @base-ui/react
npm install @base-ui/react
yarn add @base-ui/react
bun add @base-ui/react

Aşağıdaki kodu kopyalayıp projenize yapıştırın.

components/ui/alert-dialog.tsx
"use client"

import * as React from "react"
import { AlertDialog as AlertDialogPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"

function AlertDialog({
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
  return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />
}

function AlertDialogTrigger({
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
  return (
    <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
  )
}

function AlertDialogPortal({
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
  return (
    <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
  )
}

function AlertDialogOverlay({
  className,
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
  return (
    <AlertDialogPrimitive.Overlay
      data-slot="alert-dialog-overlay"
      className={cn(
        "fixed inset-0 z-50 bg-foreground/20 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
        className
      )}
      {...props}
    />
  )
}

function AlertDialogContent({
  className,
  size = "default",
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {
  size?: "default" | "sm"
}) {
  return (
    <AlertDialogPortal>
      <AlertDialogOverlay />
      <AlertDialogPrimitive.Content
        data-slot="alert-dialog-content"
        data-size={size}
        className={cn(
          "group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded border-2 bg-popover p-4 text-popover-foreground shadow-md duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
          className
        )}
        {...props}
      />
    </AlertDialogPortal>
  )
}

function AlertDialogHeader({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-dialog-header"
      className={cn(
        "grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
        className
      )}
      {...props}
    />
  )
}

function AlertDialogFooter({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-dialog-footer"
      className={cn(
        "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t-2 bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
        className
      )}
      {...props}
    />
  )
}

function AlertDialogMedia({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-dialog-media"
      className={cn(
        "mb-2 inline-flex size-10 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6",
        className
      )}
      {...props}
    />
  )
}

function AlertDialogTitle({
  className,
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
  return (
    <AlertDialogPrimitive.Title
      data-slot="alert-dialog-title"
      className={cn(
        "font-head text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
        className
      )}
      {...props}
    />
  )
}

function AlertDialogDescription({
  className,
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
  return (
    <AlertDialogPrimitive.Description
      data-slot="alert-dialog-description"
      className={cn(
        "text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
        className
      )}
      {...props}
    />
  )
}

function AlertDialogAction({
  className,
  variant = "default",
  size = "default",
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Action> &
  Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
  return (
    <Button variant={variant} size={size} asChild>
      <AlertDialogPrimitive.Action
        data-slot="alert-dialog-action"
        className={cn(className)}
        {...props}
      />
    </Button>
  )
}

function AlertDialogCancel({
  className,
  variant = "outline",
  size = "default",
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel> &
  Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
  return (
    <Button variant={variant} size={size} asChild>
      <AlertDialogPrimitive.Cancel
        data-slot="alert-dialog-cancel"
        className={cn(className)}
        {...props}
      />
    </Button>
  )
}

export {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogMedia,
  AlertDialogOverlay,
  AlertDialogPortal,
  AlertDialogTitle,
  AlertDialogTrigger,
}

Import yollarını projenizin yapısına uyacak şekilde güncelleyin.

Kullanım

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
<AlertDialog>
  <AlertDialogTrigger render={<Button variant="outline" />}>
    Show Dialog
  </AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
      <AlertDialogDescription>
        This action cannot be undone. This will permanently delete your account
        from our servers.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction>Continue</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Kompozisyon

Bir AlertDialog oluşturmak için şu kompozisyonu kullanın:

AlertDialog
├── AlertDialogTrigger
└── AlertDialogContent
    ├── AlertDialogHeader
    │   ├── AlertDialogMedia
    │   ├── AlertDialogTitle
    │   └── AlertDialogDescription
    └── AlertDialogFooter
        ├── AlertDialogCancel
        └── AlertDialogAction

Örnekler

Temel

Başlık, açıklama ve iptal ile devam butonları içeren temel bir uyarı iletişim kutusu.

import {
  AlertDialog,
  AlertDialogAction,

Küçük

Uyarı iletişim kutusunu küçültmek için size="sm" prop'unu kullanın.

import {
  AlertDialog,
  AlertDialogAction,

Medya

Uyarı iletişim kutusuna simge veya görsel gibi bir medya öğesi eklemek için AlertDialogMedia bileşenini kullanın.

import { CircleFadingPlusIcon } from "lucide-react"

import {

Medyalı Küçük

Uyarı iletişim kutusunu küçültmek için size="sm" prop'unu ve ona simge veya görsel gibi bir medya öğesi eklemek için AlertDialogMedia bileşenini kullanın.

import { BluetoothIcon } from "lucide-react"

import {

Yıkıcı

Uyarı iletişim kutusuna yıkıcı bir eylem butonu eklemek için AlertDialogAction bileşenini kullanın.

import { Trash2Icon } from "lucide-react"

import {

RTL

Neobrutalism'de RTL desteğini etkinleştirmek için RTL yapılandırma kılavuzuna bakın.

"use client"

import { BluetoothIcon } from "lucide-react"

Erişilebilirlik

Uyarı diyaloğu, WAI-ARIA Alert Dialog desenini izler: açılır pencere, aria-labelledby ve aria-describedby ile başlığa ve açıklamaya bağlanan role="alertdialog" olarak işlenir ve diyalog açıkken odak içeride hapsedilir.

Klavye etkileşimleri:

TuşEylem
Space / EnterOdaklanılan tetikleyiciden diyaloğu açar
Tab / Shift + TabOdağı diyaloğun odaklanabilir öğeleri arasında gezdirir
EscDiyaloğu kapatır ve odağı tetikleyiciye geri döndürür

API Referansı

size

Uyarı iletişim kutusunun boyutunu kontrol etmek için AlertDialogContent bileşeninde size prop'unu kullanın. Şu değerleri kabul eder:

PropTypeDefault
size"default" | "sm""default"

Diğer bileşenler ve prop'ları hakkında daha fazla bilgi için Base UI dokümanlarına bakın.