All checks were successful
Build & Publish / publish (push) Successful in 1m2s
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>
88 lines
2.3 KiB
TypeScript
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>
|
|
)
|
|
}
|