A dialog that requires user response to proceed.
Installation
npx shadcn@latest add @caprice/alert-dialogpnpm dlx shadcn@latest add @caprice/alert-dialogyarn dlx shadcn@latest add @caprice/alert-dialogbunx shadcn@latest add @caprice/alert-dialognpm install @caprice-ui/reactpnpm add @caprice-ui/reactyarn add @caprice-ui/reactbun add @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactpnpm add @base-ui/react lucide-reactyarn add @base-ui/react lucide-reactbun add @base-ui/react lucide-reactAdd a cn helper
import { defineConfig, getSchema, type VariantProps } from 'cva';
import { twMerge } from 'tailwind-merge';
export const { cva, cx: cn } = defineConfig({
hooks: {
onComplete: (className: string) => twMerge(className),
},
});
export type { VariantProps };
export { getSchema };
Copy and paste the following code into your project.
'use client';
import { mergeProps, 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 alert 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: mergeProps<'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: mergeProps<'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
Default
Trigger
Prop
Type
Default
Popup
Prop
Type
Default
Title
Prop
Type
Default
Description
Prop
Type
Default
Footer
Close
Prop
Type
Default
Last updated on