Alert Dialog
A blocking confirm for destructive or irreversible actions. No close icon; clicking outside does nothing.
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";
export default function Demo() { return ( <AlertDialog> <AlertDialogTrigger render={<Button variant="outline" />}> Close index </AlertDialogTrigger> <AlertDialogContent> <AlertDialogHeader> <AlertDialogTitle>Close this index?</AlertDialogTitle> <AlertDialogDescription> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogAction variant="destructive"> Close index </AlertDialogAction> </AlertDialogFooter> </AlertDialogContent> </AlertDialog> );}<script setup lang="ts">import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";</script>
<template> <AlertDialog> <AlertDialogTrigger as-child> <Button variant="outline">Close index</Button> </AlertDialogTrigger> <AlertDialogContent> <AlertDialogHeader> <AlertDialogTitle>Close this index?</AlertDialogTitle> <AlertDialogDescription> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogAction variant="destructive">Close index</AlertDialogAction> </AlertDialogFooter> </AlertDialogContent> </AlertDialog></template><script lang="ts"> import * as AlertDialog from "$lib/components/ui/alert-dialog"; import { Button } from "$lib/components/ui/button";</script>
<AlertDialog.Root> <AlertDialog.Trigger> {#snippet child({ props })} <Button variant="outline" {...props}>Close index</Button> {/snippet} </AlertDialog.Trigger> <AlertDialog.Content> <AlertDialog.Header> <AlertDialog.Title>Close this index?</AlertDialog.Title> <AlertDialog.Description> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialog.Description> </AlertDialog.Header> <AlertDialog.Footer> <AlertDialog.Cancel>Cancel</AlertDialog.Cancel> <AlertDialog.Action variant="destructive">Close index</AlertDialog.Action> </AlertDialog.Footer> </AlertDialog.Content></AlertDialog.Root>Installation
Section titled “Installation”npx shadcn@latest add @edmi-ui/alert-dialogpnpm dlx shadcn@latest add @edmi-ui/alert-dialogyarn dlx shadcn@latest add @edmi-ui/alert-dialogbunx shadcn@latest add @edmi-ui/alert-dialogPick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Install the dependencies:
Terminal window npm install @base-ui/reactTerminal window pnpm add @base-ui/reactTerminal window yarn add @base-ui/reactTerminal window bun add @base-ui/reactAdd the Edmi components this one builds on:
button,elevation.Copy the code from Component source into your project and update the import paths to match your aliases.
npx shadcn-vue@latest add @edmi-ui/alert-dialogpnpm dlx shadcn-vue@latest add @edmi-ui/alert-dialogyarn dlx shadcn-vue@latest add @edmi-ui/alert-dialogbunx shadcn-vue@latest add @edmi-ui/alert-dialogPick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Install the dependencies:
Terminal window npm install reka-ui @vueuse/coreTerminal window pnpm add reka-ui @vueuse/coreTerminal window yarn add reka-ui @vueuse/coreTerminal window bun add reka-ui @vueuse/coreAdd the Edmi components this one builds on:
button,elevation.Copy the code from Component source into your project and update the import paths to match your aliases.
npx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/alert-dialog.jsonpnpm dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/alert-dialog.jsonyarn dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/alert-dialog.jsonbunx --bun shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/alert-dialog.jsonPick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Add the Edmi components this one builds on:
button,elevation.Copy the code from Component source into your project and update the import paths to match your aliases.
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";
<AlertDialog> <AlertDialogTrigger render={<Button variant="outline" />}> Close index </AlertDialogTrigger> <AlertDialogContent> <AlertDialogHeader> <AlertDialogTitle>Close this index?</AlertDialogTitle> <AlertDialogDescription> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogAction variant="destructive"> Close index </AlertDialogAction> </AlertDialogFooter> </AlertDialogContent></AlertDialog><script setup lang="ts">import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";</script>
<template> <AlertDialog> <AlertDialogTrigger as-child> <Button variant="outline">Close index</Button> </AlertDialogTrigger> <AlertDialogContent> <AlertDialogHeader> <AlertDialogTitle>Close this index?</AlertDialogTitle> <AlertDialogDescription> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogAction variant="destructive">Close index</AlertDialogAction> </AlertDialogFooter> </AlertDialogContent> </AlertDialog></template><script lang="ts"> import * as AlertDialog from "$lib/components/ui/alert-dialog"; import { Button } from "$lib/components/ui/button";</script>
<AlertDialog.Root> <AlertDialog.Trigger> {#snippet child({ props })} <Button variant="outline" {...props}>Close index</Button> {/snippet} </AlertDialog.Trigger> <AlertDialog.Content> <AlertDialog.Header> <AlertDialog.Title>Close this index?</AlertDialog.Title> <AlertDialog.Description> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialog.Description> </AlertDialog.Header> <AlertDialog.Footer> <AlertDialog.Cancel>Cancel</AlertDialog.Cancel> <AlertDialog.Action variant="destructive">Close index</AlertDialog.Action> </AlertDialog.Footer> </AlertDialog.Content></AlertDialog.Root>Component source
Section titled “Component source”"use client";
import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog";import { cn } from "cn";import type * as React from "react";
import { Button } from "@/registry/edmi/ui/button";import { type Elevation, SurfaceProvider, useElevation,} from "@/registry/edmi/ui/elevation";
// ✦ depth (v4): overlay role. Natural level is floating in layered mode; flat otherwise.const overlayElevation = { sunken: "", flat: "", raised: "border-transparent shadow-raised", floating: "border-transparent shadow-floating",};
function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) { return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;}
function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) { return ( <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} /> );}
function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) { return ( <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} /> );}
function AlertDialogOverlay({ className, ...props}: AlertDialogPrimitive.Backdrop.Props) { return ( <AlertDialogPrimitive.Backdrop data-slot="alert-dialog-overlay" className={cn( "fixed inset-0 isolate z-50 bg-overlay transition-opacity duration-150 data-[ending-style]:opacity-0 data-[starting-style]:opacity-0", className, )} {...props} /> );}
function AlertDialogContent({ className, size = "default", elevation, children, ...props}: AlertDialogPrimitive.Popup.Props & { size?: "default" | "sm"; /** ✦ depth: flat 0, raised +1 (bevel), floating +2 (bevel + drop). */ elevation?: Elevation;}) { const level = useElevation(elevation, "overlay"); return ( <AlertDialogPortal> <AlertDialogOverlay /> <AlertDialogPrimitive.Popup 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-2xl border border-border bg-popover p-[22px] text-popover-foreground outline-none transition-[opacity,scale] duration-150 data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:scale-95 data-[starting-style]:opacity-0 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm", overlayElevation[level], className, )} {...props} > <SurfaceProvider level={level}>{children}</SurfaceProvider> </AlertDialogPrimitive.Popup> </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( "flex flex-col-reverse gap-2 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( "text-base leading-snug font-semibold tracking-[-0.2px] 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-[13px] text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className, )} {...props} /> );}
function AlertDialogAction({ className, ...props}: React.ComponentProps<typeof Button>) { return ( <Button data-slot="alert-dialog-action" className={cn(className)} {...props} /> );}
function AlertDialogCancel({ className, variant = "outline", size = "default", ...props}: AlertDialogPrimitive.Close.Props & Pick<React.ComponentProps<typeof Button>, "variant" | "size">) { return ( <AlertDialogPrimitive.Close data-slot="alert-dialog-cancel" className={cn(className)} render={<Button variant={variant} size={size} />} {...props} /> );}
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger,};<script setup lang="ts">import type { AlertDialogEmits, AlertDialogProps } from 'reka-ui'import { AlertDialogRoot, useForwardPropsEmits } from 'reka-ui'
const props = defineProps<AlertDialogProps>()const emits = defineEmits<AlertDialogEmits>()
const forwarded = useForwardPropsEmits(props, emits)</script>
<template> <AlertDialogRoot v-slot="slotProps" data-slot="alert-dialog" v-bind="forwarded"> <slot v-bind="slotProps" /> </AlertDialogRoot></template><script setup lang="ts">import type { AlertDialogActionProps } from 'reka-ui'import type { HTMLAttributes } from 'vue'import type { ButtonVariants } from '@/registry/edmi/ui/button'import { reactiveOmit } from '@vueuse/core'import { AlertDialogAction } from 'reka-ui'import { cn } from '@/registry/edmi/lib/utils'import { buttonVariants } from '@/registry/edmi/ui/button'
const props = defineProps<AlertDialogActionProps & { class?: HTMLAttributes['class'] variant?: ButtonVariants['variant'] size?: ButtonVariants['size']}>()
const delegatedProps = reactiveOmit(props, 'class', 'variant', 'size')</script>
<template> <AlertDialogAction data-slot="alert-dialog-action" v-bind="delegatedProps" :class="cn(buttonVariants({ variant, size }), props.class)" > <slot /> </AlertDialogAction></template><script setup lang="ts">import type { AlertDialogCancelProps } from 'reka-ui'import type { HTMLAttributes } from 'vue'import type { ButtonVariants } from '@/registry/edmi/ui/button'import { reactiveOmit } from '@vueuse/core'import { AlertDialogCancel } from 'reka-ui'import { cn } from '@/registry/edmi/lib/utils'import { buttonVariants } from '@/registry/edmi/ui/button'
const props = withDefaults(defineProps<AlertDialogCancelProps & { class?: HTMLAttributes['class'] variant?: ButtonVariants['variant'] size?: ButtonVariants['size']}>(), { variant: 'outline', size: 'default',})
const delegatedProps = reactiveOmit(props, 'class', 'variant', 'size')</script>
<template> <AlertDialogCancel data-slot="alert-dialog-cancel" v-bind="delegatedProps" :class="cn(buttonVariants({ variant, size }), props.class)" > <slot /> </AlertDialogCancel></template><script setup lang="ts">import type { AlertDialogContentEmits, AlertDialogContentProps } from 'reka-ui'import type { HTMLAttributes } from 'vue'import { reactiveOmit } from '@vueuse/core'import { AlertDialogContent, AlertDialogOverlay, AlertDialogPortal, useForwardPropsEmits,} from 'reka-ui'import { cn } from '@/registry/edmi/lib/utils'import { type Elevation, provideSurface, useElevation } from '@/registry/edmi/ui/elevation'
defineOptions({ inheritAttrs: false,})
const props = withDefaults(defineProps<AlertDialogContentProps & { class?: HTMLAttributes['class'], size?: 'default' | 'sm', elevation?: Elevation }>(), { size: 'default', elevation: undefined,})const emits = defineEmits<AlertDialogContentEmits>()
// ✦ depth (v4): overlay role. Natural level is floating in layered mode; flat otherwise.const overlayElevation = { sunken: '', flat: '', raised: 'border-transparent shadow-raised', floating: 'border-transparent shadow-floating',}const level = useElevation(() => props.elevation, 'overlay')provideSurface(() => level.value)
const delegatedProps = reactiveOmit(props, 'class', 'size', 'elevation')
const forwarded = useForwardPropsEmits(delegatedProps, emits)</script>
<template> <AlertDialogPortal> <AlertDialogOverlay data-slot="alert-dialog-overlay" class="fixed inset-0 isolate z-50 bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" /> <AlertDialogContent data-slot="alert-dialog-content" :data-size="size" v-bind="{ ...$attrs, ...forwarded }" :class=" 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-2xl border border-border bg-popover p-[22px] text-popover-foreground outline-none duration-150 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm', overlayElevation[level], props.class, ) " > <slot /> </AlertDialogContent> </AlertDialogPortal></template><script setup lang="ts">import type { AlertDialogDescriptionProps } from 'reka-ui'import type { HTMLAttributes } from 'vue'import { reactiveOmit } from '@vueuse/core'import { AlertDialogDescription } from 'reka-ui'import { cn } from '@/registry/edmi/lib/utils'
const props = defineProps<AlertDialogDescriptionProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = reactiveOmit(props, 'class')</script>
<template> <AlertDialogDescription data-slot="alert-dialog-description" v-bind="delegatedProps" :class="cn('text-[13px] text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground', props.class)" > <slot /> </AlertDialogDescription></template><script setup lang="ts">import type { HTMLAttributes } from 'vue'import { cn } from '@/registry/edmi/lib/utils'
const props = defineProps<{ class?: HTMLAttributes['class']}>()</script>
<template> <div data-slot="alert-dialog-footer" :class="cn('flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end', props.class)" > <slot /> </div></template><script setup lang="ts">import type { HTMLAttributes } from 'vue'import { cn } from '@/registry/edmi/lib/utils'
const props = defineProps<{ class?: HTMLAttributes['class']}>()</script>
<template> <div data-slot="alert-dialog-header" :class="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]', props.class)" > <slot /> </div></template><script setup lang="ts">import type { HTMLAttributes } from 'vue'import { cn } from '@/registry/edmi/lib/utils'
const props = defineProps<{ class?: HTMLAttributes['class']}>()</script>
<template> <div data-slot="alert-dialog-media" :class="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', props.class)" > <slot /> </div></template><script setup lang="ts">import type { AlertDialogTitleProps } from 'reka-ui'import type { HTMLAttributes } from 'vue'import { reactiveOmit } from '@vueuse/core'import { AlertDialogTitle } from 'reka-ui'import { cn } from '@/registry/edmi/lib/utils'
const props = defineProps<AlertDialogTitleProps & { class?: HTMLAttributes['class'] }>()
const delegatedProps = reactiveOmit(props, 'class')</script>
<template> <AlertDialogTitle data-slot="alert-dialog-title" v-bind="delegatedProps" :class="cn('text-base leading-snug font-semibold tracking-[-0.2px] sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2', props.class)" > <slot /> </AlertDialogTitle></template><script setup lang="ts">import type { AlertDialogTriggerProps } from 'reka-ui'import { AlertDialogTrigger } from 'reka-ui'
const props = defineProps<AlertDialogTriggerProps>()</script>
<template> <AlertDialogTrigger data-slot="alert-dialog-trigger" v-bind="props"> <slot /> </AlertDialogTrigger></template>export { default as AlertDialog } from "./AlertDialog.vue";export { default as AlertDialogAction } from "./AlertDialogAction.vue";export { default as AlertDialogCancel } from "./AlertDialogCancel.vue";export { default as AlertDialogContent } from "./AlertDialogContent.vue";export { default as AlertDialogDescription } from "./AlertDialogDescription.vue";export { default as AlertDialogFooter } from "./AlertDialogFooter.vue";export { default as AlertDialogHeader } from "./AlertDialogHeader.vue";export { default as AlertDialogMedia } from "./AlertDialogMedia.vue";export { default as AlertDialogTitle } from "./AlertDialogTitle.vue";export { default as AlertDialogTrigger } from "./AlertDialogTrigger.vue";<script lang="ts"> import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; import { buttonVariants, type ButtonVariant, type ButtonSize, } from "$lib/registry/ui/button/index.js"; import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, variant = "default", size = "default", ...restProps }: AlertDialogPrimitive.ActionProps & { variant?: ButtonVariant; size?: ButtonSize; } = $props();</script>
<AlertDialogPrimitive.Action bind:ref data-slot="alert-dialog-action" class={cn(buttonVariants({ variant, size }), className)} {...restProps}/><script lang="ts"> import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; import { buttonVariants, type ButtonVariant, type ButtonSize, } from "$lib/registry/ui/button/index.js"; import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, variant = "outline", size = "default", ...restProps }: AlertDialogPrimitive.CancelProps & { variant?: ButtonVariant; size?: ButtonSize; } = $props();</script>
<AlertDialogPrimitive.Cancel bind:ref data-slot="alert-dialog-cancel" class={cn(buttonVariants({ variant, size }), className)} {...restProps}/><script lang="ts"> import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; import { cn, type WithoutChild, type WithoutChildrenOrChild } from "$lib/utils.js"; import { type Elevation, setSurface, useElevation } from "$lib/registry/ui/elevation/index.js"; import AlertDialogOverlay from "./alert-dialog-overlay.svelte"; import AlertDialogPortal from "./alert-dialog-portal.svelte"; import type { ComponentProps } from "svelte";
let { ref = $bindable(null), class: className, size = "default", portalProps, elevation = "auto", ...restProps }: WithoutChild<AlertDialogPrimitive.ContentProps> & { size?: "default" | "sm"; /** ✦ depth: flat 0, raised +1 (bevel), floating +2 (bevel + drop). */ elevation?: Elevation; portalProps?: WithoutChildrenOrChild<ComponentProps<typeof AlertDialogPortal>>; } = $props();
// ✦ depth (v4): overlay role. Natural level is floating in layered mode; flat otherwise. const overlayElevation = { sunken: "", flat: "", raised: "border-transparent shadow-raised", floating: "border-transparent shadow-floating", }; const level = useElevation(() => elevation, "overlay"); setSurface(() => level.current);</script>
<AlertDialogPortal {...portalProps}> <AlertDialogOverlay /> <AlertDialogPrimitive.Content bind:ref data-slot="alert-dialog-content" data-size={size} class={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-2xl border border-border bg-popover p-[22px] text-popover-foreground outline-none duration-150 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm", overlayElevation[level.current], className )} {...restProps} /></AlertDialogPortal><script lang="ts"> import { AlertDialog as Primitive } from "bits-ui"; import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, ...restProps }: Primitive.DescriptionProps = $props();</script>
<Primitive.Description bind:ref data-slot="alert-dialog-description" class={cn("text-[13px] text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className)} {...restProps}/><script lang="ts"> import { cn, type WithElementRef } from "$lib/utils.js"; import type { HTMLAttributes } from "svelte/elements";
let { ref = $bindable(null), class: className, children, ...restProps }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();</script>
<div bind:this={ref} data-slot="alert-dialog-footer" class={cn("flex flex-col-reverse gap-2 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)} {...restProps}> {@render children?.()}</div><script lang="ts"> import { cn, type WithElementRef } from "$lib/utils.js"; import type { HTMLAttributes } from "svelte/elements";
let { ref = $bindable(null), class: className, children, ...restProps }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();</script>
<div bind:this={ref} data-slot="alert-dialog-header" class={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)} {...restProps}> {@render children?.()}</div><script lang="ts"> import { cn, type WithElementRef } from "$lib/utils.js"; import type { HTMLAttributes } from "svelte/elements";
let { ref = $bindable(null), class: className, children, ...restProps }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();</script>
<div bind:this={ref} data-slot="alert-dialog-media" class={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)} {...restProps}> {@render children?.()}</div><script lang="ts"> import { AlertDialog as Primitive } from "bits-ui"; import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, ...restProps }: Primitive.OverlayProps = $props();</script>
<Primitive.Overlay bind:ref data-slot="alert-dialog-overlay" class={cn("fixed inset-0 isolate z-50 bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className)} {...restProps}/><script lang="ts"> import { AlertDialog as Primitive } from "bits-ui";
let { ...restProps }: Primitive.PortalProps = $props();</script>
<Primitive.Portal {...restProps} /><script lang="ts"> import { AlertDialog as Primitive } from "bits-ui"; import { cn } from "$lib/utils.js";
let { ref = $bindable(null), class: className, ...restProps }: Primitive.TitleProps = $props();</script>
<Primitive.Title bind:ref data-slot="alert-dialog-title" class={cn("text-base leading-snug font-semibold tracking-[-0.2px] sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className)} {...restProps}/><script lang="ts"> import { AlertDialog as Primitive } from "bits-ui";
let { ref = $bindable(null), ...restProps }: Primitive.TriggerProps = $props();</script>
<Primitive.Trigger bind:ref data-slot="alert-dialog-trigger" {...restProps} /><script lang="ts"> import { AlertDialog as Primitive } from "bits-ui";
let { open = $bindable(false), ...restProps }: Primitive.RootProps = $props();</script>
<Primitive.Root bind:open {...restProps} />import Root from "./alert-dialog.svelte";import Action from "./alert-dialog-action.svelte";import Cancel from "./alert-dialog-cancel.svelte";import Content from "./alert-dialog-content.svelte";import Description from "./alert-dialog-description.svelte";import Footer from "./alert-dialog-footer.svelte";import Header from "./alert-dialog-header.svelte";import Media from "./alert-dialog-media.svelte";import Overlay from "./alert-dialog-overlay.svelte";import Portal from "./alert-dialog-portal.svelte";import Title from "./alert-dialog-title.svelte";import Trigger from "./alert-dialog-trigger.svelte";
export { Action, Action as AlertDialogAction, Cancel, Cancel as AlertDialogCancel, Content, Content as AlertDialogContent, Description, Description as AlertDialogDescription, Footer, Footer as AlertDialogFooter, Header, Header as AlertDialogHeader, Media, Media as AlertDialogMedia, Overlay, Overlay as AlertDialogOverlay, Portal, Portal as AlertDialogPortal, Root, // Root as AlertDialog, Title, Title as AlertDialogTitle, Trigger, Trigger as AlertDialogTrigger,};Elevation ✦
Section titled “Elevation ✦”See the Elevation guide for the levels, roles and layered mode.
Flat by default. On AlertDialogContent, raised (+1) adds the bevel and floating (+2) the bevel plus one soft drop (the natural level in layered mode).
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";
export default function Demo() { return ( <AlertDialog> <AlertDialogTrigger render={<Button variant="outline" />}> Close index </AlertDialogTrigger> <AlertDialogContent elevation="floating"> <AlertDialogHeader> <AlertDialogTitle>Close this index?</AlertDialogTitle> <AlertDialogDescription> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogAction variant="destructive"> Close index </AlertDialogAction> </AlertDialogFooter> </AlertDialogContent> </AlertDialog> );}<script setup lang="ts">import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";</script>
<template> <AlertDialog> <AlertDialogTrigger as-child> <Button variant="outline">Close index</Button> </AlertDialogTrigger> <AlertDialogContent elevation="floating"> <AlertDialogHeader> <AlertDialogTitle>Close this index?</AlertDialogTitle> <AlertDialogDescription> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogAction variant="destructive">Close index</AlertDialogAction> </AlertDialogFooter> </AlertDialogContent> </AlertDialog></template><script lang="ts"> import * as AlertDialog from "$lib/components/ui/alert-dialog"; import { Button } from "$lib/components/ui/button";</script>
<AlertDialog.Root> <AlertDialog.Trigger> {#snippet child({ props })} <Button variant="outline" {...props}>Close index</Button> {/snippet} </AlertDialog.Trigger> <AlertDialog.Content elevation="floating"> <AlertDialog.Header> <AlertDialog.Title>Close this index?</AlertDialog.Title> <AlertDialog.Description> Holders can still withdraw, but no one can join. This cannot be undone. </AlertDialog.Description> </AlertDialog.Header> <AlertDialog.Footer> <AlertDialog.Cancel>Cancel</AlertDialog.Cancel> <AlertDialog.Action variant="destructive">Close index</AlertDialog.Action> </AlertDialog.Footer> </AlertDialog.Content></AlertDialog.Root>| Prop | Type | Default |
|---|---|---|
AlertDialogContent size |
default | sm |
default |
AlertDialogAction |
Button props | default variant |
AlertDialogCancel variant / size |
Button props | outline / default |
elevation |
"auto" | "sunken" | "flat" | "raised" | "floating" |
"auto" |
Parts: AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogMedia, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction.
✦ Edmi additions
Section titled “✦ Edmi additions”--overlayscrim without blur, optional bevel / drop viaelevation. Passvariant="destructive"toAlertDialogActionfor the red confirm.