diff --git a/src/components/MentionSuggestions.js b/src/components/MentionSuggestions.tsx similarity index 64% rename from src/components/MentionSuggestions.js rename to src/components/MentionSuggestions.tsx index d18b8947e68d..2d0f3bf32b41 100644 --- a/src/components/MentionSuggestions.js +++ b/src/components/MentionSuggestions.tsx @@ -1,73 +1,61 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; -import _ from 'underscore'; import getStyledTextArray from '@libs/GetStyledTextArray'; import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; import themeColors from '@styles/themes/default'; import CONST from '@src/CONST'; +import {Icon} from '@src/types/onyx/OnyxCommon'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import Avatar from './Avatar'; -import avatarPropTypes from './avatarPropTypes'; import Text from './Text'; -const propTypes = { - /** The index of the highlighted mention */ - highlightedMentionIndex: PropTypes.number, +type Mention = { + /** Display name of the user */ + text: string; - /** Array of suggested mentions */ - mentions: PropTypes.arrayOf( - PropTypes.shape({ - /** Display name of the user */ - text: PropTypes.string, + /** Email/phone number of the user */ + alternateText: string; + + /** Array of icons of the user. We use the first element of this array */ + icons: Icon[]; +}; - /** Email/phone number of the user */ - alternateText: PropTypes.string, +type MentionSuggestionsProps = { + /** The index of the highlighted mention */ + highlightedMentionIndex?: number; - /** Array of icons of the user. We use the first element of this array */ - icons: PropTypes.arrayOf(avatarPropTypes), - }), - ).isRequired, + /** Array of suggested mentions */ + mentions: Mention[]; /** Fired when the user selects an mention */ - onSelect: PropTypes.func.isRequired, + onSelect: () => void; /** Mention prefix that follows the @ sign */ - prefix: PropTypes.string.isRequired, + prefix: string; /** Show that we can use large mention picker. * Depending on available space and whether the input is expanded, we can have a small or large mention suggester. * When this value is false, the suggester will have a height of 2.5 items. When this value is true, the height can be up to 5 items. */ - isMentionPickerLarge: PropTypes.bool.isRequired, + isMentionPickerLarge: boolean; /** Meaures the parent container's position and dimensions. */ - measureParentContainer: PropTypes.func, -}; - -const defaultProps = { - highlightedMentionIndex: 0, - measureParentContainer: () => {}, + measureParentContainer: () => void; }; /** * Create unique keys for each mention item - * @param {Object} item - * @param {Number} index - * @returns {String} */ -const keyExtractor = (item) => item.alternateText; +const keyExtractor = (item: Mention) => item.alternateText; -function MentionSuggestions(props) { +function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSelect, isMentionPickerLarge, measureParentContainer = () => {}}: MentionSuggestionsProps) { /** * Render a suggestion menu item component. - * @param {Object} item - * @returns {JSX.Element} */ - const renderSuggestionMenuItem = (item) => { + const renderSuggestionMenuItem = (item: Mention) => { const isIcon = item.text === CONST.AUTO_COMPLETE_SUGGESTER.HERE_TEXT; - const styledDisplayName = getStyledTextArray(item.text, props.prefix); - const styledHandle = item.text === item.alternateText ? '' : getStyledTextArray(item.alternateText, props.prefix); + const styledDisplayName = getStyledTextArray(item.text, prefix); + const styledHandle = item.text === item.alternateText ? undefined : getStyledTextArray(item.alternateText, prefix); return ( @@ -85,8 +73,9 @@ function MentionSuggestions(props) { style={[styles.mentionSuggestionsText, styles.flexShrink1]} numberOfLines={1} > - {_.map(styledDisplayName, ({text, isColored}, i) => ( + {styledDisplayName?.map(({text, isColored}, i) => ( @@ -98,13 +87,13 @@ function MentionSuggestions(props) { style={[styles.mentionSuggestionsText, styles.flex1]} numberOfLines={1} > - {_.map( - styledHandle, + {styledHandle?.map( ({text, isColored}, i) => - text !== '' && ( + Boolean(text) && ( {text} @@ -117,20 +106,18 @@ function MentionSuggestions(props) { return ( ); } -MentionSuggestions.propTypes = propTypes; -MentionSuggestions.defaultProps = defaultProps; MentionSuggestions.displayName = 'MentionSuggestions'; export default MentionSuggestions; diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index de936570291f..bdfa7c1dd196 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -1018,7 +1018,7 @@ function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle /** * Select the correct color for text. */ -function getColoredBackgroundStyle(isColored: boolean): TextStyle { +function getColoredBackgroundStyle(isColored: boolean): StyleProp { return {backgroundColor: isColored ? themeColors.link : undefined}; } diff --git a/src/styles/styles.ts b/src/styles/styles.ts index b70b50ffbbbc..644b809ebae4 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -328,10 +328,6 @@ const styles = (theme: ThemeColors) => textAlign: 'left', }, - textUnderline: { - textDecorationLine: 'underline', - }, - verticalAlignMiddle: { verticalAlign: 'middle', }, @@ -392,10 +388,6 @@ const styles = (theme: ThemeColors) => fontSize: variables.fontSizeLarge, }, - textXLarge: { - fontSize: variables.fontSizeXLarge, - }, - textXXLarge: { fontSize: variables.fontSizeXXLarge, }, @@ -415,11 +407,6 @@ const styles = (theme: ThemeColors) => fontWeight: fontWeightBold, }, - textItalic: { - fontFamily: fontFamily.EXP_NEUE_ITALIC, - fontStyle: 'italic', - }, - textHeadline: { ...headlineFont, ...whiteSpace.preWrap, @@ -436,10 +423,6 @@ const styles = (theme: ThemeColors) => lineHeight: variables.lineHeightSizeh1, }, - textDecorationNoLine: { - textDecorationLine: 'none', - }, - textWhite: { color: theme.textLight, }, @@ -448,10 +431,6 @@ const styles = (theme: ThemeColors) => color: theme.link, }, - textUppercase: { - textTransform: 'uppercase', - }, - textNoWrap: { ...whiteSpace.noWrap, }, diff --git a/src/types/onyx/OnyxCommon.ts b/src/types/onyx/OnyxCommon.ts index ef2944d6af82..202407d6a2e8 100644 --- a/src/types/onyx/OnyxCommon.ts +++ b/src/types/onyx/OnyxCommon.ts @@ -1,4 +1,5 @@ import * as React from 'react'; +import {SvgProps} from 'react-native-svg'; import {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; @@ -11,9 +12,11 @@ type ErrorFields = Record; type Icon = { - source: React.ReactNode | string; - type: 'avatar' | 'workspace'; + source: string | React.FC; + type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; name: string; + id: number | string; + fallbackIcon?: string | React.FC; }; export type {Icon, PendingAction, PendingFields, ErrorFields, Errors};