{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "dynamic-dialog-confirmation", "title": "Dynamic Confirmation Dialog", "description": "A dynamic confirmation dialog.", "dependencies": [ "zod", "@hookform/resolvers", "react-hook-form" ], "registryDependencies": [ "button", "dialog", "Quackzoer/shadcn-registry/dynamic-dialog" ], "files": [ { "path": "components/dynamic-dialog/dialogs/confirm-dialog.tsx", "content": "\"use client\"\r\n\r\nimport React, { type ReactNode } from \"react\";\r\nimport { dialog, type DialogActions, type DialogComponentProps } from \"@/registry/lib/dynamic-dialog-state\";\r\nimport {\r\n type DialogActionButton,\r\n type DialogActionsContainer,\r\n renderStandardDialogActions,\r\n} from \"@/lib/dynamic-dialog-actions\";\r\nimport { AlertDialog, AlertDialogContent, AlertDialogDescription, AlertDialogHeader, AlertDialogTitle } from \"@/registry/ui/alert-dialog\";\r\nimport { Trash2 } from \"lucide-react\";\r\n\r\ntype ResolveValue = boolean | undefined;\r\n\r\nexport interface ConfirmDialogHeader {\r\n title?: ReactNode;\r\n description?: ReactNode;\r\n icon?: ReactNode;\r\n}\r\n\r\n// Each dialog defines its own actions shape using DialogActionButton directly.\r\n// confirmDialog exposes cancel + optional custom buttons + confirm.\r\n// There is no shared DialogActionsConfig — the slot names and their presence\r\n// are specific to this dialog's semantics.\r\nexport interface ConfirmDialogActionsConfig {\r\n cancelButton?: DialogActionButton;\r\n customButtons?: DialogActionButton[];\r\n confirmButton?: DialogActionButton;\r\n container?: DialogActionsContainer;\r\n}\r\n\r\nexport interface ConfirmDialogProps {\r\n header?: ReactNode | ((props: DialogActions) => ReactNode) | ConfirmDialogHeader;\r\n actions?: ConfirmDialogActionsConfig;\r\n}\r\n\r\nfunction isConfirmDialogHeader(value: unknown): value is ConfirmDialogHeader {\r\n return (\r\n value !== null &&\r\n typeof value === \"object\" &&\r\n !React.isValidElement(value) &&\r\n (\"title\" in value || \"description\" in value || \"icon\" in value)\r\n );\r\n}\r\n\r\nexport const confirmDialog = dialog(function (\r\n props: DialogComponentProps,\r\n) {\r\n const renderHeader = () => {\r\n if (typeof props.header === \"function\") {\r\n return props.header(props);\r\n }\r\n if (isConfirmDialogHeader(props.header)) {\r\n return (\r\n
\r\n
\r\n {props.header.icon ?? }\r\n
\r\n
\r\n \r\n {props.header.title ?? \"Are you sure?\"}\r\n \r\n \r\n {props.header.description ?? \"\"}\r\n \r\n
\r\n
\r\n );\r\n }\r\n return props.header;\r\n };\r\n\r\n return (\r\n \r\n \r\n \r\n {renderHeader()}\r\n \r\n {renderStandardDialogActions(\r\n props.actions ?? {},\r\n props,\r\n undefined,\r\n {\r\n cancel: {\r\n label: \"Cancel\",\r\n variant: \"outline\",\r\n type: \"button\",\r\n onClick: (a) => a.dismiss(\"cancel\"),\r\n },\r\n confirm: {\r\n label: \"Confirm\",\r\n variant: \"destructive\",\r\n type: \"submit\",\r\n onClick: (a) => a.confirm(true),\r\n },\r\n },\r\n )}\r\n \r\n \r\n );\r\n});\r\n", "type": "registry:component", "target": "@components/dynamic-dialog/dialogs/confirm-dialog.tsx" } ], "type": "registry:component" }