Files
design-system/src/design-system/composites/AlertDialog/AlertDialog.tsx
hsiegeln 433d582da6
All checks were successful
Build & Publish / publish (push) Successful in 1m2s
feat: migrate all icons to Lucide React
Replace unicode characters, emoji, and inline SVGs with lucide-react
components across the entire design system and page layer. Update
tests to assert on SVG elements instead of text content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 23:25:43 +01:00

88 lines
2.3 KiB
TypeScript

import React, { useEffect, useRef } from 'react'
import { XCircle, AlertTriangle, Info } from 'lucide-react'
import { Modal } from '../Modal/Modal'
import { Button } from '../../primitives/Button/Button'
import styles from './AlertDialog.module.css'
interface AlertDialogProps {
open: boolean
onClose: () => void
onConfirm: () => void
title: string
description: string
confirmLabel?: string
cancelLabel?: string
variant?: 'danger' | 'warning' | 'info'
loading?: boolean
className?: string
}
const variantIcons: Record<NonNullable<AlertDialogProps['variant']>, React.ReactNode> = {
danger: <XCircle size={20} />,
warning: <AlertTriangle size={20} />,
info: <Info size={20} />,
}
export function AlertDialog({
open,
onClose,
onConfirm,
title,
description,
confirmLabel = 'Confirm',
cancelLabel = 'Cancel',
variant = 'danger',
loading = false,
className,
}: AlertDialogProps) {
const cancelWrapRef = useRef<HTMLSpanElement>(null)
useEffect(() => {
if (open) {
// Defer to allow Modal portal to render first
const id = setTimeout(() => {
const btn = cancelWrapRef.current?.querySelector('button')
btn?.focus()
}, 0)
return () => clearTimeout(id)
}
}, [open])
const confirmButtonVariant = variant === 'danger' ? 'danger' : 'primary'
return (
<Modal open={open} onClose={onClose} size="sm" className={className}>
<div className={styles.content}>
<div className={`${styles.iconCircle} ${styles[variant]}`} aria-hidden="true">
<span className={styles.icon}>{variantIcons[variant]}</span>
</div>
<h2 className={styles.title}>{title}</h2>
<p className={styles.description}>{description}</p>
<div className={styles.buttonRow}>
<span ref={cancelWrapRef}>
<Button
variant="secondary"
onClick={onClose}
disabled={loading}
type="button"
>
{cancelLabel}
</Button>
</span>
<Button
variant={confirmButtonVariant}
onClick={onConfirm}
loading={loading}
disabled={loading}
type="button"
>
{confirmLabel}
</Button>
</div>
</div>
</Modal>
)
}