import * as React from 'react'; import { TextStyle, Text, StyleProp } from 'react-native'; import { FontAwesome5 } from '@react-native-vector-icons/fontawesome5'; import { MaterialDesignIcons } from '@react-native-vector-icons/material-design-icons'; import { Ionicons } from '@react-native-vector-icons/ionicons'; type IconNameProp = IconComponent extends (props: { name: infer NameType })=> unknown ? NameType : never; type FontAwesome5Name = IconNameProp; type MaterialIconName = IconNameProp; type IoniconsName = IconNameProp; interface Props { name: string; style: StyleProp; // If `null` is given, the content must be labeled elsewhere. accessibilityLabel: string|null; allowFontScaling?: boolean; } const Icon: React.FC = props => { // Matches: // 1. A prefix of word characters (\w+) // 2. A suffix of non-spaces (\S+) // An "fa-" at the beginning of the suffix is ignored. const nameMatch = props.name.match(/^(\w+)\s+(?:fa-)?(\S+)$/); const namePrefix = nameMatch ? nameMatch[1] : ''; const nameSuffix = nameMatch ? nameMatch[2] : props.name; // If there's no label, make sure that the screen reader doesn't try // to read the characters from the icon font (they don't make sense // without the icon font applied). const accessibilityHidden = props.accessibilityLabel === null; const importantForAccessibility = accessibilityHidden ? 'no-hide-descendants' as const : 'yes' as const; const sharedProps = { importantForAccessibility, // Android accessibilityElementsHidden: accessibilityHidden, // iOS 'aria-hidden': accessibilityHidden, // Web accessibilityLabel: props.accessibilityLabel, style: props.style, allowFontScaling: props.allowFontScaling, }; if (namePrefix.match(/^fa[bsr]?$/)) { let iconStyle: 'solid'|'brand' = 'solid'; if (namePrefix.startsWith('fab')) { iconStyle = 'brand'; } else if (namePrefix.startsWith('fas')) { iconStyle = 'solid'; } return ( ); } else if (namePrefix === 'material') { return ; } else if (namePrefix === 'ionicon') { return ; } else if (namePrefix === 'text') { return ( {nameSuffix} ); } else { return ; } }; export default Icon;