import { isValidElement, forwardRef, ElementType, useMemo } from 'react'; import { getWebProps } from 'react-native-unistyles/web'; import { alertStyles } from './Alert.styles'; import type { AlertProps } from './types'; import { IconSvg } from '../Icon/IconSvg/IconSvg.web'; import { IconRegistry } from '../Icon/IconRegistry'; import { isIconName } from '../Icon/icon-resolver'; import useMergeRefs from '../hooks/useMergeRefs'; import type { IdealystElement } from '../utils/refTypes'; import { flattenStyle } from '../utils/flattenStyle'; import { mdiInformation, mdiCheckCircle, mdiAlertCircle, mdiAlert, mdiRecordCircle, mdiClose } from '@mdi/js'; // Self-register icons used internally by Alert IconRegistry.registerMany({ 'information': mdiInformation, 'check-circle': mdiCheckCircle, 'alert-circle': mdiAlertCircle, 'alert': mdiAlert, 'record-circle': mdiRecordCircle, 'close': mdiClose, }); // Default icons for each intent const defaultIcons: Record> = { primary: (props: any) => , success: (props: any) => , error: (props: any) => , warning: (props: any) => , info: (props: any) => , neutral: (props: any) => , }; /** * Notification banner for displaying important messages, warnings, or status updates. * Supports multiple intents, dismissibility, and custom actions. */ const Alert = forwardRef(({ title, message, children, intent = 'neutral', type = 'soft', size = 'md', icon, showIcon = true, dismissible = false, onDismiss, actions, style, testID, id, }, ref) => { // Apply variants for size, intent, and type alertStyles.useVariants({ size, intent, type }); // Compute dynamic styles with intent, type, and size const dynamicProps = { intent, type, size }; const containerProps = getWebProps([(alertStyles.container as any)(dynamicProps), flattenStyle(style)]); const iconContainerProps = getWebProps([(alertStyles.iconContainer as any)(dynamicProps)]); const contentProps = getWebProps([(alertStyles.content as any)(dynamicProps)]); const titleProps = getWebProps([(alertStyles.title as any)(dynamicProps)]); const messageProps = getWebProps([(alertStyles.message as any)(dynamicProps)]); const actionsProps = getWebProps([(alertStyles.actions as any)(dynamicProps)]); const closeButtonProps = getWebProps([(alertStyles.closeButton as any)(dynamicProps)]); const closeIconProps = getWebProps([(alertStyles.closeIcon as any)(dynamicProps)]); const Icon = useMemo(() => { if (!showIcon) return null; if (!icon) { const Element = defaultIcons[intent]; if (Element) { return ; } return null } else if (typeof icon === 'string') { return } else if (isValidElement(icon)) { return icon; } return null; }, [icon, showIcon, intent]); const mergedRef = useMergeRefs(ref, containerProps.ref); return ( ); }); Alert.displayName = 'Alert'; export default Alert;