From 499a416c2b3a9012272ab86ad78a0f81e3d18959 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 22 Nov 2023 12:46:53 +0100 Subject: [PATCH 01/17] feat: migrate MultipleAvatars --- src/components/Icon/index.tsx | 1 + src/components/MultipleAvatars.tsx | 47 ++++++++++--------- src/components/OfflineWithFeedback.js | 1 + src/components/Onfido/BaseOnfidoWeb.js | 2 +- .../OptionsSelector/BaseOptionsSelector.js | 1 + src/components/SelectCircle.tsx | 1 + 6 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 022c740907ea..5b92ca3ca361 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -59,6 +59,7 @@ class Icon extends PureComponent { }; render() { + console.log('Icon'); const width = this.props.small ? variables.iconSizeSmall : this.props.width; const height = this.props.small ? variables.iconSizeSmall : this.props.height; const iconStyles = [StyleUtils.getWidthAndHeightStyle(width ?? 0, height), IconWrapperStyles, styles.pAbsolute, this.props.additionalStyles]; diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index febe18f30c7d..9251cdded6e1 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -2,8 +2,10 @@ import React, {memo, useMemo} from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; import {ValueOf} from 'type-fest'; import {AvatarSource} from '@libs/UserUtils'; -import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; +import useTheme from "@styles/themes/useTheme"; +import useThemeStyles from "@styles/useThemeStyles"; +// TODO: should it be removed? import themeColors from '@styles/themes/default'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -63,21 +65,6 @@ type AvatarSizeToStyles = typeof CONST.AVATAR_SIZE.SMALL | typeof CONST.AVATAR_S type AvatarSizeToStylesMap = Record; -const avatarSizeToStylesMap: AvatarSizeToStylesMap = { - [CONST.AVATAR_SIZE.SMALL]: { - singleAvatarStyle: styles.singleAvatarSmall, - secondAvatarStyles: styles.secondAvatarSmall, - }, - [CONST.AVATAR_SIZE.LARGE]: { - singleAvatarStyle: styles.singleAvatarMedium, - secondAvatarStyles: styles.secondAvatarMedium, - }, - [CONST.AVATAR_SIZE.DEFAULT]: { - singleAvatarStyle: styles.singleAvatar, - secondAvatarStyles: styles.secondAvatar, - }, -}; - function MultipleAvatars({ fallbackIcon, icons = [], @@ -93,6 +80,24 @@ function MultipleAvatars({ shouldUseCardBackground = false, maxAvatarsInRow = CONST.AVATAR_ROW_SIZE.DEFAULT, }: MultipleAvatarsProps) { + const theme = useTheme(); + const styles = useThemeStyles(); + + const avatarSizeToStylesMap: AvatarSizeToStylesMap = useMemo(() => ({ + [CONST.AVATAR_SIZE.SMALL]: { + singleAvatarStyle: styles.singleAvatarSmall, + secondAvatarStyles: styles.secondAvatarSmall, + }, + [CONST.AVATAR_SIZE.LARGE]: { + singleAvatarStyle: styles.singleAvatarMedium, + secondAvatarStyles: styles.secondAvatarMedium, + }, + [CONST.AVATAR_SIZE.DEFAULT]: { + singleAvatarStyle: styles.singleAvatar, + secondAvatarStyles: styles.secondAvatar, + }, + }), [styles]); + let avatarContainerStyles = StyleUtils.getContainerStyles(size, isInReportAction); const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[size as AvatarSizeToStyles] ?? avatarSizeToStylesMap.default, [size]); @@ -143,7 +148,7 @@ function MultipleAvatars({ { diff --git a/src/components/SelectCircle.tsx b/src/components/SelectCircle.tsx index cf8ee6af975d..e55fbe9a611a 100644 --- a/src/components/SelectCircle.tsx +++ b/src/components/SelectCircle.tsx @@ -14,6 +14,7 @@ type SelectCircleProps = { }; function SelectCircle({isChecked = false, styles}: SelectCircleProps) { + console.log('SelectCircle'); return ( {isChecked && ( From dbe88eb6e0b0bb0c876a846ba8f8f1e1f210e429 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 22 Nov 2023 14:18:08 +0100 Subject: [PATCH 02/17] fix: migrate SelectCircle --- src/components/OptionsList/BaseOptionsList.js | 2 +- src/components/SelectCircle.tsx | 16 +++++++++------- src/components/SingleOptionSelector.js | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/OptionsList/BaseOptionsList.js b/src/components/OptionsList/BaseOptionsList.js index 2f81e6d80e7d..22cca0ed8659 100644 --- a/src/components/OptionsList/BaseOptionsList.js +++ b/src/components/OptionsList/BaseOptionsList.js @@ -203,7 +203,7 @@ function BaseOptionsList({ optionIsFocused={!disableFocusOptions && !isItemDisabled && focusedIndex === index + section.indexOffset} onSelectRow={onSelectRow} isSelected={isSelected} - showSelectedState={canSelectMultipleOptions} + showSelectedState={true} shouldShowSelectedStateAsButton={shouldShowMultipleOptionSelectorAsButton} selectedStateButtonText={multipleOptionSelectorButtonText} onSelectedStatePressed={onAddToSelection} diff --git a/src/components/SelectCircle.tsx b/src/components/SelectCircle.tsx index e55fbe9a611a..106532f0f2ec 100644 --- a/src/components/SelectCircle.tsx +++ b/src/components/SelectCircle.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; -import globalStyles from '@styles/styles'; -import themeColors from '@styles/themes/default'; +import useTheme from "@styles/themes/useTheme"; +import useThemeStyles from "@styles/useThemeStyles"; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; @@ -10,17 +10,19 @@ type SelectCircleProps = { isChecked: boolean; /** Additional styles to pass to SelectCircle */ - styles?: StyleProp; + selectCircleStyles?: StyleProp; }; -function SelectCircle({isChecked = false, styles}: SelectCircleProps) { - console.log('SelectCircle'); +function SelectCircle({isChecked = false, selectCircleStyles}: SelectCircleProps) { + const theme = useTheme(); + const styles = useThemeStyles(); + return ( - + {isChecked && ( )} diff --git a/src/components/SingleOptionSelector.js b/src/components/SingleOptionSelector.js index 967ae5443a81..9567ad2331ef 100644 --- a/src/components/SingleOptionSelector.js +++ b/src/components/SingleOptionSelector.js @@ -51,7 +51,7 @@ function SingleOptionSelector({options, selectedOptionKey, onSelectOption, trans > {translate(option.label)} From d38b9e38434bdbe064b9b7cff2d5e457f0b001e2 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 22 Nov 2023 14:45:10 +0100 Subject: [PATCH 03/17] feat: migrate OfflineWithFeedback --- src/components/OfflineWithFeedback.js | 43 ++++++++++++++------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/components/OfflineWithFeedback.js b/src/components/OfflineWithFeedback.js index ea6a72bdd937..aac4eb86f364 100644 --- a/src/components/OfflineWithFeedback.js +++ b/src/components/OfflineWithFeedback.js @@ -1,12 +1,12 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, {useCallback} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import useNetwork from '@hooks/useNetwork'; import shouldRenderOffscreen from '@libs/shouldRenderOffscreen'; import stylePropTypes from '@styles/stylePropTypes'; -import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; +import useThemeStyles from "@styles/useThemeStyles"; import CONST from '@src/CONST'; import MessagesRow from './MessagesRow'; @@ -64,7 +64,8 @@ const defaultProps = { errors: null, shouldShowErrorMessages: true, shouldDisableOpacity: false, - onClose: () => {}, + onClose: () => { + }, style: [], contentContainerStyle: [], errorRowStyles: [], @@ -73,26 +74,9 @@ const defaultProps = { canDismissError: true, }; -/** - * This method applies the strikethrough to all the children passed recursively - * @param {Array} children - * @return {Array} - */ -function applyStrikeThrough(children) { - return React.Children.map(children, (child) => { - if (!React.isValidElement(child)) { - return child; - } - const props = {style: StyleUtils.combineStyles(child.props.style, styles.offlineFeedback.deleted, styles.userSelectNone)}; - if (child.props.children) { - props.children = applyStrikeThrough(child.props.children); - } - return React.cloneElement(child, props); - }); -} function OfflineWithFeedback(props) { - console.log('OfflineWithFeedback'); + const styles = useThemeStyles(); const {isOffline} = useNetwork(); const hasErrors = !_.isEmpty(props.errors); @@ -108,6 +92,23 @@ function OfflineWithFeedback(props) { const hideChildren = props.shouldHideOnDelete && !isOffline && props.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && !hasErrors; let children = props.children; + /** + * This method applies the strikethrough to all the children passed recursively + * @param {Array} children + * @return {Array} + */ + const applyStrikeThrough = useCallback((childrenToStyle) => React.Children.map(childrenToStyle, (child) => { + if (!React.isValidElement(child)) { + return child; + } + const elementProps = {style: StyleUtils.combineStyles(child.props.style, styles.offlineFeedback.deleted, styles.userSelectNone)}; + if (child.props.children) { + elementProps.children = applyStrikeThrough(child.props.children); + } + return React.cloneElement(child, elementProps); + }), [styles]) + + // Apply strikethrough to children if needed, but skip it if we are not going to render them if (needsStrikeThrough && !hideChildren) { children = applyStrikeThrough(children); From c3fa464bb9128605ca95283b6d6f4c87f7c340d5 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 22 Nov 2023 16:49:09 +0100 Subject: [PATCH 04/17] feat: migrate BaseOptionsSelector --- .../OptionsSelector/BaseOptionsSelector.js | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/components/OptionsSelector/BaseOptionsSelector.js b/src/components/OptionsSelector/BaseOptionsSelector.js index 78e8b32b5b37..d4287f02169f 100755 --- a/src/components/OptionsSelector/BaseOptionsSelector.js +++ b/src/components/OptionsSelector/BaseOptionsSelector.js @@ -13,6 +13,8 @@ import OptionsList from '@components/OptionsList'; import {PressableWithoutFeedback} from '@components/Pressable'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; +import withThemeStyles from "@components/withThemeStyles"; +import withTheme from "@components/withTheme"; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withNavigationFocus from '@components/withNavigationFocus'; import compose from '@libs/compose'; @@ -20,8 +22,6 @@ import getPlatform from '@libs/getPlatform'; import KeyboardShortcut from '@libs/KeyboardShortcut'; import Navigation from '@libs/Navigation/Navigation'; import setSelection from '@libs/setSelection'; -import colors from '@styles/colors'; -import styles from '@styles/styles'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import {defaultProps as optionsSelectorDefaultProps, propTypes as optionsSelectorPropTypes} from './optionsSelectorPropTypes'; @@ -58,7 +58,7 @@ const defaultProps = { referralContentType: CONST.REFERRAL_PROGRAM.CONTENT_TYPES.REFER_FRIEND, safeAreaPaddingBottomStyle: {}, contentContainerStyles: [], - listContainerStyles: [styles.flex1], + listContainerStyles: [{flex: 1}], listStyles: [], ...optionsSelectorDefaultProps, }; @@ -90,7 +90,6 @@ class BaseOptionsSelector extends Component { componentDidMount() { this.subscribeToKeyboardShortcut(); - console.log('BaseOptionsSelector'); if (this.props.isFocused && this.props.autoFocus && this.textInput) { this.focusTimeout = setTimeout(() => { @@ -464,8 +463,8 @@ class BaseOptionsSelector extends Component { const optionsAndInputsBelowThem = ( <> - {optionsList} - + {optionsList} + {this.props.children} {this.props.shouldShowTextInput && textInput} @@ -480,18 +479,18 @@ class BaseOptionsSelector extends Component { onFocusedIndexChanged={this.props.disableArrowKeysActions ? () => {} : this.updateFocusedIndex} shouldResetIndexOnEndReached={false} > - + {/* * The OptionsList component uses a SectionList which uses a VirtualizedList internally. * VirtualizedList cannot be directly nested within ScrollViews of the same orientation. * To work around this, we wrap the OptionsList component with a horizontal ScrollView. */} {this.props.shouldTextInputAppearBelowOptions && this.props.shouldAllowScrollingChildren && ( - + {optionsAndInputsBelowThem} @@ -502,13 +501,13 @@ class BaseOptionsSelector extends Component { {!this.props.shouldTextInputAppearBelowOptions && ( <> - + {this.props.children} {this.props.shouldShowTextInput && textInput} {Boolean(this.props.textInputAlert) && ( )} @@ -518,20 +517,20 @@ class BaseOptionsSelector extends Component { )} {this.props.shouldShowReferralCTA && ( - + { Navigation.navigate(ROUTES.REFERRAL_DETAILS_MODAL.getRoute(this.props.referralContentType)); }} - style={[styles.p5, styles.w100, styles.br2, styles.highlightBG, styles.flexRow, styles.justifyContentBetween, styles.alignItemsCenter, {gap: 10}]} + style={[this.props.themeStyles.p5, this.props.themeStyles.w100, this.props.themeStyles.br2, this.props.themeStyles.highlightBG, this.props.themeStyles.flexRow, this.props.themeStyles.justifyContentBetween, this.props.themeStyles.alignItemsCenter, {gap: 10}]} accessibilityLabel="referral" role={CONST.ACCESSIBILITY_ROLE.BUTTON} > {this.props.translate(`referralProgram.${this.props.referralContentType}.buttonText1`)} {this.props.translate(`referralProgram.${this.props.referralContentType}.buttonText2`)} @@ -550,7 +549,7 @@ class BaseOptionsSelector extends Component { {shouldShowDefaultConfirmButton && (