A dialog that requires user response to proceed.
Installation
npx shadcn@latest add @caprice/alert-dialognpm install @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactAdd a cn helper
import { defineConfig, type VariantProps } from 'cva';import { twMerge } from 'tailwind-merge';export const { compose, cva, cx: cn,} = defineConfig({ hooks: { onComplete: (className: string) => twMerge(className), },});export type { VariantProps };Copy and paste the following code into your project.
'use client';import { mergePropsN, useRender } from '@base-ui/react';import { AlertDialog as AlertDialogPrimitive } from '@base-ui/react/alert-dialog';import type * as React from 'react';import { Button } from '@/components/caprice-ui/button';import { cn } from '@/lib/utils';/** * Groups all parts of the alert dialog. * Doesn’t render its own HTML element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#root) */export namespace Root { export type Props = React.ComponentProps<typeof AlertDialogPrimitive.Root>; export type Actions = AlertDialogPrimitive.Root.Actions; export type ChangeEventDetails = AlertDialogPrimitive.Root.ChangeEventDetails; export type ChangeEventReason = AlertDialogPrimitive.Root.ChangeEventReason;}export function Root({ ...props }: Root.Props) { return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;}/** * A button that opens the dialog. * Renders a `<button>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#trigger) */export namespace Trigger { export type State = AlertDialogPrimitive.Trigger.State; export type Props = React.ComponentProps<typeof AlertDialogPrimitive.Trigger>;}export function Trigger({ ...props }: Trigger.Props) { return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />;}/** * A portal element that moves the popup to a different part of the DOM. * By default, the portal element is appended to `<body>`. * Renders a `<div>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#portal) */export namespace Portal { export interface State extends AlertDialogPrimitive.Portal.State {} export type Props = React.ComponentProps<typeof AlertDialogPrimitive.Portal>;}export function Portal({ ...props }: Portal.Props) { return <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />;}/** * An overlay displayed beneath the popup. * Renders a `<div>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#backdrop) */export namespace Backdrop { export type State = AlertDialogPrimitive.Backdrop.State; export type Props = React.ComponentProps<typeof AlertDialogPrimitive.Backdrop>;}export function Backdrop({ className, ...props }: Backdrop.Props) { return ( <AlertDialogPrimitive.Backdrop className={cn( 'fixed inset-0 z-50 bg-black/40 backdrop-blur-[10px] transition-all duration-200 ease-in-out [[data-starting-style],[data-ending-style]]:opacity-0', className )} data-slot="alert-dialog-backdrop" {...props} /> );}/** * A container for the dialog contents. * Renders a `<div>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#popup) */export namespace Popup { export type State = AlertDialogPrimitive.Popup.State; export type Props = React.ComponentProps<typeof AlertDialogPrimitive.Popup>;}export function Popup({ className, ...props }: Popup.Props) { return ( <Portal> <Backdrop /> <AlertDialogPrimitive.Popup className={cn( // Position 'fixed start-1/2 z-50 -translate-x-1/2 max-sm:bottom-2 sm:-translate-y-1/2', // Sizing 'max-h-[calc(100vh-1rem)] w-full max-w-[calc(100%-4rem)] overflow-y-auto sm:max-w-lg', // Display 'grid gap-4 rounded-2xl border bg-background p-6 text-foreground shadow-lg', // Animation 'origin-top transition-all duration-200 ease-out will-change-transform motion-reduce:transition-none [[data-starting-style],[data-ending-style]]:scale-98 [[data-starting-style],[data-ending-style]]:opacity-0 max-sm:[[data-starting-style],[data-ending-style]]:translate-y-4', // Nested dialogs 'data-nested-dialog-open:after:absolute data-nested-dialog-open:after:inset-0 data-nested-dialog-open:after:backdrop-blur-xs sm:top-[calc(50%+1.25rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))] sm:data-nested:[[data-starting-style],[data-ending-style]]:translate-y-8', className )} data-slot="alert-dialog-popup" {...props} /> </Portal> );}/** * @deprecated Use {@link Popup} instead * @see {@link https://caprice-ui.com/docs/components/alert-dialog} */export const Content = Popup;/** * A header that contains the title and description of the alert dialog. * Renders a `<div>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#header) */export namespace Header { export type Props = useRender.ComponentProps<'div'>;}export function Header({ className, render, ...props }: Header.Props) { const defaultProps: useRender.ElementProps<'div'> & { 'data-slot'?: string } = { 'data-slot': 'alert-dialog-header', className: cn('flex flex-col gap-2 text-center sm:text-start', className), }; return useRender({ defaultTagName: 'div', render, props: mergePropsN<'div'>([defaultProps, props]), });}/** * A footer that contains the actions of the alert dialog. * Renders a `<div>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) */export namespace Footer { export type Props = useRender.ComponentProps<'div'>;}export function Footer({ className, render, ...props }: Footer.Props) { const defaultProps: useRender.ElementProps<'div'> & { 'data-slot'?: string } = { 'data-slot': 'alert-dialog-footer', className: cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className), }; return useRender({ defaultTagName: 'div', render, props: mergePropsN<'div'>([defaultProps, props]), });}/** * A heading that labels the dialog. * Renders an `<h2>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#title) */export namespace Title { export type State = AlertDialogPrimitive.Title.State; export type Props = React.ComponentProps<typeof AlertDialogPrimitive.Title>;}export function Title({ className, ...props }: Title.Props) { return ( <AlertDialogPrimitive.Title className={cn('font-semibold text-lg', className)} data-slot="alert-dialog-title" {...props} /> );}/** * A paragraph with additional information about the dialog. * Renders a `<p>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#description) */export namespace Description { export type State = AlertDialogPrimitive.Description.State; export type Props = React.ComponentProps<typeof AlertDialogPrimitive.Description>;}export function Description({ className, ...props }: Description.Props) { return ( <AlertDialogPrimitive.Description className={cn('text-muted-foreground text-sm', className)} data-slot="alert-dialog-description" {...props} /> );}/** * A button that closes the dialog. * Renders a `<button>` element. * * Documentation: [Caprice UI Alert Dialog](https://caprice-ui.com/docs/components/alert-dialog) * * API Reference: [Base UI Alert Dialog](https://base-ui.com/react/components/alert-dialog#close) */export namespace Close { export type State = AlertDialogPrimitive.Close.State; export type Props = React.ComponentProps<typeof AlertDialogPrimitive.Close> & Button.Variants;}export function Close({ render, variant = 'outline', size, ...props }: Close.Props) { return ( <AlertDialogPrimitive.Close {...props} data-slot="alert-dialog-close" render={render ?? <Button size={size} variant={variant} />} /> );}Update the import paths to match your project setup.
Usage
import * as AlertDialog from "@/components/caprice-ui/alertdialog"import * as AlertDialog from "@caprice-ui/react/alertdialog"<AlertDialog.Root>
<AlertDialog.Trigger render={<Button>Discard draft</Button>} />
<AlertDialog.Popup>
<AlertDialog.Title>Discard draft?</AlertDialog.Title>
<AlertDialog.Description>You can't undo this action.</AlertDialog.Description>
<AlertDialog.Footer>
<AlertDialog.Close>Cancel</AlertDialog.Close>
<AlertDialog.Close variant="default">Discard</AlertDialog.Close>
</AlertDialog.Footer>
</AlertDialog.Popup>
</AlertDialog.Root>Examples
Open from a menu
Close confirmation (nested dialogs)
API Reference
Root
Prop
Type
Trigger
Prop
Type
Popup
Prop
Type
Title
Prop
Type
Description
Prop
Type
Footer
Prop
Type
Close
Prop
Type