import React, { forwardRef, ComponentType, useRef, useImperativeHandle, } from 'react'; import { StyleSheet, View, Text, TouchableOpacity, StyleProp, TextStyle, Pressable, } from 'react-native'; import { NoticeBarInstance, NoticeBarProps, NoticeBarType, DetailButtonInstance, } from './interface'; import Marquee from './Marquee'; import createStyles from './styles/notice-bar.style'; import { IconXWarn2, IconXSuccess2, IconXRemind2, IconXError2, } from '../../icons'; import { renderTextLikeJSX } from '../../core/helpers'; import ShouldRender from '../ShouldRender'; import { useTheme } from '../Theme'; import DetailButton from './DetailButton'; import { useLocale } from '../Locale/locale'; interface IconProps { color?: string; size?: string | number; fillColor?: string; } type Icon = ComponentType; const IconUrlMap: { [key: string]: Icon } = { success: IconXSuccess2, fail: IconXError2, warn: IconXWarn2, remind: IconXRemind2, }; const rnRenderIcon = (type?: NoticeBarType, iconProps?: IconProps) => { if (!type) return null; const IconComponent = IconUrlMap[type]; if (!IconComponent) return null; return ; }; const getTextsConfig = ({ texts, showBullets, numberOfLines, buttonStyle, }: { texts?: NoticeBarProps['texts']; showBullets?: boolean; numberOfLines?: number; buttonStyle?: StyleProp; }) => { if (!texts) return {}; const defaultShowBullets = showBullets ?? texts.length > 1; const lastLine = numberOfLines || 2; return { numberOfLines: lastLine, text: texts.map((item, index) => ( {index === 0 ? '' : '\n'} {defaultShowBullets ? '• ' : ''} {item.content} {item.actionName ? ( <>   {item.actionName} ) : null} )), wrapable: true, }; }; const NoticeBar = forwardRef( (props, ref) => { const token = useTheme(); const styles = createStyles(token); const locale = useLocale(); const detailButtonRef = useRef(null); const marqueeRef = useRef(null); const { onPress, backgroundColor, style, leftIcon, rightIcon, contentStyle, borderRadius, title, texts, showBullets, popupTitle = locale.NoticeBar.detail, showMoreText = locale.NoticeBar.viewMore, size = 'middle', children, showType = 'text', onRightPress, popupUseNative, ...restProps } = props; let { text, wrapable, numberOfLines, renderOverFlow } = props; if (showType === 'multipleLines') { const { numberOfLines: textNumberOfLines, text: textContent, wrapable: textWrapable, } = getTextsConfig({ texts, showBullets, numberOfLines, buttonStyle: styles.defaultText, }); wrapable = textWrapable; text = textContent; numberOfLines = textNumberOfLines; const defaultShowBulletsComputed = showBullets === undefined ? (texts?.length || 0) > 1 : showBullets; renderOverFlow = (isOverflow: boolean) => { return isOverflow ? ( ) : null; }; } useImperativeHandle(ref, () => ({ reset: () => { marqueeRef.current?.reset?.(); }, hideModal: () => { detailButtonRef.current?.hideModal?.(); }, })); const colorMap = { warn: token['--color-warning-1'], remind: token['--color-gray-2'], success: token['--color-success-1'], fail: token['--color-danger-1'], }; const renderLeftIcon = () => { if (!leftIcon) { return null; } // 如果传入的是bool值,那么就用默认icon,否则用自定义icon if (leftIcon === true) { return ( ); } else if ( ['remind', 'warn', 'fail', 'success'].includes( leftIcon as NoticeBarType ) ) { return ( {rnRenderIcon(leftIcon as NoticeBarType, { size: 24 })} ); } return {renderTextLikeJSX(leftIcon)}; }; const wrapperBgColor = colorMap?.[leftIcon as NoticeBarType]; return ( {renderLeftIcon()} {renderTextLikeJSX(title)} onRightPress?.()} > {renderTextLikeJSX(rightIcon)} ); } ); export default NoticeBar;