import React, { isValidElement, useMemo } from 'react'; import { StyleSheet, Animated, Platform, DimensionValue } from 'react-native'; import { Text } from '../../components/Text'; import { Ripple } from '../../components/Ripple'; import useTheme from '../../context/theme/useTheme'; import { isValidChild } from '../../utils/render'; import { AlertProps, AlertType, FuncRenderIcon } from './types'; import { Box } from '../../components/Box'; import createSxStyle from '../../lib/sx'; import { Button } from '../Button'; import { CheckSuccessIcon, InfoOutlineIcon, WarningOutlineIcon, CloseOutlineIcon } from '../../icons'; const icons: Record = { default: , success: , info: , warning: , error: }; export const Alert: React.FC = ({ endContent, content, onPress, onClose, opacity, type, sx, closeText = 'Close', withInternalClose = false, closable = !onPress, withBoxShadow = false, withIcon = true, translateYAnimation = new Animated.Value(0), startContent = withIcon ? icons[type] : null, style = {}, styleText = {}, Component = (closable || onPress) && !withInternalClose ? Ripple : Box, ...restSxProps }) => { const theme = useTheme(); const [internalClose, setInternalClose] = React.useState(false); const { colors, isDark, activeOpacity, borderRadius } = theme; const boxShadowColor = React.useMemo(() => { return isDark ? colors.get('gray.800') : colors.get('gray.200'); }, [colors, isDark]); const standardContent = useMemo(() => { return { title: (content as any)?.title || content, description: (content as any)?.description }; }, [content]); const internalPress = (event: any) => { onPress?.(event); closable && onClose?.(); }; const start = useMemo(() => { if (!startContent) return null; return isValidElement(startContent) ? (startContent as React.ReactNode) : (startContent as FuncRenderIcon)(onClose); }, [onClose, startContent]); const end = useMemo(() => { if (!endContent) return null; return isValidElement(endContent) ? (endContent as React.ReactNode) : (endContent as FuncRenderIcon)(onClose); }, [onClose, endContent]); const showStartContent = withIcon || !!startContent; if (internalClose) return null; const height = Platform.select({ default: '100%', web: undefined }); const flex = Platform.select({ default: 1, web: undefined }); return ( {showStartContent ? start : null} {isValidChild(standardContent?.title) ? ( standardContent?.title ) : ( {standardContent?.title} )} {isValidChild(standardContent?.description) ? ( standardContent?.description ) : ( {standardContent?.description} )} {end} {withInternalClose && ( )} ); }; const styles = StyleSheet.create({ shadowStyle: { shadowOpacity: 0.5, shadowOffset: { width: 0, height: 5 }, shadowRadius: 5 } });