'use client'; import { AnimatePresence, LazyMotion, m } from 'motion/react'; import React, { useCallback, useEffect, useState, useMemo } from 'react'; import { useBreakpoint } from '../../hook/breakpoints.hook.js'; import { resolveResponsiveVariant } from '../../utils/breakpoint.util.js'; import { Button } from '../button/button.component.js'; import { AlertIcon, CloseIcon, InfoIcon, LimitIcon, SuccessIcon, WarningIcon } from '../icon/index.js'; import { styles as alertStyles } from './alert.styles.js'; import { type AlertProps } from './alert.types.js'; const loadAnimations = () => import('./alert.utils.js').then(res => res.default); export function Alert({ look = 'info', mode = 'box', heading, headingTag: HeadingTag = 'h2', dismissible = false, open: isOpen = true, onClose, icon, iconSize, tag: Tag = 'div', className, children, ...props }: AlertProps) { const [open, setOpen] = useState(isOpen); const iconMap = { info: InfoIcon, success: SuccessIcon, warning: WarningIcon, danger: AlertIcon, system: LimitIcon, } as const; const breakpoint = useBreakpoint(); const resolvedLook = resolveResponsiveVariant(look, breakpoint); // A11y: Only info look allows a custom icon const Icon = resolvedLook === 'info' && icon ? icon : iconMap[resolvedLook || 'info']; const styles = alertStyles({ look: resolvedLook, mode: resolveResponsiveVariant(mode, breakpoint), dismissible, iconSize: resolveResponsiveVariant(iconSize, breakpoint), }); useEffect(() => { setOpen(isOpen); }, [isOpen]); const handleClose = useCallback(() => { setOpen(false); onClose?.(); }, [onClose]); const iconColor = useMemo(() => { if (resolvedLook === 'system') { return 'system-error-dark'; } return resolvedLook; }, [resolvedLook]); return ( {open && (
{!!heading && {heading}} {children}
{dismissible && mode !== 'text' && ( )}
)}
); }