Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import React from 'react';
import classNames from 'classnames';
import { AlertCircle, CheckCircle, AlertTriangle, Info, X } from 'lucide-react';
import './Alert.css';
interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
variant?: 'info' | 'success' | 'warning' | 'error';
title?: string;
message: string;
closeable?: boolean;
onClose?: () => void;
}
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
({ variant = 'info', title, message, closeable = false, onClose, className, ...props }, ref) => {
const [isVisible, setIsVisible] = React.useState(true);
const variantConfig = {
info: {
icon: Info,
role: 'status',
},
success: {
icon: CheckCircle,
role: 'status',
},
warning: {
icon: AlertTriangle,
role: 'alert',
},
error: {
icon: AlertCircle,
role: 'alert',
},
};
const config = variantConfig[variant];
const Icon = config.icon;
const handleClose = () => {
setIsVisible(false);
onClose?.();
};
if (!isVisible) return null;
return (
<div
ref={ref}
className={classNames(
'alert',
`alert-${variant}`,
className
)}
role={config.role}
aria-live={variant === 'error' || variant === 'warning' ? 'assertive' : 'polite'}
aria-atomic="true"
{...props}
>
<Icon className="alert-icon" size={20} aria-hidden="true" />
<div className="alert-content">
{title && <h3 className="alert-title">{title}</h3>}
<p className="alert-message">{message}</p>
</div>
{closeable && (
<button
onClick={handleClose}
className="alert-close-button"
aria-label={`Close ${variant} alert: ${title || message}`}
>
<X size={18} aria-hidden="true" />
</button>
)}
</div>
);
}
);
Alert.displayName = 'Alert';
export default Alert;
|