From c1a84ba82a47b4888eb8171f76a4afc706e3087b Mon Sep 17 00:00:00 2001 From: Misaka Date: Wed, 1 Apr 2026 20:15:36 +0800 Subject: [PATCH] feat(ui): migrate ConfirmDialog to shadcn AlertDialog Replace Modal-based ConfirmDialog with Radix AlertDialog primitives. Preserves variant icons/colors, Enter key confirm, and useConfirmDialog hook API unchanged. Co-Authored-By: Claude Opus 4.6 --- .../src/components/ui/ConfirmDialog.tsx | 86 ++++++------ .../src/components/ui/shadcn/alert-dialog.tsx | 132 ++++++++++++++++++ 2 files changed, 177 insertions(+), 41 deletions(-) create mode 100644 src/renderer/src/components/ui/shadcn/alert-dialog.tsx diff --git a/src/renderer/src/components/ui/ConfirmDialog.tsx b/src/renderer/src/components/ui/ConfirmDialog.tsx index 3262c5c..a25ca21 100644 --- a/src/renderer/src/components/ui/ConfirmDialog.tsx +++ b/src/renderer/src/components/ui/ConfirmDialog.tsx @@ -1,14 +1,23 @@ /** * ConfirmDialog Component * - * A confirmation dialog component for displaying confirmation prompts. - * Extends the Modal component with consistent styling and behavior. + * A confirmation dialog using shadcn AlertDialog primitives. + * Supports danger/warning/info variants with icons. */ import React, { useCallback, useEffect } from 'react' import { AlertTriangle, Info, AlertCircle } from 'lucide-react' -import { Modal } from './Modal' import { Button } from './Button' +import { + AlertDialog, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogCancel, + AlertDialogAction +} from './shadcn/alert-dialog' export type ConfirmDialogVariant = 'danger' | 'warning' | 'info' @@ -54,19 +63,16 @@ export function ConfirmDialog({ onConfirm, onCancel }: ConfirmDialogProps) { - // Handle keyboard shortcuts + // Handle Enter key to confirm (Radix handles Escape automatically) const handleKeyDown = useCallback( (e: KeyboardEvent) => { if (!isOpen) return if (e.key === 'Enter') { e.preventDefault() onConfirm() - } else if (e.key === 'Escape') { - e.preventDefault() - onCancel() } }, - [isOpen, onConfirm, onCancel] + [isOpen, onConfirm] ) useEffect(() => { @@ -79,39 +85,37 @@ export function ConfirmDialog({ const styles = variantStyles[variant] return ( - -
- {/* Icon */} -
{styles.icon}
- - {/* Message */} -
- {typeof message === 'string' ? ( -

{message}

- ) : ( - message - )} -
-
- - {/* Buttons */} -
- - -
-
+ { if (!open) onCancel() }}> + + + {title} + +
+
{styles.icon}
+
+ {typeof message === 'string' ? ( +

{message}

+ ) : ( + message + )} +
+
+
+
+ + + + + + + + +
+
) } diff --git a/src/renderer/src/components/ui/shadcn/alert-dialog.tsx b/src/renderer/src/components/ui/shadcn/alert-dialog.tsx new file mode 100644 index 0000000..2ed0a27 --- /dev/null +++ b/src/renderer/src/components/ui/shadcn/alert-dialog.tsx @@ -0,0 +1,132 @@ +import * as React from 'react' +import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog' + +import { cn } from '@renderer/lib/utils' + +function AlertDialog({ + ...props +}: React.ComponentProps) { + return +} + +function AlertDialogTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + + ) +} + +function AlertDialogHeader({ + className, + ...props +}: React.ComponentProps<'div'>) { + return ( +
+ ) +} + +function AlertDialogFooter({ + className, + ...props +}: React.ComponentProps<'div'>) { + return ( +
+ ) +} + +function AlertDialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogAction({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogCancel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + AlertDialog, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel +}