diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 022c740907ea..82a5045b7ad4 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -1,6 +1,6 @@ import React, {PureComponent} from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; -import styles from '@styles/styles'; +import withThemeStyles, {ThemeStylesProps} from '@components/withThemeStyles'; import * as StyleUtils from '@styles/StyleUtils'; import themeColors from '@styles/themes/default'; import variables from '@styles/variables'; @@ -41,7 +41,7 @@ type IconProps = { /** Additional styles to add to the Icon */ additionalStyles?: StyleProp; -}; +} & ThemeStylesProps; // We must use a class component to create an animatable component with the Animated API // eslint-disable-next-line react/prefer-stateless-function @@ -61,13 +61,13 @@ class Icon extends PureComponent { render() { 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]; + const iconStyles = [StyleUtils.getWidthAndHeightStyle(width ?? 0, height), IconWrapperStyles, this.props.themeStyles.pAbsolute, this.props.additionalStyles]; if (this.props.inline) { return ( { } } -export default Icon; +export default withThemeStyles(Icon); diff --git a/src/components/LHNOptionsList/OptionRowLHN.js b/src/components/LHNOptionsList/OptionRowLHN.js index 4e01ee4d7830..3b2de574ba17 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.js +++ b/src/components/LHNOptionsList/OptionRowLHN.js @@ -103,7 +103,7 @@ function OptionRowLHN(props) { props.style, ); const contentContainerStyles = - props.viewMode === CONST.OPTION_MODE.COMPACT ? [styles.flex1, styles.flexRow, styles.overflowHidden, optionRowStyles.compactContentContainerStyles] : [styles.flex1]; + props.viewMode === CONST.OPTION_MODE.COMPACT ? [styles.flex1, styles.flexRow, styles.overflowHidden, optionRowStyles.compactContentContainerStyles(styles)] : [styles.flex1]; const sidebarInnerRowStyle = StyleSheet.flatten( props.viewMode === CONST.OPTION_MODE.COMPACT ? [styles.chatLinkRowPressable, styles.flexGrow1, styles.optionItemAvatarNameWrapper, styles.optionRowCompact, styles.justifyContentCenter] diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index febe18f30c7d..6f15612736ef 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -2,9 +2,9 @@ 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 themeColors from '@styles/themes/default'; +import useTheme from '@styles/themes/useTheme'; +import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import type {Icon} from '@src/types/onyx/OnyxCommon'; @@ -63,26 +63,11 @@ 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 = [], size = CONST.AVATAR_SIZE.DEFAULT, - secondAvatarStyle = [StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)], + secondAvatarStyle: secondAvatarStyleProp, shouldStackHorizontally = false, shouldDisplayAvatarsInRows = false, isHovered = false, @@ -93,8 +78,31 @@ 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], + ); + + const secondAvatarStyle = secondAvatarStyleProp ?? [StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)]; + let avatarContainerStyles = StyleUtils.getContainerStyles(size, isInReportAction); - const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[size as AvatarSizeToStyles] ?? avatarSizeToStylesMap.default, [size]); + const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[size as AvatarSizeToStyles] ?? avatarSizeToStylesMap.default, [size, avatarSizeToStylesMap]); const tooltipTexts = useMemo(() => (shouldShowTooltip ? icons.map((icon) => icon.name) : ['']), [shouldShowTooltip, icons]); const avatarSize = useMemo(() => { @@ -143,7 +151,7 @@ function MultipleAvatars({ { 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); + props.children = applyStrikeThrough(child.props.children, styles); } return React.cloneElement(child, props); }); } function OfflineWithFeedback(props) { + const styles = useThemeStyles(); const {isOffline} = useNetwork(); const hasErrors = !_.isEmpty(props.errors); @@ -109,7 +111,7 @@ function OfflineWithFeedback(props) { // Apply strikethrough to children if needed, but skip it if we are not going to render them if (needsStrikeThrough && !hideChildren) { - children = applyStrikeThrough(children); + children = applyStrikeThrough(children, styles); } return ( diff --git a/src/components/OptionsSelector/BaseOptionsSelector.js b/src/components/OptionsSelector/BaseOptionsSelector.js index be89132a0731..ba6a3067284f 100755 --- a/src/components/OptionsSelector/BaseOptionsSelector.js +++ b/src/components/OptionsSelector/BaseOptionsSelector.js @@ -16,13 +16,13 @@ import Text from '@components/Text'; import TextInput from '@components/TextInput'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withNavigationFocus from '@components/withNavigationFocus'; +import withTheme, {withThemePropTypes} from '@components/withTheme'; +import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; import compose from '@libs/compose'; 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'; @@ -51,6 +51,8 @@ const propTypes = { ...optionsSelectorPropTypes, ...withLocalizePropTypes, + ...withThemeStylesPropTypes, + ...withThemePropTypes, }; const defaultProps = { @@ -59,7 +61,7 @@ const defaultProps = { referralContentType: CONST.REFERRAL_PROGRAM.CONTENT_TYPES.REFER_FRIEND, safeAreaPaddingBottomStyle: {}, contentContainerStyles: [], - listContainerStyles: [styles.flex1], + listContainerStyles: undefined, listStyles: [], ...optionsSelectorDefaultProps, }; @@ -460,6 +462,8 @@ class BaseOptionsSelector extends Component { const defaultConfirmButtonText = _.isUndefined(this.props.confirmButtonText) ? this.props.translate('common.confirm') : this.props.confirmButtonText; const shouldShowDefaultConfirmButton = !this.props.footerContent && defaultConfirmButtonText; const safeAreaPaddingBottomStyle = shouldShowFooter ? undefined : this.props.safeAreaPaddingBottomStyle; + const listContainerStyles = this.props.listContainerStyles || [this.props.themeStyles.flex1]; + const textInput = ( (this.textInput = el)} @@ -516,7 +520,7 @@ class BaseOptionsSelector extends Component { }} contentContainerStyles={[safeAreaPaddingBottomStyle, ...this.props.contentContainerStyles]} sectionHeaderStyle={this.props.sectionHeaderStyle} - listContainerStyles={this.props.listContainerStyles} + listContainerStyles={listContainerStyles} listStyles={this.props.listStyles} isLoading={!this.props.shouldShowOptions} showScrollIndicator={this.props.showScrollIndicator} @@ -528,7 +532,7 @@ class BaseOptionsSelector extends Component { renderFooterContent={() => shouldShowShowMoreButton && ( - {optionsList} - + + {optionsList} + + {this.props.children} {this.props.shouldShowTextInput && textInput} @@ -556,18 +576,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} @@ -578,13 +598,13 @@ class BaseOptionsSelector extends Component { {!this.props.shouldTextInputAppearBelowOptions && ( <> - + {this.props.children} {this.props.shouldShowTextInput && textInput} {Boolean(this.props.textInputAlert) && ( )} @@ -594,20 +614,29 @@ 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`)} @@ -626,7 +655,7 @@ class BaseOptionsSelector extends Component { {shouldShowDefaultConfirmButton && (