A flexible and customizable confirm dialog component for React applications, built with accessibility in mind.
- Easy to use with the
useConfirm
hook - Fully customizable appearance and behavior
- Supports custom actions
- Seamless integration with Shadcn UI
If you are using Shadcn UI, copy the following files:
- packages/
- confirm-dialog/
- src/
- components/ui/
- alert-dialog.tsx
- confirm-dialog.tsx
If you're not using Shadcn UI or prefer to install via npm:
npm install @omit/react-confirm-dialog
import { ConfirmDialogProvider } from '@omit/react-confirm-dialog'
function App() {
return (
<ConfirmDialogProvider>{/* Your app components */}</ConfirmDialogProvider>
)
}
import { useConfirm } from '@omit/react-confirm-dialog'
function YourComponent() {
const confirm = useConfirm()
const handleClick = async () => {
const isConfirmed = await confirm({
title: 'Delete Item',
description: 'Are you sure you want to delete this item?',
confirmText: 'Delete',
cancelText: 'Cancel'
})
if (isConfirmed) {
// Perform delete action
}
}
return <button onClick={handleClick}>Delete</button>
}
Add the library classes to your tailwind.config.js
:
module.exports = {
content: [
'./node_modules/@omit/react-confirm-dialog/dist/index.js'
// ... your other content paths
]
// ... other configurations
}
If you're not using Shadcn UI, follow these additional steps:
module.exports = {
theme: {
extend: {
colors: {
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))'
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))'
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))'
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))'
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))'
}
}
}
},
plugins: [require('tailwindcss-animate')]
}
Add these CSS variables to your main CSS file (or get your colors from Shadcn UI):
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 5.9% 10%;
--radius: 0.5rem;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
}
}
You can customize the appearance and behavior of the confirm dialog:
confirm({
title: 'Custom Dialog',
description: 'This is a custom confirm dialog.',
confirmText: 'OK',
cancelText: 'No, thanks',
icon: <CustomIcon />,
confirmButton: {
variant: 'destructive',
size: 'sm'
},
cancelButton: {
variant: 'outline',
size: 'sm'
},
alertDialogContent: {
className: 'custom-dialog-content'
}
// ... other customization options
})
Set default options for all confirm dialogs in your app:
<ConfirmDialogProvider
defaultOptions={{
confirmText: 'Yes',
cancelText: 'No',
alertDialogContent: { className: 'my-default-dialog-class' }
}}
>
{/* Your app components */}
</ConfirmDialogProvider>
The confirm
function accepts an options object with the following properties:
type ConfirmOptions = {
title: React.ReactNode
description?: React.ReactNode
confirmButton?: {
// any normal react button props and Shadcn UI Button props
size?: 'sm' | 'lg' | 'icon'
variant?: 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'
}
cancelButton?: {
// any normal react button props and Shadcn UI Button props
size?: 'sm' | 'lg' | 'icon'
variant?: 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'
} | null // set to null to hide the cancel button
confirmText?: string // default: 'Confirm'
cancelText?: string // default: 'Cancel'
icon?: React.ReactNode
customActions?: (
onConfirm: () => void,
onCancel: () => void
) => React.ReactNode
alertDialogOverlay?: React.ComponentPropsWithRef<typeof AlertDialogOverlay>
alertDialogContent?: React.ComponentPropsWithRef<typeof AlertDialogContent>
alertDialogHeader?: React.ComponentPropsWithRef<typeof AlertDialogHeader>
alertDialogTitle?: React.ComponentPropsWithRef<typeof AlertDialogTitle>
alertDialogDescription?: React.ComponentPropsWithRef<
typeof AlertDialogDescription
>
alertDialogFooter?: React.ComponentPropsWithRef<typeof AlertDialogFooter>
}
To enable class name completion for the className
prop, add this to your editor settings:
{
"tailwindCSS.experimental.classRegex": [
"class:\\s*?[\"'`]([^\"'`]*).*?,",
+ "className:\\s*[\"']([^\"']*)[\"']"
]
}
This project is licensed under the MIT License. See the LICENSE file for details.