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
Install the package from 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 add additional content between the description and actions:
handleClick = async () => {
const isConfirmed = await confirm({
title: 'Custom Content',
description: 'This dialog includes custom content.',
contentSlot: <CustomComponent />
})
}
The library supports custom actions API that provides access to the dialog's configuration:
const handleClick = async () => {
const isConfirmed = await confirm({
title: 'Custom Actions',
customActions: ({ confirm, cancel, config, setConfig }) => (
<div>
<button
onClick={() => {
setConfig((prev) => ({ ...prev, title: 'Updated Title' }))
}}
>
Update Title
</button>
<button onClick={confirm}>Confirm</button>
<button onClick={cancel}>Cancel</button>
</div>
)
})
}
You can update the dialog's configuration even after it's opened:
const confirm = useConfirm()
confirm.updateConfig((prev) => ({
...prev,
description: 'Updated description'
}))
You can set default options for all confirm dialogs in your app:
<ConfirmDialogProvider
defaultOptions={{
confirmText: 'Yes',
cancelText: 'No',
confirmButton: {
variant: 'destructive',
size: 'sm'
},
cancelButton: {
variant: 'outline',
size: 'sm'
},
alertDialogContent: {
className: 'sm:max-w-[425px]'
}
}}
>
{/* Your app components */}
</ConfirmDialogProvider>
The confirm
function accepts an options object with the following properties:
interface ConfirmOptions {
// Content
title?: ReactNode
description?: ReactNode
contentSlot?: ReactNode
icon?: ReactNode
// Button Text
confirmText?: string
cancelText?: string
// Custom Actions
customActions?: LegacyCustomActions | EnhancedCustomActions
// Button Props
confirmButton?: ComponentPropsWithRef<typeof AlertDialogAction>
cancelButton?: ComponentPropsWithRef<typeof AlertDialogCancel> | null
// Component Props
alertDialogOverlay?: ComponentPropsWithRef<typeof AlertDialogOverlay>
alertDialogContent?: ComponentPropsWithRef<typeof AlertDialogContent>
alertDialogHeader?: ComponentPropsWithRef<typeof AlertDialogHeader>
alertDialogTitle?: ComponentPropsWithRef<typeof AlertDialogTitle>
alertDialogDescription?: ComponentPropsWithRef<typeof AlertDialogDescription>
alertDialogFooter?: 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.