From eec906a14b2f6f9d9e34cf5508c0eec7139ecb33 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 16:49:18 +0100 Subject: [PATCH 01/39] implement dynamic StyleUtils --- src/styles/StyleUtils.ts | 78 ++++++++++++++++++++++++++++-- src/styles/ThemeStylesContext.ts | 11 ++++- src/styles/ThemeStylesProvider.tsx | 7 ++- src/styles/useStyleUtils.ts | 14 ++++++ src/styles/useThemeStyles.ts | 6 +-- 5 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 src/styles/useStyleUtils.ts diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index 64ef54a8ab84..545769ebb6a7 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -1377,9 +1377,7 @@ function getDotIndicatorTextStyles(styles: ThemeStyles, isErrorText = true): Tex return isErrorText ? {...styles.offlineFeedback.text, color: styles.formError.color} : {...styles.offlineFeedback.text}; } -export type {AvatarSizeName}; - -export { +const StyleUtils = { combineStyles, displayIfTrue, getAmountFontSizeAndLineHeight, @@ -1463,3 +1461,77 @@ export { getEReceiptColorStyles, getEReceiptColorCode, }; + +type StyleUtilsType = typeof StyleUtils; + +type DropParameters = Parameters<(typeof StyleUtils)[FunctionName]> extends [...OmittedParams, ...infer U] + ? U + : never; +type FunctionWithoutParameters = ( + ...restProps: DropParameters +) => ReturnType; +type FunctionWithoutFirstParameter = FunctionWithoutParameters; +type FunctionWithoutFirstTwoParameter = FunctionWithoutParameters; + +type ThemeDependentStyleUtilsFunctions = { + getAutoCompleteSuggestionItemStyle: FunctionWithoutFirstParameter<'getAutoCompleteSuggestionItemStyle'>; + getAutoGrowHeightInputStyle: FunctionWithoutFirstParameter<'getAutoGrowHeightInputStyle'>; + getAvatarStyle: FunctionWithoutFirstParameter<'getAvatarStyle'>; + getBadgeColorStyle: FunctionWithoutFirstParameter<'getBadgeColorStyle'>; + getButtonBackgroundColorStyle: FunctionWithoutFirstParameter<'getButtonBackgroundColorStyle'>; + getCheckboxContainerStyle: FunctionWithoutFirstParameter<'getCheckboxContainerStyle'>; + getColoredBackgroundStyle: FunctionWithoutFirstParameter<'getColoredBackgroundStyle'>; + getDisabledLinkStyles: FunctionWithoutFirstTwoParameter<'getDisabledLinkStyles'>; + getDotIndicatorTextStyles: FunctionWithoutFirstParameter<'getDotIndicatorTextStyles'>; + getEmojiReactionBubbleStyle: FunctionWithoutFirstParameter<'getEmojiReactionBubbleStyle'>; + getEmojiReactionCounterTextStyle: FunctionWithoutFirstParameter<'getEmojiReactionCounterTextStyle'>; + getErrorPageContainerStyle: FunctionWithoutFirstParameter<'getErrorPageContainerStyle'>; + getGoogleListViewStyle: FunctionWithoutFirstParameter<'getGoogleListViewStyle'>; + getHeightOfMagicCodeInput: FunctionWithoutFirstParameter<'getHeightOfMagicCodeInput'>; + getIconFillColor: FunctionWithoutFirstParameter<'getIconFillColor'>; + getMentionStyle: FunctionWithoutFirstParameter<'getMentionStyle'>; + getMentionTextColor: FunctionWithoutFirstParameter<'getMentionTextColor'>; + getMiniReportActionContextMenuWrapperStyle: FunctionWithoutFirstParameter<'getMiniReportActionContextMenuWrapperStyle'>; + getReportActionItemStyle: FunctionWithoutFirstTwoParameter<'getReportActionItemStyle'>; + getThemeBackgroundColor: FunctionWithoutFirstParameter<'getThemeBackgroundColor'>; + getZoomCursorStyle: FunctionWithoutFirstParameter<'getZoomCursorStyle'>; + getContainerStyles: FunctionWithoutFirstParameter<'getContainerStyles'>; +}; + +type StyleUtilsWithoutThemeParametersType = StyleUtilsType & ThemeDependentStyleUtilsFunctions; + +const createStyleUtilsWithoutThemeParameters = (theme: ThemeColors, styles: ThemeStyles): StyleUtilsWithoutThemeParametersType => { + const themeDependentStylUtilsFunctions = { + getAutoCompleteSuggestionItemStyle: (...restProps) => getAutoCompleteSuggestionItemStyle(theme, ...restProps), + getAutoGrowHeightInputStyle: (...restProps) => getAutoGrowHeightInputStyle(styles, ...restProps), + getAvatarStyle: (...restProps) => getAvatarStyle(theme, ...restProps), + getBadgeColorStyle: (...restProps) => getBadgeColorStyle(styles, ...restProps), + getButtonBackgroundColorStyle: (...restProps) => getButtonBackgroundColorStyle(theme, ...restProps), + getCheckboxContainerStyle: (...restProps) => getCheckboxContainerStyle(theme, ...restProps), + getColoredBackgroundStyle: (...restProps) => getColoredBackgroundStyle(theme, ...restProps), + getDisabledLinkStyles: (...restProps) => getDisabledLinkStyles(theme, styles, ...restProps), + getDotIndicatorTextStyles: (...restProps) => getDotIndicatorTextStyles(styles, ...restProps), + getEmojiReactionBubbleStyle: (...restProps) => getEmojiReactionBubbleStyle(theme, ...restProps), + getEmojiReactionCounterTextStyle: (...restProps) => getEmojiReactionCounterTextStyle(theme, ...restProps), + getErrorPageContainerStyle: (...restProps) => getErrorPageContainerStyle(theme, ...restProps), + getGoogleListViewStyle: (...restProps) => getGoogleListViewStyle(styles, ...restProps), + getHeightOfMagicCodeInput: (...restProps) => getHeightOfMagicCodeInput(styles, ...restProps), + getIconFillColor: (...restProps) => getIconFillColor(theme, ...restProps), + getMentionStyle: (...restProps) => getMentionStyle(theme, ...restProps), + getMentionTextColor: (...restProps) => getMentionTextColor(theme, ...restProps), + getMiniReportActionContextMenuWrapperStyle: (...restProps) => getMiniReportActionContextMenuWrapperStyle(styles, ...restProps), + getReportActionItemStyle: (...restProps) => getReportActionItemStyle(theme, styles, ...restProps), + getThemeBackgroundColor: (...restProps) => getThemeBackgroundColor(theme, ...restProps), + getZoomCursorStyle: (...restProps) => getZoomCursorStyle(styles, ...restProps), + getContainerStyles: (...restProps) => getContainerStyles(styles, ...restProps), + } satisfies ThemeDependentStyleUtilsFunctions; + + return { + ...StyleUtils, + ...themeDependentStylUtilsFunctions, + } as StyleUtilsWithoutThemeParametersType; +}; + +export default StyleUtils; +export {createStyleUtilsWithoutThemeParameters}; +export type {StyleUtilsType, ThemeDependentStyleUtilsFunctions, StyleUtilsWithoutThemeParametersType, AvatarSizeName}; diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index 1c81ab3b39a5..0a61d0eb8d03 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,6 +1,13 @@ import React from 'react'; -import styles from './styles'; +import {ThemeStyles} from './styles'; +import {StyleUtilsWithoutThemeParams} from './StyleUtils'; -const ThemeStylesContext = React.createContext(styles); +type ThemeStylesContextType = { + styles: ThemeStyles; + StyleUtils: StyleUtilsWithoutThemeParams; +}; + +const ThemeStylesContext = React.createContext(undefined); export default ThemeStylesContext; +export {type ThemeStylesContextType}; diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index 1a60d61c4ea5..f78d8aa8501b 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -1,5 +1,6 @@ import React, {useMemo} from 'react'; import {stylesGenerator} from './styles'; +import {createStyleUtilsWithoutThemeParameters} from './StyleUtils'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; @@ -8,9 +9,11 @@ type ThemeStylesProviderProps = React.PropsWithChildren; function ThemeStylesProvider({children}: ThemeStylesProviderProps) { const theme = useTheme(); - const themeStyles = useMemo(() => stylesGenerator(theme), [theme]); + const styles = useMemo(() => stylesGenerator(theme), [theme]); + const StyleUtils = useMemo(() => createStyleUtilsWithoutThemeParameters(theme, styles), [theme, styles]); + const contextValue = useMemo(() => ({styles, StyleUtils}), [styles, StyleUtils]); - return {children}; + return {children}; } ThemeStylesProvider.displayName = 'ThemeStylesProvider'; diff --git a/src/styles/useStyleUtils.ts b/src/styles/useStyleUtils.ts new file mode 100644 index 000000000000..aadb3f884220 --- /dev/null +++ b/src/styles/useStyleUtils.ts @@ -0,0 +1,14 @@ +import {useContext} from 'react'; +import ThemeStylesContext from './ThemeStylesContext'; + +function useStyleUtils() { + const themeStylesContext = useContext(ThemeStylesContext); + + if (!themeStylesContext) { + throw new Error('ThemeStylesContext was null! Are you sure that you wrapped the component under a ?'); + } + + return themeStylesContext.StyleUtils; +} + +export default useStyleUtils; diff --git a/src/styles/useThemeStyles.ts b/src/styles/useThemeStyles.ts index 06a4f7f5d626..164806a908e4 100644 --- a/src/styles/useThemeStyles.ts +++ b/src/styles/useThemeStyles.ts @@ -2,13 +2,13 @@ import {useContext} from 'react'; import ThemeStylesContext from './ThemeStylesContext'; function useThemeStyles() { - const themeStyles = useContext(ThemeStylesContext); + const themeStylesContext = useContext(ThemeStylesContext); - if (!themeStyles) { + if (!themeStylesContext) { throw new Error('ThemeStylesContext was null! Are you sure that you wrapped the component under a ?'); } - return themeStyles; + return themeStylesContext.styles; } export default useThemeStyles; From b7abf5932c9bb955ecc7971938f09561083b2bfd Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 16:52:54 +0100 Subject: [PATCH 02/39] add separate StyleUtilsProvider --- src/styles/StyleUtils.ts | 8 ++++---- src/styles/StyleUtilsContext.ts | 6 ++++++ src/styles/StyleUtilsProvider.tsx | 20 ++++++++++++++++++++ src/styles/ThemeStylesContext.ts | 11 ++--------- src/styles/ThemeStylesProvider.tsx | 5 +---- src/styles/useStyleUtils.ts | 8 ++++---- 6 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 src/styles/StyleUtilsContext.ts create mode 100644 src/styles/StyleUtilsProvider.tsx diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index 545769ebb6a7..3ec6bae10648 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -1498,9 +1498,9 @@ type ThemeDependentStyleUtilsFunctions = { getContainerStyles: FunctionWithoutFirstParameter<'getContainerStyles'>; }; -type StyleUtilsWithoutThemeParametersType = StyleUtilsType & ThemeDependentStyleUtilsFunctions; +type StyleUtilsWithoutThemeParameters = StyleUtilsType & ThemeDependentStyleUtilsFunctions; -const createStyleUtilsWithoutThemeParameters = (theme: ThemeColors, styles: ThemeStyles): StyleUtilsWithoutThemeParametersType => { +const createStyleUtilsWithoutThemeParameters = (theme: ThemeColors, styles: ThemeStyles): StyleUtilsWithoutThemeParameters => { const themeDependentStylUtilsFunctions = { getAutoCompleteSuggestionItemStyle: (...restProps) => getAutoCompleteSuggestionItemStyle(theme, ...restProps), getAutoGrowHeightInputStyle: (...restProps) => getAutoGrowHeightInputStyle(styles, ...restProps), @@ -1529,9 +1529,9 @@ const createStyleUtilsWithoutThemeParameters = (theme: ThemeColors, styles: Them return { ...StyleUtils, ...themeDependentStylUtilsFunctions, - } as StyleUtilsWithoutThemeParametersType; + } as StyleUtilsWithoutThemeParameters; }; export default StyleUtils; export {createStyleUtilsWithoutThemeParameters}; -export type {StyleUtilsType, ThemeDependentStyleUtilsFunctions, StyleUtilsWithoutThemeParametersType, AvatarSizeName}; +export type {StyleUtilsType, ThemeDependentStyleUtilsFunctions, StyleUtilsWithoutThemeParameters, AvatarSizeName}; diff --git a/src/styles/StyleUtilsContext.ts b/src/styles/StyleUtilsContext.ts new file mode 100644 index 000000000000..a9eea3da38de --- /dev/null +++ b/src/styles/StyleUtilsContext.ts @@ -0,0 +1,6 @@ +import React from 'react'; +import {StyleUtilsWithoutThemeParameters} from './StyleUtils'; + +const StyleUtilsContext = React.createContext(undefined); + +export default StyleUtilsContext; diff --git a/src/styles/StyleUtilsProvider.tsx b/src/styles/StyleUtilsProvider.tsx new file mode 100644 index 000000000000..e8ec8ccb2755 --- /dev/null +++ b/src/styles/StyleUtilsProvider.tsx @@ -0,0 +1,20 @@ +import React, {useMemo} from 'react'; +import {createStyleUtilsWithoutThemeParameters} from './StyleUtils'; +import StyleUtilsContext from './StyleUtilsContext'; +import useTheme from './themes/useTheme'; +import useThemeStyles from './useThemeStyles'; + +type ThemeStylesProviderProps = React.PropsWithChildren; + +function ThemeStylesProvider({children}: ThemeStylesProviderProps) { + const theme = useTheme(); + const styles = useThemeStyles(); + + const StyleUtils = useMemo(() => createStyleUtilsWithoutThemeParameters(theme, styles), [theme, styles]); + + return {children}; +} + +ThemeStylesProvider.displayName = 'ThemeStylesProvider'; + +export default ThemeStylesProvider; diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index 0a61d0eb8d03..475d2e98a0c9 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,13 +1,6 @@ import React from 'react'; -import {ThemeStyles} from './styles'; -import {StyleUtilsWithoutThemeParams} from './StyleUtils'; +import defaultStyles, {ThemeStyles} from './styles'; -type ThemeStylesContextType = { - styles: ThemeStyles; - StyleUtils: StyleUtilsWithoutThemeParams; -}; - -const ThemeStylesContext = React.createContext(undefined); +const ThemeStylesContext = React.createContext(defaultStyles); export default ThemeStylesContext; -export {type ThemeStylesContextType}; diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index f78d8aa8501b..5e2df4da8af7 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -1,6 +1,5 @@ import React, {useMemo} from 'react'; import {stylesGenerator} from './styles'; -import {createStyleUtilsWithoutThemeParameters} from './StyleUtils'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; @@ -10,10 +9,8 @@ function ThemeStylesProvider({children}: ThemeStylesProviderProps) { const theme = useTheme(); const styles = useMemo(() => stylesGenerator(theme), [theme]); - const StyleUtils = useMemo(() => createStyleUtilsWithoutThemeParameters(theme, styles), [theme, styles]); - const contextValue = useMemo(() => ({styles, StyleUtils}), [styles, StyleUtils]); - return {children}; + return {children}; } ThemeStylesProvider.displayName = 'ThemeStylesProvider'; diff --git a/src/styles/useStyleUtils.ts b/src/styles/useStyleUtils.ts index aadb3f884220..6b14e59cd605 100644 --- a/src/styles/useStyleUtils.ts +++ b/src/styles/useStyleUtils.ts @@ -1,14 +1,14 @@ import {useContext} from 'react'; -import ThemeStylesContext from './ThemeStylesContext'; +import StyleUtilsContext from './StyleUtilsContext'; function useStyleUtils() { - const themeStylesContext = useContext(ThemeStylesContext); + const styleUtils = useContext(StyleUtilsContext); - if (!themeStylesContext) { + if (!styleUtils) { throw new Error('ThemeStylesContext was null! Are you sure that you wrapped the component under a ?'); } - return themeStylesContext.StyleUtils; + return styleUtils; } export default useStyleUtils; From 6ddf86a808a96d14a79d53d3eee6422a80d681fc Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 17:51:38 +0100 Subject: [PATCH 03/39] update --- .../AddressSearch/CurrentLocationButton.js | 7 +- src/components/AddressSearch/index.js | 13 +- .../BaseAnchorForCommentsOnly.js | 3 +- .../Attachments/AttachmentView/index.js | 3 +- .../BaseAutoCompleteSuggestions.tsx | 10 +- .../AutoCompleteSuggestions/index.tsx | 3 +- .../AvatarCropModal/AvatarCropModal.js | 3 +- .../AvatarCropModal/ImageCropView.js | 3 +- src/components/Composer/index.js | 5 +- .../index.tsx | 3 +- .../DatePicker/CalendarPicker/ArrowIcon.js | 3 +- .../DatePicker/CalendarPicker/index.js | 6 +- .../DistanceMapView/index.android.js | 3 +- src/components/Icon/index.tsx | 10 +- src/components/withStyleUtils.tsx | 32 + src/components/withTheme.tsx | 11 +- src/components/withThemeStyles.tsx | 11 +- src/stories/Composer.stories.js | 2 +- src/styles/StyleUtils.ts | 618 +----------------- src/styles/ThemeStylesContext.ts | 11 +- src/styles/ThemeStylesProvider.tsx | 5 +- src/styles/useThemeStyleUtils.ts | 14 + src/styles/utils/ThemeStyleUtils.ts | 409 ++++++++++++ src/styles/utils/functions.ts | 18 + src/styles/utils/types.ts | 59 ++ 25 files changed, 631 insertions(+), 634 deletions(-) create mode 100644 src/components/withStyleUtils.tsx create mode 100644 src/styles/useThemeStyleUtils.ts create mode 100644 src/styles/utils/ThemeStyleUtils.ts create mode 100644 src/styles/utils/functions.ts create mode 100644 src/styles/utils/types.ts diff --git a/src/components/AddressSearch/CurrentLocationButton.js b/src/components/AddressSearch/CurrentLocationButton.js index 6f5148edd436..c11c2344dbc2 100644 --- a/src/components/AddressSearch/CurrentLocationButton.js +++ b/src/components/AddressSearch/CurrentLocationButton.js @@ -7,9 +7,8 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import useLocalize from '@hooks/useLocalize'; import getButtonState from '@libs/getButtonState'; import colors from '@styles/colors'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; const propTypes = { /** Callback that runs when location button is clicked */ @@ -25,14 +24,14 @@ const defaultProps = { }; function CurrentLocationButton({onPress, isDisabled}) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useStyleUtils(); const {translate} = useLocalize(); return ( + () => { ReportActionContextMenu.hideContextMenu(); diff --git a/src/components/Attachments/AttachmentView/index.js b/src/components/Attachments/AttachmentView/index.js index e484abe041b9..5425c05a43a2 100755 --- a/src/components/Attachments/AttachmentView/index.js +++ b/src/components/Attachments/AttachmentView/index.js @@ -15,9 +15,9 @@ import useNetwork from '@hooks/useNetwork'; import addEncryptedAuthTokenToURL from '@libs/addEncryptedAuthTokenToURL'; import compose from '@libs/compose'; import * as TransactionUtils from '@libs/TransactionUtils'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import cursor from '@styles/utilities/cursor'; import variables from '@styles/variables'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -80,6 +80,7 @@ function AttachmentView({ }) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const [loadComplete, setLoadComplete] = useState(false); const [imageError, setImageError] = useState(false); diff --git a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx index efde2b24992f..158081f2ca02 100644 --- a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx +++ b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx @@ -5,9 +5,9 @@ import {View} from 'react-native'; import {ScrollView} from 'react-native-gesture-handler'; import Animated, {Easing, FadeOutDown, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import viewForwardedRef from '@src/types/utils/viewForwardedRef'; import type {AutoCompleteSuggestionsProps, RenderSuggestionMenuItemProps} from './types'; @@ -39,8 +39,8 @@ function BaseAutoCompleteSuggestions( }: AutoCompleteSuggestionsProps, ref: ForwardedRef, ) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useStyleUtils(); const rowHeight = useSharedValue(0); const scrollRef = useRef>(null); /** @@ -49,7 +49,7 @@ function BaseAutoCompleteSuggestions( const renderItem = useCallback( ({item, index}: RenderSuggestionMenuItemProps): ReactElement => ( StyleUtils.getAutoCompleteSuggestionItemStyle(theme, highlightedSuggestionIndex, CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, hovered, index)} + style={({hovered}) => ThemeStyleUtils.getAutoCompleteSuggestionItemStyle(highlightedSuggestionIndex, CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, hovered, index)} hoverDimmingValue={1} onMouseDown={(e) => e.preventDefault()} onPress={() => onSelect(index)} @@ -59,7 +59,7 @@ function BaseAutoCompleteSuggestions( {renderSuggestionMenuItem(item, index)} ), - [highlightedSuggestionIndex, renderSuggestionMenuItem, onSelect, accessibilityLabelExtractor, theme], + [accessibilityLabelExtractor, renderSuggestionMenuItem, ThemeStyleUtils, highlightedSuggestionIndex, onSelect], ); const innerHeight = CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT * suggestions.length; diff --git a/src/components/AutoCompleteSuggestions/index.tsx b/src/components/AutoCompleteSuggestions/index.tsx index 24b846c265a9..82ce93e19791 100644 --- a/src/components/AutoCompleteSuggestions/index.tsx +++ b/src/components/AutoCompleteSuggestions/index.tsx @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'; import {View} from 'react-native'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import * as StyleUtils from '@styles/StyleUtils'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import BaseAutoCompleteSuggestions from './BaseAutoCompleteSuggestions'; import type {AutoCompleteSuggestionsProps} from './types'; @@ -15,6 +15,7 @@ import type {AutoCompleteSuggestionsProps} from './types'; */ function AutoCompleteSuggestions({measureParentContainer = () => {}, ...props}: AutoCompleteSuggestionsProps) { + const StyleUtils = useStyleUtils(); const containerRef = React.useRef(null); const {windowHeight, windowWidth} = useWindowDimensions(); const [{width, left, bottom}, setContainerState] = React.useState({ diff --git a/src/components/AvatarCropModal/AvatarCropModal.js b/src/components/AvatarCropModal/AvatarCropModal.js index a37f228a0d0d..988c0ba7b7d0 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.js +++ b/src/components/AvatarCropModal/AvatarCropModal.js @@ -17,9 +17,9 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import compose from '@libs/compose'; import cropOrRotateImage from '@libs/cropOrRotateImage'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import ImageCropView from './ImageCropView'; import Slider from './Slider'; @@ -63,6 +63,7 @@ const defaultProps = { function AvatarCropModal(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const originalImageWidth = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); const originalImageHeight = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); const translateY = useSharedValue(0); diff --git a/src/components/AvatarCropModal/ImageCropView.js b/src/components/AvatarCropModal/ImageCropView.js index a50409da64f4..6d3a60211c5e 100644 --- a/src/components/AvatarCropModal/ImageCropView.js +++ b/src/components/AvatarCropModal/ImageCropView.js @@ -6,8 +6,8 @@ import Animated, {interpolate, useAnimatedStyle} from 'react-native-reanimated'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import ControlSelection from '@libs/ControlSelection'; -import * as StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import gestureHandlerPropTypes from './gestureHandlerPropTypes'; const propTypes = { @@ -51,6 +51,7 @@ const defaultProps = { function ImageCropView(props) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const containerStyle = StyleUtils.getWidthAndHeightStyle(props.containerSize, props.containerSize); const originalImageHeight = props.originalImageHeight; diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 48eb89bb0296..39cdddfd169b 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -15,9 +15,9 @@ import * as ComposerUtils from '@libs/ComposerUtils'; import updateIsFullComposerAvailable from '@libs/ComposerUtils/updateIsFullComposerAvailable'; import isEnterWhileComposition from '@libs/KeyboardShortcut/isEnterWhileComposition'; import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -168,6 +168,7 @@ function Composer({ }) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {windowWidth} = useWindowDimensions(); const textRef = useRef(null); const textInput = useRef(null); @@ -428,7 +429,7 @@ function Composer({ Browser.isMobileSafari() || Browser.isSafari() ? styles.rtlTextRenderForSafari : {}, ], - [numberOfLines, maxLines, styles.overflowHidden, styles.rtlTextRenderForSafari, style, isComposerFullSize], + [numberOfLines, maxLines, styles.overflowHidden, styles.rtlTextRenderForSafari, style, StyleUtils, isComposerFullSize], ); return ( diff --git a/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx b/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx index 685db8031330..d67ff319f558 100644 --- a/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx +++ b/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx @@ -3,9 +3,9 @@ import {View} from 'react-native'; import {Circle, Rect} from 'react-native-svg'; import {ValueOf} from 'type-fest'; import SkeletonViewContentLoader from '@components/SkeletonViewContentLoader'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -26,6 +26,7 @@ type CurrentUserPersonalDetailsSkeletonViewProps = { function CurrentUserPersonalDetailsSkeletonView({shouldAnimate = true, avatarSize = CONST.AVATAR_SIZE.LARGE, backgroundColor, foregroundColor}: CurrentUserPersonalDetailsSkeletonViewProps) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const avatarPlaceholderSize = StyleUtils.getAvatarSize(avatarSize); const avatarPlaceholderRadius = avatarPlaceholderSize / 2; const spaceBetweenAvatarAndHeadline = styles.mb3.marginBottom + styles.mt1.marginTop + (variables.lineHeightXXLarge - variables.fontSizeXLarge) / 2; diff --git a/src/components/DatePicker/CalendarPicker/ArrowIcon.js b/src/components/DatePicker/CalendarPicker/ArrowIcon.js index 1b9c9a06db34..d8ca277afe50 100644 --- a/src/components/DatePicker/CalendarPicker/ArrowIcon.js +++ b/src/components/DatePicker/CalendarPicker/ArrowIcon.js @@ -3,8 +3,8 @@ import React from 'react'; import {View} from 'react-native'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; -import * as StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -22,6 +22,7 @@ const defaultProps = { function ArrowIcon(props) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); return ( diff --git a/src/components/DatePicker/CalendarPicker/index.js b/src/components/DatePicker/CalendarPicker/index.js index eaa6a8b45b33..62da413a5b65 100644 --- a/src/components/DatePicker/CalendarPicker/index.js +++ b/src/components/DatePicker/CalendarPicker/index.js @@ -8,12 +8,12 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import Text from '@components/Text'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import withStyleUtils from '@components/withStyleUtils'; import withTheme, {withThemePropTypes} from '@components/withTheme'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; import compose from '@libs/compose'; import DateUtils from '@libs/DateUtils'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; import CONST from '@src/CONST'; import ArrowIcon from './ArrowIcon'; import generateMonthMatrix from './generateMonthMatrix'; @@ -238,7 +238,7 @@ class CalendarPicker extends React.PureComponent { style={[ this.props.themeStyles.calendarDayContainer, isSelected ? this.props.themeStyles.calendarDayContainerSelected : {}, - !isDisabled ? StyleUtils.getButtonBackgroundColorStyle(this.props.theme, getButtonState(hovered, pressed)) : {}, + !isDisabled ? this.props.StyleUtils.getButtonBackgroundColorStyle(this.props.theme, getButtonState(hovered, pressed)) : {}, ]} > {day} @@ -264,4 +264,4 @@ class CalendarPicker extends React.PureComponent { CalendarPicker.propTypes = propTypes; CalendarPicker.defaultProps = defaultProps; -export default compose(withLocalize, withTheme, withThemeStyles)(CalendarPicker); +export default compose(withLocalize, withTheme, withThemeStyles, withStyleUtils)(CalendarPicker); diff --git a/src/components/DistanceMapView/index.android.js b/src/components/DistanceMapView/index.android.js index 848167de653d..c25c1ba65e40 100644 --- a/src/components/DistanceMapView/index.android.js +++ b/src/components/DistanceMapView/index.android.js @@ -6,12 +6,13 @@ import * as Expensicons from '@components/Icon/Expensicons'; import MapView from '@components/MapView'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; -import * as StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useThemeStyleUtils'; import * as distanceMapViewPropTypes from './distanceMapViewPropTypes'; function DistanceMapView(props) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const [isMapReady, setIsMapReady] = useState(false); const {isOffline} = useNetwork(); const {translate} = useLocalize(); diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 25bd0a083be0..5a9eaae1e864 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -1,8 +1,8 @@ import React, {PureComponent} from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; -import withTheme, {ThemeProps} from '@components/withTheme'; -import withThemeStyles, {type ThemeStylesProps} from '@components/withThemeStyles'; -import * as StyleUtils from '@styles/StyleUtils'; +import withTheme, {WithThemeProps} from '@components/withTheme'; +import withThemeStyles, {type WithThemeStylesProps} from '@components/withThemeStyles'; +import StyleUtils from '@styles/StyleUtils'; import variables from '@styles/variables'; import IconWrapperStyles from './IconWrapperStyles'; @@ -41,8 +41,8 @@ type IconProps = { /** Additional styles to add to the Icon */ additionalStyles?: StyleProp; -} & ThemeStylesProps & - ThemeProps; +} & WithThemeStylesProps & + WithThemeProps; // We must use a class component to create an animatable component with the Animated API // eslint-disable-next-line react/prefer-stateless-function diff --git a/src/components/withStyleUtils.tsx b/src/components/withStyleUtils.tsx new file mode 100644 index 000000000000..e6f0112ebeff --- /dev/null +++ b/src/components/withStyleUtils.tsx @@ -0,0 +1,32 @@ +import PropTypes from 'prop-types'; +import React, {ComponentType, ForwardedRef, forwardRef, ReactElement, RefAttributes} from 'react'; +import getComponentDisplayName from '@libs/getComponentDisplayName'; +import {StyleUtilsWithoutThemeParameters} from '@styles/StyleUtils'; +import useStyleUtils from '@styles/useThemeStyleUtils'; + +const withStyleUtilsPropTypes = { + themeStyles: PropTypes.object.isRequired, +}; +type WithStyleUtilsProps = {StyleUtils: StyleUtilsWithoutThemeParameters}; + +export default function withStyleUtils( + WrappedComponent: ComponentType>, +): (props: Omit & React.RefAttributes) => ReactElement | null { + function WithThemeStyles(props: Omit, ref: ForwardedRef): ReactElement { + const StyleUtils = useStyleUtils(); + return ( + + ); + } + + WithThemeStyles.displayName = `withThemeStyles(${getComponentDisplayName(WrappedComponent)})`; + + return forwardRef(WithThemeStyles); +} + +export {withStyleUtilsPropTypes, type WithStyleUtilsProps}; diff --git a/src/components/withTheme.tsx b/src/components/withTheme.tsx index 532ff6e5c375..59380110904a 100644 --- a/src/components/withTheme.tsx +++ b/src/components/withTheme.tsx @@ -7,12 +7,12 @@ import useTheme from '@styles/themes/useTheme'; const withThemePropTypes = { theme: PropTypes.object.isRequired, }; -type ThemeProps = {theme: ThemeColors}; +type WithThemeProps = {theme: ThemeColors}; -export default function withTheme( +export default function withTheme( WrappedComponent: ComponentType>, -): (props: Omit & React.RefAttributes) => ReactElement | null { - function WithTheme(props: Omit, ref: ForwardedRef): ReactElement { +): (props: Omit & React.RefAttributes) => ReactElement | null { + function WithTheme(props: Omit, ref: ForwardedRef): ReactElement { const theme = useTheme(); return ( ( return forwardRef(WithTheme); } -export {withThemePropTypes, type ThemeProps}; +export {withThemePropTypes}; +export type {WithThemeProps}; diff --git a/src/components/withThemeStyles.tsx b/src/components/withThemeStyles.tsx index bdd5e50fe8e3..d811573d1730 100644 --- a/src/components/withThemeStyles.tsx +++ b/src/components/withThemeStyles.tsx @@ -7,12 +7,12 @@ import useThemeStyles from '@styles/useThemeStyles'; const withThemeStylesPropTypes = { themeStyles: PropTypes.object.isRequired, }; -type ThemeStylesProps = {themeStyles: ThemeStyles}; +type WithThemeStylesProps = {themeStyles: ThemeStyles}; -export default function withThemeStyles( +export default function withThemeStyles( WrappedComponent: ComponentType>, -): (props: Omit & React.RefAttributes) => ReactElement | null { - function WithThemeStyles(props: Omit, ref: ForwardedRef): ReactElement { +): (props: Omit & React.RefAttributes) => ReactElement | null { + function WithThemeStyles(props: Omit, ref: ForwardedRef): ReactElement { const themeStyles = useThemeStyles(); return ( ( return forwardRef(WithThemeStyles); } -export {withThemeStylesPropTypes, type ThemeStylesProps}; +export {withThemeStylesPropTypes}; +export type {WithThemeStylesProps}; diff --git a/src/stories/Composer.stories.js b/src/stories/Composer.stories.js index 2db1011d1b3a..0dcde20752ba 100644 --- a/src/stories/Composer.stories.js +++ b/src/stories/Composer.stories.js @@ -6,8 +6,8 @@ import RenderHTML from '@components/RenderHTML'; import Text from '@components/Text'; import withNavigationFallback from '@components/withNavigationFallback'; import styles from '@styles/styles'; -import * as StyleUtils from '@styles/StyleUtils'; import themeColors from '@styles/themes/default'; +import * as StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const ComposerWithNavigation = withNavigationFallback(Composer); diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index 3ec6bae10648..b980f1b7cc00 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -1,5 +1,5 @@ import {CSSProperties} from 'react'; -import {Animated, DimensionValue, ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native'; +import {Animated, DimensionValue, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native'; import {EdgeInsets} from 'react-native-safe-area-context'; import {ValueOf} from 'type-fest'; import * as Browser from '@libs/Browser'; @@ -8,80 +8,13 @@ import CONST from '@src/CONST'; import {Transaction} from '@src/types/onyx'; import colors from './colors'; import fontFamily from './fontFamily'; -import {type ThemeStyles} from './styles'; -import {type ThemeColors} from './themes/types'; -import cursor from './utilities/cursor'; +import {ThemeColors} from './themes/types'; import positioning from './utilities/positioning'; import spacing from './utilities/spacing'; +import {hexadecimalToRGBArray} from './utils/functions'; +import {AllStyles, AvatarSize, AvatarSizeName, AvatarSizeValue, ButtonSizeValue, EReceiptColorName, EreceiptColorStyle, ParsableStyle, WorkspaceColorStyle} from './utils/types'; import variables from './variables'; -type AllStyles = ViewStyle | TextStyle | ImageStyle; -type ParsableStyle = StyleProp | ((state: PressableStateCallbackType) => StyleProp); -type AvatarStyle = { - width: number; - height: number; - borderRadius: number; - backgroundColor: string; -}; - -type ColorValue = ValueOf; -type AvatarSizeName = ValueOf; -type EReceiptColorName = ValueOf; -type AvatarSizeValue = ValueOf< - Pick< - typeof variables, - | 'avatarSizeNormal' - | 'avatarSizeSmallSubscript' - | 'avatarSizeMidSubscript' - | 'avatarSizeSubscript' - | 'avatarSizeSmall' - | 'avatarSizeSmaller' - | 'avatarSizeXLarge' - | 'avatarSizeLarge' - | 'avatarSizeMedium' - | 'avatarSizeLargeBordered' - | 'avatarSizeHeader' - | 'avatarSizeMentionIcon' - | 'avatarSizeSmallNormal' - > ->; -type ButtonSizeValue = ValueOf; -type ButtonStateName = ValueOf; -type AvatarSize = {width: number}; - -type WorkspaceColorStyle = {backgroundColor: ColorValue; fill: ColorValue}; -type EreceiptColorStyle = {backgroundColor: ColorValue; color: ColorValue}; - -type ModalPaddingStylesParams = { - shouldAddBottomSafeAreaMargin: boolean; - shouldAddTopSafeAreaMargin: boolean; - shouldAddBottomSafeAreaPadding: boolean; - shouldAddTopSafeAreaPadding: boolean; - safeAreaPaddingTop: number; - safeAreaPaddingBottom: number; - safeAreaPaddingLeft: number; - safeAreaPaddingRight: number; - modalContainerStyleMarginTop: DimensionValue | undefined; - modalContainerStyleMarginBottom: DimensionValue | undefined; - modalContainerStylePaddingTop: DimensionValue | undefined; - modalContainerStylePaddingBottom: DimensionValue | undefined; - insets: EdgeInsets; -}; - -type AvatarBorderStyleParams = { - theme: ThemeColors; - isHovered: boolean; - isPressed: boolean; - isInReportAction: boolean; - shouldUseCardBackground: boolean; -}; - -type GetBaseAutoCompleteSuggestionContainerStyleParams = { - left: number; - bottom: number; - width: number; -}; - const workspaceColorOptions: WorkspaceColorStyle[] = [ {backgroundColor: colors.blue200, fill: colors.blue700}, {backgroundColor: colors.blue400, fill: colors.blue800}, @@ -183,13 +116,6 @@ function getAvatarSize(size: AvatarSizeName): number { return avatarSizes[size]; } -/** - * Return the height of magic code input container - */ -function getHeightOfMagicCodeInput(styles: ThemeStyles): ViewStyle { - return {height: styles.magicCodeInputContainer.minHeight - styles.textInputContainer.borderBottomWidth}; -} - /** * Return the width style from an avatar size constant */ @@ -200,19 +126,6 @@ function getAvatarWidthStyle(size: AvatarSizeName): ViewStyle { }; } -/** - * Return the style from an avatar size constant - */ -function getAvatarStyle(theme: ThemeColors, size: AvatarSizeName): AvatarStyle { - const avatarSize = getAvatarSize(size); - return { - height: avatarSize, - width: avatarSize, - borderRadius: avatarSize, - backgroundColor: theme.offline, - }; -} - /** * Get Font size of '+1' text on avatar overlay */ @@ -307,17 +220,6 @@ function getSafeAreaMargins(insets?: EdgeInsets): ViewStyle { return {marginBottom: (insets?.bottom ?? 0) * variables.safeInsertPercentage}; } -function getZoomCursorStyle(styles: ThemeStyles, isZoomed: boolean, isDragging: boolean): ViewStyle { - if (!isZoomed) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return styles.cursorZoomIn; - } - - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return isDragging ? styles.cursorGrabbing : styles.cursorZoomOut; -} - // NOTE: asserting some web style properties to a valid type, because it isn't possible to augment them. function getZoomSizingStyle( isZoomed: boolean, @@ -385,30 +287,6 @@ function getWidthStyle(width: number): ViewStyle { }; } -/** - * Returns auto grow height text input style - */ -function getAutoGrowHeightInputStyle(styles: ThemeStyles, textInputHeight: number, maxHeight: number): ViewStyle { - if (textInputHeight > maxHeight) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...styles.pr0, - ...styles.overflowAuto, - }; - } - - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...styles.pr0, - ...styles.overflowHidden, - // maxHeight is not of the input only but the of the whole input container - // which also includes the top padding and bottom border - height: maxHeight - styles.textInputMultilineContainer.paddingTop - styles.textInputContainer.borderBottomWidth, - }; -} - /** * Returns a style with backgroundColor and borderColor set to the same color */ @@ -462,22 +340,6 @@ function getSignInWordmarkWidthStyle(isSmallScreenWidth: boolean, environment: V return isSmallScreenWidth ? {width: variables.signInLogoWidthPill} : {width: variables.signInLogoWidthLargeScreenPill}; } -/** - * Converts a color in hexadecimal notation into RGB notation. - * - * @param hexadecimal A color in hexadecimal notation. - * @returns `undefined` if the input color is not in hexadecimal notation. Otherwise, the RGB components of the input color. - */ -function hexadecimalToRGBArray(hexadecimal: string): number[] | undefined { - const components = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexadecimal); - - if (components === null) { - return undefined; - } - - return components.slice(1).map((component) => parseInt(component, 16)); -} - /** * Returns a background color with opacity style */ @@ -491,70 +353,6 @@ function getBackgroundColorWithOpacityStyle(backgroundColor: string, opacity: nu return {}; } -/** - * Generate a style for the background color of the Badge - */ -function getBadgeColorStyle(styles: ThemeStyles, isSuccess: boolean, isError: boolean, isPressed = false, isAdHoc = false): ViewStyle { - if (isSuccess) { - if (isAdHoc) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return isPressed ? styles.badgeAdHocSuccessPressed : styles.badgeAdHocSuccess; - } - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return isPressed ? styles.badgeSuccessPressed : styles.badgeSuccess; - } - if (isError) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return isPressed ? styles.badgeDangerPressed : styles.badgeDanger; - } - return {}; -} - -/** - * Generate a style for the background color of the button, based on its current state. - * - * @param buttonState - One of {'default', 'hovered', 'pressed'} - * @param isMenuItem - whether this button is apart of a list - */ -function getButtonBackgroundColorStyle(theme: ThemeColors, buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuItem = false): ViewStyle { - switch (buttonState) { - case CONST.BUTTON_STATES.PRESSED: - return {backgroundColor: theme.buttonPressedBG}; - case CONST.BUTTON_STATES.ACTIVE: - return isMenuItem ? {backgroundColor: theme.border} : {backgroundColor: theme.buttonHoveredBG}; - case CONST.BUTTON_STATES.DISABLED: - case CONST.BUTTON_STATES.DEFAULT: - default: - return {}; - } -} - -/** - * Generate fill color of an icon based on its state. - * - * @param buttonState - One of {'default', 'hovered', 'pressed'} - * @param isMenuIcon - whether this icon is apart of a list - */ -function getIconFillColor(theme: ThemeColors, buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuIcon = false): string { - switch (buttonState) { - case CONST.BUTTON_STATES.ACTIVE: - case CONST.BUTTON_STATES.PRESSED: - return theme.iconHovered; - case CONST.BUTTON_STATES.COMPLETE: - return theme.iconSuccessFill; - case CONST.BUTTON_STATES.DEFAULT: - case CONST.BUTTON_STATES.DISABLED: - default: - if (isMenuIcon) { - return theme.iconMenu; - } - return theme.icon; - } -} - function getAnimatedFABStyle(rotate: Animated.Value, backgroundColor: Animated.Value): Animated.WithAnimatedValue { return { transform: [{rotate}], @@ -585,6 +383,22 @@ function getCombinedSpacing(modalContainerValue: DimensionValue | undefined, saf return modalContainerValue; } +type ModalPaddingStylesParams = { + shouldAddBottomSafeAreaMargin: boolean; + shouldAddTopSafeAreaMargin: boolean; + shouldAddBottomSafeAreaPadding: boolean; + shouldAddTopSafeAreaPadding: boolean; + safeAreaPaddingTop: number; + safeAreaPaddingBottom: number; + safeAreaPaddingLeft: number; + safeAreaPaddingRight: number; + modalContainerStyleMarginTop: DimensionValue | undefined; + modalContainerStyleMarginBottom: DimensionValue | undefined; + modalContainerStylePaddingTop: DimensionValue | undefined; + modalContainerStylePaddingBottom: DimensionValue | undefined; + insets: EdgeInsets; +}; + function getModalPaddingStyles({ shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaMargin, @@ -645,122 +459,11 @@ function getEmojiPickerStyle(isSmallScreenWidth: boolean): ViewStyle { }; } -/** - * Generate the styles for the ReportActionItem wrapper view. - */ -function getReportActionItemStyle(theme: ThemeColors, styles: ThemeStyles, isHovered = false): ViewStyle { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - display: 'flex', - justifyContent: 'space-between', - backgroundColor: isHovered - ? theme.hoverComponentBG - : // Warning: Setting this to a non-transparent color will cause unread indicator to break on Android - theme.transparent, - opacity: 1, - ...styles.cursorInitial, - }; -} - -/** - * Generate the wrapper styles for the mini ReportActionContextMenu. - */ -function getMiniReportActionContextMenuWrapperStyle(styles: ThemeStyles, isReportActionItemGrouped: boolean): ViewStyle { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...(isReportActionItemGrouped ? positioning.tn8 : positioning.tn4), - ...positioning.r4, - ...styles.cursorDefault, - position: 'absolute', - zIndex: 8, - }; -} - function getPaymentMethodMenuWidth(isSmallScreenWidth: boolean): ViewStyle { const margin = 20; return {width: !isSmallScreenWidth ? variables.sideBarWidth - margin * 2 : undefined}; } -/** - * Converts a color in RGBA notation to an equivalent color in RGB notation. - * - * @param foregroundRGB The three components of the foreground color in RGB notation. - * @param backgroundRGB The three components of the background color in RGB notation. - * @param opacity The desired opacity of the foreground color. - * @returns The RGB components of the RGBA color converted to RGB. - */ -function convertRGBAToRGB(foregroundRGB: number[], backgroundRGB: number[], opacity: number): number[] { - const [foregroundRed, foregroundGreen, foregroundBlue] = foregroundRGB; - const [backgroundRed, backgroundGreen, backgroundBlue] = backgroundRGB; - - return [(1 - opacity) * backgroundRed + opacity * foregroundRed, (1 - opacity) * backgroundGreen + opacity * foregroundGreen, (1 - opacity) * backgroundBlue + opacity * foregroundBlue]; -} - -/** - * Converts three unit values to the three components of a color in RGB notation. - * - * @param red A unit value representing the first component of a color in RGB notation. - * @param green A unit value representing the second component of a color in RGB notation. - * @param blue A unit value representing the third component of a color in RGB notation. - * @returns An array with the three components of a color in RGB notation. - */ -function convertUnitValuesToRGB(red: number, green: number, blue: number): number[] { - return [Math.floor(red * 255), Math.floor(green * 255), Math.floor(blue * 255)]; -} - -/** - * Converts the three components of a color in RGB notation to three unit values. - * - * @param red The first component of a color in RGB notation. - * @param green The second component of a color in RGB notation. - * @param blue The third component of a color in RGB notation. - * @returns An array with three unit values representing the components of a color in RGB notation. - */ -function convertRGBToUnitValues(red: number, green: number, blue: number): number[] { - return [red / 255, green / 255, blue / 255]; -} - -/** - * Matches an RGBA or RGB color value and extracts the color components. - * - * @param color - The RGBA or RGB color value to match and extract components from. - * @returns An array containing the extracted color components [red, green, blue, alpha]. - * - * Returns null if the input string does not match the pattern. - */ -function extractValuesFromRGB(color: string): number[] | null { - const rgbaPattern = /rgba?\((?[.\d]+)[, ]+(?[.\d]+)[, ]+(?[.\d]+)(?:\s?[,/]\s?(?[.\d]+%?))?\)$/i; - const matchRGBA = color.match(rgbaPattern); - if (matchRGBA) { - const [, red, green, blue, alpha] = matchRGBA; - return [parseInt(red, 10), parseInt(green, 10), parseInt(blue, 10), alpha ? parseFloat(alpha) : 1]; - } - - return null; -} - -/** - * Determines the theme color for a modal based on the app's background color, - * the modal's backdrop, and the backdrop's opacity. - * - * @param bgColor - theme background color - * @returns The theme color as an RGB value. - */ -function getThemeBackgroundColor(theme: ThemeColors, bgColor: string): string { - const backdropOpacity = variables.overlayOpacity; - - const [backgroundRed, backgroundGreen, backgroundBlue] = extractValuesFromRGB(bgColor) ?? hexadecimalToRGBArray(bgColor) ?? []; - const [backdropRed, backdropGreen, backdropBlue] = hexadecimalToRGBArray(theme.overlay) ?? []; - const normalizedBackdropRGB = convertRGBToUnitValues(backdropRed, backdropGreen, backdropBlue); - const normalizedBackgroundRGB = convertRGBToUnitValues(backgroundRed, backgroundGreen, backgroundBlue); - const [red, green, blue] = convertRGBAToRGB(normalizedBackdropRGB, normalizedBackgroundRGB, backdropOpacity); - const themeRGB = convertUnitValuesToRGB(red, green, blue); - - return `rgb(${themeRGB.join(', ')})`; -} - /** * Parse styleParam and return Styles array */ @@ -857,6 +560,14 @@ function fade(fadeAnimation: Animated.Value): Animated.WithAnimatedValue { - return {backgroundColor: isColored ? theme.link : undefined}; -} - -function getEmojiReactionBubbleStyle(theme: ThemeColors, isHovered: boolean, hasUserReacted: boolean, isContextMenu = false): ViewStyle { - let backgroundColor = theme.border; - - if (isHovered) { - backgroundColor = theme.buttonHoveredBG; - } - - if (hasUserReacted) { - backgroundColor = theme.reactionActiveBackground; - } - - if (isContextMenu) { - return { - paddingVertical: 3, - paddingHorizontal: 12, - backgroundColor, - }; - } - - return { - paddingVertical: 2, - paddingHorizontal: 8, - backgroundColor, - }; -} - function getEmojiReactionBubbleTextStyle(isContextMenu = false): TextStyle { if (isContextMenu) { return { @@ -1079,14 +731,6 @@ function getEmojiReactionBubbleTextStyle(isContextMenu = false): TextStyle { }; } -function getEmojiReactionCounterTextStyle(theme: ThemeColors, hasUserReacted: boolean): TextStyle { - if (hasUserReacted) { - return {color: theme.reactionActiveText}; - } - - return {color: theme.text}; -} - /** * Returns a style object with a rotation transformation applied based on the provided direction prop. * @@ -1107,23 +751,6 @@ function displayIfTrue(condition: boolean): ViewStyle { return {display: condition ? 'flex' : 'none'}; } -function getGoogleListViewStyle(styles: ThemeStyles, shouldDisplayBorder: boolean): ViewStyle { - if (shouldDisplayBorder) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...styles.borderTopRounded, - ...styles.borderBottomRounded, - marginTop: 4, - paddingVertical: 6, - }; - } - - return { - transform: 'scale(0)', - }; -} - /** * Gets the correct height for emoji picker list based on screen dimensions */ @@ -1144,25 +771,6 @@ function getEmojiPickerListHeight(hasAdditionalSpace: boolean, windowHeight: num return style; } -/** - * Returns style object for the user mention component based on whether the mention is ours or not. - */ -function getMentionStyle(theme: ThemeColors, isOurMention: boolean): ViewStyle { - const backgroundColor = isOurMention ? theme.ourMentionBG : theme.mentionBG; - return { - backgroundColor, - borderRadius: variables.componentBorderRadiusSmall, - paddingHorizontal: 2, - }; -} - -/** - * Returns text color for the user mention text based on whether the mention is ours or not. - */ -function getMentionTextColor(theme: ThemeColors, isOurMention: boolean): string { - return isOurMention ? theme.ourMentionText : theme.mentionText; -} - /** * Returns padding vertical based on number of lines */ @@ -1209,23 +817,6 @@ function getMenuItemTextContainerStyle(isSmallAvatarSubscriptMenu: boolean): Vie }; } -/** - * Returns link styles based on whether the link is disabled or not - */ -function getDisabledLinkStyles(theme: ThemeColors, styles: ThemeStyles, isDisabled = false): ViewStyle { - const disabledLinkStyles = { - color: theme.textSupporting, - ...cursor.cursorDisabled, - }; - - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...styles.link, - ...(isDisabled ? disabledLinkStyles : {}), - }; -} - /** * Returns color style */ @@ -1246,23 +837,6 @@ function getCheckboxPressableStyle(borderRadius = 6): ViewStyle { }; } -/** - * Returns the checkbox container style - */ -function getCheckboxContainerStyle(theme: ThemeColors, size: number, borderRadius = 4): ViewStyle { - return { - backgroundColor: theme.componentBG, - height: size, - width: size, - borderColor: theme.borderLighter, - borderWidth: 2, - justifyContent: 'center', - alignItems: 'center', - // eslint-disable-next-line object-shorthand - borderRadius: borderRadius, - }; -} - /** * Returns style object for the dropbutton height */ @@ -1337,32 +911,6 @@ function getAmountFontSizeAndLineHeight(isSmallScreenWidth: boolean, windowWidth }; } -/** - * Returns container styles for showing the icons in MultipleAvatars/SubscriptAvatar - */ -function getContainerStyles(styles: ThemeStyles, size: string, isInReportAction = false): ViewStyle[] { - let containerStyles: ViewStyle[]; - - switch (size) { - case CONST.AVATAR_SIZE.SMALL: - containerStyles = [styles.emptyAvatarSmall, styles.emptyAvatarMarginSmall]; - break; - case CONST.AVATAR_SIZE.SMALLER: - containerStyles = [styles.emptyAvatarSmaller, styles.emptyAvatarMarginSmaller]; - break; - case CONST.AVATAR_SIZE.MEDIUM: - containerStyles = [styles.emptyAvatarMedium, styles.emptyAvatarMargin]; - break; - case CONST.AVATAR_SIZE.LARGE: - containerStyles = [styles.emptyAvatarLarge, styles.mb2, styles.mr2]; - break; - default: - containerStyles = [styles.emptyAvatar, isInReportAction ? styles.emptyAvatarMarginChat : styles.emptyAvatarMargin]; - } - - return containerStyles; -} - /** * Get transparent color by setting alpha value 0 of the passed hex(#xxxxxx) color code */ @@ -1370,33 +918,21 @@ function getTransparentColor(color: string) { return `${color}00`; } -/** - * Get the styles of the text next to dot indicators - */ -function getDotIndicatorTextStyles(styles: ThemeStyles, isErrorText = true): TextStyle { - return isErrorText ? {...styles.offlineFeedback.text, color: styles.formError.color} : {...styles.offlineFeedback.text}; -} - const StyleUtils = { combineStyles, displayIfTrue, getAmountFontSizeAndLineHeight, getAnimatedFABStyle, getAutoCompleteSuggestionContainerStyle, - getAutoCompleteSuggestionItemStyle, - getAutoGrowHeightInputStyle, getAvatarBorderRadius, getAvatarBorderStyle, getAvatarBorderWidth, getAvatarExtraFontSizeStyle, getAvatarSize, - getAvatarStyle, getAvatarWidthStyle, getBackgroundAndBorderStyle, getBackgroundColorStyle, getBackgroundColorWithOpacityStyle, - getBadgeColorStyle, - getButtonBackgroundColorStyle, getPaddingLeft, hasSafeAreas, getHeight, @@ -1413,125 +949,39 @@ const StyleUtils = { getReportWelcomeContainerStyle, getBaseAutoCompleteSuggestionContainerStyle, getBorderColorStyle, - getCheckboxContainerStyle, getCheckboxPressableStyle, - getColoredBackgroundStyle, getComposeTextAreaPadding, getColorStyle, getDefaultWorkspaceAvatarColor, getDirectionStyle, - getDisabledLinkStyles, getDropDownButtonHeight, - getDotIndicatorTextStyles, getEmojiPickerListHeight, getEmojiPickerStyle, - getEmojiReactionBubbleStyle, getEmojiReactionBubbleTextStyle, - getEmojiReactionCounterTextStyle, - getErrorPageContainerStyle, getFontFamilyMonospace, getCodeFontSize, getFontSizeStyle, - getGoogleListViewStyle, - getHeightOfMagicCodeInput, - getIconFillColor, getLineHeightStyle, - getMentionStyle, - getMentionTextColor, getMenuItemTextContainerStyle, - getMiniReportActionContextMenuWrapperStyle, getModalPaddingStyles, getOuterModalStyle, getPaymentMethodMenuWidth, - getReportActionItemStyle, getSafeAreaMargins, getSafeAreaPadding, getSignInWordmarkWidthStyle, getTextColorStyle, - getThemeBackgroundColor, getTransparentColor, getWidthAndHeightStyle, getWidthStyle, getWrappingStyle, - getZoomCursorStyle, getZoomSizingStyle, parseStyleAsArray, parseStyleFromFunction, - getContainerStyles, getEReceiptColorStyles, getEReceiptColorCode, }; type StyleUtilsType = typeof StyleUtils; -type DropParameters = Parameters<(typeof StyleUtils)[FunctionName]> extends [...OmittedParams, ...infer U] - ? U - : never; -type FunctionWithoutParameters = ( - ...restProps: DropParameters -) => ReturnType; -type FunctionWithoutFirstParameter = FunctionWithoutParameters; -type FunctionWithoutFirstTwoParameter = FunctionWithoutParameters; - -type ThemeDependentStyleUtilsFunctions = { - getAutoCompleteSuggestionItemStyle: FunctionWithoutFirstParameter<'getAutoCompleteSuggestionItemStyle'>; - getAutoGrowHeightInputStyle: FunctionWithoutFirstParameter<'getAutoGrowHeightInputStyle'>; - getAvatarStyle: FunctionWithoutFirstParameter<'getAvatarStyle'>; - getBadgeColorStyle: FunctionWithoutFirstParameter<'getBadgeColorStyle'>; - getButtonBackgroundColorStyle: FunctionWithoutFirstParameter<'getButtonBackgroundColorStyle'>; - getCheckboxContainerStyle: FunctionWithoutFirstParameter<'getCheckboxContainerStyle'>; - getColoredBackgroundStyle: FunctionWithoutFirstParameter<'getColoredBackgroundStyle'>; - getDisabledLinkStyles: FunctionWithoutFirstTwoParameter<'getDisabledLinkStyles'>; - getDotIndicatorTextStyles: FunctionWithoutFirstParameter<'getDotIndicatorTextStyles'>; - getEmojiReactionBubbleStyle: FunctionWithoutFirstParameter<'getEmojiReactionBubbleStyle'>; - getEmojiReactionCounterTextStyle: FunctionWithoutFirstParameter<'getEmojiReactionCounterTextStyle'>; - getErrorPageContainerStyle: FunctionWithoutFirstParameter<'getErrorPageContainerStyle'>; - getGoogleListViewStyle: FunctionWithoutFirstParameter<'getGoogleListViewStyle'>; - getHeightOfMagicCodeInput: FunctionWithoutFirstParameter<'getHeightOfMagicCodeInput'>; - getIconFillColor: FunctionWithoutFirstParameter<'getIconFillColor'>; - getMentionStyle: FunctionWithoutFirstParameter<'getMentionStyle'>; - getMentionTextColor: FunctionWithoutFirstParameter<'getMentionTextColor'>; - getMiniReportActionContextMenuWrapperStyle: FunctionWithoutFirstParameter<'getMiniReportActionContextMenuWrapperStyle'>; - getReportActionItemStyle: FunctionWithoutFirstTwoParameter<'getReportActionItemStyle'>; - getThemeBackgroundColor: FunctionWithoutFirstParameter<'getThemeBackgroundColor'>; - getZoomCursorStyle: FunctionWithoutFirstParameter<'getZoomCursorStyle'>; - getContainerStyles: FunctionWithoutFirstParameter<'getContainerStyles'>; -}; - -type StyleUtilsWithoutThemeParameters = StyleUtilsType & ThemeDependentStyleUtilsFunctions; - -const createStyleUtilsWithoutThemeParameters = (theme: ThemeColors, styles: ThemeStyles): StyleUtilsWithoutThemeParameters => { - const themeDependentStylUtilsFunctions = { - getAutoCompleteSuggestionItemStyle: (...restProps) => getAutoCompleteSuggestionItemStyle(theme, ...restProps), - getAutoGrowHeightInputStyle: (...restProps) => getAutoGrowHeightInputStyle(styles, ...restProps), - getAvatarStyle: (...restProps) => getAvatarStyle(theme, ...restProps), - getBadgeColorStyle: (...restProps) => getBadgeColorStyle(styles, ...restProps), - getButtonBackgroundColorStyle: (...restProps) => getButtonBackgroundColorStyle(theme, ...restProps), - getCheckboxContainerStyle: (...restProps) => getCheckboxContainerStyle(theme, ...restProps), - getColoredBackgroundStyle: (...restProps) => getColoredBackgroundStyle(theme, ...restProps), - getDisabledLinkStyles: (...restProps) => getDisabledLinkStyles(theme, styles, ...restProps), - getDotIndicatorTextStyles: (...restProps) => getDotIndicatorTextStyles(styles, ...restProps), - getEmojiReactionBubbleStyle: (...restProps) => getEmojiReactionBubbleStyle(theme, ...restProps), - getEmojiReactionCounterTextStyle: (...restProps) => getEmojiReactionCounterTextStyle(theme, ...restProps), - getErrorPageContainerStyle: (...restProps) => getErrorPageContainerStyle(theme, ...restProps), - getGoogleListViewStyle: (...restProps) => getGoogleListViewStyle(styles, ...restProps), - getHeightOfMagicCodeInput: (...restProps) => getHeightOfMagicCodeInput(styles, ...restProps), - getIconFillColor: (...restProps) => getIconFillColor(theme, ...restProps), - getMentionStyle: (...restProps) => getMentionStyle(theme, ...restProps), - getMentionTextColor: (...restProps) => getMentionTextColor(theme, ...restProps), - getMiniReportActionContextMenuWrapperStyle: (...restProps) => getMiniReportActionContextMenuWrapperStyle(styles, ...restProps), - getReportActionItemStyle: (...restProps) => getReportActionItemStyle(theme, styles, ...restProps), - getThemeBackgroundColor: (...restProps) => getThemeBackgroundColor(theme, ...restProps), - getZoomCursorStyle: (...restProps) => getZoomCursorStyle(styles, ...restProps), - getContainerStyles: (...restProps) => getContainerStyles(styles, ...restProps), - } satisfies ThemeDependentStyleUtilsFunctions; - - return { - ...StyleUtils, - ...themeDependentStylUtilsFunctions, - } as StyleUtilsWithoutThemeParameters; -}; - export default StyleUtils; -export {createStyleUtilsWithoutThemeParameters}; -export type {StyleUtilsType, ThemeDependentStyleUtilsFunctions, StyleUtilsWithoutThemeParameters, AvatarSizeName}; +export type {StyleUtilsType, AvatarSizeName}; diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index 475d2e98a0c9..faed9c969af1 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,6 +1,13 @@ import React from 'react'; -import defaultStyles, {ThemeStyles} from './styles'; +import {ThemeStyles} from './styles'; +import {ThemeStyleUtilsType} from './utils/ThemeStyleUtils'; -const ThemeStylesContext = React.createContext(defaultStyles); +type ThemeStylesContextType = { + styles: ThemeStyles; + ThemeStyleUtils: ThemeStyleUtilsType; +}; + +const ThemeStylesContext = React.createContext(undefined); export default ThemeStylesContext; +export {type ThemeStylesContextType}; diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index 5e2df4da8af7..c67b506fd581 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -2,6 +2,7 @@ import React, {useMemo} from 'react'; import {stylesGenerator} from './styles'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; +import createThemeStyleUtils from './utils/ThemeStyleUtils'; type ThemeStylesProviderProps = React.PropsWithChildren; @@ -9,8 +10,10 @@ function ThemeStylesProvider({children}: ThemeStylesProviderProps) { const theme = useTheme(); const styles = useMemo(() => stylesGenerator(theme), [theme]); + const ThemeStyleUtils = useMemo(() => createThemeStyleUtils(theme, styles), [theme, styles]); + const contextValue = useMemo(() => ({styles, ThemeStyleUtils}), [styles, ThemeStyleUtils]); - return {children}; + return {children}; } ThemeStylesProvider.displayName = 'ThemeStylesProvider'; diff --git a/src/styles/useThemeStyleUtils.ts b/src/styles/useThemeStyleUtils.ts new file mode 100644 index 000000000000..3588dc032642 --- /dev/null +++ b/src/styles/useThemeStyleUtils.ts @@ -0,0 +1,14 @@ +import {useContext} from 'react'; +import ThemeStylesContext from './ThemeStylesContext'; + +function useStyleUtils() { + const themeStylesContext = useContext(ThemeStylesContext); + + if (!themeStylesContext) { + throw new Error('ThemeStylesContext was null! Are you sure that you wrapped the component under a ?'); + } + + return themeStylesContext.ThemeStyleUtils; +} + +export default useStyleUtils; diff --git a/src/styles/utils/ThemeStyleUtils.ts b/src/styles/utils/ThemeStyleUtils.ts new file mode 100644 index 000000000000..8f157f973611 --- /dev/null +++ b/src/styles/utils/ThemeStyleUtils.ts @@ -0,0 +1,409 @@ +import {StyleProp, TextStyle, ViewStyle} from 'react-native'; +import {type ThemeStyles} from '@styles/styles'; +import StyleUtils from '@styles/StyleUtils'; +import {type ThemeColors} from '@styles/themes/types'; +import cursor from '@styles/utilities/cursor'; +import positioning from '@styles/utilities/positioning'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; +import {hexadecimalToRGBArray} from './functions'; +import {AvatarSizeName, AvatarStyle, ButtonStateName} from './types'; + +/** + * Converts a color in RGBA notation to an equivalent color in RGB notation. + * + * @param foregroundRGB The three components of the foreground color in RGB notation. + * @param backgroundRGB The three components of the background color in RGB notation. + * @param opacity The desired opacity of the foreground color. + * @returns The RGB components of the RGBA color converted to RGB. + */ +function convertRGBAToRGB(foregroundRGB: number[], backgroundRGB: number[], opacity: number): number[] { + const [foregroundRed, foregroundGreen, foregroundBlue] = foregroundRGB; + const [backgroundRed, backgroundGreen, backgroundBlue] = backgroundRGB; + + return [(1 - opacity) * backgroundRed + opacity * foregroundRed, (1 - opacity) * backgroundGreen + opacity * foregroundGreen, (1 - opacity) * backgroundBlue + opacity * foregroundBlue]; +} + +/** + * Converts three unit values to the three components of a color in RGB notation. + * + * @param red A unit value representing the first component of a color in RGB notation. + * @param green A unit value representing the second component of a color in RGB notation. + * @param blue A unit value representing the third component of a color in RGB notation. + * @returns An array with the three components of a color in RGB notation. + */ +function convertUnitValuesToRGB(red: number, green: number, blue: number): number[] { + return [Math.floor(red * 255), Math.floor(green * 255), Math.floor(blue * 255)]; +} + +/** + * Converts the three components of a color in RGB notation to three unit values. + * + * @param red The first component of a color in RGB notation. + * @param green The second component of a color in RGB notation. + * @param blue The third component of a color in RGB notation. + * @returns An array with three unit values representing the components of a color in RGB notation. + */ +function convertRGBToUnitValues(red: number, green: number, blue: number): number[] { + return [red / 255, green / 255, blue / 255]; +} + +/** + * Matches an RGBA or RGB color value and extracts the color components. + * + * @param color - The RGBA or RGB color value to match and extract components from. + * @returns An array containing the extracted color components [red, green, blue, alpha]. + * + * Returns null if the input string does not match the pattern. + */ +function extractValuesFromRGB(color: string): number[] | null { + const rgbaPattern = /rgba?\((?[.\d]+)[, ]+(?[.\d]+)[, ]+(?[.\d]+)(?:\s?[,/]\s?(?[.\d]+%?))?\)$/i; + const matchRGBA = color.match(rgbaPattern); + if (matchRGBA) { + const [, red, green, blue, alpha] = matchRGBA; + return [parseInt(red, 10), parseInt(green, 10), parseInt(blue, 10), alpha ? parseFloat(alpha) : 1]; + } + + return null; +} + +const createThemeStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ + /** + * Gets styles for AutoCompleteSuggestion row + */ + getAutoCompleteSuggestionItemStyle: (highlightedEmojiIndex: number, rowHeight: number, isHovered: boolean, currentEmojiIndex: number): ViewStyle[] => { + let backgroundColor; + + if (currentEmojiIndex === highlightedEmojiIndex) { + backgroundColor = theme.activeComponentBG; + } else if (isHovered) { + backgroundColor = theme.hoverComponentBG; + } + + return [ + { + height: rowHeight, + justifyContent: 'center', + }, + backgroundColor + ? { + backgroundColor, + } + : {}, + ]; + }, + + /** + * Returns auto grow height text input style + */ + getAutoGrowHeightInputStyle: (textInputHeight: number, maxHeight: number): ViewStyle => { + if (textInputHeight > maxHeight) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...styles.pr0, + ...styles.overflowAuto, + }; + } + + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...styles.pr0, + ...styles.overflowHidden, + // maxHeight is not of the input only but the of the whole input container + // which also includes the top padding and bottom border + height: maxHeight - styles.textInputMultilineContainer.paddingTop - styles.textInputContainer.borderBottomWidth, + }; + }, + + /** + * Return the style from an avatar size constant + */ + getAvatarStyle: (size: AvatarSizeName): AvatarStyle => { + const avatarSize = StyleUtils.getAvatarSize(size); + return { + height: avatarSize, + width: avatarSize, + borderRadius: avatarSize, + backgroundColor: theme.offline, + }; + }, + + /** + * Generate a style for the background color of the Badge + */ + getBadgeColorStyle: (isSuccess: boolean, isError: boolean, isPressed = false, isAdHoc = false): ViewStyle => { + if (isSuccess) { + if (isAdHoc) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return isPressed ? styles.badgeAdHocSuccessPressed : styles.badgeAdHocSuccess; + } + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return isPressed ? styles.badgeSuccessPressed : styles.badgeSuccess; + } + if (isError) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return isPressed ? styles.badgeDangerPressed : styles.badgeDanger; + } + return {}; + }, + + /** + * Generate a style for the background color of the button, based on its current state. + * + * @param buttonState - One of {'default', 'hovered', 'pressed'} + * @param isMenuItem - whether this button is apart of a list + */ + getButtonBackgroundColorStyle: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuItem = false): ViewStyle => { + switch (buttonState) { + case CONST.BUTTON_STATES.PRESSED: + return {backgroundColor: theme.buttonPressedBG}; + case CONST.BUTTON_STATES.ACTIVE: + return isMenuItem ? {backgroundColor: theme.border} : {backgroundColor: theme.buttonHoveredBG}; + case CONST.BUTTON_STATES.DISABLED: + case CONST.BUTTON_STATES.DEFAULT: + default: + return {}; + } + }, + + /** + * Returns the checkbox container style + */ + getCheckboxContainerStyle: (size: number, borderRadius = 4): ViewStyle => ({ + backgroundColor: theme.componentBG, + height: size, + width: size, + borderColor: theme.borderLighter, + borderWidth: 2, + justifyContent: 'center', + alignItems: 'center', + // eslint-disable-next-line object-shorthand + borderRadius: borderRadius, + }), + + /** + * Select the correct color for text. + */ + getColoredBackgroundStyle: (isColored: boolean): StyleProp => ({backgroundColor: isColored ? theme.link : undefined}), + + /** + * Returns link styles based on whether the link is disabled or not + */ + getDisabledLinkStyles: (isDisabled = false): ViewStyle => { + const disabledLinkStyles = { + color: theme.textSupporting, + ...cursor.cursorDisabled, + }; + + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...styles.link, + ...(isDisabled ? disabledLinkStyles : {}), + }; + }, + + /** + * Get the styles of the text next to dot indicators + */ + getDotIndicatorTextStyles: (isErrorText = true): TextStyle => (isErrorText ? {...styles.offlineFeedback.text, color: styles.formError.color} : {...styles.offlineFeedback.text}), + + getEmojiReactionBubbleStyle: (isHovered: boolean, hasUserReacted: boolean, isContextMenu = false): ViewStyle => { + let backgroundColor = theme.border; + + if (isHovered) { + backgroundColor = theme.buttonHoveredBG; + } + + if (hasUserReacted) { + backgroundColor = theme.reactionActiveBackground; + } + + if (isContextMenu) { + return { + paddingVertical: 3, + paddingHorizontal: 12, + backgroundColor, + }; + } + + return { + paddingVertical: 2, + paddingHorizontal: 8, + backgroundColor, + }; + }, + + getEmojiReactionCounterTextStyle: (hasUserReacted: boolean): TextStyle => { + if (hasUserReacted) { + return {color: theme.reactionActiveText}; + } + + return {color: theme.text}; + }, + + getErrorPageContainerStyle: (safeAreaPaddingBottom = 0): ViewStyle => ({ + backgroundColor: theme.componentBG, + paddingBottom: 40 + safeAreaPaddingBottom, + }), + + getGoogleListViewStyle: (shouldDisplayBorder: boolean): ViewStyle => { + if (shouldDisplayBorder) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...styles.borderTopRounded, + ...styles.borderBottomRounded, + marginTop: 4, + paddingVertical: 6, + }; + } + + return { + transform: 'scale(0)', + }; + }, + + /** + * Return the height of magic code input container + */ + getHeightOfMagicCodeInput: (): ViewStyle => ({height: styles.magicCodeInputContainer.minHeight - styles.textInputContainer.borderBottomWidth}), + + /** + * Generate fill color of an icon based on its state. + * + * @param buttonState - One of {'default', 'hovered', 'pressed'} + * @param isMenuIcon - whether this icon is apart of a list + */ + getIconFillColor: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuIcon = false): string => { + switch (buttonState) { + case CONST.BUTTON_STATES.ACTIVE: + case CONST.BUTTON_STATES.PRESSED: + return theme.iconHovered; + case CONST.BUTTON_STATES.COMPLETE: + return theme.iconSuccessFill; + case CONST.BUTTON_STATES.DEFAULT: + case CONST.BUTTON_STATES.DISABLED: + default: + if (isMenuIcon) { + return theme.iconMenu; + } + return theme.icon; + } + }, + + /** + * Returns style object for the user mention component based on whether the mention is ours or not. + */ + getMentionStyle: (isOurMention: boolean): ViewStyle => { + const backgroundColor = isOurMention ? theme.ourMentionBG : theme.mentionBG; + return { + backgroundColor, + borderRadius: variables.componentBorderRadiusSmall, + paddingHorizontal: 2, + }; + }, + + /** + * Returns text color for the user mention text based on whether the mention is ours or not. + */ + getMentionTextColor: (isOurMention: boolean): string => (isOurMention ? theme.ourMentionText : theme.mentionText), + + /** + * Generate the wrapper styles for the mini ReportActionContextMenu. + */ + getMiniReportActionContextMenuWrapperStyle: (isReportActionItemGrouped: boolean): ViewStyle => + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + ({ + ...(isReportActionItemGrouped ? positioning.tn8 : positioning.tn4), + ...positioning.r4, + ...styles.cursorDefault, + position: 'absolute', + zIndex: 8, + }), + + /** + * Generate the styles for the ReportActionItem wrapper view. + */ + getReportActionItemStyle: (isHovered = false): ViewStyle => + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + ({ + display: 'flex', + justifyContent: 'space-between', + backgroundColor: isHovered + ? theme.hoverComponentBG + : // Warning: Setting this to a non-transparent color will cause unread indicator to break on Android + theme.transparent, + opacity: 1, + ...styles.cursorInitial, + }), + + /** + * Determines the theme color for a modal based on the app's background color, + * the modal's backdrop, and the backdrop's opacity. + * + * @param bgColor - theme background color + * @returns The theme color as an RGB value. + */ + getThemeBackgroundColor: (bgColor: string): string => { + const backdropOpacity = variables.overlayOpacity; + + const [backgroundRed, backgroundGreen, backgroundBlue] = extractValuesFromRGB(bgColor) ?? hexadecimalToRGBArray(bgColor) ?? []; + const [backdropRed, backdropGreen, backdropBlue] = hexadecimalToRGBArray(theme.overlay) ?? []; + const normalizedBackdropRGB = convertRGBToUnitValues(backdropRed, backdropGreen, backdropBlue); + const normalizedBackgroundRGB = convertRGBToUnitValues(backgroundRed, backgroundGreen, backgroundBlue); + const [red, green, blue] = convertRGBAToRGB(normalizedBackdropRGB, normalizedBackgroundRGB, backdropOpacity); + const themeRGB = convertUnitValuesToRGB(red, green, blue); + + return `rgb(${themeRGB.join(', ')})`; + }, + + getZoomCursorStyle: (isZoomed: boolean, isDragging: boolean): ViewStyle => { + if (!isZoomed) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return styles.cursorZoomIn; + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return isDragging ? styles.cursorGrabbing : styles.cursorZoomOut; + }, + + /** + * Returns container styles for showing the icons in MultipleAvatars/SubscriptAvatar + */ + getContainerStyles: (size: string, isInReportAction = false): ViewStyle[] => { + let containerStyles: ViewStyle[]; + + switch (size) { + case CONST.AVATAR_SIZE.SMALL: + containerStyles = [styles.emptyAvatarSmall, styles.emptyAvatarMarginSmall]; + break; + case CONST.AVATAR_SIZE.SMALLER: + containerStyles = [styles.emptyAvatarSmaller, styles.emptyAvatarMarginSmaller]; + break; + case CONST.AVATAR_SIZE.MEDIUM: + containerStyles = [styles.emptyAvatarMedium, styles.emptyAvatarMargin]; + break; + case CONST.AVATAR_SIZE.LARGE: + containerStyles = [styles.emptyAvatarLarge, styles.mb2, styles.mr2]; + break; + default: + containerStyles = [styles.emptyAvatar, isInReportAction ? styles.emptyAvatarMarginChat : styles.emptyAvatarMargin]; + } + + return containerStyles; + }, +}); + +type ThemeStyleUtilsType = ReturnType; + +export default createThemeStyleUtils; +export type {ThemeStyleUtilsType}; diff --git a/src/styles/utils/functions.ts b/src/styles/utils/functions.ts new file mode 100644 index 000000000000..a71b3488e96d --- /dev/null +++ b/src/styles/utils/functions.ts @@ -0,0 +1,18 @@ +/** + * Converts a color in hexadecimal notation into RGB notation. + * + * @param hexadecimal A color in hexadecimal notation. + * @returns `undefined` if the input color is not in hexadecimal notation. Otherwise, the RGB components of the input color. + */ +function hexadecimalToRGBArray(hexadecimal: string): number[] | undefined { + const components = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexadecimal); + + if (components === null) { + return undefined; + } + + return components.slice(1).map((component) => parseInt(component, 16)); +} + +// eslint-disable-next-line import/prefer-default-export +export {hexadecimalToRGBArray}; diff --git a/src/styles/utils/types.ts b/src/styles/utils/types.ts new file mode 100644 index 000000000000..ee1e4787b47d --- /dev/null +++ b/src/styles/utils/types.ts @@ -0,0 +1,59 @@ +import {ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native'; +import {ValueOf} from 'type-fest'; +import colors from '@styles/colors'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; + +type AllStyles = ViewStyle | TextStyle | ImageStyle; +type ParsableStyle = StyleProp | ((state: PressableStateCallbackType) => StyleProp); + +type ColorValue = ValueOf; +type AvatarSizeName = ValueOf; +type EReceiptColorName = ValueOf; +type AvatarSizeValue = ValueOf< + Pick< + typeof variables, + | 'avatarSizeNormal' + | 'avatarSizeSmallSubscript' + | 'avatarSizeMidSubscript' + | 'avatarSizeSubscript' + | 'avatarSizeSmall' + | 'avatarSizeSmaller' + | 'avatarSizeXLarge' + | 'avatarSizeLarge' + | 'avatarSizeMedium' + | 'avatarSizeLargeBordered' + | 'avatarSizeHeader' + | 'avatarSizeMentionIcon' + | 'avatarSizeSmallNormal' + > +>; + +type AvatarStyle = { + width: number; + height: number; + borderRadius: number; + backgroundColor: string; +}; + +type ButtonSizeValue = ValueOf; +type ButtonStateName = ValueOf; +type AvatarSize = {width: number}; + +type WorkspaceColorStyle = {backgroundColor: ColorValue; fill: ColorValue}; +type EreceiptColorStyle = {backgroundColor: ColorValue; color: ColorValue}; + +export type { + AllStyles, + ParsableStyle, + ColorValue, + AvatarSizeName, + AvatarStyle, + EReceiptColorName, + AvatarSizeValue, + ButtonSizeValue, + ButtonStateName, + AvatarSize, + WorkspaceColorStyle, + EreceiptColorStyle, +}; From b5b1b783b96dfcd758ace004dd21c7f5447c7994 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 18:08:30 +0100 Subject: [PATCH 04/39] improve --- src/components/AddressSearch/CurrentLocationButton.js | 4 ++-- src/components/AddressSearch/index.js | 4 ++-- .../AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js | 4 ++-- src/components/Attachments/AttachmentView/index.js | 4 ++-- .../BaseAutoCompleteSuggestions.tsx | 4 ++-- src/components/AutoCompleteSuggestions/index.tsx | 4 ++-- src/components/AvatarCropModal/AvatarCropModal.js | 4 ++-- src/components/AvatarCropModal/ImageCropView.js | 4 ++-- src/components/Composer/index.js | 4 ++-- .../CurrentUserPersonalDetailsSkeletonView/index.tsx | 4 ++-- src/components/DatePicker/CalendarPicker/ArrowIcon.js | 4 ++-- src/components/DatePicker/CalendarPicker/index.js | 8 +++----- src/components/DistanceMapView/index.android.js | 4 ++-- src/components/EmojiPicker/CategoryShortcutButton.js | 5 +++-- src/components/EmojiPicker/EmojiPicker.js | 2 +- src/components/EmojiPicker/EmojiPickerButton.js | 9 ++++----- .../EmojiPicker/EmojiPickerButtonDropdown.js | 7 +++---- src/components/EmojiPicker/EmojiPickerMenu/index.js | 2 +- .../EmojiPicker/EmojiPickerMenu/index.native.js | 2 +- .../EmojiPicker/EmojiPickerMenuItem/index.js | 10 ++++------ .../EmojiPicker/EmojiPickerMenuItem/index.native.js | 10 ++++------ .../GrowlNotificationContainer/index.native.js | 2 +- .../HTMLEngineProvider/HTMLRenderers/CodeRenderer.js | 2 +- .../HTMLRenderers/MentionHereRenderer.js | 9 ++++----- src/components/HeaderWithBackButton/index.js | 8 ++++---- .../{withStyleUtils.tsx => withThemeStyleUtils.tsx} | 10 +++++----- src/styles/useThemeStyleUtils.ts | 4 ++-- 27 files changed, 65 insertions(+), 73 deletions(-) rename src/components/{withStyleUtils.tsx => withThemeStyleUtils.tsx} (76%) diff --git a/src/components/AddressSearch/CurrentLocationButton.js b/src/components/AddressSearch/CurrentLocationButton.js index c11c2344dbc2..20b6c5a08181 100644 --- a/src/components/AddressSearch/CurrentLocationButton.js +++ b/src/components/AddressSearch/CurrentLocationButton.js @@ -8,7 +8,7 @@ import useLocalize from '@hooks/useLocalize'; import getButtonState from '@libs/getButtonState'; import colors from '@styles/colors'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; const propTypes = { /** Callback that runs when location button is clicked */ @@ -25,7 +25,7 @@ const defaultProps = { function CurrentLocationButton({onPress, isDisabled}) { const styles = useThemeStyles(); - const ThemeStyleUtils = useStyleUtils(); + const ThemeStyleUtils = useThemeStyleUtils(); const {translate} = useLocalize(); return ( diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index e911ca41139a..fce4d6938ce2 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -16,7 +16,7 @@ import getCurrentPosition from '@libs/getCurrentPosition'; import * as GooglePlacesUtils from '@libs/GooglePlacesUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import CurrentLocationButton from './CurrentLocationButton'; @@ -165,7 +165,7 @@ function AddressSearch({ }) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); const [displayListViewBorder, setDisplayListViewBorder] = useState(false); const [isTyping, setIsTyping] = useState(false); const [isFocused, setIsFocused] = useState(false); diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js index 9a64db069a9b..70650c43614e 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js @@ -12,7 +12,7 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as ContextMenuActions from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import {propTypes as anchorForCommentsOnlyPropTypes} from './anchorForCommentsOnlyPropTypes'; @@ -33,7 +33,7 @@ const propTypes = { */ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', target = '', children = null, style = {}, onPress, ...rest}) { const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); useEffect( () => () => { ReportActionContextMenu.hideContextMenu(); diff --git a/src/components/Attachments/AttachmentView/index.js b/src/components/Attachments/AttachmentView/index.js index 5425c05a43a2..3de6fa5d9c9e 100755 --- a/src/components/Attachments/AttachmentView/index.js +++ b/src/components/Attachments/AttachmentView/index.js @@ -17,7 +17,7 @@ import compose from '@libs/compose'; import * as TransactionUtils from '@libs/TransactionUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import cursor from '@styles/utilities/cursor'; import variables from '@styles/variables'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -80,7 +80,7 @@ function AttachmentView({ }) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); const [loadComplete, setLoadComplete] = useState(false); const [imageError, setImageError] = useState(false); diff --git a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx index 158081f2ca02..07a437bf9c29 100644 --- a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx +++ b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx @@ -7,7 +7,7 @@ import Animated, {Easing, FadeOutDown, useAnimatedStyle, useSharedValue, withTim import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import viewForwardedRef from '@src/types/utils/viewForwardedRef'; import type {AutoCompleteSuggestionsProps, RenderSuggestionMenuItemProps} from './types'; @@ -40,7 +40,7 @@ function BaseAutoCompleteSuggestions( ref: ForwardedRef, ) { const styles = useThemeStyles(); - const ThemeStyleUtils = useStyleUtils(); + const ThemeStyleUtils = useThemeStyleUtils(); const rowHeight = useSharedValue(0); const scrollRef = useRef>(null); /** diff --git a/src/components/AutoCompleteSuggestions/index.tsx b/src/components/AutoCompleteSuggestions/index.tsx index 82ce93e19791..5ae494a08b9a 100644 --- a/src/components/AutoCompleteSuggestions/index.tsx +++ b/src/components/AutoCompleteSuggestions/index.tsx @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'; import {View} from 'react-native'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import BaseAutoCompleteSuggestions from './BaseAutoCompleteSuggestions'; import type {AutoCompleteSuggestionsProps} from './types'; @@ -15,7 +15,7 @@ import type {AutoCompleteSuggestionsProps} from './types'; */ function AutoCompleteSuggestions({measureParentContainer = () => {}, ...props}: AutoCompleteSuggestionsProps) { - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); const containerRef = React.useRef(null); const {windowHeight, windowWidth} = useWindowDimensions(); const [{width, left, bottom}, setContainerState] = React.useState({ diff --git a/src/components/AvatarCropModal/AvatarCropModal.js b/src/components/AvatarCropModal/AvatarCropModal.js index 988c0ba7b7d0..a2d4e1810365 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.js +++ b/src/components/AvatarCropModal/AvatarCropModal.js @@ -19,7 +19,7 @@ import compose from '@libs/compose'; import cropOrRotateImage from '@libs/cropOrRotateImage'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import ImageCropView from './ImageCropView'; import Slider from './Slider'; @@ -63,7 +63,7 @@ const defaultProps = { function AvatarCropModal(props) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); const originalImageWidth = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); const originalImageHeight = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); const translateY = useSharedValue(0); diff --git a/src/components/AvatarCropModal/ImageCropView.js b/src/components/AvatarCropModal/ImageCropView.js index 6d3a60211c5e..fb1e95ae1ef5 100644 --- a/src/components/AvatarCropModal/ImageCropView.js +++ b/src/components/AvatarCropModal/ImageCropView.js @@ -7,7 +7,7 @@ import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import ControlSelection from '@libs/ControlSelection'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import gestureHandlerPropTypes from './gestureHandlerPropTypes'; const propTypes = { @@ -51,7 +51,7 @@ const defaultProps = { function ImageCropView(props) { const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); const containerStyle = StyleUtils.getWidthAndHeightStyle(props.containerSize, props.containerSize); const originalImageHeight = props.originalImageHeight; diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 39cdddfd169b..996dc0837cc1 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -17,7 +17,7 @@ import isEnterWhileComposition from '@libs/KeyboardShortcut/isEnterWhileComposit import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -168,7 +168,7 @@ function Composer({ }) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); const {windowWidth} = useWindowDimensions(); const textRef = useRef(null); const textInput = useRef(null); diff --git a/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx b/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx index d67ff319f558..a1755a43ef8a 100644 --- a/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx +++ b/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx @@ -5,7 +5,7 @@ import {ValueOf} from 'type-fest'; import SkeletonViewContentLoader from '@components/SkeletonViewContentLoader'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -26,7 +26,7 @@ type CurrentUserPersonalDetailsSkeletonViewProps = { function CurrentUserPersonalDetailsSkeletonView({shouldAnimate = true, avatarSize = CONST.AVATAR_SIZE.LARGE, backgroundColor, foregroundColor}: CurrentUserPersonalDetailsSkeletonViewProps) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); const avatarPlaceholderSize = StyleUtils.getAvatarSize(avatarSize); const avatarPlaceholderRadius = avatarPlaceholderSize / 2; const spaceBetweenAvatarAndHeadline = styles.mb3.marginBottom + styles.mt1.marginTop + (variables.lineHeightXXLarge - variables.fontSizeXLarge) / 2; diff --git a/src/components/DatePicker/CalendarPicker/ArrowIcon.js b/src/components/DatePicker/CalendarPicker/ArrowIcon.js index d8ca277afe50..eda63439ebad 100644 --- a/src/components/DatePicker/CalendarPicker/ArrowIcon.js +++ b/src/components/DatePicker/CalendarPicker/ArrowIcon.js @@ -4,7 +4,7 @@ import {View} from 'react-native'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -22,7 +22,7 @@ const defaultProps = { function ArrowIcon(props) { const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); return ( diff --git a/src/components/DatePicker/CalendarPicker/index.js b/src/components/DatePicker/CalendarPicker/index.js index 62da413a5b65..20bc36af16ff 100644 --- a/src/components/DatePicker/CalendarPicker/index.js +++ b/src/components/DatePicker/CalendarPicker/index.js @@ -8,9 +8,8 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import Text from '@components/Text'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; -import withStyleUtils from '@components/withStyleUtils'; -import withTheme, {withThemePropTypes} from '@components/withTheme'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; +import withThemeStyleUtils from '@components/withThemeStyleUtils'; import compose from '@libs/compose'; import DateUtils from '@libs/DateUtils'; import getButtonState from '@libs/getButtonState'; @@ -34,7 +33,6 @@ const propTypes = { ...withLocalizePropTypes, ...withThemeStylesPropTypes, - ...withThemePropTypes, }; const defaultProps = { @@ -238,7 +236,7 @@ class CalendarPicker extends React.PureComponent { style={[ this.props.themeStyles.calendarDayContainer, isSelected ? this.props.themeStyles.calendarDayContainerSelected : {}, - !isDisabled ? this.props.StyleUtils.getButtonBackgroundColorStyle(this.props.theme, getButtonState(hovered, pressed)) : {}, + !isDisabled ? this.props.ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed)) : {}, ]} > {day} @@ -264,4 +262,4 @@ class CalendarPicker extends React.PureComponent { CalendarPicker.propTypes = propTypes; CalendarPicker.defaultProps = defaultProps; -export default compose(withLocalize, withTheme, withThemeStyles, withStyleUtils)(CalendarPicker); +export default compose(withLocalize, withThemeStyles, withThemeStyleUtils)(CalendarPicker); diff --git a/src/components/DistanceMapView/index.android.js b/src/components/DistanceMapView/index.android.js index c25c1ba65e40..f4b7feab6a0b 100644 --- a/src/components/DistanceMapView/index.android.js +++ b/src/components/DistanceMapView/index.android.js @@ -7,12 +7,12 @@ import MapView from '@components/MapView'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@styles/useThemeStyles'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as distanceMapViewPropTypes from './distanceMapViewPropTypes'; function DistanceMapView(props) { const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); const [isMapReady, setIsMapReady] = useState(false); const {isOffline} = useNetwork(); const {translate} = useLocalize(); diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js index aeb31dd87397..bf4ebc1060f4 100644 --- a/src/components/EmojiPicker/CategoryShortcutButton.js +++ b/src/components/EmojiPicker/CategoryShortcutButton.js @@ -5,9 +5,9 @@ import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeed import Tooltip from '@components/Tooltip'; import useLocalize from '@hooks/useLocalize'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -25,6 +25,7 @@ const propTypes = { function CategoryShortcutButton(props) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const {translate} = useLocalize(); const [isHighlighted, setIsHighlighted] = useState(false); @@ -39,7 +40,7 @@ function CategoryShortcutButton(props) { onHoverIn={() => setIsHighlighted(true)} onHoverOut={() => setIsHighlighted(false)} style={({pressed}) => [ - StyleUtils.getButtonBackgroundColorStyle(theme, getButtonState(false, pressed)), + ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), styles.categoryShortcutButton, isHighlighted && styles.emojiItemHighlighted, ]} diff --git a/src/components/EmojiPicker/EmojiPicker.js b/src/components/EmojiPicker/EmojiPicker.js index 9fc1224f96c0..c1f95ff1879d 100644 --- a/src/components/EmojiPicker/EmojiPicker.js +++ b/src/components/EmojiPicker/EmojiPicker.js @@ -6,7 +6,7 @@ import PopoverWithMeasuredContent from '@components/PopoverWithMeasuredContent'; import withViewportOffsetTop from '@components/withViewportOffsetTop'; import useWindowDimensions from '@hooks/useWindowDimensions'; import calculateAnchorPosition from '@libs/calculateAnchorPosition'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; import EmojiPickerMenu from './EmojiPickerMenu'; diff --git a/src/components/EmojiPicker/EmojiPickerButton.js b/src/components/EmojiPicker/EmojiPickerButton.js index 2926d6346b1b..35b6e0511581 100644 --- a/src/components/EmojiPicker/EmojiPickerButton.js +++ b/src/components/EmojiPicker/EmojiPickerButton.js @@ -6,9 +6,8 @@ import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeed import Tooltip from '@components/Tooltip/PopoverAnchorTooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; const propTypes = { @@ -31,8 +30,8 @@ const defaultProps = { }; function EmojiPickerButton(props) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const emojiPopoverAnchor = useRef(null); useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []); @@ -41,7 +40,7 @@ function EmojiPickerButton(props) { [styles.chatItemEmojiButton, StyleUtils.getButtonBackgroundColorStyle(theme, getButtonState(hovered, pressed))]} + style={({hovered, pressed}) => [styles.chatItemEmojiButton, ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed))]} disabled={props.isDisabled} onPress={() => { if (!EmojiPickerAction.emojiPickerRef.current.isEmojiPickerVisible) { @@ -56,7 +55,7 @@ function EmojiPickerButton(props) { {({hovered, pressed}) => ( )} diff --git a/src/components/EmojiPicker/EmojiPickerButtonDropdown.js b/src/components/EmojiPicker/EmojiPickerButtonDropdown.js index 6fd24adf04aa..1ba0c0d35b52 100644 --- a/src/components/EmojiPicker/EmojiPickerButtonDropdown.js +++ b/src/components/EmojiPicker/EmojiPickerButtonDropdown.js @@ -8,9 +8,8 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import CONST from '@src/CONST'; @@ -26,8 +25,8 @@ const defaultProps = { }; function EmojiPickerButtonDropdown(props) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const emojiPopoverAnchor = useRef(null); useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []); @@ -66,7 +65,7 @@ function EmojiPickerButtonDropdown(props) { diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 5a2211b70ba1..af9afb366e47 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -17,7 +17,7 @@ import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; import isEnterWhileComposition from '@libs/KeyboardShortcut/isEnterWhileComposition'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 772c32ff4a88..f4bb8d40f0fc 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -15,7 +15,7 @@ import useSingleExecution from '@hooks/useSingleExecution'; import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; diff --git a/src/components/EmojiPicker/EmojiPickerMenuItem/index.js b/src/components/EmojiPicker/EmojiPickerMenuItem/index.js index f674d3c4fa0e..177056631c8a 100644 --- a/src/components/EmojiPicker/EmojiPickerMenuItem/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenuItem/index.js @@ -2,11 +2,10 @@ import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import Text from '@components/Text'; -import withTheme, {withThemePropTypes} from '@components/withTheme'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; +import withThemeStyleUtils from '@components/withThemeStyleUtils'; import * as Browser from '@libs/Browser'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -35,7 +34,6 @@ const propTypes = { isHighlighted: PropTypes.bool, ...withThemeStylesPropTypes, - ...withThemePropTypes, }; class EmojiPickerMenuItem extends PureComponent { @@ -100,7 +98,7 @@ class EmojiPickerMenuItem extends PureComponent { style={({pressed}) => [ this.props.isFocused ? this.props.themeStyles.emojiItemKeyboardHighlighted : {}, this.state.isHovered || this.props.isHighlighted ? this.props.themeStyles.emojiItemHighlighted : {}, - Browser.isMobile() && StyleUtils.getButtonBackgroundColorStyle(this.props.theme, getButtonState(false, pressed)), + Browser.isMobile() && this.props.ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), this.props.themeStyles.emojiItem, ]} accessibilityLabel={this.props.emoji} @@ -124,8 +122,8 @@ EmojiPickerMenuItem.defaultProps = { // Significantly speeds up re-renders of the EmojiPickerMenu's FlatList // by only re-rendering at most two EmojiPickerMenuItems that are highlighted/un-highlighted per user action. -export default withTheme( - withThemeStyles( +export default withThemeStyles( + withThemeStyleUtils( React.memo( EmojiPickerMenuItem, (prevProps, nextProps) => prevProps.isFocused === nextProps.isFocused && prevProps.isHighlighted === nextProps.isHighlighted && prevProps.emoji === nextProps.emoji, diff --git a/src/components/EmojiPicker/EmojiPickerMenuItem/index.native.js b/src/components/EmojiPicker/EmojiPickerMenuItem/index.native.js index ca24dde6b861..49a0c56da3a6 100644 --- a/src/components/EmojiPicker/EmojiPickerMenuItem/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenuItem/index.native.js @@ -2,10 +2,9 @@ import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import Text from '@components/Text'; -import withTheme, {withThemePropTypes} from '@components/withTheme'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; +import withThemeStyleUtils from '@components/withThemeStyleUtils'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -37,7 +36,6 @@ const propTypes = { isUsingKeyboardMovement: PropTypes.bool, ...withThemeStylesPropTypes, - ...withThemePropTypes, }; class EmojiPickerMenuItem extends PureComponent { @@ -75,7 +73,7 @@ class EmojiPickerMenuItem extends PureComponent { onBlur={this.props.onBlur} ref={(ref) => (this.ref = ref)} style={({pressed}) => [ - StyleUtils.getButtonBackgroundColorStyle(this.props.theme, getButtonState(false, pressed)), + this.props.ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), this.props.isHighlighted && this.props.isUsingKeyboardMovement ? this.props.themeStyles.emojiItemKeyboardHighlighted : {}, this.props.isHighlighted && !this.props.isUsingKeyboardMovement ? this.props.themeStyles.emojiItemHighlighted : {}, this.props.themeStyles.emojiItem, @@ -102,8 +100,8 @@ EmojiPickerMenuItem.defaultProps = { // Significantly speeds up re-renders of the EmojiPickerMenu's FlatList // by only re-rendering at most two EmojiPickerMenuItems that are highlighted/un-highlighted per user action. -export default withTheme( - withThemeStyles( +export default withThemeStyles( + withThemeStyleUtils( React.memo( EmojiPickerMenuItem, (prevProps, nextProps) => diff --git a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js index 1b59219f38be..93bf14c54980 100644 --- a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js +++ b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js @@ -1,7 +1,7 @@ import React from 'react'; import {Animated} from 'react-native'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import growlNotificationContainerPropTypes from './growlNotificationContainerPropTypes'; diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js index 8cc062d754bc..ea1d4d13c7dd 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js @@ -3,7 +3,7 @@ import {splitBoxModelStyle} from 'react-native-render-html'; import _ from 'underscore'; import * as HTMLEngineUtils from '@components/HTMLEngineProvider/htmlEngineUtils'; import InlineCodeBlock from '@components/InlineCodeBlock'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import htmlRendererPropTypes from './htmlRendererPropTypes'; function CodeRenderer(props) { diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionHereRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionHereRenderer.js index 65c287b8e86b..a885fb5c8ed0 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionHereRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionHereRenderer.js @@ -2,18 +2,17 @@ import React from 'react'; import {TNodeChildrenRenderer} from 'react-native-render-html'; import _ from 'underscore'; import Text from '@components/Text'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import htmlRendererPropTypes from './htmlRendererPropTypes'; function MentionHereRenderer(props) { - const theme = useTheme(); + const ThemeStyleUtils = useThemeStyleUtils(); return ( diff --git a/src/components/HeaderWithBackButton/index.js b/src/components/HeaderWithBackButton/index.js index a6477fcf2ce0..24fc926dd49f 100755 --- a/src/components/HeaderWithBackButton/index.js +++ b/src/components/HeaderWithBackButton/index.js @@ -14,9 +14,9 @@ import useThrottledButtonState from '@hooks/useThrottledButtonState'; import useWaitForNavigation from '@hooks/useWaitForNavigation'; import getButtonState from '@libs/getButtonState'; import Navigation from '@libs/Navigation/Navigation'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import headerWithBackButtonPropTypes from './headerWithBackButtonPropTypes'; @@ -56,8 +56,8 @@ function HeaderWithBackButton({ singleExecution = (func) => func, shouldNavigateToTopMostReport = false, }) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const [isDownloadButtonActive, temporarilyDisableDownloadButton] = useThrottledButtonState(); const {translate} = useLocalize(); const {isKeyboardShown} = useKeyboardState(); @@ -133,7 +133,7 @@ function HeaderWithBackButton({ > diff --git a/src/components/withStyleUtils.tsx b/src/components/withThemeStyleUtils.tsx similarity index 76% rename from src/components/withStyleUtils.tsx rename to src/components/withThemeStyleUtils.tsx index e6f0112ebeff..a7ee705a5cfa 100644 --- a/src/components/withStyleUtils.tsx +++ b/src/components/withThemeStyleUtils.tsx @@ -1,19 +1,19 @@ import PropTypes from 'prop-types'; import React, {ComponentType, ForwardedRef, forwardRef, ReactElement, RefAttributes} from 'react'; import getComponentDisplayName from '@libs/getComponentDisplayName'; -import {StyleUtilsWithoutThemeParameters} from '@styles/StyleUtils'; -import useStyleUtils from '@styles/useThemeStyleUtils'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import {ThemeStyleUtilsType} from '@styles/utils/ThemeStyleUtils'; const withStyleUtilsPropTypes = { themeStyles: PropTypes.object.isRequired, }; -type WithStyleUtilsProps = {StyleUtils: StyleUtilsWithoutThemeParameters}; +type WithStyleUtilsProps = {StyleUtils: ThemeStyleUtilsType}; -export default function withStyleUtils( +export default function withThemeStyleUtils( WrappedComponent: ComponentType>, ): (props: Omit & React.RefAttributes) => ReactElement | null { function WithThemeStyles(props: Omit, ref: ForwardedRef): ReactElement { - const StyleUtils = useStyleUtils(); + const StyleUtils = useThemeStyleUtils(); return ( Date: Tue, 5 Dec 2023 18:46:56 +0100 Subject: [PATCH 05/39] fix: remaining style utils migration --- src/components/AddressSearch/index.js | 6 +++--- src/components/AttachmentModal.js | 2 +- src/components/Avatar.tsx | 10 ++++++---- src/components/AvatarWithDisplayName.tsx | 2 +- src/components/Badge.tsx | 7 ++++--- src/components/Banner.tsx | 6 +++--- src/components/BaseMiniContextMenuItem.js | 8 ++++---- src/components/ButtonWithDropdownMenu.js | 2 +- src/components/Checkbox.tsx | 6 ++++-- src/components/ContextMenuItem.js | 7 +++---- src/components/DotIndicatorMessage.tsx | 5 +++-- src/components/EReceipt.js | 2 +- src/components/EReceiptThumbnail.js | 2 +- src/components/EmojiSuggestions.tsx | 7 ++++--- src/components/ExpensifyWordmark.tsx | 2 +- src/components/FloatingActionButton.js | 2 +- .../HTMLRenderers/MentionUserRenderer.js | 7 +++---- src/components/HeaderPageLayout.js | 2 +- src/components/ImageView/index.js | 6 ++++-- src/components/LHNOptionsList/OptionRowLHN.js | 2 +- .../BaseLocationErrorMessage.js | 7 ++++--- src/components/MagicCodeInput.js | 5 +++-- src/components/MapView/MapView.web.tsx | 2 +- src/components/MentionSuggestions.tsx | 7 ++++--- src/components/MenuItem.js | 14 +++++++------- src/components/MessagesRow.js | 2 +- src/components/Modal/BaseModal.tsx | 2 +- src/components/Modal/index.tsx | 5 +++-- src/components/MultipleAvatars.tsx | 8 +++++--- src/components/OfflineWithFeedback.js | 2 +- src/components/OptionRow.js | 2 +- src/components/PDFView/index.native.js | 2 +- src/components/PopoverWithoutOverlay/index.js | 2 +- .../GenericPressable/BaseGenericPressable.tsx | 2 +- .../Pressable/PressableWithDelayToggle.tsx | 5 +++-- .../PressableWithSecondaryInteraction/index.tsx | 2 +- src/components/Reactions/AddReactionBubble.js | 10 +++++----- src/components/Reactions/EmojiReactionBubble.js | 10 +++++----- .../Reactions/MiniQuickEmojiReactions.js | 7 +++---- src/components/ReportActionItem/MoneyReportView.js | 2 +- .../ReportActionItem/MoneyRequestPreview.js | 2 +- .../ReportActionItem/MoneyRequestView.js | 2 +- .../ReportActionItem/ReportActionItemImages.js | 2 +- src/components/ReportActionItem/TaskPreview.js | 7 +++---- src/components/ReportActionItem/TaskView.js | 9 ++++----- src/components/RoomHeaderAvatars.js | 6 ++++-- src/components/SafeAreaConsumer/index.android.tsx | 2 +- src/components/SafeAreaConsumer/index.tsx | 2 +- src/components/SelectionList/BaseListItem.js | 6 ++++-- src/components/SpacerView.js | 2 +- src/components/SubscriptAvatar.tsx | 6 ++++-- src/components/TagPicker/index.js | 2 +- src/components/TextInput/BaseTextInput/index.js | 6 ++++-- .../TextInput/BaseTextInput/index.native.js | 2 +- src/components/ThumbnailImage.tsx | 2 +- src/components/ValuePicker/index.js | 2 +- src/pages/ErrorPage/GenericErrorPage.js | 5 +++-- .../home/report/AnimatedEmptyStateBackground.js | 2 +- .../MiniReportActionContextMenu/index.js | 7 +++---- src/pages/home/report/LinkPreviewer.js | 2 +- .../home/report/ReactionList/HeaderReactionList.js | 10 +++++----- src/pages/home/report/ReportActionItem.js | 6 ++++-- src/pages/home/report/ReportActionItemCreated.js | 2 +- .../home/report/ReportActionItemParentAction.js | 2 +- src/pages/home/report/ReportActionItemSingle.js | 2 +- src/pages/home/sidebar/SidebarLinks.js | 2 +- .../ValidateCodeForm/BaseValidateCodeForm.js | 7 +++++-- src/pages/settings/Wallet/PaymentMethodList.js | 11 +++++------ src/pages/signin/SignInHeroCopy.js | 2 +- src/pages/signin/SignInPage.js | 2 +- src/pages/signin/SignInPageHero.js | 2 +- src/pages/signin/SignInPageLayout/Footer.js | 2 +- .../signin/SignInPageLayout/SignInPageContent.js | 2 +- src/pages/signin/SignInPageLayout/index.js | 2 +- .../ValidateCodeForm/BaseValidateCodeForm.js | 2 +- src/stories/Composer.stories.js | 2 +- src/styles/StyleUtils.ts | 2 +- 77 files changed, 175 insertions(+), 152 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index fce4d6938ce2..326be8b1f10d 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -165,7 +165,7 @@ function AddressSearch({ }) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useThemeStyleUtils(); + const ThemeStyleUtils = useThemeStyleUtils(); const [displayListViewBorder, setDisplayListViewBorder] = useState(false); const [isTyping, setIsTyping] = useState(false); const [isFocused, setIsFocused] = useState(false); @@ -510,7 +510,7 @@ function AddressSearch({ }} styles={{ textInputContainer: [styles.flexColumn], - listView: [StyleUtils.getGoogleListViewStyle(displayListViewBorder), styles.overflowAuto, styles.borderLeft, styles.borderRight, !isFocused && {height: 0}], + listView: [ThemeStyleUtils.getGoogleListViewStyle(displayListViewBorder), styles.overflowAuto, styles.borderLeft, styles.borderRight, !isFocused && {height: 0}], row: [styles.pv4, styles.ph3, styles.overflowAuto], description: [styles.googleSearchText], separator: [styles.googleSearchSeparator], @@ -527,7 +527,7 @@ function AddressSearch({ inbetweenCompo={ // We want to show the current location button even if there are no recent destinations predefinedPlaces.length === 0 && shouldShowCurrentLocationButton ? ( - + setImageError(false)}); @@ -75,8 +77,8 @@ function Avatar({ const isWorkspace = type === CONST.ICON_TYPE_WORKSPACE; const iconSize = StyleUtils.getAvatarSize(size); - const imageStyle = [StyleUtils.getAvatarStyle(theme, size), imageStyles, styles.noBorderRadius]; - const iconStyle = imageStyles ? [StyleUtils.getAvatarStyle(theme, size), styles.bgTransparent, imageStyles] : undefined; + const imageStyle = [ThemeStyleUtils.getAvatarStyle(size), imageStyles, styles.noBorderRadius]; + const iconStyle = imageStyles ? [ThemeStyleUtils.getAvatarStyle(size), styles.bgTransparent, imageStyles] : undefined; const iconFillColor = isWorkspace ? StyleUtils.getDefaultWorkspaceAvatarColor(name).fill : fill ?? theme.icon; const fallbackAvatar = isWorkspace ? ReportUtils.getDefaultWorkspaceAvatar(name) : fallbackIcon || Expensicons.FallbackAvatar; diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index 9229cb80cf4c..01a9c4b07334 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -5,7 +5,7 @@ import {ValueOf} from 'type-fest'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index ff963589d80f..37865777b95f 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -1,7 +1,7 @@ import React, {useCallback} from 'react'; import {GestureResponderEvent, PressableStateCallbackType, StyleProp, TextStyle, View, ViewStyle} from 'react-native'; -import * as StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Text from './Text'; @@ -34,12 +34,13 @@ type BadgeProps = { function Badge({success = false, error = false, pressable = false, text, environment = CONST.ENVIRONMENT.DEV, badgeStyles, textStyles, onPress = () => {}}: BadgeProps) { const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const textColorStyles = success || error ? styles.textWhite : undefined; const Wrapper = pressable ? PressableWithoutFeedback : View; const wrapperStyles: (state: PressableStateCallbackType) => StyleProp = useCallback( - ({pressed}) => [styles.badge, styles.ml2, StyleUtils.getBadgeColorStyle(styles, success, error, pressed, environment === CONST.ENVIRONMENT.ADHOC), badgeStyles], - [success, error, environment, badgeStyles, styles], + ({pressed}) => [styles.badge, styles.ml2, ThemeStyleUtils.getBadgeColorStyle(success, error, pressed, environment === CONST.ENVIRONMENT.ADHOC), badgeStyles], + [styles.badge, styles.ml2, ThemeStyleUtils, success, error, environment, badgeStyles], ); return ( diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx index 6e5ad8970f1a..f79c07f70c5b 100644 --- a/src/components/Banner.tsx +++ b/src/components/Banner.tsx @@ -2,9 +2,9 @@ import React, {memo} from 'react'; import {StyleProp, TextStyle, View, ViewStyle} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import Hoverable from './Hoverable'; import Icon from './Icon'; @@ -41,8 +41,8 @@ type BannerProps = { }; function Banner({text, onClose, onPress, containerStyles, textStyles, shouldRenderHTML = false, shouldShowIcon = false, shouldShowCloseButton = false}: BannerProps) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const {translate} = useLocalize(); return ( @@ -67,7 +67,7 @@ function Banner({text, onClose, onPress, containerStyles, textStyles, shouldRend )} diff --git a/src/components/BaseMiniContextMenuItem.js b/src/components/BaseMiniContextMenuItem.js index 3252938e4ca5..e36e2981ac18 100644 --- a/src/components/BaseMiniContextMenuItem.js +++ b/src/components/BaseMiniContextMenuItem.js @@ -5,9 +5,9 @@ import _ from 'underscore'; import DomUtils from '@libs/DomUtils'; import getButtonState from '@libs/getButtonState'; import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Tooltip from './Tooltip/PopoverAnchorTooltip'; @@ -51,8 +51,8 @@ const defaultProps = { * @returns {JSX.Element} */ function BaseMiniContextMenuItem(props) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); return ( [ styles.reportActionContextMenuMiniButton, - StyleUtils.getButtonBackgroundColorStyle(theme, getButtonState(hovered, pressed, props.isDelayButtonStateComplete)), + ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, props.isDelayButtonStateComplete)), props.isDelayButtonStateComplete && styles.cursorDefault, ]} > diff --git a/src/components/ButtonWithDropdownMenu.js b/src/components/ButtonWithDropdownMenu.js index 15f2e2f4d6de..369ae0905cf7 100644 --- a/src/components/ButtonWithDropdownMenu.js +++ b/src/components/ButtonWithDropdownMenu.js @@ -3,7 +3,7 @@ import React, {useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 22577ec2b7f9..d292f9c8c71a 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -1,8 +1,9 @@ import React, {ForwardedRef, forwardRef, KeyboardEvent as ReactKeyboardEvent} from 'react'; import {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import ChildrenProps from '@src/types/utils/ChildrenProps'; import Icon from './Icon'; @@ -63,6 +64,7 @@ function Checkbox( ) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const handleSpaceKey = (event?: ReactKeyboardEvent) => { if (event?.code !== 'Space') { @@ -98,7 +100,7 @@ function Checkbox( {children ?? ( )} diff --git a/src/components/DotIndicatorMessage.tsx b/src/components/DotIndicatorMessage.tsx index b90093e20fc3..fa570cfdf375 100644 --- a/src/components/DotIndicatorMessage.tsx +++ b/src/components/DotIndicatorMessage.tsx @@ -3,9 +3,9 @@ import React from 'react'; import {StyleProp, TextStyle, View, ViewStyle} from 'react-native'; import fileDownload from '@libs/fileDownload'; import * as Localize from '@libs/Localize'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; @@ -45,6 +45,7 @@ function isReceiptError(message: string | ReceiptError): message is ReceiptError function DotIndicatorMessage({messages = {}, style, type, textStyles}: DotIndicatorMessageProps) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); if (Object.keys(messages).length === 0) { return null; @@ -92,7 +93,7 @@ function DotIndicatorMessage({messages = {}, style, type, textStyles}: DotIndica {message} diff --git a/src/components/EReceipt.js b/src/components/EReceipt.js index 85c753c7ccb3..4aa3169f56e3 100644 --- a/src/components/EReceipt.js +++ b/src/components/EReceipt.js @@ -6,7 +6,7 @@ import useLocalize from '@hooks/useLocalize'; import * as CardUtils from '@libs/CardUtils'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; diff --git a/src/components/EReceiptThumbnail.js b/src/components/EReceiptThumbnail.js index f54e246b8b1e..cfaf086d8cde 100644 --- a/src/components/EReceiptThumbnail.js +++ b/src/components/EReceiptThumbnail.js @@ -3,7 +3,7 @@ import React, {useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import * as ReportUtils from '@libs/ReportUtils'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; diff --git a/src/components/EmojiSuggestions.tsx b/src/components/EmojiSuggestions.tsx index 6917d3dec185..5ddcb6b6a947 100644 --- a/src/components/EmojiSuggestions.tsx +++ b/src/components/EmojiSuggestions.tsx @@ -3,9 +3,9 @@ import {View} from 'react-native'; import type {SimpleEmoji} from '@libs/EmojiTrie'; import * as EmojiUtils from '@libs/EmojiUtils'; import getStyledTextArray from '@libs/GetStyledTextArray'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import Text from './Text'; @@ -45,6 +45,7 @@ const keyExtractor = (item: SimpleEmoji, index: number): string => `${item.name} function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferredSkinToneIndex, highlightedEmojiIndex = 0, measureParentContainer = () => {}}: EmojiSuggestionsProps) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); /** * Render an emoji suggestion menu item component. */ @@ -63,7 +64,7 @@ function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferr {styledTextArray.map(({text, isColored}) => ( {text} @@ -73,7 +74,7 @@ function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferr ); }, - [styles, theme, prefix, preferredSkinToneIndex], + [prefix, styles.autoCompleteSuggestionContainer, styles.emojiSuggestionsEmoji, styles.emojiSuggestionsText, preferredSkinToneIndex, ThemeStyleUtils], ); return ( diff --git a/src/components/ExpensifyWordmark.tsx b/src/components/ExpensifyWordmark.tsx index 1402b48df0d9..2abec86584ee 100644 --- a/src/components/ExpensifyWordmark.tsx +++ b/src/components/ExpensifyWordmark.tsx @@ -5,7 +5,7 @@ import DevLogo from '@assets/images/expensify-logo--dev.svg'; import StagingLogo from '@assets/images/expensify-logo--staging.svg'; import ProductionLogo from '@assets/images/expensify-wordmark.svg'; import useEnvironment from '@hooks/useEnvironment'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/components/FloatingActionButton.js b/src/components/FloatingActionButton.js index c49f69c336eb..b0b6ac23aed1 100644 --- a/src/components/FloatingActionButton.js +++ b/src/components/FloatingActionButton.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import {Animated, Easing, View} from 'react-native'; import compose from '@libs/compose'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import PressableWithFeedback from './Pressable/PressableWithFeedback'; diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js index 0027a557ab02..642eda8598f1 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js @@ -13,9 +13,8 @@ import Navigation from '@libs/Navigation/Navigation'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import personalDetailsPropType from '@pages/personalDetailsPropType'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import htmlRendererPropTypes from './htmlRendererPropTypes'; @@ -28,8 +27,8 @@ const propTypes = { }; function MentionUserRenderer(props) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const {translate} = useLocalize(); const defaultRendererProps = _.omit(props, ['TDefaultRenderer', 'style']); const htmlAttribAccountID = lodashGet(props.tnode.attributes, 'accountid'); @@ -77,7 +76,7 @@ function MentionUserRenderer(props) { }} > = 1 ? styles.pRelative : styles.pAbsolute), ...styles.flex1, }} diff --git a/src/components/LHNOptionsList/OptionRowLHN.js b/src/components/LHNOptionsList/OptionRowLHN.js index 3b2de574ba17..92be2d7bcfae 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.js +++ b/src/components/LHNOptionsList/OptionRowLHN.js @@ -25,7 +25,7 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as ContextMenuActions from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import * as optionRowStyles from '@styles/optionRowStyles'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; diff --git a/src/components/LocationErrorMessage/BaseLocationErrorMessage.js b/src/components/LocationErrorMessage/BaseLocationErrorMessage.js index 4e4912322bb1..434310612271 100644 --- a/src/components/LocationErrorMessage/BaseLocationErrorMessage.js +++ b/src/components/LocationErrorMessage/BaseLocationErrorMessage.js @@ -9,8 +9,8 @@ import TextLink from '@components/TextLink'; import Tooltip from '@components/Tooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import colors from '@styles/colors'; -import * as StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import * as locationErrorMessagePropTypes from './locationErrorMessagePropTypes'; @@ -27,6 +27,7 @@ const propTypes = { function BaseLocationErrorMessage({onClose, onAllowLocationLinkPress, locationErrorCode, translate}) { const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); if (!locationErrorCode) { return null; } @@ -44,14 +45,14 @@ function BaseLocationErrorMessage({onClose, onAllowLocationLinkPress, locationEr {isPermissionDenied ? ( - {`${translate('location.permissionDenied')} ${translate('location.please')}`} + {`${translate('location.permissionDenied')} ${translate('location.please')}`} {` ${translate('location.allowPermission')} `} - {translate('location.tryAgain')} + {translate('location.tryAgain')} ) : ( {translate('location.notFound')} diff --git a/src/components/MagicCodeInput.js b/src/components/MagicCodeInput.js index c40962c8e631..058f898db812 100644 --- a/src/components/MagicCodeInput.js +++ b/src/components/MagicCodeInput.js @@ -6,8 +6,8 @@ import _ from 'underscore'; import useNetwork from '@hooks/useNetwork'; import * as Browser from '@libs/Browser'; import * as ValidationUtils from '@libs/ValidationUtils'; -import * as StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import FormHelpMessage from './FormHelpMessage'; import networkPropTypes from './networkPropTypes'; @@ -108,6 +108,7 @@ const getInputPlaceholderSlots = (length) => Array.from(Array(length).keys()); function MagicCodeInput(props) { const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const inputRefs = useRef(); const [input, setInput] = useState(TEXT_INPUT_EMPTY_STATE); const [focusedIndex, setFocusedIndex] = useState(0); @@ -407,7 +408,7 @@ function MagicCodeInput(props) { item.alternateText; function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSelect, isMentionPickerLarge, measureParentContainer = () => {}}: MentionSuggestionsProps) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); /** * Render a suggestion menu item component. */ @@ -83,7 +84,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe {text} @@ -99,7 +100,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe {text} diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index a551d4a9205a..caab8a5ff5cd 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -7,9 +7,10 @@ import ControlSelection from '@libs/ControlSelection'; import convertToLTR from '@libs/convertToLTR'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; @@ -88,6 +89,7 @@ const defaultProps = { const MenuItem = React.forwardRef((props, ref) => { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const style = StyleUtils.combineStyles(props.style, styles.popoverMenuItem); const {isSmallScreenWidth} = useWindowDimensions(); const [html, setHtml] = React.useState(''); @@ -181,7 +183,7 @@ const MenuItem = React.forwardRef((props, ref) => { style={({pressed}) => [ style, !props.interactive && styles.cursorDefault, - StyleUtils.getButtonBackgroundColorStyle(theme, getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true), + ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true), (isHovered || pressed) && props.hoverAndPressStyle, ...(_.isArray(props.wrapperStyle) ? props.wrapperStyle : [props.wrapperStyle]), props.shouldGreyOutWhenDisabled && props.disabled && styles.buttonOpacityDisabled, @@ -226,8 +228,7 @@ const MenuItem = React.forwardRef((props, ref) => { height={props.iconHeight} fill={ props.iconFill || - StyleUtils.getIconFillColor( - theme, + ThemeStyleUtils.getIconFillColor( getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true, ) @@ -262,8 +263,7 @@ const MenuItem = React.forwardRef((props, ref) => { height={props.iconHeight} fill={ props.secondaryIconFill || - StyleUtils.getIconFillColor( - theme, + ThemeStyleUtils.getIconFillColor( getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true, ) @@ -382,7 +382,7 @@ const MenuItem = React.forwardRef((props, ref) => { )} diff --git a/src/components/MessagesRow.js b/src/components/MessagesRow.js index e4d6240ba0fd..45adb16a0f6f 100644 --- a/src/components/MessagesRow.js +++ b/src/components/MessagesRow.js @@ -4,7 +4,7 @@ import {View} from 'react-native'; import _ from 'underscore'; import useLocalize from '@hooks/useLocalize'; import stylePropTypes from '@styles/stylePropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; import DotIndicatorMessage from './DotIndicatorMessage'; diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index f5c498b24893..b9318a77b413 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -8,7 +8,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; import ComposerFocusManager from '@libs/ComposerFocusManager'; import useNativeDriver from '@libs/useNativeDriver'; import getModalStyles from '@styles/getModalStyles'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index bc683b6f6311..7181dcafc56b 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -1,14 +1,15 @@ import React, {useState} from 'react'; import withWindowDimensions from '@components/withWindowDimensions'; import StatusBar from '@libs/StatusBar'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import BaseModal from './BaseModal'; import BaseModalProps from './types'; function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = () => {}, children, ...rest}: BaseModalProps) { const theme = useTheme(); + const ThemeStyleUtils = useThemeStyleUtils(); const [previousStatusBarColor, setPreviousStatusBarColor] = useState(); const setStatusBarColor = (color = theme.appBG) => { @@ -32,7 +33,7 @@ function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = ( if (statusBarColor) { setPreviousStatusBarColor(statusBarColor); // If it is a full screen modal then match it with appBG, otherwise we use the backdrop color - setStatusBarColor(isFullScreenModal ? theme.appBG : StyleUtils.getThemeBackgroundColor(theme, statusBarColor)); + setStatusBarColor(isFullScreenModal ? theme.appBG : ThemeStyleUtils.getThemeBackgroundColor(statusBarColor)); } onModalShow?.(); diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index efff279324ac..d76ede294d72 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -2,9 +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 * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import type {Icon} from '@src/types/onyx/OnyxCommon'; @@ -80,6 +81,7 @@ function MultipleAvatars({ }: MultipleAvatarsProps) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const avatarSizeToStylesMap: AvatarSizeToStylesMap = useMemo( () => ({ @@ -101,7 +103,7 @@ function MultipleAvatars({ const secondAvatarStyle = secondAvatarStyleProp ?? [StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)]; - let avatarContainerStyles = StyleUtils.getContainerStyles(styles, size, isInReportAction); + let avatarContainerStyles = ThemeStyleUtils.getContainerStyles(size, isInReportAction); const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[size as AvatarSizeToStyles] ?? avatarSizeToStylesMap.default, [size, avatarSizeToStylesMap]); const tooltipTexts = useMemo(() => (shouldShowTooltip ? icons.map((icon) => icon.name) : ['']), [shouldShowTooltip, icons]); @@ -161,7 +163,7 @@ function MultipleAvatars({ ); } - const oneAvatarSize = StyleUtils.getAvatarStyle(theme, size); + const oneAvatarSize = ThemeStyleUtils.getAvatarStyle(size); const oneAvatarBorderWidth = StyleUtils.getAvatarBorderWidth(size).borderWidth ?? 0; const overlapSize = oneAvatarSize.width / 3; diff --git a/src/components/OfflineWithFeedback.js b/src/components/OfflineWithFeedback.js index 7a2dfbd2b6da..62987ab8507e 100644 --- a/src/components/OfflineWithFeedback.js +++ b/src/components/OfflineWithFeedback.js @@ -5,7 +5,7 @@ import _ from 'underscore'; import useNetwork from '@hooks/useNetwork'; import shouldRenderOffscreen from '@libs/shouldRenderOffscreen'; import stylePropTypes from '@styles/stylePropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; import MessagesRow from './MessagesRow'; diff --git a/src/components/OptionRow.js b/src/components/OptionRow.js index cb670f3cf6ce..675e87ed49b0 100644 --- a/src/components/OptionRow.js +++ b/src/components/OptionRow.js @@ -5,7 +5,7 @@ import {InteractionManager, StyleSheet, View} from 'react-native'; import _ from 'underscore'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index b022823d215a..649dae749ef1 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -10,7 +10,7 @@ import withLocalize from '@components/withLocalize'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; import withWindowDimensions from '@components/withWindowDimensions'; import compose from '@libs/compose'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import CONST from '@src/CONST'; import PDFPasswordForm from './PDFPasswordForm'; import {defaultProps, propTypes as pdfViewPropTypes} from './pdfViewPropTypes'; diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 6572a55ed889..6a5bbd9582c5 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -6,7 +6,7 @@ import {PopoverContext} from '@components/PopoverProvider'; import withWindowDimensions from '@components/withWindowDimensions'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; import getModalStyles from '@styles/getModalStyles'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import * as Modal from '@userActions/Modal'; diff --git a/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx b/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx index c0bb531db007..f7d518852a45 100644 --- a/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx +++ b/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx @@ -5,7 +5,7 @@ import useSingleExecution from '@hooks/useSingleExecution'; import Accessibility from '@libs/Accessibility'; import HapticFeedback from '@libs/HapticFeedback'; import KeyboardShortcut from '@libs/KeyboardShortcut'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; import PressableProps, {PressableRef} from './types'; diff --git a/src/components/Pressable/PressableWithDelayToggle.tsx b/src/components/Pressable/PressableWithDelayToggle.tsx index a80272ee05cf..7d740cd43620 100644 --- a/src/components/Pressable/PressableWithDelayToggle.tsx +++ b/src/components/Pressable/PressableWithDelayToggle.tsx @@ -8,9 +8,9 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; import useThrottledButtonState from '@hooks/useThrottledButtonState'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import PressableProps, {PressableRef} from './GenericPressable/types'; import PressableWithoutFeedback from './PressableWithoutFeedback'; @@ -69,6 +69,7 @@ function PressableWithDelayToggle( ) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const [isActive, temporarilyDisableInteractions] = useThrottledButtonState(); const updatePressState = () => { @@ -122,7 +123,7 @@ function PressableWithDelayToggle( {icon && ( EmojiPickerAction.resetEmojiPopoverAnchor, []); @@ -92,7 +92,7 @@ function AddReactionBubble(props) { style={({hovered, pressed}) => [ styles.emojiReactionBubble, styles.userSelectNone, - StyleUtils.getEmojiReactionBubbleStyle(theme, hovered || pressed, false, props.isContextMenu), + ThemeStyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, false, props.isContextMenu), ]} onPress={Session.checkIfActionIsAllowed(onPress)} onMouseDown={(e) => { @@ -121,7 +121,7 @@ function AddReactionBubble(props) { src={Expensicons.AddReaction} width={props.isContextMenu ? variables.iconSizeNormal : variables.iconSizeSmall} height={props.isContextMenu ? variables.iconSizeNormal : variables.iconSizeSmall} - fill={StyleUtils.getIconFillColor(theme, getButtonState(hovered, pressed))} + fill={ThemeStyleUtils.getIconFillColor(getButtonState(hovered, pressed))} /> diff --git a/src/components/Reactions/EmojiReactionBubble.js b/src/components/Reactions/EmojiReactionBubble.js index 73538a032e38..e0dbcf25b9fb 100644 --- a/src/components/Reactions/EmojiReactionBubble.js +++ b/src/components/Reactions/EmojiReactionBubble.js @@ -4,9 +4,9 @@ import PressableWithSecondaryInteraction from '@components/PressableWithSecondar import Text from '@components/Text'; import {withCurrentUserPersonalDetailsDefaultProps} from '@components/withCurrentUserPersonalDetails'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -55,13 +55,13 @@ const defaultProps = { }; function EmojiReactionBubble(props) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); return ( [ styles.emojiReactionBubble, - StyleUtils.getEmojiReactionBubbleStyle(theme, hovered || pressed, props.hasUserReacted, props.isContextMenu), + ThemeStyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, props.hasUserReacted, props.isContextMenu), props.shouldBlockReactions && styles.cursorDisabled, styles.userSelectNone, ]} @@ -89,7 +89,7 @@ function EmojiReactionBubble(props) { dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} > {props.emojiCodes.join('')} - {props.count > 0 && {props.count}} + {props.count > 0 && {props.count}} ); } diff --git a/src/components/Reactions/MiniQuickEmojiReactions.js b/src/components/Reactions/MiniQuickEmojiReactions.js index 7795f77d5d53..fedbc7fd1458 100644 --- a/src/components/Reactions/MiniQuickEmojiReactions.js +++ b/src/components/Reactions/MiniQuickEmojiReactions.js @@ -11,9 +11,8 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; import getButtonState from '@libs/getButtonState'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; @@ -56,8 +55,8 @@ const defaultProps = { * @returns {JSX.Element} */ function MiniQuickEmojiReactions(props) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const ref = useRef(); const openEmojiPicker = () => { @@ -107,7 +106,7 @@ function MiniQuickEmojiReactions(props) { )} diff --git a/src/components/ReportActionItem/MoneyReportView.js b/src/components/ReportActionItem/MoneyReportView.js index c870f11d6f3c..b24beb9ff9c1 100644 --- a/src/components/ReportActionItem/MoneyReportView.js +++ b/src/components/ReportActionItem/MoneyReportView.js @@ -11,7 +11,7 @@ import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import reportPropTypes from '@pages/reportPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/components/ReportActionItem/MoneyRequestPreview.js b/src/components/ReportActionItem/MoneyRequestPreview.js index 7391b8ccd933..e537233bfd43 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.js +++ b/src/components/ReportActionItem/MoneyRequestPreview.js @@ -28,7 +28,7 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import walletTermsPropTypes from '@pages/EnablePayments/walletTermsPropTypes'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import * as PaymentMethods from '@userActions/PaymentMethods'; diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index 0249a9f5bb11..d0b7cbbdfcb6 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -31,7 +31,7 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import iouReportPropTypes from '@pages/iouReportPropTypes'; import reportPropTypes from '@pages/reportPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import * as IOU from '@userActions/IOU'; diff --git a/src/components/ReportActionItem/ReportActionItemImages.js b/src/components/ReportActionItem/ReportActionItemImages.js index de9ff3b6c30b..e4ddf571976d 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.js +++ b/src/components/ReportActionItem/ReportActionItemImages.js @@ -5,7 +5,7 @@ import {Polygon, Svg} from 'react-native-svg'; import _ from 'underscore'; import Text from '@components/Text'; import transactionPropTypes from '@components/transactionPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/components/ReportActionItem/TaskPreview.js b/src/components/ReportActionItem/TaskPreview.js index abc65b513ab9..5bfd98c8a682 100644 --- a/src/components/ReportActionItem/TaskPreview.js +++ b/src/components/ReportActionItem/TaskPreview.js @@ -22,9 +22,8 @@ import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as Session from '@userActions/Session'; import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; @@ -76,8 +75,8 @@ const defaultProps = { }; function TaskPreview(props) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; // The reportAction might not contain details regarding the taskReport // Only the direct parent reportAction will contain details about the taskReport @@ -130,7 +129,7 @@ function TaskPreview(props) { diff --git a/src/components/ReportActionItem/TaskView.js b/src/components/ReportActionItem/TaskView.js index 3d3ed9315f6e..fa2a1d69442d 100644 --- a/src/components/ReportActionItem/TaskView.js +++ b/src/components/ReportActionItem/TaskView.js @@ -24,9 +24,8 @@ import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as Session from '@userActions/Session'; import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; @@ -46,8 +45,8 @@ const propTypes = { }; function TaskView(props) { - const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); useEffect(() => { Task.setTaskReport({...props.report}); }, [props.report]); @@ -85,7 +84,7 @@ function TaskView(props) { style={({pressed}) => [ styles.ph5, styles.pv2, - StyleUtils.getButtonBackgroundColorStyle(theme, getButtonState(hovered, pressed, false, disableState, !isDisableInteractive), true), + ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, false, disableState, !isDisableInteractive), true), isDisableInteractive && !disableState && styles.cursorDefault, ]} ref={props.forwardedRef} @@ -125,7 +124,7 @@ function TaskView(props) { )} diff --git a/src/components/RoomHeaderAvatars.js b/src/components/RoomHeaderAvatars.js index bd7a24d15f1f..c1b980824885 100644 --- a/src/components/RoomHeaderAvatars.js +++ b/src/components/RoomHeaderAvatars.js @@ -3,9 +3,10 @@ import React, {memo} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import * as UserUtils from '@libs/UserUtils'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import AttachmentModal from './AttachmentModal'; import Avatar from './Avatar'; @@ -24,6 +25,7 @@ const defaultProps = { function RoomHeaderAvatars(props) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); if (!props.icons.length) { return null; } @@ -65,7 +67,7 @@ function RoomHeaderAvatars(props) { styles.roomHeaderAvatar, // Due to border-box box-sizing, the Avatars have to be larger when bordered to visually match size with non-bordered Avatars - StyleUtils.getAvatarStyle(theme, CONST.AVATAR_SIZE.LARGE_BORDERED), + ThemeStyleUtils.getAvatarStyle(theme, CONST.AVATAR_SIZE.LARGE_BORDERED), ]; return ( diff --git a/src/components/SafeAreaConsumer/index.android.tsx b/src/components/SafeAreaConsumer/index.android.tsx index 472c2f037d29..afd81dc65ac5 100644 --- a/src/components/SafeAreaConsumer/index.android.tsx +++ b/src/components/SafeAreaConsumer/index.android.tsx @@ -2,7 +2,7 @@ import React from 'react'; // eslint-disable-next-line no-restricted-imports import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; import StatusBar from '@libs/StatusBar'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import SafeAreaConsumerProps from './types'; /** diff --git a/src/components/SafeAreaConsumer/index.tsx b/src/components/SafeAreaConsumer/index.tsx index f515d6697bb4..adc372aa42d5 100644 --- a/src/components/SafeAreaConsumer/index.tsx +++ b/src/components/SafeAreaConsumer/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; // eslint-disable-next-line no-restricted-imports import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import SafeAreaConsumerProps from './types'; /** diff --git a/src/components/SelectionList/BaseListItem.js b/src/components/SelectionList/BaseListItem.js index 3a58b63954bd..20c05b88d49f 100644 --- a/src/components/SelectionList/BaseListItem.js +++ b/src/components/SelectionList/BaseListItem.js @@ -7,9 +7,10 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import RadioListItem from './RadioListItem'; import {baseListItemPropTypes} from './selectionListPropTypes'; @@ -27,6 +28,7 @@ function BaseListItem({ }) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const {translate} = useLocalize(); const isUserItem = lodashGet(item, 'icons.length', 0) > 0; const ListItem = isUserItem ? UserListItem : RadioListItem; @@ -62,7 +64,7 @@ function BaseListItem({ diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index 78724718b2af..a9684ae71dd6 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -6,7 +6,7 @@ import OptionsSelector from '@components/OptionsSelector'; import useLocalize from '@hooks/useLocalize'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/components/TextInput/BaseTextInput/index.js b/src/components/TextInput/BaseTextInput/index.js index cf8ae90c727a..f47bfbcc5936 100644 --- a/src/components/TextInput/BaseTextInput/index.js +++ b/src/components/TextInput/BaseTextInput/index.js @@ -16,9 +16,10 @@ import withLocalize from '@components/withLocalize'; import * as Browser from '@libs/Browser'; import isInputAutoFilled from '@libs/isInputAutoFilled'; import useNativeDriver from '@libs/useNativeDriver'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import * as baseTextInputPropTypes from './baseTextInputPropTypes'; @@ -26,6 +27,7 @@ import * as baseTextInputPropTypes from './baseTextInputPropTypes'; function BaseTextInput(props) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const initialValue = props.value || props.defaultValue || ''; const initialActiveLabel = props.forceActiveLabel || initialValue.length > 0 || Boolean(props.prefixCharacter); @@ -333,7 +335,7 @@ function BaseTextInput(props) { !isMultiline && Browser.isMobileChrome() && {boxSizing: 'content-box', height: undefined}, // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. - ...(props.autoGrowHeight ? [StyleUtils.getAutoGrowHeightInputStyle(styles, textInputHeight, maxHeight), styles.verticalAlignTop] : []), + ...(props.autoGrowHeight ? [ThemeStyleUtils.getAutoGrowHeightInputStyle(textInputHeight, maxHeight), styles.verticalAlignTop] : []), // Add disabled color theme when field is not editable. props.disabled && styles.textInputDisabled, diff --git a/src/components/TextInput/BaseTextInput/index.native.js b/src/components/TextInput/BaseTextInput/index.native.js index 190104198986..a862eec3145b 100644 --- a/src/components/TextInput/BaseTextInput/index.native.js +++ b/src/components/TextInput/BaseTextInput/index.native.js @@ -16,7 +16,7 @@ import withLocalize from '@components/withLocalize'; import getSecureEntryKeyboardType from '@libs/getSecureEntryKeyboardType'; import isInputAutoFilled from '@libs/isInputAutoFilled'; import useNativeDriver from '@libs/useNativeDriver'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/components/ThumbnailImage.tsx b/src/components/ThumbnailImage.tsx index 0fdd626a1517..5f9db7b4464e 100644 --- a/src/components/ThumbnailImage.tsx +++ b/src/components/ThumbnailImage.tsx @@ -3,7 +3,7 @@ import React, {useCallback, useState} from 'react'; import {Dimensions, StyleProp, View, ViewStyle} from 'react-native'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import ImageWithSizeCalculation from './ImageWithSizeCalculation'; diff --git a/src/components/ValuePicker/index.js b/src/components/ValuePicker/index.js index 35b8d2babdb0..09b74d50f59e 100644 --- a/src/components/ValuePicker/index.js +++ b/src/components/ValuePicker/index.js @@ -5,7 +5,7 @@ import {View} from 'react-native'; import FormHelpMessage from '@components/FormHelpMessage'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import refPropTypes from '@components/refPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; import ValueSelectorModal from './ValueSelectorModal'; diff --git a/src/pages/ErrorPage/GenericErrorPage.js b/src/pages/ErrorPage/GenericErrorPage.js index ba9bd783752b..baf06188184e 100644 --- a/src/pages/ErrorPage/GenericErrorPage.js +++ b/src/pages/ErrorPage/GenericErrorPage.js @@ -9,9 +9,9 @@ import SafeAreaConsumer from '@components/SafeAreaConsumer'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; @@ -24,12 +24,13 @@ const propTypes = { function GenericErrorPage({translate}) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const {resetBoundary} = useErrorBoundary(); return ( {({paddingBottom}) => ( - + diff --git a/src/pages/home/report/AnimatedEmptyStateBackground.js b/src/pages/home/report/AnimatedEmptyStateBackground.js index c003a3809130..e7fd7708f386 100644 --- a/src/pages/home/report/AnimatedEmptyStateBackground.js +++ b/src/pages/home/report/AnimatedEmptyStateBackground.js @@ -3,7 +3,7 @@ import Animated, {SensorType, useAnimatedSensor, useAnimatedStyle, useSharedValu import useWindowDimensions from '@hooks/useWindowDimensions'; import * as NumberUtils from '@libs/NumberUtils'; import useThemeIllustrations from '@styles/illustrations/useThemeIllustrations'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; diff --git a/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js b/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js index 37901db09954..c6c40a9339a6 100644 --- a/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js +++ b/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js @@ -7,8 +7,7 @@ import { defaultProps as GenericReportActionContextMenuDefaultProps, propTypes as genericReportActionContextMenuPropTypes, } from '@pages/home/report/ContextMenu/genericReportActionContextMenuPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; -import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -25,11 +24,11 @@ const defaultProps = { }; function MiniReportActionContextMenu(props) { - const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); return ( - + {props.emojiCodes.join('')} - {props.emojiCount} + {props.emojiCount} {`:${EmojiUtils.getLocalizedEmojiName(props.emojiName, props.preferredLocale)}:`} diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 92bb370155c9..99bbe32f11a8 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -46,9 +46,10 @@ import SelectionScraper from '@libs/SelectionScraper'; import userWalletPropTypes from '@pages/EnablePayments/userWalletPropTypes'; import {ReactionListContext} from '@pages/home/ReportScreenContext'; import reportPropTypes from '@pages/reportPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as BankAccounts from '@userActions/BankAccounts'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as store from '@userActions/ReimbursementAccount/store'; @@ -137,6 +138,7 @@ const defaultProps = { function ReportActionItem(props) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const [isContextMenuActive, setIsContextMenuActive] = useState(() => ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); const [isHidden, setIsHidden] = useState(false); @@ -693,7 +695,7 @@ function ReportActionItem(props) { draftMessage={props.draftMessage} isChronosReport={ReportUtils.chatIncludesChronos(originalReport)} /> - + ReportActions.clearReportActionErrors(props.report.reportID, props.action)} pendingAction={props.draftMessage ? null : props.action.pendingAction} diff --git a/src/pages/home/report/ReportActionItemCreated.js b/src/pages/home/report/ReportActionItemCreated.js index 4c7f14a21abc..86d3a5d24436 100644 --- a/src/pages/home/report/ReportActionItemCreated.js +++ b/src/pages/home/report/ReportActionItemCreated.js @@ -14,7 +14,7 @@ import compose from '@libs/compose'; import reportWithoutHasDraftSelector from '@libs/OnyxSelectors/reportWithoutHasDraftSelector'; import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; diff --git a/src/pages/home/report/ReportActionItemParentAction.js b/src/pages/home/report/ReportActionItemParentAction.js index ad319b86e634..a58c2b283933 100644 --- a/src/pages/home/report/ReportActionItemParentAction.js +++ b/src/pages/home/report/ReportActionItemParentAction.js @@ -9,7 +9,7 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withW import compose from '@libs/compose'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import reportPropTypes from '@pages/reportPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import * as Report from '@userActions/Report'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index b13d57ad2976..29c487c08458 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -20,7 +20,7 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as UserUtils from '@libs/UserUtils'; import reportPropTypes from '@pages/reportPropTypes'; import stylePropTypes from '@styles/stylePropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 2aba742f157f..3b982e5102b2 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -19,7 +19,7 @@ import onyxSubscribe from '@libs/onyxSubscribe'; import SidebarUtils from '@libs/SidebarUtils'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import safeAreaInsetPropTypes from '@pages/safeAreaInsetPropTypes'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js index f0aea2301383..59335ef53d1b 100644 --- a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js @@ -16,9 +16,9 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; import * as ValidationUtils from '@libs/ValidationUtils'; -import * as StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as Session from '@userActions/Session'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; @@ -74,6 +74,7 @@ const defaultProps = { function BaseValidateCodeForm(props) { const theme = useTheme(); const styles = useThemeStyles(); + const ThemeStyleUtils = useThemeStyleUtils(); const [formError, setFormError] = useState({}); const [validateCode, setValidateCode] = useState(''); const loginData = props.loginList[props.contactMethod]; @@ -209,7 +210,9 @@ function BaseValidateCodeForm(props) { role={CONST.ACCESSIBILITY_ROLE.BUTTON} accessibilityLabel={props.translate('validateCodeForm.magicCodeNotReceived')} > - {props.translate('validateCodeForm.magicCodeNotReceived')} + + {props.translate('validateCodeForm.magicCodeNotReceived')} + {props.hasMagicCodeBeenSent && ( onPress(e, paymentMethod.accountType, paymentMethod.accountData, paymentMethod.isDefault, paymentMethod.methodID), - iconFill: isMethodActive ? StyleUtils.getIconFillColor(theme, CONST.BUTTON_STATES.PRESSED) : null, - wrapperStyle: isMethodActive ? [StyleUtils.getButtonBackgroundColorStyle(theme, CONST.BUTTON_STATES.PRESSED)] : null, + iconFill: isMethodActive ? ThemeStyleUtils.getIconFillColor(CONST.BUTTON_STATES.PRESSED) : null, + wrapperStyle: isMethodActive ? [ThemeStyleUtils.getButtonBackgroundColorStyle(CONST.BUTTON_STATES.PRESSED)] : null, disabled: paymentMethod.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, }; }); return combinedPaymentMethods; - }, [shouldShowAssignedCards, fundList, bankAccountList, filterType, isOffline, cardList, translate, actionPaymentMethodType, activePaymentMethodID, onPress, styles, theme]); + }, [shouldShowAssignedCards, fundList, bankAccountList, styles, filterType, isOffline, cardList, translate, actionPaymentMethodType, activePaymentMethodID, ThemeStyleUtils, onPress]); /** * Render placeholder when there are no payments methods diff --git a/src/pages/signin/SignInHeroCopy.js b/src/pages/signin/SignInHeroCopy.js index 7c770169df82..d6c633d6fcd9 100644 --- a/src/pages/signin/SignInHeroCopy.js +++ b/src/pages/signin/SignInHeroCopy.js @@ -5,7 +5,7 @@ import Text from '@components/Text'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import compose from '@libs/compose'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index 6676dc99b911..b8938a533309 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -14,7 +14,7 @@ import * as Localize from '@libs/Localize'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import Performance from '@libs/Performance'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import ThemeProvider from '@styles/themes/ThemeProvider'; import ThemeStylesProvider from '@styles/ThemeStylesProvider'; import useThemeStyles from '@styles/useThemeStyles'; diff --git a/src/pages/signin/SignInPageHero.js b/src/pages/signin/SignInPageHero.js index 56ccb45503a9..eef8066e05fc 100644 --- a/src/pages/signin/SignInPageHero.js +++ b/src/pages/signin/SignInPageHero.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; import SignInHeroCopy from './SignInHeroCopy'; diff --git a/src/pages/signin/SignInPageLayout/Footer.js b/src/pages/signin/SignInPageLayout/Footer.js index 86fb6a08341a..2a35a4c318d0 100644 --- a/src/pages/signin/SignInPageLayout/Footer.js +++ b/src/pages/signin/SignInPageLayout/Footer.js @@ -10,7 +10,7 @@ import TextLink from '@components/TextLink'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import Licenses from '@pages/signin/Licenses'; import Socials from '@pages/signin/Socials'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/pages/signin/SignInPageLayout/SignInPageContent.js b/src/pages/signin/SignInPageLayout/SignInPageContent.js index d09cee9aa1c2..477f41bfdbd7 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageContent.js +++ b/src/pages/signin/SignInPageLayout/SignInPageContent.js @@ -10,7 +10,7 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import SignInHeroImage from '@pages/signin/SignInHeroImage'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index b6c82fc843cd..430b365b65c1 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -8,7 +8,7 @@ import usePrevious from '@hooks/usePrevious'; import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import SignInPageHero from '@pages/signin/SignInPageHero'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js index 7c48d557cd16..bc891b855c90 100755 --- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js @@ -20,7 +20,7 @@ import * as ErrorUtils from '@libs/ErrorUtils'; import * as ValidationUtils from '@libs/ValidationUtils'; import ChangeExpensifyLoginLink from '@pages/signin/ChangeExpensifyLoginLink'; import Terms from '@pages/signin/Terms'; -import * as StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import * as Session from '@userActions/Session'; diff --git a/src/stories/Composer.stories.js b/src/stories/Composer.stories.js index 0dcde20752ba..467f9243cb09 100644 --- a/src/stories/Composer.stories.js +++ b/src/stories/Composer.stories.js @@ -7,7 +7,7 @@ import Text from '@components/Text'; import withNavigationFallback from '@components/withNavigationFallback'; import styles from '@styles/styles'; import themeColors from '@styles/themes/default'; -import * as StyleUtils from '@styles/utils/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const ComposerWithNavigation = withNavigationFallback(Composer); diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index b980f1b7cc00..e567aa1b32cd 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -984,4 +984,4 @@ const StyleUtils = { type StyleUtilsType = typeof StyleUtils; export default StyleUtils; -export type {StyleUtilsType, AvatarSizeName}; +export type {StyleUtilsType}; From dbcc908a69a35961776a8e880748ab9571137882 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 18:47:41 +0100 Subject: [PATCH 06/39] update imports --- src/components/AttachmentModal.js | 2 +- .../BaseAutoCompleteSuggestions.tsx | 2 +- src/components/Avatar.tsx | 2 +- src/components/AvatarWithDisplayName.tsx | 2 +- src/components/BaseMiniContextMenuItem.js | 2 +- src/components/ButtonWithDropdownMenu.js | 2 +- src/components/Checkbox.tsx | 2 +- src/components/EReceipt.js | 2 +- src/components/EReceiptThumbnail.js | 2 +- src/components/EmojiPicker/EmojiPicker.js | 2 +- .../EmojiPicker/EmojiPickerMenu/index.js | 2 +- .../EmojiPickerMenu/index.native.js | 2 +- src/components/ExpensifyWordmark.tsx | 2 +- src/components/FloatingActionButton.js | 2 +- .../index.native.js | 2 +- .../HTMLRenderers/CodeRenderer.js | 2 +- src/components/HeaderPageLayout.js | 2 +- src/components/HeaderWithBackButton/index.js | 2 +- src/components/Icon/index.tsx | 2 +- src/components/ImageView/index.js | 2 +- src/components/LHNOptionsList/OptionRowLHN.js | 2 +- src/components/MapView/MapView.web.tsx | 2 +- src/components/MenuItem.js | 2 +- src/components/MessagesRow.js | 2 +- src/components/Modal/BaseModal.tsx | 2 +- src/components/MultipleAvatars.tsx | 2 +- src/components/OfflineWithFeedback.js | 2 +- src/components/OptionRow.js | 2 +- src/components/PDFView/index.native.js | 2 +- src/components/PopoverWithoutOverlay/index.js | 2 +- .../GenericPressable/BaseGenericPressable.tsx | 2 +- .../index.tsx | 2 +- src/components/Reactions/AddReactionBubble.js | 2 +- .../Reactions/EmojiReactionBubble.js | 2 +- .../ReportActionItem/MoneyReportView.js | 2 +- .../ReportActionItem/MoneyRequestPreview.js | 2 +- .../ReportActionItem/MoneyRequestView.js | 2 +- .../ReportActionItemImages.js | 2 +- src/components/RoomHeaderAvatars.js | 2 +- .../SafeAreaConsumer/index.android.tsx | 2 +- src/components/SafeAreaConsumer/index.tsx | 2 +- src/components/SelectionList/BaseListItem.js | 2 +- src/components/SpacerView.js | 2 +- src/components/SubscriptAvatar.tsx | 2 +- src/components/TagPicker/index.js | 2 +- .../TextInput/BaseTextInput/index.js | 2 +- .../TextInput/BaseTextInput/index.native.js | 2 +- src/components/ThumbnailImage.tsx | 2 +- src/components/ValuePicker/index.js | 2 +- .../report/AnimatedEmptyStateBackground.js | 2 +- src/pages/home/report/LinkPreviewer.js | 2 +- .../report/ReactionList/HeaderReactionList.js | 2 +- src/pages/home/report/ReportActionItem.js | 2 +- .../home/report/ReportActionItemCreated.js | 2 +- .../report/ReportActionItemParentAction.js | 2 +- .../home/report/ReportActionItemSingle.js | 2 +- src/pages/home/sidebar/SidebarLinks.js | 2 +- src/pages/signin/SignInHeroCopy.js | 2 +- src/pages/signin/SignInPage.js | 2 +- src/pages/signin/SignInPageHero.js | 2 +- src/pages/signin/SignInPageLayout/Footer.js | 2 +- .../SignInPageLayout/SignInPageContent.js | 2 +- src/pages/signin/SignInPageLayout/index.js | 2 +- .../ValidateCodeForm/BaseValidateCodeForm.js | 2 +- src/styles/StyleUtilsContext.ts | 6 ------ src/styles/StyleUtilsProvider.tsx | 20 ------------------- src/styles/{ => utils}/StyleUtils.ts | 16 +++++++-------- src/styles/utils/ThemeStyleUtils.ts | 2 +- 68 files changed, 73 insertions(+), 99 deletions(-) delete mode 100644 src/styles/StyleUtilsContext.ts delete mode 100644 src/styles/StyleUtilsProvider.tsx rename src/styles/{ => utils}/StyleUtils.ts (98%) diff --git a/src/components/AttachmentModal.js b/src/components/AttachmentModal.js index 859fabcd885d..6d57001d810e 100755 --- a/src/components/AttachmentModal.js +++ b/src/components/AttachmentModal.js @@ -19,9 +19,9 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import useNativeDriver from '@libs/useNativeDriver'; import reportPropTypes from '@pages/reportPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx index 07a437bf9c29..3fe0072eea28 100644 --- a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx +++ b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx @@ -5,9 +5,9 @@ import {View} from 'react-native'; import {ScrollView} from 'react-native-gesture-handler'; import Animated, {Easing, FadeOutDown, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import viewForwardedRef from '@src/types/utils/viewForwardedRef'; import type {AutoCompleteSuggestionsProps, RenderSuggestionMenuItemProps} from './types'; diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 7bb06f486c2f..c3fa36f4d169 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -3,10 +3,10 @@ import {StyleProp, View, ViewStyle} from 'react-native'; import useNetwork from '@hooks/useNetwork'; import * as ReportUtils from '@libs/ReportUtils'; import {AvatarSource} from '@libs/UserUtils'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import type {AvatarSizeName} from '@styles/utils/types'; import CONST from '@src/CONST'; import {AvatarType} from '@src/types/onyx/OnyxCommon'; diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index 01a9c4b07334..ba8a1819a350 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -5,9 +5,9 @@ import {ValueOf} from 'type-fest'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; diff --git a/src/components/BaseMiniContextMenuItem.js b/src/components/BaseMiniContextMenuItem.js index e36e2981ac18..3d67ef7bd393 100644 --- a/src/components/BaseMiniContextMenuItem.js +++ b/src/components/BaseMiniContextMenuItem.js @@ -5,9 +5,9 @@ import _ from 'underscore'; import DomUtils from '@libs/DomUtils'; import getButtonState from '@libs/getButtonState'; import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Tooltip from './Tooltip/PopoverAnchorTooltip'; diff --git a/src/components/ButtonWithDropdownMenu.js b/src/components/ButtonWithDropdownMenu.js index 369ae0905cf7..de5f2edc5b9d 100644 --- a/src/components/ButtonWithDropdownMenu.js +++ b/src/components/ButtonWithDropdownMenu.js @@ -3,9 +3,9 @@ import React, {useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import Button from './Button'; import Icon from './Icon'; diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index d292f9c8c71a..8cb5d1b13e5b 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -1,9 +1,9 @@ import React, {ForwardedRef, forwardRef, KeyboardEvent as ReactKeyboardEvent} from 'react'; import {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ChildrenProps from '@src/types/utils/ChildrenProps'; import Icon from './Icon'; diff --git a/src/components/EReceipt.js b/src/components/EReceipt.js index 4aa3169f56e3..3007e27bded7 100644 --- a/src/components/EReceipt.js +++ b/src/components/EReceipt.js @@ -6,8 +6,8 @@ import useLocalize from '@hooks/useLocalize'; import * as CardUtils from '@libs/CardUtils'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/components/EReceiptThumbnail.js b/src/components/EReceiptThumbnail.js index cfaf086d8cde..6137a3a8dc36 100644 --- a/src/components/EReceiptThumbnail.js +++ b/src/components/EReceiptThumbnail.js @@ -3,8 +3,8 @@ import React, {useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import * as ReportUtils from '@libs/ReportUtils'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/components/EmojiPicker/EmojiPicker.js b/src/components/EmojiPicker/EmojiPicker.js index c1f95ff1879d..265ae1f5b872 100644 --- a/src/components/EmojiPicker/EmojiPicker.js +++ b/src/components/EmojiPicker/EmojiPicker.js @@ -6,8 +6,8 @@ import PopoverWithMeasuredContent from '@components/PopoverWithMeasuredContent'; import withViewportOffsetTop from '@components/withViewportOffsetTop'; import useWindowDimensions from '@hooks/useWindowDimensions'; import calculateAnchorPosition from '@libs/calculateAnchorPosition'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import EmojiPickerMenu from './EmojiPickerMenu'; diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index af9afb366e47..2ec7ce31d9d1 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -17,8 +17,8 @@ import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; import isEnterWhileComposition from '@libs/KeyboardShortcut/isEnterWhileComposition'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index f4bb8d40f0fc..6f6fd1283f02 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -15,8 +15,8 @@ import useSingleExecution from '@hooks/useSingleExecution'; import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/components/ExpensifyWordmark.tsx b/src/components/ExpensifyWordmark.tsx index 2abec86584ee..1de6bcc01386 100644 --- a/src/components/ExpensifyWordmark.tsx +++ b/src/components/ExpensifyWordmark.tsx @@ -5,9 +5,9 @@ import DevLogo from '@assets/images/expensify-logo--dev.svg'; import StagingLogo from '@assets/images/expensify-logo--staging.svg'; import ProductionLogo from '@assets/images/expensify-wordmark.svg'; import useEnvironment from '@hooks/useEnvironment'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import withWindowDimensions from './withWindowDimensions'; diff --git a/src/components/FloatingActionButton.js b/src/components/FloatingActionButton.js index b0b6ac23aed1..fe26f63d0b75 100644 --- a/src/components/FloatingActionButton.js +++ b/src/components/FloatingActionButton.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import {Animated, Easing, View} from 'react-native'; import compose from '@libs/compose'; -import StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import PressableWithFeedback from './Pressable/PressableWithFeedback'; diff --git a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js index 93bf14c54980..1a16f1f146fe 100644 --- a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js +++ b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js @@ -1,8 +1,8 @@ import React from 'react'; import {Animated} from 'react-native'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import growlNotificationContainerPropTypes from './growlNotificationContainerPropTypes'; const propTypes = { diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js index ea1d4d13c7dd..65acffb0e87b 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js @@ -3,7 +3,7 @@ import {splitBoxModelStyle} from 'react-native-render-html'; import _ from 'underscore'; import * as HTMLEngineUtils from '@components/HTMLEngineProvider/htmlEngineUtils'; import InlineCodeBlock from '@components/InlineCodeBlock'; -import StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import htmlRendererPropTypes from './htmlRendererPropTypes'; function CodeRenderer(props) { diff --git a/src/components/HeaderPageLayout.js b/src/components/HeaderPageLayout.js index 755cf066eaa6..0c621df2bb51 100644 --- a/src/components/HeaderPageLayout.js +++ b/src/components/HeaderPageLayout.js @@ -5,9 +5,9 @@ import _ from 'underscore'; import useNetwork from '@hooks/useNetwork'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import FixedFooter from './FixedFooter'; import HeaderWithBackButton from './HeaderWithBackButton'; import headerWithBackButtonPropTypes from './HeaderWithBackButton/headerWithBackButtonPropTypes'; diff --git a/src/components/HeaderWithBackButton/index.js b/src/components/HeaderWithBackButton/index.js index 24fc926dd49f..4d93839ce11c 100755 --- a/src/components/HeaderWithBackButton/index.js +++ b/src/components/HeaderWithBackButton/index.js @@ -14,9 +14,9 @@ import useThrottledButtonState from '@hooks/useThrottledButtonState'; import useWaitForNavigation from '@hooks/useWaitForNavigation'; import getButtonState from '@libs/getButtonState'; import Navigation from '@libs/Navigation/Navigation'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import headerWithBackButtonPropTypes from './headerWithBackButtonPropTypes'; diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 5a9eaae1e864..9b2df9e67d20 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -2,7 +2,7 @@ import React, {PureComponent} from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; import withTheme, {WithThemeProps} from '@components/withTheme'; import withThemeStyles, {type WithThemeStylesProps} from '@components/withThemeStyles'; -import StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import IconWrapperStyles from './IconWrapperStyles'; diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 7d3ee98cd9db..116975c64e4f 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -5,9 +5,9 @@ import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import Image from '@components/Image'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { diff --git a/src/components/LHNOptionsList/OptionRowLHN.js b/src/components/LHNOptionsList/OptionRowLHN.js index 92be2d7bcfae..1828c6013352 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.js +++ b/src/components/LHNOptionsList/OptionRowLHN.js @@ -25,9 +25,9 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as ContextMenuActions from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import * as optionRowStyles from '@styles/optionRowStyles'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { diff --git a/src/components/MapView/MapView.web.tsx b/src/components/MapView/MapView.web.tsx index e02b9769e158..09877526de55 100644 --- a/src/components/MapView/MapView.web.tsx +++ b/src/components/MapView/MapView.web.tsx @@ -9,9 +9,9 @@ import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useState import Map, {MapRef, Marker} from 'react-map-gl'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import setUserLocation from '@userActions/UserLocation'; import CONST from '@src/CONST'; import useLocalize from '@src/hooks/useLocalize'; diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index caab8a5ff5cd..1e5f41f34aa5 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -7,10 +7,10 @@ import ControlSelection from '@libs/ControlSelection'; import convertToLTR from '@libs/convertToLTR'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import getButtonState from '@libs/getButtonState'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; diff --git a/src/components/MessagesRow.js b/src/components/MessagesRow.js index 45adb16a0f6f..a63ecf768e3d 100644 --- a/src/components/MessagesRow.js +++ b/src/components/MessagesRow.js @@ -4,8 +4,8 @@ import {View} from 'react-native'; import _ from 'underscore'; import useLocalize from '@hooks/useLocalize'; import stylePropTypes from '@styles/stylePropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import DotIndicatorMessage from './DotIndicatorMessage'; import Icon from './Icon'; diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index b9318a77b413..520559d1fbb3 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -8,9 +8,9 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; import ComposerFocusManager from '@libs/ComposerFocusManager'; import useNativeDriver from '@libs/useNativeDriver'; import getModalStyles from '@styles/getModalStyles'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as Modal from '@userActions/Modal'; import CONST from '@src/CONST'; diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index d76ede294d72..97aacab1a58e 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -2,10 +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 StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import type {Icon} from '@src/types/onyx/OnyxCommon'; diff --git a/src/components/OfflineWithFeedback.js b/src/components/OfflineWithFeedback.js index 62987ab8507e..c8372b4d9705 100644 --- a/src/components/OfflineWithFeedback.js +++ b/src/components/OfflineWithFeedback.js @@ -5,8 +5,8 @@ import _ from 'underscore'; import useNetwork from '@hooks/useNetwork'; import shouldRenderOffscreen from '@libs/shouldRenderOffscreen'; import stylePropTypes from '@styles/stylePropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import MessagesRow from './MessagesRow'; diff --git a/src/components/OptionRow.js b/src/components/OptionRow.js index 675e87ed49b0..10ef08eff316 100644 --- a/src/components/OptionRow.js +++ b/src/components/OptionRow.js @@ -5,9 +5,9 @@ import {InteractionManager, StyleSheet, View} from 'react-native'; import _ from 'underscore'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import Button from './Button'; import DisplayNames from './DisplayNames'; diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index 649dae749ef1..063094af2f21 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -10,7 +10,7 @@ import withLocalize from '@components/withLocalize'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; import withWindowDimensions from '@components/withWindowDimensions'; import compose from '@libs/compose'; -import StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import PDFPasswordForm from './PDFPasswordForm'; import {defaultProps, propTypes as pdfViewPropTypes} from './pdfViewPropTypes'; diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 6a5bbd9582c5..89406f832a00 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -6,9 +6,9 @@ import {PopoverContext} from '@components/PopoverProvider'; import withWindowDimensions from '@components/withWindowDimensions'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; import getModalStyles from '@styles/getModalStyles'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as Modal from '@userActions/Modal'; function Popover(props) { diff --git a/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx b/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx index f7d518852a45..a9f37c8cd8c5 100644 --- a/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx +++ b/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx @@ -5,8 +5,8 @@ import useSingleExecution from '@hooks/useSingleExecution'; import Accessibility from '@libs/Accessibility'; import HapticFeedback from '@libs/HapticFeedback'; import KeyboardShortcut from '@libs/KeyboardShortcut'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import PressableProps, {PressableRef} from './types'; diff --git a/src/components/PressableWithSecondaryInteraction/index.tsx b/src/components/PressableWithSecondaryInteraction/index.tsx index 928f96d2ec3a..2f0c30c11718 100644 --- a/src/components/PressableWithSecondaryInteraction/index.tsx +++ b/src/components/PressableWithSecondaryInteraction/index.tsx @@ -3,8 +3,8 @@ import {GestureResponderEvent} from 'react-native'; import {PressableRef} from '@components/Pressable/GenericPressable/types'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import PressableWithSecondaryInteractionProps from './types'; /** This is a special Pressable that calls onSecondaryInteraction when LongPressed, or right-clicked. */ diff --git a/src/components/Reactions/AddReactionBubble.js b/src/components/Reactions/AddReactionBubble.js index 5a2e0cec24f2..b93953a9d1ae 100644 --- a/src/components/Reactions/AddReactionBubble.js +++ b/src/components/Reactions/AddReactionBubble.js @@ -8,9 +8,9 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip/PopoverAnchorTooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import getButtonState from '@libs/getButtonState'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as Session from '@userActions/Session'; diff --git a/src/components/Reactions/EmojiReactionBubble.js b/src/components/Reactions/EmojiReactionBubble.js index e0dbcf25b9fb..0c8877c62f94 100644 --- a/src/components/Reactions/EmojiReactionBubble.js +++ b/src/components/Reactions/EmojiReactionBubble.js @@ -4,9 +4,9 @@ import PressableWithSecondaryInteraction from '@components/PressableWithSecondar import Text from '@components/Text'; import {withCurrentUserPersonalDetailsDefaultProps} from '@components/withCurrentUserPersonalDetails'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { diff --git a/src/components/ReportActionItem/MoneyReportView.js b/src/components/ReportActionItem/MoneyReportView.js index b24beb9ff9c1..ef0a1a3d9bef 100644 --- a/src/components/ReportActionItem/MoneyReportView.js +++ b/src/components/ReportActionItem/MoneyReportView.js @@ -11,9 +11,9 @@ import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import reportPropTypes from '@pages/reportPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; const propTypes = { diff --git a/src/components/ReportActionItem/MoneyRequestPreview.js b/src/components/ReportActionItem/MoneyRequestPreview.js index e537233bfd43..82d792443b97 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.js +++ b/src/components/ReportActionItem/MoneyRequestPreview.js @@ -28,9 +28,9 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import walletTermsPropTypes from '@pages/EnablePayments/walletTermsPropTypes'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as PaymentMethods from '@userActions/PaymentMethods'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index d0b7cbbdfcb6..eea08ab2c440 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -31,9 +31,9 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import iouReportPropTypes from '@pages/iouReportPropTypes'; import reportPropTypes from '@pages/reportPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/components/ReportActionItem/ReportActionItemImages.js b/src/components/ReportActionItem/ReportActionItemImages.js index e4ddf571976d..aef442013baa 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.js +++ b/src/components/ReportActionItem/ReportActionItemImages.js @@ -5,9 +5,9 @@ import {Polygon, Svg} from 'react-native-svg'; import _ from 'underscore'; import Text from '@components/Text'; import transactionPropTypes from '@components/transactionPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import ReportActionItemImage from './ReportActionItemImage'; diff --git a/src/components/RoomHeaderAvatars.js b/src/components/RoomHeaderAvatars.js index c1b980824885..6e82758f96fa 100644 --- a/src/components/RoomHeaderAvatars.js +++ b/src/components/RoomHeaderAvatars.js @@ -3,10 +3,10 @@ import React, {memo} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import * as UserUtils from '@libs/UserUtils'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import AttachmentModal from './AttachmentModal'; import Avatar from './Avatar'; diff --git a/src/components/SafeAreaConsumer/index.android.tsx b/src/components/SafeAreaConsumer/index.android.tsx index afd81dc65ac5..95a3b309d5e7 100644 --- a/src/components/SafeAreaConsumer/index.android.tsx +++ b/src/components/SafeAreaConsumer/index.android.tsx @@ -2,7 +2,7 @@ import React from 'react'; // eslint-disable-next-line no-restricted-imports import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; import StatusBar from '@libs/StatusBar'; -import StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import SafeAreaConsumerProps from './types'; /** diff --git a/src/components/SafeAreaConsumer/index.tsx b/src/components/SafeAreaConsumer/index.tsx index adc372aa42d5..f52509cc738c 100644 --- a/src/components/SafeAreaConsumer/index.tsx +++ b/src/components/SafeAreaConsumer/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; // eslint-disable-next-line no-restricted-imports import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; -import StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import SafeAreaConsumerProps from './types'; /** diff --git a/src/components/SelectionList/BaseListItem.js b/src/components/SelectionList/BaseListItem.js index 20c05b88d49f..ab16f9638dda 100644 --- a/src/components/SelectionList/BaseListItem.js +++ b/src/components/SelectionList/BaseListItem.js @@ -7,10 +7,10 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import RadioListItem from './RadioListItem'; import {baseListItemPropTypes} from './selectionListPropTypes'; diff --git a/src/components/SpacerView.js b/src/components/SpacerView.js index f18ccb0a41f1..d8336ae8aad5 100644 --- a/src/components/SpacerView.js +++ b/src/components/SpacerView.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import stylePropTypes from '@styles/stylePropTypes'; -import StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { diff --git a/src/components/SubscriptAvatar.tsx b/src/components/SubscriptAvatar.tsx index f19f67c2fd08..0c73d63b672a 100644 --- a/src/components/SubscriptAvatar.tsx +++ b/src/components/SubscriptAvatar.tsx @@ -2,10 +2,10 @@ import React, {memo} from 'react'; import {View} from 'react-native'; import {ValueOf} from 'type-fest'; import type {AvatarSource} from '@libs/UserUtils'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import {AvatarType} from '@src/types/onyx/OnyxCommon'; import Avatar from './Avatar'; diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index a9684ae71dd6..57cfd975ea3c 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -6,8 +6,8 @@ import OptionsSelector from '@components/OptionsSelector'; import useLocalize from '@hooks/useLocalize'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import {defaultProps, propTypes} from './tagPickerPropTypes'; diff --git a/src/components/TextInput/BaseTextInput/index.js b/src/components/TextInput/BaseTextInput/index.js index f47bfbcc5936..134500a1ea59 100644 --- a/src/components/TextInput/BaseTextInput/index.js +++ b/src/components/TextInput/BaseTextInput/index.js @@ -16,10 +16,10 @@ import withLocalize from '@components/withLocalize'; import * as Browser from '@libs/Browser'; import isInputAutoFilled from '@libs/isInputAutoFilled'; import useNativeDriver from '@libs/useNativeDriver'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import * as baseTextInputPropTypes from './baseTextInputPropTypes'; diff --git a/src/components/TextInput/BaseTextInput/index.native.js b/src/components/TextInput/BaseTextInput/index.native.js index a862eec3145b..375ca0f4ee35 100644 --- a/src/components/TextInput/BaseTextInput/index.native.js +++ b/src/components/TextInput/BaseTextInput/index.native.js @@ -16,9 +16,9 @@ import withLocalize from '@components/withLocalize'; import getSecureEntryKeyboardType from '@libs/getSecureEntryKeyboardType'; import isInputAutoFilled from '@libs/isInputAutoFilled'; import useNativeDriver from '@libs/useNativeDriver'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import * as baseTextInputPropTypes from './baseTextInputPropTypes'; diff --git a/src/components/ThumbnailImage.tsx b/src/components/ThumbnailImage.tsx index 5f9db7b4464e..7f4157893c8d 100644 --- a/src/components/ThumbnailImage.tsx +++ b/src/components/ThumbnailImage.tsx @@ -3,8 +3,8 @@ import React, {useCallback, useState} from 'react'; import {Dimensions, StyleProp, View, ViewStyle} from 'react-native'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import ImageWithSizeCalculation from './ImageWithSizeCalculation'; type ThumbnailImageProps = { diff --git a/src/components/ValuePicker/index.js b/src/components/ValuePicker/index.js index 09b74d50f59e..03d61fe26de8 100644 --- a/src/components/ValuePicker/index.js +++ b/src/components/ValuePicker/index.js @@ -5,8 +5,8 @@ import {View} from 'react-native'; import FormHelpMessage from '@components/FormHelpMessage'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import refPropTypes from '@components/refPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import ValueSelectorModal from './ValueSelectorModal'; diff --git a/src/pages/home/report/AnimatedEmptyStateBackground.js b/src/pages/home/report/AnimatedEmptyStateBackground.js index e7fd7708f386..a1bb3c038a2c 100644 --- a/src/pages/home/report/AnimatedEmptyStateBackground.js +++ b/src/pages/home/report/AnimatedEmptyStateBackground.js @@ -3,7 +3,7 @@ import Animated, {SensorType, useAnimatedSensor, useAnimatedStyle, useSharedValu import useWindowDimensions from '@hooks/useWindowDimensions'; import * as NumberUtils from '@libs/NumberUtils'; import useThemeIllustrations from '@styles/illustrations/useThemeIllustrations'; -import StyleUtils from '@styles/StyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; diff --git a/src/pages/home/report/LinkPreviewer.js b/src/pages/home/report/LinkPreviewer.js index b6b132c41468..e268301a3413 100644 --- a/src/pages/home/report/LinkPreviewer.js +++ b/src/pages/home/report/LinkPreviewer.js @@ -5,9 +5,9 @@ import {Image, View} from 'react-native'; import _ from 'underscore'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; const IMAGE_TYPES = ['jpg', 'jpeg', 'png']; diff --git a/src/pages/home/report/ReactionList/HeaderReactionList.js b/src/pages/home/report/ReactionList/HeaderReactionList.js index b83c3104316f..970eb456b550 100644 --- a/src/pages/home/report/ReactionList/HeaderReactionList.js +++ b/src/pages/home/report/ReactionList/HeaderReactionList.js @@ -6,9 +6,9 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import reactionPropTypes from './reactionPropTypes'; const propTypes = { diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 99bbe32f11a8..777d43ce8d8b 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -46,10 +46,10 @@ import SelectionScraper from '@libs/SelectionScraper'; import userWalletPropTypes from '@pages/EnablePayments/userWalletPropTypes'; import {ReactionListContext} from '@pages/home/ReportScreenContext'; import reportPropTypes from '@pages/reportPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as BankAccounts from '@userActions/BankAccounts'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as store from '@userActions/ReimbursementAccount/store'; diff --git a/src/pages/home/report/ReportActionItemCreated.js b/src/pages/home/report/ReportActionItemCreated.js index 86d3a5d24436..3fd4ea76beee 100644 --- a/src/pages/home/report/ReportActionItemCreated.js +++ b/src/pages/home/report/ReportActionItemCreated.js @@ -14,8 +14,8 @@ import compose from '@libs/compose'; import reportWithoutHasDraftSelector from '@libs/OnyxSelectors/reportWithoutHasDraftSelector'; import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/pages/home/report/ReportActionItemParentAction.js b/src/pages/home/report/ReportActionItemParentAction.js index a58c2b283933..96311024a367 100644 --- a/src/pages/home/report/ReportActionItemParentAction.js +++ b/src/pages/home/report/ReportActionItemParentAction.js @@ -9,8 +9,8 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withW import compose from '@libs/compose'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import reportPropTypes from '@pages/reportPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as Report from '@userActions/Report'; import ONYXKEYS from '@src/ONYXKEYS'; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 29c487c08458..6264de4ca231 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -20,9 +20,9 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as UserUtils from '@libs/UserUtils'; import reportPropTypes from '@pages/reportPropTypes'; import stylePropTypes from '@styles/stylePropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import ReportActionItemDate from './ReportActionItemDate'; diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 3b982e5102b2..446a0c9efb14 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -19,9 +19,9 @@ import onyxSubscribe from '@libs/onyxSubscribe'; import SidebarUtils from '@libs/SidebarUtils'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import safeAreaInsetPropTypes from '@pages/safeAreaInsetPropTypes'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as App from '@userActions/App'; import * as Session from '@userActions/Session'; diff --git a/src/pages/signin/SignInHeroCopy.js b/src/pages/signin/SignInHeroCopy.js index d6c633d6fcd9..172cf086c8b3 100644 --- a/src/pages/signin/SignInHeroCopy.js +++ b/src/pages/signin/SignInHeroCopy.js @@ -5,8 +5,8 @@ import Text from '@components/Text'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import compose from '@libs/compose'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; const propTypes = { diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index b8938a533309..69082b39b12a 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -14,10 +14,10 @@ import * as Localize from '@libs/Localize'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import Performance from '@libs/Performance'; -import StyleUtils from '@styles/StyleUtils'; import ThemeProvider from '@styles/themes/ThemeProvider'; import ThemeStylesProvider from '@styles/ThemeStylesProvider'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as App from '@userActions/App'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; diff --git a/src/pages/signin/SignInPageHero.js b/src/pages/signin/SignInPageHero.js index eef8066e05fc..2023d715545c 100644 --- a/src/pages/signin/SignInPageHero.js +++ b/src/pages/signin/SignInPageHero.js @@ -2,8 +2,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import SignInHeroCopy from './SignInHeroCopy'; import SignInHeroImage from './SignInHeroImage'; diff --git a/src/pages/signin/SignInPageLayout/Footer.js b/src/pages/signin/SignInPageLayout/Footer.js index 2a35a4c318d0..1a22d6fdf80f 100644 --- a/src/pages/signin/SignInPageLayout/Footer.js +++ b/src/pages/signin/SignInPageLayout/Footer.js @@ -10,9 +10,9 @@ import TextLink from '@components/TextLink'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import Licenses from '@pages/signin/Licenses'; import Socials from '@pages/signin/Socials'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; diff --git a/src/pages/signin/SignInPageLayout/SignInPageContent.js b/src/pages/signin/SignInPageLayout/SignInPageContent.js index 477f41bfdbd7..26dca0b6c1a3 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageContent.js +++ b/src/pages/signin/SignInPageLayout/SignInPageContent.js @@ -10,8 +10,8 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import SignInHeroImage from '@pages/signin/SignInHeroImage'; -import StyleUtils from '@styles/StyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; const propTypes = { diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index 430b365b65c1..bd8448671f9d 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -8,9 +8,9 @@ import usePrevious from '@hooks/usePrevious'; import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import SignInPageHero from '@pages/signin/SignInPageHero'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import BackgroundImage from './BackgroundImage'; import Footer from './Footer'; diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js index bc891b855c90..6b57d8fa2388 100755 --- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js @@ -20,9 +20,9 @@ import * as ErrorUtils from '@libs/ErrorUtils'; import * as ValidationUtils from '@libs/ValidationUtils'; import ChangeExpensifyLoginLink from '@pages/signin/ChangeExpensifyLoginLink'; import Terms from '@pages/signin/Terms'; -import StyleUtils from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; +import StyleUtils from '@styles/utils/StyleUtils'; import * as Session from '@userActions/Session'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; diff --git a/src/styles/StyleUtilsContext.ts b/src/styles/StyleUtilsContext.ts deleted file mode 100644 index a9eea3da38de..000000000000 --- a/src/styles/StyleUtilsContext.ts +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import {StyleUtilsWithoutThemeParameters} from './StyleUtils'; - -const StyleUtilsContext = React.createContext(undefined); - -export default StyleUtilsContext; diff --git a/src/styles/StyleUtilsProvider.tsx b/src/styles/StyleUtilsProvider.tsx deleted file mode 100644 index e8ec8ccb2755..000000000000 --- a/src/styles/StyleUtilsProvider.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React, {useMemo} from 'react'; -import {createStyleUtilsWithoutThemeParameters} from './StyleUtils'; -import StyleUtilsContext from './StyleUtilsContext'; -import useTheme from './themes/useTheme'; -import useThemeStyles from './useThemeStyles'; - -type ThemeStylesProviderProps = React.PropsWithChildren; - -function ThemeStylesProvider({children}: ThemeStylesProviderProps) { - const theme = useTheme(); - const styles = useThemeStyles(); - - const StyleUtils = useMemo(() => createStyleUtilsWithoutThemeParameters(theme, styles), [theme, styles]); - - return {children}; -} - -ThemeStylesProvider.displayName = 'ThemeStylesProvider'; - -export default ThemeStylesProvider; diff --git a/src/styles/StyleUtils.ts b/src/styles/utils/StyleUtils.ts similarity index 98% rename from src/styles/StyleUtils.ts rename to src/styles/utils/StyleUtils.ts index e567aa1b32cd..fa7254de90b8 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/utils/StyleUtils.ts @@ -4,16 +4,16 @@ import {EdgeInsets} from 'react-native-safe-area-context'; import {ValueOf} from 'type-fest'; import * as Browser from '@libs/Browser'; import * as UserUtils from '@libs/UserUtils'; +import colors from '@styles/colors'; +import fontFamily from '@styles/fontFamily'; +import {ThemeColors} from '@styles/themes/types'; +import positioning from '@styles/utilities/positioning'; +import spacing from '@styles/utilities/spacing'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import {Transaction} from '@src/types/onyx'; -import colors from './colors'; -import fontFamily from './fontFamily'; -import {ThemeColors} from './themes/types'; -import positioning from './utilities/positioning'; -import spacing from './utilities/spacing'; -import {hexadecimalToRGBArray} from './utils/functions'; -import {AllStyles, AvatarSize, AvatarSizeName, AvatarSizeValue, ButtonSizeValue, EReceiptColorName, EreceiptColorStyle, ParsableStyle, WorkspaceColorStyle} from './utils/types'; -import variables from './variables'; +import {hexadecimalToRGBArray} from './functions'; +import {AllStyles, AvatarSize, AvatarSizeName, AvatarSizeValue, ButtonSizeValue, EReceiptColorName, EreceiptColorStyle, ParsableStyle, WorkspaceColorStyle} from './types'; const workspaceColorOptions: WorkspaceColorStyle[] = [ {backgroundColor: colors.blue200, fill: colors.blue700}, diff --git a/src/styles/utils/ThemeStyleUtils.ts b/src/styles/utils/ThemeStyleUtils.ts index 8f157f973611..53da23250b85 100644 --- a/src/styles/utils/ThemeStyleUtils.ts +++ b/src/styles/utils/ThemeStyleUtils.ts @@ -1,12 +1,12 @@ import {StyleProp, TextStyle, ViewStyle} from 'react-native'; import {type ThemeStyles} from '@styles/styles'; -import StyleUtils from '@styles/StyleUtils'; import {type ThemeColors} from '@styles/themes/types'; import cursor from '@styles/utilities/cursor'; import positioning from '@styles/utilities/positioning'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import {hexadecimalToRGBArray} from './functions'; +import StyleUtils from './StyleUtils'; import {AvatarSizeName, AvatarStyle, ButtonStateName} from './types'; /** From a5edd5a57041aee4e26aaf099afd412b193a781e Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 18:54:19 +0100 Subject: [PATCH 07/39] fix: eslint errros --- contributingGuides/TS_STYLE.md | 38 ++++++------------- src/components/Banner.tsx | 1 - src/components/EmojiSuggestions.tsx | 2 - src/components/MentionSuggestions.tsx | 14 ++++++- .../Pressable/PressableWithDelayToggle.tsx | 2 - src/styles/useStyleUtils.ts | 8 ++-- 6 files changed, 28 insertions(+), 37 deletions(-) diff --git a/contributingGuides/TS_STYLE.md b/contributingGuides/TS_STYLE.md index bc62020ffd54..e2a8b928349d 100644 --- a/contributingGuides/TS_STYLE.md +++ b/contributingGuides/TS_STYLE.md @@ -2,32 +2,16 @@ ## Table of Contents -- [Other Expensify Resources on TypeScript](#other-expensify-resources-on-typescript) -- [General Rules](#general-rules) -- [Guidelines](#guidelines) - - [1.1 Naming Conventions](#naming-conventions) - - [1.2 `d.ts` Extension](#d-ts-extension) - - [1.3 Type Alias vs. Interface](#type-alias-vs-interface) - - [1.4 Enum vs. Union Type](#enum-vs-union-type) - - [1.5 `unknown` vs. `any`](#unknown-vs-any) - - [1.6 `T[]` vs. `Array`](#array) - - [1.7 @ts-ignore](#ts-ignore) - - [1.8 Optional chaining and nullish coalescing](#ts-nullish-coalescing) - - [1.9 Type Inference](#type-inference) - - [1.10 JSDoc](#jsdoc) - - [1.11 `propTypes` and `defaultProps`](#proptypes-and-defaultprops) - - [1.12 Utility Types](#utility-types) - - [1.13 `object` Type](#object-type) - - [1.14 Export Prop Types](#export-prop-types) - - [1.15 File Organization](#file-organization) - - [1.16 Reusable Types](#reusable-types) - - [1.17 `.tsx`](#tsx) - - [1.18 No inline prop types](#no-inline-prop-types) - - [1.19 Satisfies operator](#satisfies-operator) -- [Exception to Rules](#exception-to-rules) -- [Communication Items](#communication-items) -- [Migration Guidelines](#migration-guidelines) -- [Learning Resources](#learning-resources) +- [Expensify TypeScript Style Guide](#expensify-typescript-style-guide) + - [Table of Contents](#table-of-contents) + - [Other Expensify Resources on TypeScript](#other-expensify-resources-on-typescript) + - [General Rules](#general-rules) + - [Guidelines](#guidelines) + - [Exception to Rules](#exception-to-rules) + - [Communication Items](#communication-items) + - [Migration Guidelines](#migration-guidelines) + - [Learning Resources](#learning-resources) + - [Quickest way to learn TypeScript](#quickest-way-to-learn-typescript) ## Other Expensify Resources on TypeScript @@ -381,7 +365,7 @@ type Foo = { -- [1.15](#file-organization) **File organization**: In modules with platform-specific implementations, create `types.ts` to define shared types. Import and use shared types in each platform specific files. Do not use [`satisfies` operator](#satisfies-operator) for platform-specific implementations, always define shared types that complies with all variants. +- [1.15](#file-organization) **File organization**: In modules with platform-specific implementations, create `types.ts` to define shared types. Import and use shared types in each platform specific files. Do not use [`satisfies` operator](#satisfies-operator) for platform-specific implementations, always define shared types that complies with all variants. > Why? To encourage consistent API across platform-specific implementations. If you're migrating module that doesn't have a default implement (i.e. `index.ts`, e.g. `getPlatform`), refer to [Migration Guidelines](#migration-guidelines) for further information. diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx index f79c07f70c5b..801d46a11a22 100644 --- a/src/components/Banner.tsx +++ b/src/components/Banner.tsx @@ -2,7 +2,6 @@ import React, {memo} from 'react'; import {StyleProp, TextStyle, View, ViewStyle} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import getButtonState from '@libs/getButtonState'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; diff --git a/src/components/EmojiSuggestions.tsx b/src/components/EmojiSuggestions.tsx index 5ddcb6b6a947..e0ecba30fa0d 100644 --- a/src/components/EmojiSuggestions.tsx +++ b/src/components/EmojiSuggestions.tsx @@ -3,7 +3,6 @@ import {View} from 'react-native'; import type {SimpleEmoji} from '@libs/EmojiTrie'; import * as EmojiUtils from '@libs/EmojiUtils'; import getStyledTextArray from '@libs/GetStyledTextArray'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; @@ -43,7 +42,6 @@ type EmojiSuggestionsProps = { const keyExtractor = (item: SimpleEmoji, index: number): string => `${item.name}+${index}}`; function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferredSkinToneIndex, highlightedEmojiIndex = 0, measureParentContainer = () => {}}: EmojiSuggestionsProps) { - const theme = useTheme(); const styles = useThemeStyles(); const ThemeStyleUtils = useThemeStyleUtils(); /** diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index 1c5ed2999371..5372b278ef2c 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -110,7 +110,19 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe ); }, - [styles, theme, prefix], + [ + prefix, + styles.autoCompleteSuggestionContainer, + styles.ph2, + styles.mentionSuggestionsAvatarContainer, + styles.mentionSuggestionsText, + styles.flexShrink1, + styles.flex1, + styles.mentionSuggestionsDisplayName, + styles.mentionSuggestionsHandle, + theme.success, + ThemeStyleUtils, + ], ); return ( diff --git a/src/components/Pressable/PressableWithDelayToggle.tsx b/src/components/Pressable/PressableWithDelayToggle.tsx index 7d740cd43620..99cb70212738 100644 --- a/src/components/Pressable/PressableWithDelayToggle.tsx +++ b/src/components/Pressable/PressableWithDelayToggle.tsx @@ -8,7 +8,6 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; import useThrottledButtonState from '@hooks/useThrottledButtonState'; import getButtonState from '@libs/getButtonState'; -import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; @@ -67,7 +66,6 @@ function PressableWithDelayToggle( }: PressableWithDelayToggleProps, ref: PressableRef, ) { - const theme = useTheme(); const styles = useThemeStyles(); const ThemeStyleUtils = useThemeStyleUtils(); const [isActive, temporarilyDisableInteractions] = useThrottledButtonState(); diff --git a/src/styles/useStyleUtils.ts b/src/styles/useStyleUtils.ts index 6b14e59cd605..d4b5bd8cd3f7 100644 --- a/src/styles/useStyleUtils.ts +++ b/src/styles/useStyleUtils.ts @@ -1,14 +1,14 @@ import {useContext} from 'react'; -import StyleUtilsContext from './StyleUtilsContext'; +import ThemeStylesContext from './ThemeStylesContext'; function useStyleUtils() { - const styleUtils = useContext(StyleUtilsContext); + const themeStyleContext = useContext(ThemeStylesContext); - if (!styleUtils) { + if (!themeStyleContext) { throw new Error('ThemeStylesContext was null! Are you sure that you wrapped the component under a ?'); } - return styleUtils; + return themeStyleContext.ThemeStyleUtils; } export default useStyleUtils; From 0c5aa4e1c36f58b5881bd270cb49a88d4f17c47c Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 19:00:03 +0100 Subject: [PATCH 08/39] fix: ts errors --- src/components/AutoCompleteSuggestions/index.tsx | 3 +-- .../CurrentUserPersonalDetailsSkeletonView/index.tsx | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/AutoCompleteSuggestions/index.tsx b/src/components/AutoCompleteSuggestions/index.tsx index 5ae494a08b9a..bdf24d497b65 100644 --- a/src/components/AutoCompleteSuggestions/index.tsx +++ b/src/components/AutoCompleteSuggestions/index.tsx @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'; import {View} from 'react-native'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import BaseAutoCompleteSuggestions from './BaseAutoCompleteSuggestions'; import type {AutoCompleteSuggestionsProps} from './types'; @@ -15,7 +15,6 @@ import type {AutoCompleteSuggestionsProps} from './types'; */ function AutoCompleteSuggestions({measureParentContainer = () => {}, ...props}: AutoCompleteSuggestionsProps) { - const StyleUtils = useThemeStyleUtils(); const containerRef = React.useRef(null); const {windowHeight, windowWidth} = useWindowDimensions(); const [{width, left, bottom}, setContainerState] = React.useState({ diff --git a/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx b/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx index a1755a43ef8a..ca5d7e7de1f3 100644 --- a/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx +++ b/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx @@ -5,7 +5,7 @@ import {ValueOf} from 'type-fest'; import SkeletonViewContentLoader from '@components/SkeletonViewContentLoader'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -26,7 +26,6 @@ type CurrentUserPersonalDetailsSkeletonViewProps = { function CurrentUserPersonalDetailsSkeletonView({shouldAnimate = true, avatarSize = CONST.AVATAR_SIZE.LARGE, backgroundColor, foregroundColor}: CurrentUserPersonalDetailsSkeletonViewProps) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useThemeStyleUtils(); const avatarPlaceholderSize = StyleUtils.getAvatarSize(avatarSize); const avatarPlaceholderRadius = avatarPlaceholderSize / 2; const spaceBetweenAvatarAndHeadline = styles.mb3.marginBottom + styles.mt1.marginTop + (variables.lineHeightXXLarge - variables.fontSizeXLarge) / 2; From ddb2b747039895800517135278b415eccafa073c Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 19:31:13 +0100 Subject: [PATCH 09/39] add default StyleUtils --- src/styles/ThemeStylesContext.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index faed9c969af1..9263f6395d4b 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,5 +1,5 @@ import React from 'react'; -import {ThemeStyles} from './styles'; +import defaultStyles, {ThemeStyles} from './styles'; import {ThemeStyleUtilsType} from './utils/ThemeStyleUtils'; type ThemeStylesContextType = { @@ -7,7 +7,16 @@ type ThemeStylesContextType = { ThemeStyleUtils: ThemeStyleUtilsType; }; -const ThemeStylesContext = React.createContext(undefined); +const defaultThemeStyles = new Proxy( + {}, + { + get() { + return () => undefined; + }, + }, +); + +const ThemeStylesContext = React.createContext({styles: defaultStyles, ThemeStyleUtils: defaultThemeStyles as ThemeStyleUtilsType}); export default ThemeStylesContext; export {type ThemeStylesContextType}; From 97d83f47624e36c356e25033d9bc2afe1c08b92c Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 19:41:59 +0100 Subject: [PATCH 10/39] revert doc updates --- contributingGuides/TS_STYLE.md | 38 ++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/contributingGuides/TS_STYLE.md b/contributingGuides/TS_STYLE.md index e2a8b928349d..bc62020ffd54 100644 --- a/contributingGuides/TS_STYLE.md +++ b/contributingGuides/TS_STYLE.md @@ -2,16 +2,32 @@ ## Table of Contents -- [Expensify TypeScript Style Guide](#expensify-typescript-style-guide) - - [Table of Contents](#table-of-contents) - - [Other Expensify Resources on TypeScript](#other-expensify-resources-on-typescript) - - [General Rules](#general-rules) - - [Guidelines](#guidelines) - - [Exception to Rules](#exception-to-rules) - - [Communication Items](#communication-items) - - [Migration Guidelines](#migration-guidelines) - - [Learning Resources](#learning-resources) - - [Quickest way to learn TypeScript](#quickest-way-to-learn-typescript) +- [Other Expensify Resources on TypeScript](#other-expensify-resources-on-typescript) +- [General Rules](#general-rules) +- [Guidelines](#guidelines) + - [1.1 Naming Conventions](#naming-conventions) + - [1.2 `d.ts` Extension](#d-ts-extension) + - [1.3 Type Alias vs. Interface](#type-alias-vs-interface) + - [1.4 Enum vs. Union Type](#enum-vs-union-type) + - [1.5 `unknown` vs. `any`](#unknown-vs-any) + - [1.6 `T[]` vs. `Array`](#array) + - [1.7 @ts-ignore](#ts-ignore) + - [1.8 Optional chaining and nullish coalescing](#ts-nullish-coalescing) + - [1.9 Type Inference](#type-inference) + - [1.10 JSDoc](#jsdoc) + - [1.11 `propTypes` and `defaultProps`](#proptypes-and-defaultprops) + - [1.12 Utility Types](#utility-types) + - [1.13 `object` Type](#object-type) + - [1.14 Export Prop Types](#export-prop-types) + - [1.15 File Organization](#file-organization) + - [1.16 Reusable Types](#reusable-types) + - [1.17 `.tsx`](#tsx) + - [1.18 No inline prop types](#no-inline-prop-types) + - [1.19 Satisfies operator](#satisfies-operator) +- [Exception to Rules](#exception-to-rules) +- [Communication Items](#communication-items) +- [Migration Guidelines](#migration-guidelines) +- [Learning Resources](#learning-resources) ## Other Expensify Resources on TypeScript @@ -365,7 +381,7 @@ type Foo = { -- [1.15](#file-organization) **File organization**: In modules with platform-specific implementations, create `types.ts` to define shared types. Import and use shared types in each platform specific files. Do not use [`satisfies` operator](#satisfies-operator) for platform-specific implementations, always define shared types that complies with all variants. +- [1.15](#file-organization) **File organization**: In modules with platform-specific implementations, create `types.ts` to define shared types. Import and use shared types in each platform specific files. Do not use [`satisfies` operator](#satisfies-operator) for platform-specific implementations, always define shared types that complies with all variants. > Why? To encourage consistent API across platform-specific implementations. If you're migrating module that doesn't have a default implement (i.e. `index.ts`, e.g. `getPlatform`), refer to [Migration Guidelines](#migration-guidelines) for further information. From 9b3ed5e8d821392b8e2ccedb942b06ef8be56e4b Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 20:08:30 +0100 Subject: [PATCH 11/39] update style utils usage --- .../AddressSearch/CurrentLocationButton.js | 6 +- src/components/AddressSearch/index.js | 8 +- .../BaseAnchorForCommentsOnly.js | 4 +- src/components/AttachmentModal.js | 3 +- .../Attachments/AttachmentView/index.js | 4 +- .../BaseAutoCompleteSuggestions.tsx | 9 +- .../AutoCompleteSuggestions/index.tsx | 3 +- src/components/Avatar.tsx | 11 +- .../AvatarCropModal/AvatarCropModal.js | 4 +- .../AvatarCropModal/ImageCropView.js | 4 +- src/components/AvatarWithDisplayName.tsx | 3 +- src/components/Badge.tsx | 6 +- src/components/Banner.tsx | 6 +- src/components/BaseMiniContextMenuItem.js | 7 +- src/components/ButtonWithDropdownMenu.js | 3 +- src/components/Checkbox.tsx | 7 +- src/components/Composer/index.js | 4 +- src/components/ContextMenuItem.js | 6 +- .../index.tsx | 3 +- .../DatePicker/CalendarPicker/ArrowIcon.js | 4 +- .../DatePicker/CalendarPicker/index.js | 7 +- .../DistanceMapView/index.android.js | 4 +- src/components/DotIndicatorMessage.tsx | 6 +- src/components/EReceipt.js | 3 +- src/components/EReceiptThumbnail.js | 10 +- .../EmojiPicker/CategoryShortcutButton.js | 10 +- src/components/EmojiPicker/EmojiPicker.js | 3 +- .../EmojiPicker/EmojiPickerButton.js | 8 +- .../EmojiPicker/EmojiPickerButtonDropdown.js | 6 +- .../EmojiPicker/EmojiPickerMenu/index.js | 3 +- .../EmojiPickerMenu/index.native.js | 3 +- .../EmojiPicker/EmojiPickerMenuItem/index.js | 7 +- .../EmojiPickerMenuItem/index.native.js | 7 +- src/components/EmojiSuggestions.tsx | 6 +- src/components/ExpensifyWordmark.tsx | 3 +- src/components/FloatingActionButton.js | 9 +- .../index.native.js | 3 +- .../HTMLRenderers/CodeRenderer.js | 3 +- .../HTMLRenderers/MentionHereRenderer.js | 8 +- .../HTMLRenderers/MentionUserRenderer.js | 6 +- src/components/HeaderPageLayout.js | 3 +- src/components/HeaderWithBackButton/index.js | 7 +- src/components/Icon/index.tsx | 11 +- src/components/ImageView/index.js | 7 +- src/components/LHNOptionsList/OptionRowLHN.js | 3 +- .../BaseLocationErrorMessage.js | 8 +- src/components/MagicCodeInput.js | 6 +- src/components/MapView/MapView.web.tsx | 3 +- src/components/MentionSuggestions.tsx | 8 +- src/components/MenuItem.js | 16 +- src/components/MessagesRow.js | 3 +- src/components/Modal/BaseModal.tsx | 3 +- src/components/Modal/index.tsx | 6 +- src/components/MultipleAvatars.tsx | 9 +- src/components/OfflineWithFeedback.js | 45 +- src/components/OptionRow.js | 3 +- src/components/PDFView/index.native.js | 5 +- src/components/PopoverWithoutOverlay/index.js | 4 +- .../GenericPressable/BaseGenericPressable.tsx | 3 +- .../Pressable/PressableWithDelayToggle.tsx | 6 +- .../index.tsx | 3 +- src/components/Reactions/AddReactionBubble.js | 13 +- .../Reactions/EmojiReactionBubble.js | 9 +- .../Reactions/MiniQuickEmojiReactions.js | 6 +- .../ReportActionItem/MoneyReportView.js | 3 +- .../ReportActionItem/MoneyRequestPreview.js | 3 +- .../ReportActionItem/MoneyRequestView.js | 3 +- .../ReportActionItemImages.js | 3 +- .../ReportActionItem/TaskPreview.js | 6 +- src/components/ReportActionItem/TaskView.js | 8 +- src/components/RoomHeaderAvatars.js | 7 +- .../SafeAreaConsumer/index.android.tsx | 4 +- src/components/SafeAreaConsumer/index.tsx | 4 +- src/components/SelectionList/BaseListItem.js | 7 +- src/components/SpacerView.js | 3 +- src/components/SubscriptAvatar.tsx | 7 +- src/components/TagPicker/index.js | 3 +- .../TextInput/BaseTextInput/index.js | 7 +- .../TextInput/BaseTextInput/index.native.js | 3 +- src/components/ThumbnailImage.tsx | 3 +- src/components/ValuePicker/index.js | 3 +- ...ThemeStyleUtils.tsx => withStyleUtils.tsx} | 18 +- src/pages/ErrorPage/GenericErrorPage.js | 6 +- .../report/AnimatedEmptyStateBackground.js | 3 +- .../MiniReportActionContextMenu/index.js | 6 +- src/pages/home/report/LinkPreviewer.js | 3 +- .../report/ReactionList/HeaderReactionList.js | 11 +- src/pages/home/report/ReportActionItem.js | 7 +- .../home/report/ReportActionItemCreated.js | 3 +- .../report/ReportActionItemParentAction.js | 3 +- .../home/report/ReportActionItemSingle.js | 3 +- src/pages/home/sidebar/SidebarLinks.js | 3 +- .../ValidateCodeForm/BaseValidateCodeForm.js | 8 +- .../settings/Wallet/PaymentMethodList.js | 8 +- src/pages/signin/SignInHeroCopy.js | 3 +- src/pages/signin/SignInPage.js | 3 +- src/pages/signin/SignInPageHero.js | 3 +- src/pages/signin/SignInPageLayout/Footer.js | 3 +- .../SignInPageLayout/SignInPageContent.js | 3 +- src/pages/signin/SignInPageLayout/index.js | 3 +- .../ValidateCodeForm/BaseValidateCodeForm.js | 3 +- src/stories/Composer.stories.js | 3 +- src/styles/{utils => }/StyleUtils.ts | 477 +++++++++++++++++- src/styles/ThemeStylesContext.ts | 6 +- src/styles/ThemeStylesProvider.tsx | 2 +- src/styles/useStyleUtils.ts | 6 +- src/styles/useThemeStyleUtils.ts | 14 - src/styles/utils/ThemeStyleUtils.ts | 409 --------------- src/styles/utils/functions.ts | 18 - src/styles/utils/types.ts | 59 --- 110 files changed, 782 insertions(+), 802 deletions(-) rename src/components/{withThemeStyleUtils.tsx => withStyleUtils.tsx} (53%) rename src/styles/{utils => }/StyleUtils.ts (63%) delete mode 100644 src/styles/useThemeStyleUtils.ts delete mode 100644 src/styles/utils/ThemeStyleUtils.ts delete mode 100644 src/styles/utils/functions.ts delete mode 100644 src/styles/utils/types.ts diff --git a/src/components/AddressSearch/CurrentLocationButton.js b/src/components/AddressSearch/CurrentLocationButton.js index 20b6c5a08181..90d2c15733f1 100644 --- a/src/components/AddressSearch/CurrentLocationButton.js +++ b/src/components/AddressSearch/CurrentLocationButton.js @@ -7,8 +7,8 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import useLocalize from '@hooks/useLocalize'; import getButtonState from '@libs/getButtonState'; import colors from '@styles/colors'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; const propTypes = { /** Callback that runs when location button is clicked */ @@ -25,13 +25,13 @@ const defaultProps = { function CurrentLocationButton({onPress, isDisabled}) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); return ( + () => { ReportActionContextMenu.hideContextMenu(); diff --git a/src/components/AttachmentModal.js b/src/components/AttachmentModal.js index 6d57001d810e..a70684f450a5 100755 --- a/src/components/AttachmentModal.js +++ b/src/components/AttachmentModal.js @@ -20,8 +20,8 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import useNativeDriver from '@libs/useNativeDriver'; import reportPropTypes from '@pages/reportPropTypes'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -116,6 +116,7 @@ const defaultProps = { function AttachmentModal(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const onModalHideCallbackRef = useRef(null); const [isModalOpen, setIsModalOpen] = useState(props.defaultOpen); const [shouldLoadAttachment, setShouldLoadAttachment] = useState(false); diff --git a/src/components/Attachments/AttachmentView/index.js b/src/components/Attachments/AttachmentView/index.js index 3de6fa5d9c9e..6e1ed651ae06 100755 --- a/src/components/Attachments/AttachmentView/index.js +++ b/src/components/Attachments/AttachmentView/index.js @@ -16,8 +16,8 @@ import addEncryptedAuthTokenToURL from '@libs/addEncryptedAuthTokenToURL'; import compose from '@libs/compose'; import * as TransactionUtils from '@libs/TransactionUtils'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import cursor from '@styles/utilities/cursor'; import variables from '@styles/variables'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -80,7 +80,7 @@ function AttachmentView({ }) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const [loadComplete, setLoadComplete] = useState(false); const [imageError, setImageError] = useState(false); diff --git a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx index 3fe0072eea28..07db455968a3 100644 --- a/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx +++ b/src/components/AutoCompleteSuggestions/BaseAutoCompleteSuggestions.tsx @@ -5,9 +5,8 @@ import {View} from 'react-native'; import {ScrollView} from 'react-native-gesture-handler'; import Animated, {Easing, FadeOutDown, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import viewForwardedRef from '@src/types/utils/viewForwardedRef'; import type {AutoCompleteSuggestionsProps, RenderSuggestionMenuItemProps} from './types'; @@ -40,7 +39,7 @@ function BaseAutoCompleteSuggestions( ref: ForwardedRef, ) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const rowHeight = useSharedValue(0); const scrollRef = useRef>(null); /** @@ -49,7 +48,7 @@ function BaseAutoCompleteSuggestions( const renderItem = useCallback( ({item, index}: RenderSuggestionMenuItemProps): ReactElement => ( ThemeStyleUtils.getAutoCompleteSuggestionItemStyle(highlightedSuggestionIndex, CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, hovered, index)} + style={({hovered}) => StyleUtils.getAutoCompleteSuggestionItemStyle(highlightedSuggestionIndex, CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT, hovered, index)} hoverDimmingValue={1} onMouseDown={(e) => e.preventDefault()} onPress={() => onSelect(index)} @@ -59,7 +58,7 @@ function BaseAutoCompleteSuggestions( {renderSuggestionMenuItem(item, index)} ), - [accessibilityLabelExtractor, renderSuggestionMenuItem, ThemeStyleUtils, highlightedSuggestionIndex, onSelect], + [accessibilityLabelExtractor, renderSuggestionMenuItem, StyleUtils, highlightedSuggestionIndex, onSelect], ); const innerHeight = CONST.AUTO_COMPLETE_SUGGESTER.SUGGESTION_ROW_HEIGHT * suggestions.length; diff --git a/src/components/AutoCompleteSuggestions/index.tsx b/src/components/AutoCompleteSuggestions/index.tsx index bdf24d497b65..3ccbb4efaf5a 100644 --- a/src/components/AutoCompleteSuggestions/index.tsx +++ b/src/components/AutoCompleteSuggestions/index.tsx @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'; import {View} from 'react-native'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; -import StyleUtils from '@styles/utils/StyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import BaseAutoCompleteSuggestions from './BaseAutoCompleteSuggestions'; import type {AutoCompleteSuggestionsProps} from './types'; @@ -15,6 +15,7 @@ import type {AutoCompleteSuggestionsProps} from './types'; */ function AutoCompleteSuggestions({measureParentContainer = () => {}, ...props}: AutoCompleteSuggestionsProps) { + const StyleUtils = useStyleUtils(); const containerRef = React.useRef(null); const {windowHeight, windowWidth} = useWindowDimensions(); const [{width, left, bottom}, setContainerState] = React.useState({ diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index c3fa36f4d169..9fbc3f37fcc0 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -3,11 +3,10 @@ import {StyleProp, View, ViewStyle} from 'react-native'; import useNetwork from '@hooks/useNetwork'; import * as ReportUtils from '@libs/ReportUtils'; import {AvatarSource} from '@libs/UserUtils'; +import {AvatarSizeName} from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; -import type {AvatarSizeName} from '@styles/utils/types'; import CONST from '@src/CONST'; import {AvatarType} from '@src/types/onyx/OnyxCommon'; import Icon from './Icon'; @@ -61,7 +60,7 @@ function Avatar({ }: AvatarProps) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const [imageError, setImageError] = useState(false); useNetwork({onReconnect: () => setImageError(false)}); @@ -77,8 +76,8 @@ function Avatar({ const isWorkspace = type === CONST.ICON_TYPE_WORKSPACE; const iconSize = StyleUtils.getAvatarSize(size); - const imageStyle = [ThemeStyleUtils.getAvatarStyle(size), imageStyles, styles.noBorderRadius]; - const iconStyle = imageStyles ? [ThemeStyleUtils.getAvatarStyle(size), styles.bgTransparent, imageStyles] : undefined; + const imageStyle = [StyleUtils.getAvatarStyle(size), imageStyles, styles.noBorderRadius]; + const iconStyle = imageStyles ? [StyleUtils.getAvatarStyle(size), styles.bgTransparent, imageStyles] : undefined; const iconFillColor = isWorkspace ? StyleUtils.getDefaultWorkspaceAvatarColor(name).fill : fill ?? theme.icon; const fallbackAvatar = isWorkspace ? ReportUtils.getDefaultWorkspaceAvatar(name) : fallbackIcon || Expensicons.FallbackAvatar; diff --git a/src/components/AvatarCropModal/AvatarCropModal.js b/src/components/AvatarCropModal/AvatarCropModal.js index a2d4e1810365..dcb0470c5ee5 100644 --- a/src/components/AvatarCropModal/AvatarCropModal.js +++ b/src/components/AvatarCropModal/AvatarCropModal.js @@ -18,8 +18,8 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withW import compose from '@libs/compose'; import cropOrRotateImage from '@libs/cropOrRotateImage'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import ImageCropView from './ImageCropView'; import Slider from './Slider'; @@ -63,7 +63,7 @@ const defaultProps = { function AvatarCropModal(props) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const originalImageWidth = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); const originalImageHeight = useSharedValue(CONST.AVATAR_CROP_MODAL.INITIAL_SIZE); const translateY = useSharedValue(0); diff --git a/src/components/AvatarCropModal/ImageCropView.js b/src/components/AvatarCropModal/ImageCropView.js index fb1e95ae1ef5..94289b24d6ca 100644 --- a/src/components/AvatarCropModal/ImageCropView.js +++ b/src/components/AvatarCropModal/ImageCropView.js @@ -6,8 +6,8 @@ import Animated, {interpolate, useAnimatedStyle} from 'react-native-reanimated'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import ControlSelection from '@libs/ControlSelection'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import gestureHandlerPropTypes from './gestureHandlerPropTypes'; const propTypes = { @@ -51,7 +51,7 @@ const defaultProps = { function ImageCropView(props) { const styles = useThemeStyles(); - const StyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const containerStyle = StyleUtils.getWidthAndHeightStyle(props.containerSize, props.containerSize); const originalImageHeight = props.originalImageHeight; diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index ba8a1819a350..171fe3c13673 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -7,11 +7,11 @@ import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import {PersonalDetails, Policy, Report, ReportActions} from '@src/types/onyx'; +import useStyleUtils from '@styles/useStyleUtils'; import DisplayNames from './DisplayNames'; import MultipleAvatars from './MultipleAvatars'; import ParentNavigationSubtitle from './ParentNavigationSubtitle'; @@ -55,6 +55,7 @@ function AvatarWithDisplayName({ }: AvatarWithDisplayNameProps) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils() const title = ReportUtils.getReportName(report); const subtitle = ReportUtils.getChatRoomSubtitle(report); const parentNavigationSubtitleData = ReportUtils.getParentNavigationSubtitle(report); diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index 37865777b95f..96855268d73c 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -1,7 +1,7 @@ import React, {useCallback} from 'react'; import {GestureResponderEvent, PressableStateCallbackType, StyleProp, TextStyle, View, ViewStyle} from 'react-native'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Text from './Text'; @@ -34,12 +34,12 @@ type BadgeProps = { function Badge({success = false, error = false, pressable = false, text, environment = CONST.ENVIRONMENT.DEV, badgeStyles, textStyles, onPress = () => {}}: BadgeProps) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const textColorStyles = success || error ? styles.textWhite : undefined; const Wrapper = pressable ? PressableWithoutFeedback : View; const wrapperStyles: (state: PressableStateCallbackType) => StyleProp = useCallback( - ({pressed}) => [styles.badge, styles.ml2, ThemeStyleUtils.getBadgeColorStyle(success, error, pressed, environment === CONST.ENVIRONMENT.ADHOC), badgeStyles], + ({pressed}) => [styles.badge, styles.ml2, StyleUtils.getBadgeColorStyle(success, error, pressed, environment === CONST.ENVIRONMENT.ADHOC), badgeStyles], [styles.badge, styles.ml2, ThemeStyleUtils, success, error, environment, badgeStyles], ); diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx index 801d46a11a22..cfe817c849c0 100644 --- a/src/components/Banner.tsx +++ b/src/components/Banner.tsx @@ -2,8 +2,8 @@ import React, {memo} from 'react'; import {StyleProp, TextStyle, View, ViewStyle} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import getButtonState from '@libs/getButtonState'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import Hoverable from './Hoverable'; import Icon from './Icon'; @@ -41,7 +41,7 @@ type BannerProps = { function Banner({text, onClose, onPress, containerStyles, textStyles, shouldRenderHTML = false, shouldShowIcon = false, shouldShowCloseButton = false}: BannerProps) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); return ( @@ -66,7 +66,7 @@ function Banner({text, onClose, onPress, containerStyles, textStyles, shouldRend )} diff --git a/src/components/BaseMiniContextMenuItem.js b/src/components/BaseMiniContextMenuItem.js index 3d67ef7bd393..a45aba6ef534 100644 --- a/src/components/BaseMiniContextMenuItem.js +++ b/src/components/BaseMiniContextMenuItem.js @@ -5,9 +5,8 @@ import _ from 'underscore'; import DomUtils from '@libs/DomUtils'; import getButtonState from '@libs/getButtonState'; import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Tooltip from './Tooltip/PopoverAnchorTooltip'; @@ -52,7 +51,7 @@ const defaultProps = { */ function BaseMiniContextMenuItem(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); return ( [ styles.reportActionContextMenuMiniButton, - ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, props.isDelayButtonStateComplete)), + StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, props.isDelayButtonStateComplete)), props.isDelayButtonStateComplete && styles.cursorDefault, ]} > diff --git a/src/components/ButtonWithDropdownMenu.js b/src/components/ButtonWithDropdownMenu.js index de5f2edc5b9d..321cd79f1318 100644 --- a/src/components/ButtonWithDropdownMenu.js +++ b/src/components/ButtonWithDropdownMenu.js @@ -4,8 +4,8 @@ import {View} from 'react-native'; import _ from 'underscore'; import useWindowDimensions from '@hooks/useWindowDimensions'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import Button from './Button'; import Icon from './Icon'; @@ -74,6 +74,7 @@ const defaultProps = { function ButtonWithDropdownMenu(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const [selectedItemIndex, setSelectedItemIndex] = useState(0); const [isMenuVisible, setIsMenuVisible] = useState(false); const [popoverAnchorPosition, setPopoverAnchorPosition] = useState(null); diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 8cb5d1b13e5b..5dd3164eadcc 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -1,9 +1,8 @@ import React, {ForwardedRef, forwardRef, KeyboardEvent as ReactKeyboardEvent} from 'react'; import {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ChildrenProps from '@src/types/utils/ChildrenProps'; import Icon from './Icon'; @@ -64,7 +63,7 @@ function Checkbox( ) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const handleSpaceKey = (event?: ReactKeyboardEvent) => { if (event?.code !== 'Space') { @@ -100,7 +99,7 @@ function Checkbox( {children ?? ( )} diff --git a/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx b/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx index ca5d7e7de1f3..6f6daddc51b8 100644 --- a/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx +++ b/src/components/CurrentUserPersonalDetailsSkeletonView/index.tsx @@ -4,8 +4,8 @@ import {Circle, Rect} from 'react-native-svg'; import {ValueOf} from 'type-fest'; import SkeletonViewContentLoader from '@components/SkeletonViewContentLoader'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -26,6 +26,7 @@ type CurrentUserPersonalDetailsSkeletonViewProps = { function CurrentUserPersonalDetailsSkeletonView({shouldAnimate = true, avatarSize = CONST.AVATAR_SIZE.LARGE, backgroundColor, foregroundColor}: CurrentUserPersonalDetailsSkeletonViewProps) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const avatarPlaceholderSize = StyleUtils.getAvatarSize(avatarSize); const avatarPlaceholderRadius = avatarPlaceholderSize / 2; const spaceBetweenAvatarAndHeadline = styles.mb3.marginBottom + styles.mt1.marginTop + (variables.lineHeightXXLarge - variables.fontSizeXLarge) / 2; diff --git a/src/components/DatePicker/CalendarPicker/ArrowIcon.js b/src/components/DatePicker/CalendarPicker/ArrowIcon.js index eda63439ebad..a03e18085706 100644 --- a/src/components/DatePicker/CalendarPicker/ArrowIcon.js +++ b/src/components/DatePicker/CalendarPicker/ArrowIcon.js @@ -3,8 +3,8 @@ import React from 'react'; import {View} from 'react-native'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -22,7 +22,7 @@ const defaultProps = { function ArrowIcon(props) { const styles = useThemeStyles(); - const StyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); return ( diff --git a/src/components/DatePicker/CalendarPicker/index.js b/src/components/DatePicker/CalendarPicker/index.js index 20bc36af16ff..a404c4746397 100644 --- a/src/components/DatePicker/CalendarPicker/index.js +++ b/src/components/DatePicker/CalendarPicker/index.js @@ -8,8 +8,8 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import Text from '@components/Text'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import withStyleUtils, {withStyleUtilsPropTypes} from '@components/withStyleUtils'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; -import withThemeStyleUtils from '@components/withThemeStyleUtils'; import compose from '@libs/compose'; import DateUtils from '@libs/DateUtils'; import getButtonState from '@libs/getButtonState'; @@ -33,6 +33,7 @@ const propTypes = { ...withLocalizePropTypes, ...withThemeStylesPropTypes, + ...withStyleUtilsPropTypes, }; const defaultProps = { @@ -236,7 +237,7 @@ class CalendarPicker extends React.PureComponent { style={[ this.props.themeStyles.calendarDayContainer, isSelected ? this.props.themeStyles.calendarDayContainerSelected : {}, - !isDisabled ? this.props.ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed)) : {}, + !isDisabled ? this.props.StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed)) : {}, ]} > {day} @@ -262,4 +263,4 @@ class CalendarPicker extends React.PureComponent { CalendarPicker.propTypes = propTypes; CalendarPicker.defaultProps = defaultProps; -export default compose(withLocalize, withThemeStyles, withThemeStyleUtils)(CalendarPicker); +export default compose(withLocalize, withThemeStyles, withStyleUtils)(CalendarPicker); diff --git a/src/components/DistanceMapView/index.android.js b/src/components/DistanceMapView/index.android.js index f4b7feab6a0b..532d42ac0be5 100644 --- a/src/components/DistanceMapView/index.android.js +++ b/src/components/DistanceMapView/index.android.js @@ -6,13 +6,13 @@ import * as Expensicons from '@components/Icon/Expensicons'; import MapView from '@components/MapView'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as distanceMapViewPropTypes from './distanceMapViewPropTypes'; function DistanceMapView(props) { const styles = useThemeStyles(); - const StyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const [isMapReady, setIsMapReady] = useState(false); const {isOffline} = useNetwork(); const {translate} = useLocalize(); diff --git a/src/components/DotIndicatorMessage.tsx b/src/components/DotIndicatorMessage.tsx index fa570cfdf375..6a7d78768ed7 100644 --- a/src/components/DotIndicatorMessage.tsx +++ b/src/components/DotIndicatorMessage.tsx @@ -4,8 +4,8 @@ import {StyleProp, TextStyle, View, ViewStyle} from 'react-native'; import fileDownload from '@libs/fileDownload'; import * as Localize from '@libs/Localize'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; @@ -45,7 +45,7 @@ function isReceiptError(message: string | ReceiptError): message is ReceiptError function DotIndicatorMessage({messages = {}, style, type, textStyles}: DotIndicatorMessageProps) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); if (Object.keys(messages).length === 0) { return null; @@ -93,7 +93,7 @@ function DotIndicatorMessage({messages = {}, style, type, textStyles}: DotIndica {message} diff --git a/src/components/EReceipt.js b/src/components/EReceipt.js index 3007e27bded7..f5e5b7f2f6b3 100644 --- a/src/components/EReceipt.js +++ b/src/components/EReceipt.js @@ -6,8 +6,8 @@ import useLocalize from '@hooks/useLocalize'; import * as CardUtils from '@libs/CardUtils'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -31,6 +31,7 @@ const defaultProps = { function EReceipt({transaction, transactionID}) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); // Get receipt colorway, or default to Yellow. diff --git a/src/components/EReceiptThumbnail.js b/src/components/EReceiptThumbnail.js index 6137a3a8dc36..42721bebb2af 100644 --- a/src/components/EReceiptThumbnail.js +++ b/src/components/EReceiptThumbnail.js @@ -1,10 +1,9 @@ import PropTypes from 'prop-types'; -import React, {useState} from 'react'; +import React, {useMemo, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import * as ReportUtils from '@libs/ReportUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -37,12 +36,9 @@ const backgroundImages = { [CONST.ERECEIPT_COLORS.PINK]: eReceiptBGs.EReceiptBG_Pink, }; -function getBackgroundImage(transaction) { - return backgroundImages[StyleUtils.getEReceiptColorCode(transaction)]; -} - function EReceiptThumbnail({transaction}) { const styles = useThemeStyles(); + const StyleUtils = useThemeStyles(); // Get receipt colorway, or default to Yellow. const {backgroundColor: primaryColor, color: secondaryColor} = StyleUtils.getEReceiptColorStyles(StyleUtils.getEReceiptColorCode(transaction)); @@ -75,6 +71,8 @@ function EReceiptThumbnail({transaction}) { receiptMCCSize = variables.eReceiptMCCHeightWidthMedium; } + const getBackgroundImage = useMemo((trans) => backgroundImages[StyleUtils.getEReceiptColorCode(trans)], [StyleUtils]); + return ( setIsHighlighted(true)} onHoverOut={() => setIsHighlighted(false)} - style={({pressed}) => [ - ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), - styles.categoryShortcutButton, - isHighlighted && styles.emojiItemHighlighted, - ]} + style={({pressed}) => [StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), styles.categoryShortcutButton, isHighlighted && styles.emojiItemHighlighted]} accessibilityLabel={`emojiPicker.headers.${props.code}`} role={CONST.ACCESSIBILITY_ROLE.BUTTON} > diff --git a/src/components/EmojiPicker/EmojiPicker.js b/src/components/EmojiPicker/EmojiPicker.js index 265ae1f5b872..96d7ee88b816 100644 --- a/src/components/EmojiPicker/EmojiPicker.js +++ b/src/components/EmojiPicker/EmojiPicker.js @@ -6,8 +6,8 @@ import PopoverWithMeasuredContent from '@components/PopoverWithMeasuredContent'; import withViewportOffsetTop from '@components/withViewportOffsetTop'; import useWindowDimensions from '@hooks/useWindowDimensions'; import calculateAnchorPosition from '@libs/calculateAnchorPosition'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import EmojiPickerMenu from './EmojiPickerMenu'; @@ -22,6 +22,7 @@ const propTypes = { const EmojiPicker = forwardRef((props, ref) => { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const [isEmojiPickerVisible, setIsEmojiPickerVisible] = useState(false); const [emojiPopoverAnchorPosition, setEmojiPopoverAnchorPosition] = useState({ horizontal: 0, diff --git a/src/components/EmojiPicker/EmojiPickerButton.js b/src/components/EmojiPicker/EmojiPickerButton.js index 35b6e0511581..165646d4795d 100644 --- a/src/components/EmojiPicker/EmojiPickerButton.js +++ b/src/components/EmojiPicker/EmojiPickerButton.js @@ -6,8 +6,8 @@ import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeed import Tooltip from '@components/Tooltip/PopoverAnchorTooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import getButtonState from '@libs/getButtonState'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; const propTypes = { @@ -31,7 +31,7 @@ const defaultProps = { function EmojiPickerButton(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const emojiPopoverAnchor = useRef(null); useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []); @@ -40,7 +40,7 @@ function EmojiPickerButton(props) { [styles.chatItemEmojiButton, ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed))]} + style={({hovered, pressed}) => [styles.chatItemEmojiButton, StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed))]} disabled={props.isDisabled} onPress={() => { if (!EmojiPickerAction.emojiPickerRef.current.isEmojiPickerVisible) { @@ -55,7 +55,7 @@ function EmojiPickerButton(props) { {({hovered, pressed}) => ( )} diff --git a/src/components/EmojiPicker/EmojiPickerButtonDropdown.js b/src/components/EmojiPicker/EmojiPickerButtonDropdown.js index 1ba0c0d35b52..02a5954cb705 100644 --- a/src/components/EmojiPicker/EmojiPickerButtonDropdown.js +++ b/src/components/EmojiPicker/EmojiPickerButtonDropdown.js @@ -8,8 +8,8 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import getButtonState from '@libs/getButtonState'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import CONST from '@src/CONST'; @@ -26,7 +26,7 @@ const defaultProps = { function EmojiPickerButtonDropdown(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const emojiPopoverAnchor = useRef(null); useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []); @@ -65,7 +65,7 @@ function EmojiPickerButtonDropdown(props) { diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.js b/src/components/EmojiPicker/EmojiPickerMenu/index.js index 2ec7ce31d9d1..132b1043dce8 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.js @@ -17,8 +17,8 @@ import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; import isEnterWhileComposition from '@libs/KeyboardShortcut/isEnterWhileComposition'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -51,6 +51,7 @@ function EmojiPickerMenu(props) { const {forwardedRef, frequentlyUsedEmojis, preferredSkinTone, onEmojiSelected, preferredLocale, translate} = props; const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {isSmallScreenWidth, windowHeight} = useWindowDimensions(); diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js index 6f6fd1283f02..f1560c07b397 100644 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.native.js @@ -15,8 +15,8 @@ import useSingleExecution from '@hooks/useSingleExecution'; import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -43,6 +43,7 @@ const defaultProps = { function EmojiPickerMenu({preferredLocale, onEmojiSelected, preferredSkinTone, translate, frequentlyUsedEmojis}) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const emojiList = useAnimatedRef(); // eslint-disable-next-line react-hooks/exhaustive-deps const allEmojis = useMemo(() => EmojiUtils.mergeEmojisWithFrequentlyUsedEmojis(emojis), [frequentlyUsedEmojis]); diff --git a/src/components/EmojiPicker/EmojiPickerMenuItem/index.js b/src/components/EmojiPicker/EmojiPickerMenuItem/index.js index 177056631c8a..ae2cdf46dfc0 100644 --- a/src/components/EmojiPicker/EmojiPickerMenuItem/index.js +++ b/src/components/EmojiPicker/EmojiPickerMenuItem/index.js @@ -2,8 +2,8 @@ import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import Text from '@components/Text'; +import withStyleUtils, {withStyleUtilsPropTypes} from '@components/withStyleUtils'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; -import withThemeStyleUtils from '@components/withThemeStyleUtils'; import * as Browser from '@libs/Browser'; import getButtonState from '@libs/getButtonState'; import CONST from '@src/CONST'; @@ -34,6 +34,7 @@ const propTypes = { isHighlighted: PropTypes.bool, ...withThemeStylesPropTypes, + ...withStyleUtilsPropTypes, }; class EmojiPickerMenuItem extends PureComponent { @@ -98,7 +99,7 @@ class EmojiPickerMenuItem extends PureComponent { style={({pressed}) => [ this.props.isFocused ? this.props.themeStyles.emojiItemKeyboardHighlighted : {}, this.state.isHovered || this.props.isHighlighted ? this.props.themeStyles.emojiItemHighlighted : {}, - Browser.isMobile() && this.props.ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), + Browser.isMobile() && this.props.StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), this.props.themeStyles.emojiItem, ]} accessibilityLabel={this.props.emoji} @@ -123,7 +124,7 @@ EmojiPickerMenuItem.defaultProps = { // Significantly speeds up re-renders of the EmojiPickerMenu's FlatList // by only re-rendering at most two EmojiPickerMenuItems that are highlighted/un-highlighted per user action. export default withThemeStyles( - withThemeStyleUtils( + withStyleUtils( React.memo( EmojiPickerMenuItem, (prevProps, nextProps) => prevProps.isFocused === nextProps.isFocused && prevProps.isHighlighted === nextProps.isHighlighted && prevProps.emoji === nextProps.emoji, diff --git a/src/components/EmojiPicker/EmojiPickerMenuItem/index.native.js b/src/components/EmojiPicker/EmojiPickerMenuItem/index.native.js index 49a0c56da3a6..7934cc0f03d4 100644 --- a/src/components/EmojiPicker/EmojiPickerMenuItem/index.native.js +++ b/src/components/EmojiPicker/EmojiPickerMenuItem/index.native.js @@ -2,8 +2,8 @@ import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import Text from '@components/Text'; +import withStyleUtils, {withStyleUtilsPropTypes} from '@components/withStyleUtils'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; -import withThemeStyleUtils from '@components/withThemeStyleUtils'; import getButtonState from '@libs/getButtonState'; import CONST from '@src/CONST'; @@ -36,6 +36,7 @@ const propTypes = { isUsingKeyboardMovement: PropTypes.bool, ...withThemeStylesPropTypes, + ...withStyleUtilsPropTypes, }; class EmojiPickerMenuItem extends PureComponent { @@ -73,7 +74,7 @@ class EmojiPickerMenuItem extends PureComponent { onBlur={this.props.onBlur} ref={(ref) => (this.ref = ref)} style={({pressed}) => [ - this.props.ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), + this.props.StyleUtils.getButtonBackgroundColorStyle(getButtonState(false, pressed)), this.props.isHighlighted && this.props.isUsingKeyboardMovement ? this.props.themeStyles.emojiItemKeyboardHighlighted : {}, this.props.isHighlighted && !this.props.isUsingKeyboardMovement ? this.props.themeStyles.emojiItemHighlighted : {}, this.props.themeStyles.emojiItem, @@ -101,7 +102,7 @@ EmojiPickerMenuItem.defaultProps = { // Significantly speeds up re-renders of the EmojiPickerMenu's FlatList // by only re-rendering at most two EmojiPickerMenuItems that are highlighted/un-highlighted per user action. export default withThemeStyles( - withThemeStyleUtils( + withStyleUtils( React.memo( EmojiPickerMenuItem, (prevProps, nextProps) => diff --git a/src/components/EmojiSuggestions.tsx b/src/components/EmojiSuggestions.tsx index e0ecba30fa0d..6972069cbaeb 100644 --- a/src/components/EmojiSuggestions.tsx +++ b/src/components/EmojiSuggestions.tsx @@ -3,8 +3,8 @@ import {View} from 'react-native'; import type {SimpleEmoji} from '@libs/EmojiTrie'; import * as EmojiUtils from '@libs/EmojiUtils'; import getStyledTextArray from '@libs/GetStyledTextArray'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import Text from './Text'; @@ -43,7 +43,7 @@ const keyExtractor = (item: SimpleEmoji, index: number): string => `${item.name} function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferredSkinToneIndex, highlightedEmojiIndex = 0, measureParentContainer = () => {}}: EmojiSuggestionsProps) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); /** * Render an emoji suggestion menu item component. */ @@ -62,7 +62,7 @@ function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferr {styledTextArray.map(({text, isColored}) => ( {text} diff --git a/src/components/ExpensifyWordmark.tsx b/src/components/ExpensifyWordmark.tsx index 1de6bcc01386..49559d1cc6d5 100644 --- a/src/components/ExpensifyWordmark.tsx +++ b/src/components/ExpensifyWordmark.tsx @@ -6,8 +6,8 @@ import StagingLogo from '@assets/images/expensify-logo--staging.svg'; import ProductionLogo from '@assets/images/expensify-wordmark.svg'; import useEnvironment from '@hooks/useEnvironment'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import withWindowDimensions from './withWindowDimensions'; @@ -28,6 +28,7 @@ const logoComponents = { function ExpensifyWordmark({isSmallScreenWidth, style}: ExpensifyWordmarkProps) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {environment} = useEnvironment(); // PascalCase is required for React components, so capitalize the const here const LogoComponent = logoComponents[environment]; diff --git a/src/components/FloatingActionButton.js b/src/components/FloatingActionButton.js index fe26f63d0b75..791eb150f8c9 100644 --- a/src/components/FloatingActionButton.js +++ b/src/components/FloatingActionButton.js @@ -2,12 +2,12 @@ import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import {Animated, Easing, View} from 'react-native'; import compose from '@libs/compose'; -import StyleUtils from '@styles/utils/StyleUtils'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import PressableWithFeedback from './Pressable/PressableWithFeedback'; import Tooltip from './Tooltip/PopoverAnchorTooltip'; import withLocalize, {withLocalizePropTypes} from './withLocalize'; +import withStyleUtils, {withStyleUtilsPropTypes} from './withStyleUtils'; import withTheme, {withThemePropTypes} from './withTheme'; import withThemeStyles, {withThemeStylesPropTypes} from './withThemeStyles'; @@ -28,8 +28,9 @@ const propTypes = { buttonRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), ...withLocalizePropTypes, - ...withThemeStylesPropTypes, ...withThemePropTypes, + ...withThemeStylesPropTypes, + ...withStyleUtilsPropTypes, }; const defaultProps = { @@ -100,7 +101,7 @@ class FloatingActionButton extends PureComponent { this.props.onPress(e); }} onLongPress={() => {}} - style={[this.props.themeStyles.floatingActionButton, StyleUtils.getAnimatedFABStyle(rotate, backgroundColor)]} + style={[this.props.themeStyles.floatingActionButton, this.props.StyleUtils.getAnimatedFABStyle(rotate, backgroundColor)]} > FloatingActionButtonWithLocalizeWithRef.displayName = 'FloatingActionButtonWithLocalizeWithRef'; -export default compose(withThemeStyles, withTheme)(FloatingActionButtonWithLocalizeWithRef); +export default compose(withThemeStyles, withTheme, withStyleUtils)(FloatingActionButtonWithLocalizeWithRef); diff --git a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js index 1a16f1f146fe..457a9dce66d9 100644 --- a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js +++ b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js @@ -1,8 +1,8 @@ import React from 'react'; import {Animated} from 'react-native'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import growlNotificationContainerPropTypes from './growlNotificationContainerPropTypes'; const propTypes = { @@ -11,6 +11,7 @@ const propTypes = { function GrowlNotificationContainer(props) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const insets = useSafeAreaInsets; return ( diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js index 65acffb0e87b..9d101b8a5190 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/CodeRenderer.js @@ -3,10 +3,11 @@ import {splitBoxModelStyle} from 'react-native-render-html'; import _ from 'underscore'; import * as HTMLEngineUtils from '@components/HTMLEngineProvider/htmlEngineUtils'; import InlineCodeBlock from '@components/InlineCodeBlock'; -import StyleUtils from '@styles/utils/StyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import htmlRendererPropTypes from './htmlRendererPropTypes'; function CodeRenderer(props) { + const StyleUtils = useStyleUtils(); // We split wrapper and inner styles // "boxModelStyle" corresponds to border, margin, padding and backgroundColor const {boxModelStyle, otherStyle: textStyle} = splitBoxModelStyle(props.style); diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionHereRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionHereRenderer.js index a885fb5c8ed0..82769598d84a 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionHereRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionHereRenderer.js @@ -2,17 +2,17 @@ import React from 'react'; import {TNodeChildrenRenderer} from 'react-native-render-html'; import _ from 'underscore'; import Text from '@components/Text'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import htmlRendererPropTypes from './htmlRendererPropTypes'; function MentionHereRenderer(props) { - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); return ( diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js index 642eda8598f1..fbdacb6b47b0 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionUserRenderer.js @@ -13,8 +13,8 @@ import Navigation from '@libs/Navigation/Navigation'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import personalDetailsPropType from '@pages/personalDetailsPropType'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import htmlRendererPropTypes from './htmlRendererPropTypes'; @@ -28,7 +28,7 @@ const propTypes = { function MentionUserRenderer(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const defaultRendererProps = _.omit(props, ['TDefaultRenderer', 'style']); const htmlAttribAccountID = lodashGet(props.tnode.attributes, 'accountid'); @@ -76,7 +76,7 @@ function MentionUserRenderer(props) { }} > diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 9b2df9e67d20..80abe1872c12 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -1,8 +1,8 @@ import React, {PureComponent} from 'react'; import {StyleProp, View, ViewStyle} from 'react-native'; +import withStyleUtils, {WithStyleUtilsProps} from '@components/withStyleUtils'; import withTheme, {WithThemeProps} from '@components/withTheme'; import withThemeStyles, {type WithThemeStylesProps} from '@components/withThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import IconWrapperStyles from './IconWrapperStyles'; @@ -42,7 +42,8 @@ type IconProps = { /** Additional styles to add to the Icon */ additionalStyles?: StyleProp; } & WithThemeStylesProps & - WithThemeProps; + WithThemeProps & + WithStyleUtilsProps; // We must use a class component to create an animatable component with the Animated API // eslint-disable-next-line react/prefer-stateless-function @@ -62,14 +63,14 @@ 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, this.props.themeStyles.pAbsolute, this.props.additionalStyles]; + const iconStyles = [this.props.StyleUtils.getWidthAndHeightStyle(width ?? 0, height), IconWrapperStyles, this.props.themeStyles.pAbsolute, this.props.additionalStyles]; const fill = this.props.fill ?? this.props.theme.icon; if (this.props.inline) { return ( { } } -export default withTheme(withThemeStyles(Icon)); +export default withTheme(withThemeStyles(withStyleUtils(Icon))); diff --git a/src/components/ImageView/index.js b/src/components/ImageView/index.js index 116975c64e4f..1fd81277b545 100644 --- a/src/components/ImageView/index.js +++ b/src/components/ImageView/index.js @@ -5,9 +5,8 @@ import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import Image from '@components/Image'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -34,7 +33,7 @@ const defaultProps = { function ImageView({isAuthTokenRequired, url, fileName, onError}) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const [isLoading, setIsLoading] = useState(true); const [containerHeight, setContainerHeight] = useState(0); const [containerWidth, setContainerWidth] = useState(0); @@ -259,7 +258,7 @@ function ImageView({isAuthTokenRequired, url, fileName, onError}) { = 1 ? styles.pRelative : styles.pAbsolute), ...styles.flex1, }} diff --git a/src/components/LHNOptionsList/OptionRowLHN.js b/src/components/LHNOptionsList/OptionRowLHN.js index 1828c6013352..3bdd4b0938de 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.js +++ b/src/components/LHNOptionsList/OptionRowLHN.js @@ -26,8 +26,8 @@ import * as ContextMenuActions from '@pages/home/report/ContextMenu/ContextMenuA import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import * as optionRowStyles from '@styles/optionRowStyles'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -66,6 +66,7 @@ const defaultProps = { function OptionRowLHN(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const popoverAnchor = useRef(null); const isFocusedRef = useRef(true); const {isSmallScreenWidth} = useWindowDimensions(); diff --git a/src/components/LocationErrorMessage/BaseLocationErrorMessage.js b/src/components/LocationErrorMessage/BaseLocationErrorMessage.js index 434310612271..4171c04a59c6 100644 --- a/src/components/LocationErrorMessage/BaseLocationErrorMessage.js +++ b/src/components/LocationErrorMessage/BaseLocationErrorMessage.js @@ -9,8 +9,8 @@ import TextLink from '@components/TextLink'; import Tooltip from '@components/Tooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import colors from '@styles/colors'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import * as locationErrorMessagePropTypes from './locationErrorMessagePropTypes'; @@ -27,7 +27,7 @@ const propTypes = { function BaseLocationErrorMessage({onClose, onAllowLocationLinkPress, locationErrorCode, translate}) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); if (!locationErrorCode) { return null; } @@ -45,14 +45,14 @@ function BaseLocationErrorMessage({onClose, onAllowLocationLinkPress, locationEr {isPermissionDenied ? ( - {`${translate('location.permissionDenied')} ${translate('location.please')}`} + {`${translate('location.permissionDenied')} ${translate('location.please')}`} {` ${translate('location.allowPermission')} `} - {translate('location.tryAgain')} + {translate('location.tryAgain')} ) : ( {translate('location.notFound')} diff --git a/src/components/MagicCodeInput.js b/src/components/MagicCodeInput.js index 058f898db812..91430602a115 100644 --- a/src/components/MagicCodeInput.js +++ b/src/components/MagicCodeInput.js @@ -6,8 +6,8 @@ import _ from 'underscore'; import useNetwork from '@hooks/useNetwork'; import * as Browser from '@libs/Browser'; import * as ValidationUtils from '@libs/ValidationUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import FormHelpMessage from './FormHelpMessage'; import networkPropTypes from './networkPropTypes'; @@ -108,7 +108,7 @@ const getInputPlaceholderSlots = (length) => Array.from(Array(length).keys()); function MagicCodeInput(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const inputRefs = useRef(); const [input, setInput] = useState(TEXT_INPUT_EMPTY_STATE); const [focusedIndex, setFocusedIndex] = useState(0); @@ -408,7 +408,7 @@ function MagicCodeInput(props) { ( const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const [mapRef, setMapRef] = useState(null); const [currentPosition, setCurrentPosition] = useState(cachedUserLocation); diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index 5372b278ef2c..6ac161342690 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -2,8 +2,8 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; import getStyledTextArray from '@libs/GetStyledTextArray'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import CONST from '@src/CONST'; import {Icon} from '@src/types/onyx/OnyxCommon'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; @@ -54,7 +54,7 @@ const keyExtractor = (item: Mention) => item.alternateText; function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSelect, isMentionPickerLarge, measureParentContainer = () => {}}: MentionSuggestionsProps) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); /** * Render a suggestion menu item component. */ @@ -84,7 +84,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe {text} @@ -100,7 +100,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe {text} diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 1e5f41f34aa5..0e07fcd22b4c 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -8,9 +8,8 @@ import convertToLTR from '@libs/convertToLTR'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import getButtonState from '@libs/getButtonState'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; @@ -89,7 +88,7 @@ const defaultProps = { const MenuItem = React.forwardRef((props, ref) => { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const style = StyleUtils.combineStyles(props.style, styles.popoverMenuItem); const {isSmallScreenWidth} = useWindowDimensions(); const [html, setHtml] = React.useState(''); @@ -183,7 +182,7 @@ const MenuItem = React.forwardRef((props, ref) => { style={({pressed}) => [ style, !props.interactive && styles.cursorDefault, - ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true), + StyleUtils.getButtonBackgroundColorStyle(getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true), (isHovered || pressed) && props.hoverAndPressStyle, ...(_.isArray(props.wrapperStyle) ? props.wrapperStyle : [props.wrapperStyle]), props.shouldGreyOutWhenDisabled && props.disabled && styles.buttonOpacityDisabled, @@ -228,7 +227,7 @@ const MenuItem = React.forwardRef((props, ref) => { height={props.iconHeight} fill={ props.iconFill || - ThemeStyleUtils.getIconFillColor( + StyleUtils.getIconFillColor( getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true, ) @@ -263,10 +262,7 @@ const MenuItem = React.forwardRef((props, ref) => { height={props.iconHeight} fill={ props.secondaryIconFill || - ThemeStyleUtils.getIconFillColor( - getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), - true, - ) + StyleUtils.getIconFillColor(getButtonState(props.focused || isHovered, pressed, props.success, props.disabled, props.interactive), true) } /> @@ -382,7 +378,7 @@ const MenuItem = React.forwardRef((props, ref) => { )} diff --git a/src/components/MessagesRow.js b/src/components/MessagesRow.js index a63ecf768e3d..a22f9724ed89 100644 --- a/src/components/MessagesRow.js +++ b/src/components/MessagesRow.js @@ -4,8 +4,8 @@ import {View} from 'react-native'; import _ from 'underscore'; import useLocalize from '@hooks/useLocalize'; import stylePropTypes from '@styles/stylePropTypes'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import DotIndicatorMessage from './DotIndicatorMessage'; import Icon from './Icon'; @@ -41,6 +41,7 @@ const defaultProps = { function MessagesRow({messages, type, onClose, containerStyles, canDismiss}) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); if (_.isEmpty(messages)) { return null; diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 520559d1fbb3..2be3967c28e7 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -9,8 +9,8 @@ import ComposerFocusManager from '@libs/ComposerFocusManager'; import useNativeDriver from '@libs/useNativeDriver'; import getModalStyles from '@styles/getModalStyles'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as Modal from '@userActions/Modal'; import CONST from '@src/CONST'; @@ -44,6 +44,7 @@ function BaseModal( ) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {windowWidth, windowHeight, isSmallScreenWidth} = useWindowDimensions(); const safeAreaInsets = useSafeAreaInsets(); diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 7181dcafc56b..bfc899f9c278 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -2,14 +2,14 @@ import React, {useState} from 'react'; import withWindowDimensions from '@components/withWindowDimensions'; import StatusBar from '@libs/StatusBar'; import useTheme from '@styles/themes/useTheme'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import CONST from '@src/CONST'; import BaseModal from './BaseModal'; import BaseModalProps from './types'; function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = () => {}, children, ...rest}: BaseModalProps) { const theme = useTheme(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const [previousStatusBarColor, setPreviousStatusBarColor] = useState(); const setStatusBarColor = (color = theme.appBG) => { @@ -33,7 +33,7 @@ function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = ( if (statusBarColor) { setPreviousStatusBarColor(statusBarColor); // If it is a full screen modal then match it with appBG, otherwise we use the backdrop color - setStatusBarColor(isFullScreenModal ? theme.appBG : ThemeStyleUtils.getThemeBackgroundColor(statusBarColor)); + setStatusBarColor(isFullScreenModal ? theme.appBG : StyleUtils.getThemeBackgroundColor(statusBarColor)); } onModalShow?.(); diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index 97aacab1a58e..a7b22a663e08 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -3,9 +3,8 @@ import {StyleProp, View, ViewStyle} from 'react-native'; import {ValueOf} from 'type-fest'; import {AvatarSource} from '@libs/UserUtils'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import type {Icon} from '@src/types/onyx/OnyxCommon'; @@ -81,7 +80,7 @@ function MultipleAvatars({ }: MultipleAvatarsProps) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const avatarSizeToStylesMap: AvatarSizeToStylesMap = useMemo( () => ({ @@ -103,7 +102,7 @@ function MultipleAvatars({ const secondAvatarStyle = secondAvatarStyleProp ?? [StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)]; - let avatarContainerStyles = ThemeStyleUtils.getContainerStyles(size, isInReportAction); + let avatarContainerStyles = StyleUtils.getContainerStyles(size, isInReportAction); const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[size as AvatarSizeToStyles] ?? avatarSizeToStylesMap.default, [size, avatarSizeToStylesMap]); const tooltipTexts = useMemo(() => (shouldShowTooltip ? icons.map((icon) => icon.name) : ['']), [shouldShowTooltip, icons]); @@ -163,7 +162,7 @@ function MultipleAvatars({ ); } - const oneAvatarSize = ThemeStyleUtils.getAvatarStyle(size); + const oneAvatarSize = StyleUtils.getAvatarStyle(size); const oneAvatarBorderWidth = StyleUtils.getAvatarBorderWidth(size).borderWidth ?? 0; const overlapSize = oneAvatarSize.width / 3; diff --git a/src/components/OfflineWithFeedback.js b/src/components/OfflineWithFeedback.js index c8372b4d9705..5fb6b93d7f98 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 useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import MessagesRow from './MessagesRow'; @@ -73,27 +73,9 @@ const defaultProps = { canDismissError: true, }; -/** - * This method applies the strikethrough to all the children passed recursively - * @param {Array} children - * @param {Object} styles - * @return {Array} - */ -function applyStrikeThrough(children, styles) { - 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, styles); - } - return React.cloneElement(child, props); - }); -} - function OfflineWithFeedback(props) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {isOffline} = useNetwork(); const hasErrors = !_.isEmpty(props.errors); @@ -109,6 +91,27 @@ 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 + * @param {Object} styles + * @return {Array} + */ + const applyStrikeThrough = useCallback( + (childrenProp) => + React.Children.map(childrenProp, (child) => { + if (!React.isValidElement(child)) { + return child; + } + const innerProps = {style: StyleUtils.combineStyles(child.props.style, styles.offlineFeedback.deleted, styles.userSelectNone)}; + if (child.props.children) { + innerProps.children = applyStrikeThrough(child.props.children, styles); + } + return React.cloneElement(child, innerProps); + }), + [StyleUtils, styles], + ); + // Apply strikethrough to children if needed, but skip it if we are not going to render them if (needsStrikeThrough && !hideChildren) { children = applyStrikeThrough(children, styles); diff --git a/src/components/OptionRow.js b/src/components/OptionRow.js index 10ef08eff316..8d100b466d1b 100644 --- a/src/components/OptionRow.js +++ b/src/components/OptionRow.js @@ -6,8 +6,8 @@ import _ from 'underscore'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import Button from './Button'; import DisplayNames from './DisplayNames'; @@ -104,6 +104,7 @@ const defaultProps = { function OptionRow(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const pressableRef = useRef(null); const [isDisabled, setIsDisabled] = useState(props.isDisabled); diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index 063094af2f21..4bcb9846c2f8 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -7,10 +7,10 @@ import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeed import Text from '@components/Text'; import withKeyboardState, {keyboardStatePropTypes} from '@components/withKeyboardState'; import withLocalize from '@components/withLocalize'; +import withStyleUtils, {withStyleUtilsPropTypes} from '@components/withStyleUtils'; import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; import withWindowDimensions from '@components/withWindowDimensions'; import compose from '@libs/compose'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import PDFPasswordForm from './PDFPasswordForm'; import {defaultProps, propTypes as pdfViewPropTypes} from './pdfViewPropTypes'; @@ -19,6 +19,7 @@ const propTypes = { ...pdfViewPropTypes, ...keyboardStatePropTypes, ...withThemeStylesPropTypes, + ...withStyleUtilsPropTypes, }; /** @@ -199,4 +200,4 @@ class PDFView extends Component { PDFView.propTypes = propTypes; PDFView.defaultProps = defaultProps; -export default compose(withWindowDimensions, withKeyboardState, withLocalize, withThemeStyles)(PDFView); +export default compose(withWindowDimensions, withKeyboardState, withLocalize, withThemeStyles, withStyleUtils)(PDFView); diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 89406f832a00..f9d9759b4b20 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -7,13 +7,14 @@ import withWindowDimensions from '@components/withWindowDimensions'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; import getModalStyles from '@styles/getModalStyles'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as Modal from '@userActions/Modal'; function Popover(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {onOpen, close} = React.useContext(PopoverContext); const insets = useSafeAreaInsets(); const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = getModalStyles( @@ -55,6 +56,7 @@ function Popover(props) { insets, }), [ + StyleUtils, insets, modalContainerStyle.marginBottom, modalContainerStyle.marginTop, diff --git a/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx b/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx index a9f37c8cd8c5..0d0ed33d5138 100644 --- a/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx +++ b/src/components/Pressable/GenericPressable/BaseGenericPressable.tsx @@ -5,8 +5,8 @@ import useSingleExecution from '@hooks/useSingleExecution'; import Accessibility from '@libs/Accessibility'; import HapticFeedback from '@libs/HapticFeedback'; import KeyboardShortcut from '@libs/KeyboardShortcut'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import PressableProps, {PressableRef} from './types'; @@ -37,6 +37,7 @@ function GenericPressable( ref: PressableRef, ) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {isExecuting, singleExecution} = useSingleExecution(); const isScreenReaderActive = Accessibility.useScreenReaderStatus(); const [hitSlop, onLayout] = Accessibility.useAutoHitSlop(); diff --git a/src/components/Pressable/PressableWithDelayToggle.tsx b/src/components/Pressable/PressableWithDelayToggle.tsx index 99cb70212738..6237ce3e4660 100644 --- a/src/components/Pressable/PressableWithDelayToggle.tsx +++ b/src/components/Pressable/PressableWithDelayToggle.tsx @@ -8,8 +8,8 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; import useThrottledButtonState from '@hooks/useThrottledButtonState'; import getButtonState from '@libs/getButtonState'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import variables from '@styles/variables'; import PressableProps, {PressableRef} from './GenericPressable/types'; import PressableWithoutFeedback from './PressableWithoutFeedback'; @@ -67,7 +67,7 @@ function PressableWithDelayToggle( ref: PressableRef, ) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const [isActive, temporarilyDisableInteractions] = useThrottledButtonState(); const updatePressState = () => { @@ -121,7 +121,7 @@ function PressableWithDelayToggle( {icon && ( (null); const executeSecondaryInteraction = (event: GestureResponderEvent) => { diff --git a/src/components/Reactions/AddReactionBubble.js b/src/components/Reactions/AddReactionBubble.js index b93953a9d1ae..994d467dfd6e 100644 --- a/src/components/Reactions/AddReactionBubble.js +++ b/src/components/Reactions/AddReactionBubble.js @@ -8,9 +8,8 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip/PopoverAnchorTooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import getButtonState from '@libs/getButtonState'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as Session from '@userActions/Session'; @@ -56,7 +55,7 @@ const defaultProps = { function AddReactionBubble(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const ref = useRef(); useEffect(() => EmojiPickerAction.resetEmojiPopoverAnchor, []); @@ -89,11 +88,7 @@ function AddReactionBubble(props) { [ - styles.emojiReactionBubble, - styles.userSelectNone, - ThemeStyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, false, props.isContextMenu), - ]} + style={({hovered, pressed}) => [styles.emojiReactionBubble, styles.userSelectNone, StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, false, props.isContextMenu)]} onPress={Session.checkIfActionIsAllowed(onPress)} onMouseDown={(e) => { // Allow text input blur when Add reaction is right clicked @@ -121,7 +116,7 @@ function AddReactionBubble(props) { src={Expensicons.AddReaction} width={props.isContextMenu ? variables.iconSizeNormal : variables.iconSizeSmall} height={props.isContextMenu ? variables.iconSizeNormal : variables.iconSizeSmall} - fill={ThemeStyleUtils.getIconFillColor(getButtonState(hovered, pressed))} + fill={StyleUtils.getIconFillColor(getButtonState(hovered, pressed))} /> diff --git a/src/components/Reactions/EmojiReactionBubble.js b/src/components/Reactions/EmojiReactionBubble.js index 0c8877c62f94..7fcdae8c0a5a 100644 --- a/src/components/Reactions/EmojiReactionBubble.js +++ b/src/components/Reactions/EmojiReactionBubble.js @@ -4,9 +4,8 @@ import PressableWithSecondaryInteraction from '@components/PressableWithSecondar import Text from '@components/Text'; import {withCurrentUserPersonalDetailsDefaultProps} from '@components/withCurrentUserPersonalDetails'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -56,12 +55,12 @@ const defaultProps = { function EmojiReactionBubble(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); return ( [ styles.emojiReactionBubble, - ThemeStyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, props.hasUserReacted, props.isContextMenu), + StyleUtils.getEmojiReactionBubbleStyle(hovered || pressed, props.hasUserReacted, props.isContextMenu), props.shouldBlockReactions && styles.cursorDisabled, styles.userSelectNone, ]} @@ -89,7 +88,7 @@ function EmojiReactionBubble(props) { dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} > {props.emojiCodes.join('')} - {props.count > 0 && {props.count}} + {props.count > 0 && {props.count}} ); } diff --git a/src/components/Reactions/MiniQuickEmojiReactions.js b/src/components/Reactions/MiniQuickEmojiReactions.js index fedbc7fd1458..92913a7c4c5e 100644 --- a/src/components/Reactions/MiniQuickEmojiReactions.js +++ b/src/components/Reactions/MiniQuickEmojiReactions.js @@ -11,8 +11,8 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; import getButtonState from '@libs/getButtonState'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; @@ -56,7 +56,7 @@ const defaultProps = { */ function MiniQuickEmojiReactions(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const ref = useRef(); const openEmojiPicker = () => { @@ -106,7 +106,7 @@ function MiniQuickEmojiReactions(props) { )} diff --git a/src/components/ReportActionItem/MoneyReportView.js b/src/components/ReportActionItem/MoneyReportView.js index ef0a1a3d9bef..c52d4abe371c 100644 --- a/src/components/ReportActionItem/MoneyReportView.js +++ b/src/components/ReportActionItem/MoneyReportView.js @@ -12,8 +12,8 @@ import * as ReportUtils from '@libs/ReportUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import reportPropTypes from '@pages/reportPropTypes'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; const propTypes = { @@ -29,6 +29,7 @@ const propTypes = { function MoneyReportView(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const isSettled = ReportUtils.isSettled(props.report.reportID); diff --git a/src/components/ReportActionItem/MoneyRequestPreview.js b/src/components/ReportActionItem/MoneyRequestPreview.js index 82d792443b97..fd10ca39b556 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.js +++ b/src/components/ReportActionItem/MoneyRequestPreview.js @@ -29,8 +29,8 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import walletTermsPropTypes from '@pages/EnablePayments/walletTermsPropTypes'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as PaymentMethods from '@userActions/PaymentMethods'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; @@ -139,6 +139,7 @@ const defaultProps = { function MoneyRequestPreview(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {isSmallScreenWidth, windowWidth} = useWindowDimensions(); if (_.isEmpty(props.iouReport) && !props.isBillSplit) { diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index eea08ab2c440..de7fc74488fb 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -32,8 +32,8 @@ import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateB import iouReportPropTypes from '@pages/iouReportPropTypes'; import reportPropTypes from '@pages/reportPropTypes'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -77,6 +77,7 @@ const defaultProps = { function MoneyRequestView({report, parentReport, policyCategories, shouldShowHorizontalRule, transaction, policyTags, policy}) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {isSmallScreenWidth} = useWindowDimensions(); const {translate} = useLocalize(); const {canUseViolations} = usePermissions(); diff --git a/src/components/ReportActionItem/ReportActionItemImages.js b/src/components/ReportActionItem/ReportActionItemImages.js index aef442013baa..b20513d63fe3 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.js +++ b/src/components/ReportActionItem/ReportActionItemImages.js @@ -6,8 +6,8 @@ import _ from 'underscore'; import Text from '@components/Text'; import transactionPropTypes from '@components/transactionPropTypes'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import ReportActionItemImage from './ReportActionItemImage'; @@ -53,6 +53,7 @@ const defaultProps = { function ReportActionItemImages({images, size, total, isHovered}) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); // Calculate the number of images to be shown, limited by the value of 'size' (if defined) // or the total number of images. const numberOfShownImages = Math.min(size || images.length, images.length); diff --git a/src/components/ReportActionItem/TaskPreview.js b/src/components/ReportActionItem/TaskPreview.js index 5bfd98c8a682..5d1c9972666a 100644 --- a/src/components/ReportActionItem/TaskPreview.js +++ b/src/components/ReportActionItem/TaskPreview.js @@ -22,8 +22,8 @@ import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as Session from '@userActions/Session'; import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; @@ -76,7 +76,7 @@ const defaultProps = { function TaskPreview(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; // The reportAction might not contain details regarding the taskReport // Only the direct parent reportAction will contain details about the taskReport @@ -129,7 +129,7 @@ function TaskPreview(props) { diff --git a/src/components/ReportActionItem/TaskView.js b/src/components/ReportActionItem/TaskView.js index fa2a1d69442d..ea02dba705a6 100644 --- a/src/components/ReportActionItem/TaskView.js +++ b/src/components/ReportActionItem/TaskView.js @@ -24,8 +24,8 @@ import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as Session from '@userActions/Session'; import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; @@ -46,7 +46,7 @@ const propTypes = { function TaskView(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); useEffect(() => { Task.setTaskReport({...props.report}); }, [props.report]); @@ -84,7 +84,7 @@ function TaskView(props) { style={({pressed}) => [ styles.ph5, styles.pv2, - ThemeStyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, false, disableState, !isDisableInteractive), true), + StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed, false, disableState, !isDisableInteractive), true), isDisableInteractive && !disableState && styles.cursorDefault, ]} ref={props.forwardedRef} @@ -124,7 +124,7 @@ function TaskView(props) { )} diff --git a/src/components/RoomHeaderAvatars.js b/src/components/RoomHeaderAvatars.js index 6e82758f96fa..04341ea6ad0a 100644 --- a/src/components/RoomHeaderAvatars.js +++ b/src/components/RoomHeaderAvatars.js @@ -4,9 +4,8 @@ import {View} from 'react-native'; import _ from 'underscore'; import * as UserUtils from '@libs/UserUtils'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import AttachmentModal from './AttachmentModal'; import Avatar from './Avatar'; @@ -25,7 +24,7 @@ const defaultProps = { function RoomHeaderAvatars(props) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); if (!props.icons.length) { return null; } @@ -67,7 +66,7 @@ function RoomHeaderAvatars(props) { styles.roomHeaderAvatar, // Due to border-box box-sizing, the Avatars have to be larger when bordered to visually match size with non-bordered Avatars - ThemeStyleUtils.getAvatarStyle(theme, CONST.AVATAR_SIZE.LARGE_BORDERED), + StyleUtils.getAvatarStyle(theme, CONST.AVATAR_SIZE.LARGE_BORDERED), ]; return ( diff --git a/src/components/SafeAreaConsumer/index.android.tsx b/src/components/SafeAreaConsumer/index.android.tsx index 95a3b309d5e7..5117000627cf 100644 --- a/src/components/SafeAreaConsumer/index.android.tsx +++ b/src/components/SafeAreaConsumer/index.android.tsx @@ -2,7 +2,7 @@ import React from 'react'; // eslint-disable-next-line no-restricted-imports import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; import StatusBar from '@libs/StatusBar'; -import StyleUtils from '@styles/utils/StyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import SafeAreaConsumerProps from './types'; /** @@ -10,6 +10,8 @@ import SafeAreaConsumerProps from './types'; * may need not just the insets, but the computed styles so we save a few lines of code with this. */ function SafeAreaConsumer({children}: SafeAreaConsumerProps) { + const StyleUtils = useStyleUtils(); + return ( {(insets) => { diff --git a/src/components/SafeAreaConsumer/index.tsx b/src/components/SafeAreaConsumer/index.tsx index f52509cc738c..54c5d984be5f 100644 --- a/src/components/SafeAreaConsumer/index.tsx +++ b/src/components/SafeAreaConsumer/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; // eslint-disable-next-line no-restricted-imports import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; -import StyleUtils from '@styles/utils/StyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import SafeAreaConsumerProps from './types'; /** @@ -9,6 +9,8 @@ import SafeAreaConsumerProps from './types'; * may need not just the insets, but the computed styles so we save a few lines of code with this. */ function SafeAreaConsumer({children}: SafeAreaConsumerProps) { + const StyleUtils = useStyleUtils(); + return ( {(insets) => { diff --git a/src/components/SelectionList/BaseListItem.js b/src/components/SelectionList/BaseListItem.js index ab16f9638dda..f58be18d93fe 100644 --- a/src/components/SelectionList/BaseListItem.js +++ b/src/components/SelectionList/BaseListItem.js @@ -8,9 +8,8 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import RadioListItem from './RadioListItem'; import {baseListItemPropTypes} from './selectionListPropTypes'; @@ -28,7 +27,7 @@ function BaseListItem({ }) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const isUserItem = lodashGet(item, 'icons.length', 0) > 0; const ListItem = isUserItem ? UserListItem : RadioListItem; @@ -64,7 +63,7 @@ function BaseListItem({ ({ diff --git a/src/components/SubscriptAvatar.tsx b/src/components/SubscriptAvatar.tsx index 0c73d63b672a..7fa2900eaffb 100644 --- a/src/components/SubscriptAvatar.tsx +++ b/src/components/SubscriptAvatar.tsx @@ -3,9 +3,8 @@ import {View} from 'react-native'; import {ValueOf} from 'type-fest'; import type {AvatarSource} from '@libs/UserUtils'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import {AvatarType} from '@src/types/onyx/OnyxCommon'; import Avatar from './Avatar'; @@ -51,10 +50,10 @@ type SubscriptAvatarProps = { function SubscriptAvatar({mainAvatar = {}, secondaryAvatar = {}, size = CONST.AVATAR_SIZE.DEFAULT, backgroundColor, noMargin = false, showTooltip = true}: SubscriptAvatarProps) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const isSmall = size === CONST.AVATAR_SIZE.SMALL; const subscriptStyle = size === CONST.AVATAR_SIZE.SMALL_NORMAL ? styles.secondAvatarSubscriptSmallNormal : styles.secondAvatarSubscript; - const containerStyle = ThemeStyleUtils.getContainerStyles(size); + const containerStyle = StyleUtils.getContainerStyles(size); return ( diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index 57cfd975ea3c..334ca3e38370 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -6,14 +6,15 @@ import OptionsSelector from '@components/OptionsSelector'; import useLocalize from '@hooks/useLocalize'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import {defaultProps, propTypes} from './tagPickerPropTypes'; function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, shouldShowDisabledAndSelectedOption, insets, onSubmit}) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const [searchValue, setSearchValue] = useState(''); diff --git a/src/components/TextInput/BaseTextInput/index.js b/src/components/TextInput/BaseTextInput/index.js index 134500a1ea59..9c9afb6ebacc 100644 --- a/src/components/TextInput/BaseTextInput/index.js +++ b/src/components/TextInput/BaseTextInput/index.js @@ -17,9 +17,8 @@ import * as Browser from '@libs/Browser'; import isInputAutoFilled from '@libs/isInputAutoFilled'; import useNativeDriver from '@libs/useNativeDriver'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import * as baseTextInputPropTypes from './baseTextInputPropTypes'; @@ -27,7 +26,7 @@ import * as baseTextInputPropTypes from './baseTextInputPropTypes'; function BaseTextInput(props) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const initialValue = props.value || props.defaultValue || ''; const initialActiveLabel = props.forceActiveLabel || initialValue.length > 0 || Boolean(props.prefixCharacter); @@ -335,7 +334,7 @@ function BaseTextInput(props) { !isMultiline && Browser.isMobileChrome() && {boxSizing: 'content-box', height: undefined}, // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. - ...(props.autoGrowHeight ? [ThemeStyleUtils.getAutoGrowHeightInputStyle(textInputHeight, maxHeight), styles.verticalAlignTop] : []), + ...(props.autoGrowHeight ? [StyleUtils.getAutoGrowHeightInputStyle(textInputHeight, maxHeight), styles.verticalAlignTop] : []), // Add disabled color theme when field is not editable. props.disabled && styles.textInputDisabled, diff --git a/src/components/TextInput/BaseTextInput/index.native.js b/src/components/TextInput/BaseTextInput/index.native.js index 375ca0f4ee35..57e3468d1502 100644 --- a/src/components/TextInput/BaseTextInput/index.native.js +++ b/src/components/TextInput/BaseTextInput/index.native.js @@ -17,8 +17,8 @@ import getSecureEntryKeyboardType from '@libs/getSecureEntryKeyboardType'; import isInputAutoFilled from '@libs/isInputAutoFilled'; import useNativeDriver from '@libs/useNativeDriver'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import * as baseTextInputPropTypes from './baseTextInputPropTypes'; @@ -26,6 +26,7 @@ import * as baseTextInputPropTypes from './baseTextInputPropTypes'; function BaseTextInput(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const initialValue = props.value || props.defaultValue || ''; const initialActiveLabel = props.forceActiveLabel || initialValue.length > 0 || Boolean(props.prefixCharacter); const isMultiline = props.multiline || props.autoGrowHeight; diff --git a/src/components/ThumbnailImage.tsx b/src/components/ThumbnailImage.tsx index 7f4157893c8d..a4a200d96082 100644 --- a/src/components/ThumbnailImage.tsx +++ b/src/components/ThumbnailImage.tsx @@ -3,8 +3,8 @@ import React, {useCallback, useState} from 'react'; import {Dimensions, StyleProp, View, ViewStyle} from 'react-native'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import ImageWithSizeCalculation from './ImageWithSizeCalculation'; type ThumbnailImageProps = { @@ -72,6 +72,7 @@ function calculateThumbnailImageSize(width: number, height: number, windowHeight function ThumbnailImage({previewSourceURL, style, isAuthTokenRequired, imageWidth = 200, imageHeight = 200, shouldDynamicallyResize = true}: ThumbnailImageProps) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {windowHeight} = useWindowDimensions(); const initialDimensions = calculateThumbnailImageSize(imageWidth, imageHeight, windowHeight); const [currentImageWidth, setCurrentImageWidth] = useState(initialDimensions.thumbnailWidth); diff --git a/src/components/ValuePicker/index.js b/src/components/ValuePicker/index.js index 03d61fe26de8..6eb20d1bde6a 100644 --- a/src/components/ValuePicker/index.js +++ b/src/components/ValuePicker/index.js @@ -5,8 +5,8 @@ import {View} from 'react-native'; import FormHelpMessage from '@components/FormHelpMessage'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import refPropTypes from '@components/refPropTypes'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import ValueSelectorModal from './ValueSelectorModal'; @@ -45,6 +45,7 @@ const defaultProps = { function ValuePicker({value, label, items, placeholder, errorText, onInputChange, forwardedRef}) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const [isPickerVisible, setIsPickerVisible] = useState(false); const showPickerModal = () => { diff --git a/src/components/withThemeStyleUtils.tsx b/src/components/withStyleUtils.tsx similarity index 53% rename from src/components/withThemeStyleUtils.tsx rename to src/components/withStyleUtils.tsx index a7ee705a5cfa..eb31cd331c49 100644 --- a/src/components/withThemeStyleUtils.tsx +++ b/src/components/withStyleUtils.tsx @@ -1,19 +1,19 @@ import PropTypes from 'prop-types'; import React, {ComponentType, ForwardedRef, forwardRef, ReactElement, RefAttributes} from 'react'; import getComponentDisplayName from '@libs/getComponentDisplayName'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import {ThemeStyleUtilsType} from '@styles/utils/ThemeStyleUtils'; +import {StyleUtilsType} from '@styles/StyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; const withStyleUtilsPropTypes = { - themeStyles: PropTypes.object.isRequired, + StyleUtils: PropTypes.object.isRequired, }; -type WithStyleUtilsProps = {StyleUtils: ThemeStyleUtilsType}; +type WithStyleUtilsProps = {StyleUtils: StyleUtilsType}; -export default function withThemeStyleUtils( +export default function withStyleUtils( WrappedComponent: ComponentType>, ): (props: Omit & React.RefAttributes) => ReactElement | null { - function WithThemeStyles(props: Omit, ref: ForwardedRef): ReactElement { - const StyleUtils = useThemeStyleUtils(); + function WithStyleUtils(props: Omit, ref: ForwardedRef): ReactElement { + const StyleUtils = useStyleUtils(); return ( {({paddingBottom}) => ( - + diff --git a/src/pages/home/report/AnimatedEmptyStateBackground.js b/src/pages/home/report/AnimatedEmptyStateBackground.js index a1bb3c038a2c..0ff401a9d3f4 100644 --- a/src/pages/home/report/AnimatedEmptyStateBackground.js +++ b/src/pages/home/report/AnimatedEmptyStateBackground.js @@ -3,13 +3,14 @@ import Animated, {SensorType, useAnimatedSensor, useAnimatedStyle, useSharedValu import useWindowDimensions from '@hooks/useWindowDimensions'; import * as NumberUtils from '@libs/NumberUtils'; import useThemeIllustrations from '@styles/illustrations/useThemeIllustrations'; -import StyleUtils from '@styles/utils/StyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; const IMAGE_OFFSET_Y = 75; function AnimatedEmptyStateBackground() { + const StyleUtils = useStyleUtils(); const {windowWidth, isSmallScreenWidth} = useWindowDimensions(); const illustrations = useThemeIllustrations(); const IMAGE_OFFSET_X = windowWidth / 2; diff --git a/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js b/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js index c6c40a9339a6..f5a688e9d8ed 100644 --- a/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js +++ b/src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js @@ -7,7 +7,7 @@ import { defaultProps as GenericReportActionContextMenuDefaultProps, propTypes as genericReportActionContextMenuPropTypes, } from '@pages/home/report/ContextMenu/genericReportActionContextMenuPropTypes'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import CONST from '@src/CONST'; const propTypes = { @@ -24,11 +24,11 @@ const defaultProps = { }; function MiniReportActionContextMenu(props) { - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); return ( = 0 ? Math.min(props.maxAmountOfPreviews, props.linkMetadata.length) : props.linkMetadata.length), (linkData) => { diff --git a/src/pages/home/report/ReactionList/HeaderReactionList.js b/src/pages/home/report/ReactionList/HeaderReactionList.js index 970eb456b550..39a1cdba505f 100644 --- a/src/pages/home/report/ReactionList/HeaderReactionList.js +++ b/src/pages/home/report/ReactionList/HeaderReactionList.js @@ -6,11 +6,12 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import compose from '@libs/compose'; import * as EmojiUtils from '@libs/EmojiUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import reactionPropTypes from './reactionPropTypes'; +('@styles/StyleUtils'); + const propTypes = { ...reactionPropTypes, ...withLocalizePropTypes, @@ -28,13 +29,13 @@ const defaultProps = { function HeaderReactionList(props) { const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); return ( - + {props.emojiCodes.join('')} - {props.emojiCount} + {props.emojiCount} {`:${EmojiUtils.getLocalizedEmojiName(props.emojiName, props.preferredLocale)}:`} diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 777d43ce8d8b..80d032669a4e 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -47,9 +47,8 @@ import userWalletPropTypes from '@pages/EnablePayments/userWalletPropTypes'; import {ReactionListContext} from '@pages/home/ReportScreenContext'; import reportPropTypes from '@pages/reportPropTypes'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as BankAccounts from '@userActions/BankAccounts'; import * as EmojiPickerAction from '@userActions/EmojiPickerAction'; import * as store from '@userActions/ReimbursementAccount/store'; @@ -138,7 +137,7 @@ const defaultProps = { function ReportActionItem(props) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const [isContextMenuActive, setIsContextMenuActive] = useState(() => ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)); const [isHidden, setIsHidden] = useState(false); @@ -695,7 +694,7 @@ function ReportActionItem(props) { draftMessage={props.draftMessage} isChronosReport={ReportUtils.chatIncludesChronos(originalReport)} /> - + ReportActions.clearReportActionErrors(props.report.reportID, props.action)} pendingAction={props.draftMessage ? null : props.action.pendingAction} diff --git a/src/pages/home/report/ReportActionItemCreated.js b/src/pages/home/report/ReportActionItemCreated.js index 3fd4ea76beee..01857e2f2f1c 100644 --- a/src/pages/home/report/ReportActionItemCreated.js +++ b/src/pages/home/report/ReportActionItemCreated.js @@ -14,8 +14,8 @@ import compose from '@libs/compose'; import reportWithoutHasDraftSelector from '@libs/OnyxSelectors/reportWithoutHasDraftSelector'; import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -50,6 +50,7 @@ const defaultProps = { function ReportActionItemCreated(props) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); if (!ReportUtils.isChatReport(props.report)) { return null; } diff --git a/src/pages/home/report/ReportActionItemParentAction.js b/src/pages/home/report/ReportActionItemParentAction.js index 96311024a367..4a125d1d5633 100644 --- a/src/pages/home/report/ReportActionItemParentAction.js +++ b/src/pages/home/report/ReportActionItemParentAction.js @@ -9,8 +9,8 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withW import compose from '@libs/compose'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import reportPropTypes from '@pages/reportPropTypes'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as Report from '@userActions/Report'; import ONYXKEYS from '@src/ONYXKEYS'; import AnimatedEmptyStateBackground from './AnimatedEmptyStateBackground'; @@ -47,6 +47,7 @@ const defaultProps = { function ReportActionItemParentAction(props) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const parentReportAction = props.parentReportActions[`${props.report.parentReportActionID}`]; // In case of transaction threads, we do not want to render the parent report action. diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 6264de4ca231..03603f201edf 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -21,8 +21,8 @@ import * as UserUtils from '@libs/UserUtils'; import reportPropTypes from '@pages/reportPropTypes'; import stylePropTypes from '@styles/stylePropTypes'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import ReportActionItemDate from './ReportActionItemDate'; @@ -81,6 +81,7 @@ const showWorkspaceDetails = (reportID) => { function ReportActionItemSingle(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const actorAccountID = props.action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && props.iouReport ? props.iouReport.managerID : props.action.actorAccountID; let displayName = ReportUtils.getDisplayNameForParticipant(actorAccountID); diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 446a0c9efb14..e9a4b75732e0 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -20,8 +20,8 @@ import SidebarUtils from '@libs/SidebarUtils'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; import safeAreaInsetPropTypes from '@pages/safeAreaInsetPropTypes'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import * as App from '@userActions/App'; import * as Session from '@userActions/Session'; @@ -54,6 +54,7 @@ const propTypes = { function SidebarLinks({onLinkClick, insets, optionListItems, isLoading, priorityMode = CONST.PRIORITY_MODE.DEFAULT, isActiveReport, isCreateMenuOpen}) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const modal = useRef({}); const {translate, updateLocale} = useLocalize(); const {isSmallScreenWidth} = useWindowDimensions(); diff --git a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js index 59335ef53d1b..899409a016c4 100644 --- a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js @@ -17,8 +17,8 @@ import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; import * as ValidationUtils from '@libs/ValidationUtils'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import useThemeStyleUtils from '@styles/useThemeStyleUtils'; import * as Session from '@userActions/Session'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; @@ -74,7 +74,7 @@ const defaultProps = { function BaseValidateCodeForm(props) { const theme = useTheme(); const styles = useThemeStyles(); - const ThemeStyleUtils = useThemeStyleUtils(); + const StyleUtils = useStyleUtils(); const [formError, setFormError] = useState({}); const [validateCode, setValidateCode] = useState(''); const loginData = props.loginList[props.contactMethod]; @@ -210,9 +210,7 @@ function BaseValidateCodeForm(props) { role={CONST.ACCESSIBILITY_ROLE.BUTTON} accessibilityLabel={props.translate('validateCodeForm.magicCodeNotReceived')} > - - {props.translate('validateCodeForm.magicCodeNotReceived')} - + {props.translate('validateCodeForm.magicCodeNotReceived')} {props.hasMagicCodeBeenSent && ( onPress(e, paymentMethod.accountType, paymentMethod.accountData, paymentMethod.isDefault, paymentMethod.methodID), - iconFill: isMethodActive ? ThemeStyleUtils.getIconFillColor(CONST.BUTTON_STATES.PRESSED) : null, - wrapperStyle: isMethodActive ? [ThemeStyleUtils.getButtonBackgroundColorStyle(CONST.BUTTON_STATES.PRESSED)] : null, + iconFill: isMethodActive ? StyleUtils.getIconFillColor(CONST.BUTTON_STATES.PRESSED) : null, + wrapperStyle: isMethodActive ? [StyleUtils.getButtonBackgroundColorStyle(CONST.BUTTON_STATES.PRESSED)] : null, disabled: paymentMethod.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, }; }); diff --git a/src/pages/signin/SignInHeroCopy.js b/src/pages/signin/SignInHeroCopy.js index 172cf086c8b3..75c53c6b2344 100644 --- a/src/pages/signin/SignInHeroCopy.js +++ b/src/pages/signin/SignInHeroCopy.js @@ -5,8 +5,8 @@ import Text from '@components/Text'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import compose from '@libs/compose'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; const propTypes = { @@ -27,6 +27,7 @@ const defaultProps = { function SignInHeroCopy(props) { const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); return ( [ function Footer(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const isVertical = props.shouldShowSmallScreen; const imageDirection = isVertical ? styles.flexRow : styles.flexColumn; const imageStyle = isVertical ? styles.pr0 : styles.alignSelfCenter; diff --git a/src/pages/signin/SignInPageLayout/SignInPageContent.js b/src/pages/signin/SignInPageLayout/SignInPageContent.js index 26dca0b6c1a3..fd48ebecf066 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageContent.js +++ b/src/pages/signin/SignInPageLayout/SignInPageContent.js @@ -10,8 +10,8 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import SignInHeroImage from '@pages/signin/SignInHeroImage'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; const propTypes = { @@ -41,6 +41,7 @@ const propTypes = { function SignInPageContent(props) { const {isSmallScreenWidth} = useWindowDimensions(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); return ( diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index bd8448671f9d..667f873c572e 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -9,8 +9,8 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; import compose from '@libs/compose'; import SignInPageHero from '@pages/signin/SignInPageHero'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import variables from '@styles/variables'; import BackgroundImage from './BackgroundImage'; import Footer from './Footer'; @@ -60,6 +60,7 @@ const defaultProps = { function SignInPageLayout(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const scrollViewRef = useRef(); const prevPreferredLocale = usePrevious(props.preferredLocale); let containerStyles = [styles.flex1, styles.signInPageInner]; diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js index 6b57d8fa2388..7e2d54b00ebd 100755 --- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js @@ -21,8 +21,8 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import ChangeExpensifyLoginLink from '@pages/signin/ChangeExpensifyLoginLink'; import Terms from '@pages/signin/Terms'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import StyleUtils from '@styles/utils/StyleUtils'; import * as Session from '@userActions/Session'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; @@ -84,6 +84,7 @@ const defaultProps = { function BaseValidateCodeForm(props) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const [formError, setFormError] = useState({}); const [validateCode, setValidateCode] = useState(props.credentials.validateCode || ''); const [twoFactorAuthCode, setTwoFactorAuthCode] = useState(''); diff --git a/src/stories/Composer.stories.js b/src/stories/Composer.stories.js index 467f9243cb09..799012e1c051 100644 --- a/src/stories/Composer.stories.js +++ b/src/stories/Composer.stories.js @@ -7,7 +7,7 @@ import Text from '@components/Text'; import withNavigationFallback from '@components/withNavigationFallback'; import styles from '@styles/styles'; import themeColors from '@styles/themes/default'; -import StyleUtils from '@styles/utils/StyleUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import CONST from '@src/CONST'; const ComposerWithNavigation = withNavigationFallback(Composer); @@ -25,6 +25,7 @@ const story = { const parser = new ExpensiMark(); function Default(args) { + const StyleUtils = useStyleUtils(); const [pastedFile, setPastedFile] = useState(null); const [comment, setComment] = useState(args.defaultValue); const renderedHTML = parser.replace(comment); diff --git a/src/styles/utils/StyleUtils.ts b/src/styles/StyleUtils.ts similarity index 63% rename from src/styles/utils/StyleUtils.ts rename to src/styles/StyleUtils.ts index fa7254de90b8..4d038b0a83ff 100644 --- a/src/styles/utils/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -1,19 +1,58 @@ import {CSSProperties} from 'react'; -import {Animated, DimensionValue, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native'; +import {Animated, DimensionValue, ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native'; import {EdgeInsets} from 'react-native-safe-area-context'; import {ValueOf} from 'type-fest'; import * as Browser from '@libs/Browser'; import * as UserUtils from '@libs/UserUtils'; -import colors from '@styles/colors'; -import fontFamily from '@styles/fontFamily'; -import {ThemeColors} from '@styles/themes/types'; -import positioning from '@styles/utilities/positioning'; -import spacing from '@styles/utilities/spacing'; -import variables from '@styles/variables'; import CONST from '@src/CONST'; import {Transaction} from '@src/types/onyx'; -import {hexadecimalToRGBArray} from './functions'; -import {AllStyles, AvatarSize, AvatarSizeName, AvatarSizeValue, ButtonSizeValue, EReceiptColorName, EreceiptColorStyle, ParsableStyle, WorkspaceColorStyle} from './types'; +import colors from './colors'; +import fontFamily from './fontFamily'; +import {type ThemeStyles} from './styles'; +import {ThemeColors} from './themes/types'; +import cursor from './utilities/cursor'; +import positioning from './utilities/positioning'; +import spacing from './utilities/spacing'; +import variables from './variables'; + +type AllStyles = ViewStyle | TextStyle | ImageStyle; +type ParsableStyle = StyleProp | ((state: PressableStateCallbackType) => StyleProp); + +type ColorValue = ValueOf; +type AvatarSizeName = ValueOf; +type EReceiptColorName = ValueOf; +type AvatarSizeValue = ValueOf< + Pick< + typeof variables, + | 'avatarSizeNormal' + | 'avatarSizeSmallSubscript' + | 'avatarSizeMidSubscript' + | 'avatarSizeSubscript' + | 'avatarSizeSmall' + | 'avatarSizeSmaller' + | 'avatarSizeXLarge' + | 'avatarSizeLarge' + | 'avatarSizeMedium' + | 'avatarSizeLargeBordered' + | 'avatarSizeHeader' + | 'avatarSizeMentionIcon' + | 'avatarSizeSmallNormal' + > +>; + +type AvatarStyle = { + width: number; + height: number; + borderRadius: number; + backgroundColor: string; +}; + +type ButtonSizeValue = ValueOf; +type ButtonStateName = ValueOf; +type AvatarSize = {width: number}; + +type WorkspaceColorStyle = {backgroundColor: ColorValue; fill: ColorValue}; +type EreceiptColorStyle = {backgroundColor: ColorValue; color: ColorValue}; const workspaceColorOptions: WorkspaceColorStyle[] = [ {backgroundColor: colors.blue200, fill: colors.blue700}, @@ -109,6 +148,80 @@ const avatarBorderWidths: Partial> = { [CONST.AVATAR_SIZE.LARGE_BORDERED]: 4, }; +/** + * Converts a color in hexadecimal notation into RGB notation. + * + * @param hexadecimal A color in hexadecimal notation. + * @returns `undefined` if the input color is not in hexadecimal notation. Otherwise, the RGB components of the input color. + */ +function hexadecimalToRGBArray(hexadecimal: string): number[] | undefined { + const components = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexadecimal); + + if (components === null) { + return undefined; + } + + return components.slice(1).map((component) => parseInt(component, 16)); +} + +/** + * Converts a color in RGBA notation to an equivalent color in RGB notation. + * + * @param foregroundRGB The three components of the foreground color in RGB notation. + * @param backgroundRGB The three components of the background color in RGB notation. + * @param opacity The desired opacity of the foreground color. + * @returns The RGB components of the RGBA color converted to RGB. + */ +function convertRGBAToRGB(foregroundRGB: number[], backgroundRGB: number[], opacity: number): number[] { + const [foregroundRed, foregroundGreen, foregroundBlue] = foregroundRGB; + const [backgroundRed, backgroundGreen, backgroundBlue] = backgroundRGB; + + return [(1 - opacity) * backgroundRed + opacity * foregroundRed, (1 - opacity) * backgroundGreen + opacity * foregroundGreen, (1 - opacity) * backgroundBlue + opacity * foregroundBlue]; +} + +/** + * Converts three unit values to the three components of a color in RGB notation. + * + * @param red A unit value representing the first component of a color in RGB notation. + * @param green A unit value representing the second component of a color in RGB notation. + * @param blue A unit value representing the third component of a color in RGB notation. + * @returns An array with the three components of a color in RGB notation. + */ +function convertUnitValuesToRGB(red: number, green: number, blue: number): number[] { + return [Math.floor(red * 255), Math.floor(green * 255), Math.floor(blue * 255)]; +} + +/** + * Converts the three components of a color in RGB notation to three unit values. + * + * @param red The first component of a color in RGB notation. + * @param green The second component of a color in RGB notation. + * @param blue The third component of a color in RGB notation. + * @returns An array with three unit values representing the components of a color in RGB notation. + */ +function convertRGBToUnitValues(red: number, green: number, blue: number): number[] { + return [red / 255, green / 255, blue / 255]; +} + +/** + * Matches an RGBA or RGB color value and extracts the color components. + * + * @param color - The RGBA or RGB color value to match and extract components from. + * @returns An array containing the extracted color components [red, green, blue, alpha]. + * + * Returns null if the input string does not match the pattern. + */ +function extractValuesFromRGB(color: string): number[] | null { + const rgbaPattern = /rgba?\((?[.\d]+)[, ]+(?[.\d]+)[, ]+(?[.\d]+)(?:\s?[,/]\s?(?[.\d]+%?))?\)$/i; + const matchRGBA = color.match(rgbaPattern); + if (matchRGBA) { + const [, red, green, blue, alpha] = matchRGBA; + return [parseInt(red, 10), parseInt(green, 10), parseInt(blue, 10), alpha ? parseFloat(alpha) : 1]; + } + + return null; +} + /** * Return the style size from an avatar size constant */ @@ -918,7 +1031,7 @@ function getTransparentColor(color: string) { return `${color}00`; } -const StyleUtils = { +const staticStyleUtils = { combineStyles, displayIfTrue, getAmountFontSizeAndLineHeight, @@ -981,7 +1094,345 @@ const StyleUtils = { getEReceiptColorCode, }; -type StyleUtilsType = typeof StyleUtils; +const createThemeStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ + ...staticStyleUtils, + + /** + * Gets styles for AutoCompleteSuggestion row + */ + getAutoCompleteSuggestionItemStyle: (highlightedEmojiIndex: number, rowHeight: number, isHovered: boolean, currentEmojiIndex: number): ViewStyle[] => { + let backgroundColor; + + if (currentEmojiIndex === highlightedEmojiIndex) { + backgroundColor = theme.activeComponentBG; + } else if (isHovered) { + backgroundColor = theme.hoverComponentBG; + } + + return [ + { + height: rowHeight, + justifyContent: 'center', + }, + backgroundColor + ? { + backgroundColor, + } + : {}, + ]; + }, + + /** + * Returns auto grow height text input style + */ + getAutoGrowHeightInputStyle: (textInputHeight: number, maxHeight: number): ViewStyle => { + if (textInputHeight > maxHeight) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...styles.pr0, + ...styles.overflowAuto, + }; + } + + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...styles.pr0, + ...styles.overflowHidden, + // maxHeight is not of the input only but the of the whole input container + // which also includes the top padding and bottom border + height: maxHeight - styles.textInputMultilineContainer.paddingTop - styles.textInputContainer.borderBottomWidth, + }; + }, + + /** + * Return the style from an avatar size constant + */ + getAvatarStyle: (size: AvatarSizeName): AvatarStyle => { + const avatarSize = getAvatarSize(size); + return { + height: avatarSize, + width: avatarSize, + borderRadius: avatarSize, + backgroundColor: theme.offline, + }; + }, + + /** + * Generate a style for the background color of the Badge + */ + getBadgeColorStyle: (isSuccess: boolean, isError: boolean, isPressed = false, isAdHoc = false): ViewStyle => { + if (isSuccess) { + if (isAdHoc) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return isPressed ? styles.badgeAdHocSuccessPressed : styles.badgeAdHocSuccess; + } + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return isPressed ? styles.badgeSuccessPressed : styles.badgeSuccess; + } + if (isError) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return isPressed ? styles.badgeDangerPressed : styles.badgeDanger; + } + return {}; + }, + + /** + * Generate a style for the background color of the button, based on its current state. + * + * @param buttonState - One of {'default', 'hovered', 'pressed'} + * @param isMenuItem - whether this button is apart of a list + */ + getButtonBackgroundColorStyle: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuItem = false): ViewStyle => { + switch (buttonState) { + case CONST.BUTTON_STATES.PRESSED: + return {backgroundColor: theme.buttonPressedBG}; + case CONST.BUTTON_STATES.ACTIVE: + return isMenuItem ? {backgroundColor: theme.border} : {backgroundColor: theme.buttonHoveredBG}; + case CONST.BUTTON_STATES.DISABLED: + case CONST.BUTTON_STATES.DEFAULT: + default: + return {}; + } + }, + + /** + * Returns the checkbox container style + */ + getCheckboxContainerStyle: (size: number, borderRadius = 4): ViewStyle => ({ + backgroundColor: theme.componentBG, + height: size, + width: size, + borderColor: theme.borderLighter, + borderWidth: 2, + justifyContent: 'center', + alignItems: 'center', + // eslint-disable-next-line object-shorthand + borderRadius: borderRadius, + }), + + /** + * Select the correct color for text. + */ + getColoredBackgroundStyle: (isColored: boolean): StyleProp => ({backgroundColor: isColored ? theme.link : undefined}), + + /** + * Returns link styles based on whether the link is disabled or not + */ + getDisabledLinkStyles: (isDisabled = false): ViewStyle => { + const disabledLinkStyles = { + color: theme.textSupporting, + ...cursor.cursorDisabled, + }; + + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...styles.link, + ...(isDisabled ? disabledLinkStyles : {}), + }; + }, + + /** + * Get the styles of the text next to dot indicators + */ + getDotIndicatorTextStyles: (isErrorText = true): TextStyle => (isErrorText ? {...styles.offlineFeedback.text, color: styles.formError.color} : {...styles.offlineFeedback.text}), + + getEmojiReactionBubbleStyle: (isHovered: boolean, hasUserReacted: boolean, isContextMenu = false): ViewStyle => { + let backgroundColor = theme.border; + + if (isHovered) { + backgroundColor = theme.buttonHoveredBG; + } + + if (hasUserReacted) { + backgroundColor = theme.reactionActiveBackground; + } + + if (isContextMenu) { + return { + paddingVertical: 3, + paddingHorizontal: 12, + backgroundColor, + }; + } + + return { + paddingVertical: 2, + paddingHorizontal: 8, + backgroundColor, + }; + }, + + getEmojiReactionCounterTextStyle: (hasUserReacted: boolean): TextStyle => { + if (hasUserReacted) { + return {color: theme.reactionActiveText}; + } + + return {color: theme.text}; + }, + + getErrorPageContainerStyle: (safeAreaPaddingBottom = 0): ViewStyle => ({ + backgroundColor: theme.componentBG, + paddingBottom: 40 + safeAreaPaddingBottom, + }), + + getGoogleListViewStyle: (shouldDisplayBorder: boolean): ViewStyle => { + if (shouldDisplayBorder) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { + ...styles.borderTopRounded, + ...styles.borderBottomRounded, + marginTop: 4, + paddingVertical: 6, + }; + } + + return { + transform: 'scale(0)', + }; + }, + + /** + * Return the height of magic code input container + */ + getHeightOfMagicCodeInput: (): ViewStyle => ({height: styles.magicCodeInputContainer.minHeight - styles.textInputContainer.borderBottomWidth}), + + /** + * Generate fill color of an icon based on its state. + * + * @param buttonState - One of {'default', 'hovered', 'pressed'} + * @param isMenuIcon - whether this icon is apart of a list + */ + getIconFillColor: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuIcon = false): string => { + switch (buttonState) { + case CONST.BUTTON_STATES.ACTIVE: + case CONST.BUTTON_STATES.PRESSED: + return theme.iconHovered; + case CONST.BUTTON_STATES.COMPLETE: + return theme.iconSuccessFill; + case CONST.BUTTON_STATES.DEFAULT: + case CONST.BUTTON_STATES.DISABLED: + default: + if (isMenuIcon) { + return theme.iconMenu; + } + return theme.icon; + } + }, + + /** + * Returns style object for the user mention component based on whether the mention is ours or not. + */ + getMentionStyle: (isOurMention: boolean): ViewStyle => { + const backgroundColor = isOurMention ? theme.ourMentionBG : theme.mentionBG; + return { + backgroundColor, + borderRadius: variables.componentBorderRadiusSmall, + paddingHorizontal: 2, + }; + }, + + /** + * Returns text color for the user mention text based on whether the mention is ours or not. + */ + getMentionTextColor: (isOurMention: boolean): string => (isOurMention ? theme.ourMentionText : theme.mentionText), + + /** + * Generate the wrapper styles for the mini ReportActionContextMenu. + */ + getMiniReportActionContextMenuWrapperStyle: (isReportActionItemGrouped: boolean): ViewStyle => + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + ({ + ...(isReportActionItemGrouped ? positioning.tn8 : positioning.tn4), + ...positioning.r4, + ...styles.cursorDefault, + position: 'absolute', + zIndex: 8, + }), + + /** + * Generate the styles for the ReportActionItem wrapper view. + */ + getReportActionItemStyle: (isHovered = false): ViewStyle => + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + ({ + display: 'flex', + justifyContent: 'space-between', + backgroundColor: isHovered + ? theme.hoverComponentBG + : // Warning: Setting this to a non-transparent color will cause unread indicator to break on Android + theme.transparent, + opacity: 1, + ...styles.cursorInitial, + }), + + /** + * Determines the theme color for a modal based on the app's background color, + * the modal's backdrop, and the backdrop's opacity. + * + * @param bgColor - theme background color + * @returns The theme color as an RGB value. + */ + getThemeBackgroundColor: (bgColor: string): string => { + const backdropOpacity = variables.overlayOpacity; + + const [backgroundRed, backgroundGreen, backgroundBlue] = extractValuesFromRGB(bgColor) ?? hexadecimalToRGBArray(bgColor) ?? []; + const [backdropRed, backdropGreen, backdropBlue] = hexadecimalToRGBArray(theme.overlay) ?? []; + const normalizedBackdropRGB = convertRGBToUnitValues(backdropRed, backdropGreen, backdropBlue); + const normalizedBackgroundRGB = convertRGBToUnitValues(backgroundRed, backgroundGreen, backgroundBlue); + const [red, green, blue] = convertRGBAToRGB(normalizedBackdropRGB, normalizedBackgroundRGB, backdropOpacity); + const themeRGB = convertUnitValuesToRGB(red, green, blue); + + return `rgb(${themeRGB.join(', ')})`; + }, + + getZoomCursorStyle: (isZoomed: boolean, isDragging: boolean): ViewStyle => { + if (!isZoomed) { + // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return styles.cursorZoomIn; + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return isDragging ? styles.cursorGrabbing : styles.cursorZoomOut; + }, + + /** + * Returns container styles for showing the icons in MultipleAvatars/SubscriptAvatar + */ + getContainerStyles: (size: string, isInReportAction = false): ViewStyle[] => { + let containerStyles: ViewStyle[]; + + switch (size) { + case CONST.AVATAR_SIZE.SMALL: + containerStyles = [styles.emptyAvatarSmall, styles.emptyAvatarMarginSmall]; + break; + case CONST.AVATAR_SIZE.SMALLER: + containerStyles = [styles.emptyAvatarSmaller, styles.emptyAvatarMarginSmaller]; + break; + case CONST.AVATAR_SIZE.MEDIUM: + containerStyles = [styles.emptyAvatarMedium, styles.emptyAvatarMargin]; + break; + case CONST.AVATAR_SIZE.LARGE: + containerStyles = [styles.emptyAvatarLarge, styles.mb2, styles.mr2]; + break; + default: + containerStyles = [styles.emptyAvatar, isInReportAction ? styles.emptyAvatarMarginChat : styles.emptyAvatarMargin]; + } + + return containerStyles; + }, +}); + +type StyleUtilsType = ReturnType; -export default StyleUtils; -export type {StyleUtilsType}; +export default createThemeStyleUtils; +export type {StyleUtilsType, AvatarSizeName}; diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index 9263f6395d4b..312a7433a75a 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,10 +1,10 @@ import React from 'react'; import defaultStyles, {ThemeStyles} from './styles'; -import {ThemeStyleUtilsType} from './utils/ThemeStyleUtils'; +import {StyleUtilsType} from './StyleUtils'; type ThemeStylesContextType = { styles: ThemeStyles; - ThemeStyleUtils: ThemeStyleUtilsType; + StyleUtils: StyleUtilsType; }; const defaultThemeStyles = new Proxy( @@ -16,7 +16,7 @@ const defaultThemeStyles = new Proxy( }, ); -const ThemeStylesContext = React.createContext({styles: defaultStyles, ThemeStyleUtils: defaultThemeStyles as ThemeStyleUtilsType}); +const ThemeStylesContext = React.createContext({styles: defaultStyles, StyleUtils: defaultThemeStyles as StyleUtilsType}); export default ThemeStylesContext; export {type ThemeStylesContextType}; diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index c67b506fd581..432f2be96ccd 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -1,8 +1,8 @@ import React, {useMemo} from 'react'; import {stylesGenerator} from './styles'; +import createThemeStyleUtils from './StyleUtils'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; -import createThemeStyleUtils from './utils/ThemeStyleUtils'; type ThemeStylesProviderProps = React.PropsWithChildren; diff --git a/src/styles/useStyleUtils.ts b/src/styles/useStyleUtils.ts index d4b5bd8cd3f7..aadb3f884220 100644 --- a/src/styles/useStyleUtils.ts +++ b/src/styles/useStyleUtils.ts @@ -2,13 +2,13 @@ import {useContext} from 'react'; import ThemeStylesContext from './ThemeStylesContext'; function useStyleUtils() { - const themeStyleContext = useContext(ThemeStylesContext); + const themeStylesContext = useContext(ThemeStylesContext); - if (!themeStyleContext) { + if (!themeStylesContext) { throw new Error('ThemeStylesContext was null! Are you sure that you wrapped the component under a ?'); } - return themeStyleContext.ThemeStyleUtils; + return themeStylesContext.StyleUtils; } export default useStyleUtils; diff --git a/src/styles/useThemeStyleUtils.ts b/src/styles/useThemeStyleUtils.ts deleted file mode 100644 index 1e2f2f4d49eb..000000000000 --- a/src/styles/useThemeStyleUtils.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {useContext} from 'react'; -import ThemeStylesContext from './ThemeStylesContext'; - -function useThemeStyleUtils() { - const themeStylesContext = useContext(ThemeStylesContext); - - if (!themeStylesContext) { - throw new Error('ThemeStylesContext was null! Are you sure that you wrapped the component under a ?'); - } - - return themeStylesContext.ThemeStyleUtils; -} - -export default useThemeStyleUtils; diff --git a/src/styles/utils/ThemeStyleUtils.ts b/src/styles/utils/ThemeStyleUtils.ts deleted file mode 100644 index 53da23250b85..000000000000 --- a/src/styles/utils/ThemeStyleUtils.ts +++ /dev/null @@ -1,409 +0,0 @@ -import {StyleProp, TextStyle, ViewStyle} from 'react-native'; -import {type ThemeStyles} from '@styles/styles'; -import {type ThemeColors} from '@styles/themes/types'; -import cursor from '@styles/utilities/cursor'; -import positioning from '@styles/utilities/positioning'; -import variables from '@styles/variables'; -import CONST from '@src/CONST'; -import {hexadecimalToRGBArray} from './functions'; -import StyleUtils from './StyleUtils'; -import {AvatarSizeName, AvatarStyle, ButtonStateName} from './types'; - -/** - * Converts a color in RGBA notation to an equivalent color in RGB notation. - * - * @param foregroundRGB The three components of the foreground color in RGB notation. - * @param backgroundRGB The three components of the background color in RGB notation. - * @param opacity The desired opacity of the foreground color. - * @returns The RGB components of the RGBA color converted to RGB. - */ -function convertRGBAToRGB(foregroundRGB: number[], backgroundRGB: number[], opacity: number): number[] { - const [foregroundRed, foregroundGreen, foregroundBlue] = foregroundRGB; - const [backgroundRed, backgroundGreen, backgroundBlue] = backgroundRGB; - - return [(1 - opacity) * backgroundRed + opacity * foregroundRed, (1 - opacity) * backgroundGreen + opacity * foregroundGreen, (1 - opacity) * backgroundBlue + opacity * foregroundBlue]; -} - -/** - * Converts three unit values to the three components of a color in RGB notation. - * - * @param red A unit value representing the first component of a color in RGB notation. - * @param green A unit value representing the second component of a color in RGB notation. - * @param blue A unit value representing the third component of a color in RGB notation. - * @returns An array with the three components of a color in RGB notation. - */ -function convertUnitValuesToRGB(red: number, green: number, blue: number): number[] { - return [Math.floor(red * 255), Math.floor(green * 255), Math.floor(blue * 255)]; -} - -/** - * Converts the three components of a color in RGB notation to three unit values. - * - * @param red The first component of a color in RGB notation. - * @param green The second component of a color in RGB notation. - * @param blue The third component of a color in RGB notation. - * @returns An array with three unit values representing the components of a color in RGB notation. - */ -function convertRGBToUnitValues(red: number, green: number, blue: number): number[] { - return [red / 255, green / 255, blue / 255]; -} - -/** - * Matches an RGBA or RGB color value and extracts the color components. - * - * @param color - The RGBA or RGB color value to match and extract components from. - * @returns An array containing the extracted color components [red, green, blue, alpha]. - * - * Returns null if the input string does not match the pattern. - */ -function extractValuesFromRGB(color: string): number[] | null { - const rgbaPattern = /rgba?\((?[.\d]+)[, ]+(?[.\d]+)[, ]+(?[.\d]+)(?:\s?[,/]\s?(?[.\d]+%?))?\)$/i; - const matchRGBA = color.match(rgbaPattern); - if (matchRGBA) { - const [, red, green, blue, alpha] = matchRGBA; - return [parseInt(red, 10), parseInt(green, 10), parseInt(blue, 10), alpha ? parseFloat(alpha) : 1]; - } - - return null; -} - -const createThemeStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ - /** - * Gets styles for AutoCompleteSuggestion row - */ - getAutoCompleteSuggestionItemStyle: (highlightedEmojiIndex: number, rowHeight: number, isHovered: boolean, currentEmojiIndex: number): ViewStyle[] => { - let backgroundColor; - - if (currentEmojiIndex === highlightedEmojiIndex) { - backgroundColor = theme.activeComponentBG; - } else if (isHovered) { - backgroundColor = theme.hoverComponentBG; - } - - return [ - { - height: rowHeight, - justifyContent: 'center', - }, - backgroundColor - ? { - backgroundColor, - } - : {}, - ]; - }, - - /** - * Returns auto grow height text input style - */ - getAutoGrowHeightInputStyle: (textInputHeight: number, maxHeight: number): ViewStyle => { - if (textInputHeight > maxHeight) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...styles.pr0, - ...styles.overflowAuto, - }; - } - - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...styles.pr0, - ...styles.overflowHidden, - // maxHeight is not of the input only but the of the whole input container - // which also includes the top padding and bottom border - height: maxHeight - styles.textInputMultilineContainer.paddingTop - styles.textInputContainer.borderBottomWidth, - }; - }, - - /** - * Return the style from an avatar size constant - */ - getAvatarStyle: (size: AvatarSizeName): AvatarStyle => { - const avatarSize = StyleUtils.getAvatarSize(size); - return { - height: avatarSize, - width: avatarSize, - borderRadius: avatarSize, - backgroundColor: theme.offline, - }; - }, - - /** - * Generate a style for the background color of the Badge - */ - getBadgeColorStyle: (isSuccess: boolean, isError: boolean, isPressed = false, isAdHoc = false): ViewStyle => { - if (isSuccess) { - if (isAdHoc) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return isPressed ? styles.badgeAdHocSuccessPressed : styles.badgeAdHocSuccess; - } - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return isPressed ? styles.badgeSuccessPressed : styles.badgeSuccess; - } - if (isError) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return isPressed ? styles.badgeDangerPressed : styles.badgeDanger; - } - return {}; - }, - - /** - * Generate a style for the background color of the button, based on its current state. - * - * @param buttonState - One of {'default', 'hovered', 'pressed'} - * @param isMenuItem - whether this button is apart of a list - */ - getButtonBackgroundColorStyle: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuItem = false): ViewStyle => { - switch (buttonState) { - case CONST.BUTTON_STATES.PRESSED: - return {backgroundColor: theme.buttonPressedBG}; - case CONST.BUTTON_STATES.ACTIVE: - return isMenuItem ? {backgroundColor: theme.border} : {backgroundColor: theme.buttonHoveredBG}; - case CONST.BUTTON_STATES.DISABLED: - case CONST.BUTTON_STATES.DEFAULT: - default: - return {}; - } - }, - - /** - * Returns the checkbox container style - */ - getCheckboxContainerStyle: (size: number, borderRadius = 4): ViewStyle => ({ - backgroundColor: theme.componentBG, - height: size, - width: size, - borderColor: theme.borderLighter, - borderWidth: 2, - justifyContent: 'center', - alignItems: 'center', - // eslint-disable-next-line object-shorthand - borderRadius: borderRadius, - }), - - /** - * Select the correct color for text. - */ - getColoredBackgroundStyle: (isColored: boolean): StyleProp => ({backgroundColor: isColored ? theme.link : undefined}), - - /** - * Returns link styles based on whether the link is disabled or not - */ - getDisabledLinkStyles: (isDisabled = false): ViewStyle => { - const disabledLinkStyles = { - color: theme.textSupporting, - ...cursor.cursorDisabled, - }; - - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...styles.link, - ...(isDisabled ? disabledLinkStyles : {}), - }; - }, - - /** - * Get the styles of the text next to dot indicators - */ - getDotIndicatorTextStyles: (isErrorText = true): TextStyle => (isErrorText ? {...styles.offlineFeedback.text, color: styles.formError.color} : {...styles.offlineFeedback.text}), - - getEmojiReactionBubbleStyle: (isHovered: boolean, hasUserReacted: boolean, isContextMenu = false): ViewStyle => { - let backgroundColor = theme.border; - - if (isHovered) { - backgroundColor = theme.buttonHoveredBG; - } - - if (hasUserReacted) { - backgroundColor = theme.reactionActiveBackground; - } - - if (isContextMenu) { - return { - paddingVertical: 3, - paddingHorizontal: 12, - backgroundColor, - }; - } - - return { - paddingVertical: 2, - paddingHorizontal: 8, - backgroundColor, - }; - }, - - getEmojiReactionCounterTextStyle: (hasUserReacted: boolean): TextStyle => { - if (hasUserReacted) { - return {color: theme.reactionActiveText}; - } - - return {color: theme.text}; - }, - - getErrorPageContainerStyle: (safeAreaPaddingBottom = 0): ViewStyle => ({ - backgroundColor: theme.componentBG, - paddingBottom: 40 + safeAreaPaddingBottom, - }), - - getGoogleListViewStyle: (shouldDisplayBorder: boolean): ViewStyle => { - if (shouldDisplayBorder) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return { - ...styles.borderTopRounded, - ...styles.borderBottomRounded, - marginTop: 4, - paddingVertical: 6, - }; - } - - return { - transform: 'scale(0)', - }; - }, - - /** - * Return the height of magic code input container - */ - getHeightOfMagicCodeInput: (): ViewStyle => ({height: styles.magicCodeInputContainer.minHeight - styles.textInputContainer.borderBottomWidth}), - - /** - * Generate fill color of an icon based on its state. - * - * @param buttonState - One of {'default', 'hovered', 'pressed'} - * @param isMenuIcon - whether this icon is apart of a list - */ - getIconFillColor: (buttonState: ButtonStateName = CONST.BUTTON_STATES.DEFAULT, isMenuIcon = false): string => { - switch (buttonState) { - case CONST.BUTTON_STATES.ACTIVE: - case CONST.BUTTON_STATES.PRESSED: - return theme.iconHovered; - case CONST.BUTTON_STATES.COMPLETE: - return theme.iconSuccessFill; - case CONST.BUTTON_STATES.DEFAULT: - case CONST.BUTTON_STATES.DISABLED: - default: - if (isMenuIcon) { - return theme.iconMenu; - } - return theme.icon; - } - }, - - /** - * Returns style object for the user mention component based on whether the mention is ours or not. - */ - getMentionStyle: (isOurMention: boolean): ViewStyle => { - const backgroundColor = isOurMention ? theme.ourMentionBG : theme.mentionBG; - return { - backgroundColor, - borderRadius: variables.componentBorderRadiusSmall, - paddingHorizontal: 2, - }; - }, - - /** - * Returns text color for the user mention text based on whether the mention is ours or not. - */ - getMentionTextColor: (isOurMention: boolean): string => (isOurMention ? theme.ourMentionText : theme.mentionText), - - /** - * Generate the wrapper styles for the mini ReportActionContextMenu. - */ - getMiniReportActionContextMenuWrapperStyle: (isReportActionItemGrouped: boolean): ViewStyle => - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - ({ - ...(isReportActionItemGrouped ? positioning.tn8 : positioning.tn4), - ...positioning.r4, - ...styles.cursorDefault, - position: 'absolute', - zIndex: 8, - }), - - /** - * Generate the styles for the ReportActionItem wrapper view. - */ - getReportActionItemStyle: (isHovered = false): ViewStyle => - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - ({ - display: 'flex', - justifyContent: 'space-between', - backgroundColor: isHovered - ? theme.hoverComponentBG - : // Warning: Setting this to a non-transparent color will cause unread indicator to break on Android - theme.transparent, - opacity: 1, - ...styles.cursorInitial, - }), - - /** - * Determines the theme color for a modal based on the app's background color, - * the modal's backdrop, and the backdrop's opacity. - * - * @param bgColor - theme background color - * @returns The theme color as an RGB value. - */ - getThemeBackgroundColor: (bgColor: string): string => { - const backdropOpacity = variables.overlayOpacity; - - const [backgroundRed, backgroundGreen, backgroundBlue] = extractValuesFromRGB(bgColor) ?? hexadecimalToRGBArray(bgColor) ?? []; - const [backdropRed, backdropGreen, backdropBlue] = hexadecimalToRGBArray(theme.overlay) ?? []; - const normalizedBackdropRGB = convertRGBToUnitValues(backdropRed, backdropGreen, backdropBlue); - const normalizedBackgroundRGB = convertRGBToUnitValues(backgroundRed, backgroundGreen, backgroundBlue); - const [red, green, blue] = convertRGBAToRGB(normalizedBackdropRGB, normalizedBackgroundRGB, backdropOpacity); - const themeRGB = convertUnitValuesToRGB(red, green, blue); - - return `rgb(${themeRGB.join(', ')})`; - }, - - getZoomCursorStyle: (isZoomed: boolean, isDragging: boolean): ViewStyle => { - if (!isZoomed) { - // TODO: Remove this "eslint-disable-next" once the theme switching migration is done and styles are fully typed (GH Issue: https://github.com/Expensify/App/issues/27337) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return styles.cursorZoomIn; - } - - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return isDragging ? styles.cursorGrabbing : styles.cursorZoomOut; - }, - - /** - * Returns container styles for showing the icons in MultipleAvatars/SubscriptAvatar - */ - getContainerStyles: (size: string, isInReportAction = false): ViewStyle[] => { - let containerStyles: ViewStyle[]; - - switch (size) { - case CONST.AVATAR_SIZE.SMALL: - containerStyles = [styles.emptyAvatarSmall, styles.emptyAvatarMarginSmall]; - break; - case CONST.AVATAR_SIZE.SMALLER: - containerStyles = [styles.emptyAvatarSmaller, styles.emptyAvatarMarginSmaller]; - break; - case CONST.AVATAR_SIZE.MEDIUM: - containerStyles = [styles.emptyAvatarMedium, styles.emptyAvatarMargin]; - break; - case CONST.AVATAR_SIZE.LARGE: - containerStyles = [styles.emptyAvatarLarge, styles.mb2, styles.mr2]; - break; - default: - containerStyles = [styles.emptyAvatar, isInReportAction ? styles.emptyAvatarMarginChat : styles.emptyAvatarMargin]; - } - - return containerStyles; - }, -}); - -type ThemeStyleUtilsType = ReturnType; - -export default createThemeStyleUtils; -export type {ThemeStyleUtilsType}; diff --git a/src/styles/utils/functions.ts b/src/styles/utils/functions.ts deleted file mode 100644 index a71b3488e96d..000000000000 --- a/src/styles/utils/functions.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Converts a color in hexadecimal notation into RGB notation. - * - * @param hexadecimal A color in hexadecimal notation. - * @returns `undefined` if the input color is not in hexadecimal notation. Otherwise, the RGB components of the input color. - */ -function hexadecimalToRGBArray(hexadecimal: string): number[] | undefined { - const components = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexadecimal); - - if (components === null) { - return undefined; - } - - return components.slice(1).map((component) => parseInt(component, 16)); -} - -// eslint-disable-next-line import/prefer-default-export -export {hexadecimalToRGBArray}; diff --git a/src/styles/utils/types.ts b/src/styles/utils/types.ts deleted file mode 100644 index ee1e4787b47d..000000000000 --- a/src/styles/utils/types.ts +++ /dev/null @@ -1,59 +0,0 @@ -import {ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native'; -import {ValueOf} from 'type-fest'; -import colors from '@styles/colors'; -import variables from '@styles/variables'; -import CONST from '@src/CONST'; - -type AllStyles = ViewStyle | TextStyle | ImageStyle; -type ParsableStyle = StyleProp | ((state: PressableStateCallbackType) => StyleProp); - -type ColorValue = ValueOf; -type AvatarSizeName = ValueOf; -type EReceiptColorName = ValueOf; -type AvatarSizeValue = ValueOf< - Pick< - typeof variables, - | 'avatarSizeNormal' - | 'avatarSizeSmallSubscript' - | 'avatarSizeMidSubscript' - | 'avatarSizeSubscript' - | 'avatarSizeSmall' - | 'avatarSizeSmaller' - | 'avatarSizeXLarge' - | 'avatarSizeLarge' - | 'avatarSizeMedium' - | 'avatarSizeLargeBordered' - | 'avatarSizeHeader' - | 'avatarSizeMentionIcon' - | 'avatarSizeSmallNormal' - > ->; - -type AvatarStyle = { - width: number; - height: number; - borderRadius: number; - backgroundColor: string; -}; - -type ButtonSizeValue = ValueOf; -type ButtonStateName = ValueOf; -type AvatarSize = {width: number}; - -type WorkspaceColorStyle = {backgroundColor: ColorValue; fill: ColorValue}; -type EreceiptColorStyle = {backgroundColor: ColorValue; color: ColorValue}; - -export type { - AllStyles, - ParsableStyle, - ColorValue, - AvatarSizeName, - AvatarStyle, - EReceiptColorName, - AvatarSizeValue, - ButtonSizeValue, - ButtonStateName, - AvatarSize, - WorkspaceColorStyle, - EreceiptColorStyle, -}; From 72848f22d533c0ea9f64d0dbc3ea074179aee0d4 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 20:09:50 +0100 Subject: [PATCH 12/39] fix: more --- src/components/AvatarWithDisplayName.tsx | 4 ++-- src/components/Badge.tsx | 2 +- src/components/EmojiSuggestions.tsx | 2 +- src/components/MentionSuggestions.tsx | 2 +- src/pages/settings/Wallet/PaymentMethodList.js | 2 +- src/styles/StyleUtils.ts | 6 +++--- src/styles/ThemeStylesProvider.tsx | 6 +++--- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index 171fe3c13673..041c180595f1 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -6,12 +6,12 @@ import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import {PersonalDetails, Policy, Report, ReportActions} from '@src/types/onyx'; -import useStyleUtils from '@styles/useStyleUtils'; import DisplayNames from './DisplayNames'; import MultipleAvatars from './MultipleAvatars'; import ParentNavigationSubtitle from './ParentNavigationSubtitle'; @@ -55,7 +55,7 @@ function AvatarWithDisplayName({ }: AvatarWithDisplayNameProps) { const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils() + const StyleUtils = useStyleUtils(); const title = ReportUtils.getReportName(report); const subtitle = ReportUtils.getChatRoomSubtitle(report); const parentNavigationSubtitleData = ReportUtils.getParentNavigationSubtitle(report); diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index 96855268d73c..82212c66db04 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -40,7 +40,7 @@ function Badge({success = false, error = false, pressable = false, text, environ const wrapperStyles: (state: PressableStateCallbackType) => StyleProp = useCallback( ({pressed}) => [styles.badge, styles.ml2, StyleUtils.getBadgeColorStyle(success, error, pressed, environment === CONST.ENVIRONMENT.ADHOC), badgeStyles], - [styles.badge, styles.ml2, ThemeStyleUtils, success, error, environment, badgeStyles], + [styles.badge, styles.ml2, StyleUtils, success, error, environment, badgeStyles], ); return ( diff --git a/src/components/EmojiSuggestions.tsx b/src/components/EmojiSuggestions.tsx index 6972069cbaeb..01f840677e5e 100644 --- a/src/components/EmojiSuggestions.tsx +++ b/src/components/EmojiSuggestions.tsx @@ -72,7 +72,7 @@ function EmojiSuggestions({emojis, onSelect, prefix, isEmojiPickerLarge, preferr ); }, - [prefix, styles.autoCompleteSuggestionContainer, styles.emojiSuggestionsEmoji, styles.emojiSuggestionsText, preferredSkinToneIndex, ThemeStyleUtils], + [prefix, styles.autoCompleteSuggestionContainer, styles.emojiSuggestionsEmoji, styles.emojiSuggestionsText, preferredSkinToneIndex, StyleUtils], ); return ( diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index 6ac161342690..b42540bacb13 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -121,7 +121,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe styles.mentionSuggestionsDisplayName, styles.mentionSuggestionsHandle, theme.success, - ThemeStyleUtils, + StyleUtils, ], ); diff --git a/src/pages/settings/Wallet/PaymentMethodList.js b/src/pages/settings/Wallet/PaymentMethodList.js index e8cfdc346265..dae0ca6ccb52 100644 --- a/src/pages/settings/Wallet/PaymentMethodList.js +++ b/src/pages/settings/Wallet/PaymentMethodList.js @@ -272,7 +272,7 @@ function PaymentMethodList({ }); return combinedPaymentMethods; - }, [shouldShowAssignedCards, fundList, bankAccountList, styles, filterType, isOffline, cardList, translate, actionPaymentMethodType, activePaymentMethodID, ThemeStyleUtils, onPress]); + }, [shouldShowAssignedCards, fundList, bankAccountList, styles, filterType, isOffline, cardList, translate, actionPaymentMethodType, activePaymentMethodID, StyleUtils, onPress]); /** * Render placeholder when there are no payments methods diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index 4d038b0a83ff..cb3580b7d535 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -1094,7 +1094,7 @@ const staticStyleUtils = { getEReceiptColorCode, }; -const createThemeStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ +const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ ...staticStyleUtils, /** @@ -1432,7 +1432,7 @@ const createThemeStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ }, }); -type StyleUtilsType = ReturnType; +type StyleUtilsType = ReturnType; -export default createThemeStyleUtils; +export default createStyleUtils; export type {StyleUtilsType, AvatarSizeName}; diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index 432f2be96ccd..a326b705b4c6 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -1,6 +1,6 @@ import React, {useMemo} from 'react'; import {stylesGenerator} from './styles'; -import createThemeStyleUtils from './StyleUtils'; +import createStyleUtils from './StyleUtils'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; @@ -10,8 +10,8 @@ function ThemeStylesProvider({children}: ThemeStylesProviderProps) { const theme = useTheme(); const styles = useMemo(() => stylesGenerator(theme), [theme]); - const ThemeStyleUtils = useMemo(() => createThemeStyleUtils(theme, styles), [theme, styles]); - const contextValue = useMemo(() => ({styles, ThemeStyleUtils}), [styles, ThemeStyleUtils]); + const StyleUtils = useMemo(() => createStyleUtils(theme, styles), [theme, styles]); + const contextValue = useMemo(() => ({styles, StyleUtils}), [styles, StyleUtils]); return {children}; } From 63dbd54e30454bc873445ad1f0f1a3fe6926a003 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 20:12:21 +0100 Subject: [PATCH 13/39] fix: more errors --- src/components/PDFView/index.native.js | 2 +- src/components/PopoverWithoutOverlay/index.js | 2 +- src/pages/home/report/ReactionList/HeaderReactionList.js | 2 -- src/pages/home/report/ReportActionItem.js | 5 ++++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index 4bcb9846c2f8..30d5e4c48d68 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -129,7 +129,7 @@ class PDFView extends Component { } renderPDFView() { - const pdfStyles = [this.props.themeStyles.imageModalPDF, StyleUtils.getWidthAndHeightStyle(this.props.windowWidth, this.props.windowHeight)]; + const pdfStyles = [this.props.themeStyles.imageModalPDF, this.props.StyleUtils.getWidthAndHeightStyle(this.props.windowWidth, this.props.windowHeight)]; // If we haven't yet successfully validated the password and loaded the PDF, // then we need to hide the react-native-pdf/PDF component so that PDFPasswordForm diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index f9d9759b4b20..3818dd1ac945 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -36,7 +36,7 @@ function Popover(props) { paddingBottom: safeAreaPaddingBottom, paddingLeft: safeAreaPaddingLeft, paddingRight: safeAreaPaddingRight, - } = useMemo(() => StyleUtils.getSafeAreaPadding(insets), [insets]); + } = useMemo(() => StyleUtils.getSafeAreaPadding(insets), [StyleUtils, insets]); const modalPaddingStyles = useMemo( () => diff --git a/src/pages/home/report/ReactionList/HeaderReactionList.js b/src/pages/home/report/ReactionList/HeaderReactionList.js index 39a1cdba505f..1b1751e32eef 100644 --- a/src/pages/home/report/ReactionList/HeaderReactionList.js +++ b/src/pages/home/report/ReactionList/HeaderReactionList.js @@ -10,8 +10,6 @@ import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import reactionPropTypes from './reactionPropTypes'; -('@styles/StyleUtils'); - const propTypes = { ...reactionPropTypes, ...withLocalizePropTypes, diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 80d032669a4e..415700de40ee 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -152,7 +152,10 @@ function ReportActionItem(props) { const originalReport = props.report.reportID === originalReportID ? props.report : ReportUtils.getReport(originalReportID); const isReportActionLinked = props.linkedReportActionID === props.action.reportActionID; - const highlightedBackgroundColorIfNeeded = useMemo(() => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(theme.highlightBG) : {}), [isReportActionLinked, theme]); + const highlightedBackgroundColorIfNeeded = useMemo( + () => (isReportActionLinked ? StyleUtils.getBackgroundColorStyle(theme.highlightBG) : {}), + [StyleUtils, isReportActionLinked, theme.highlightBG], + ); const originalMessage = lodashGet(props.action, 'originalMessage', {}); // IOUDetails only exists when we are sending money From 3afb415dd8c4d7582dd2decb2656af7d10a20069 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 5 Dec 2023 20:25:47 +0100 Subject: [PATCH 14/39] fix: default style utils --- src/styles/ThemeStylesContext.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index 312a7433a75a..5e26050f6f0c 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,22 +1,16 @@ import React from 'react'; import defaultStyles, {ThemeStyles} from './styles'; -import {StyleUtilsType} from './StyleUtils'; +import createStyleUtils, {StyleUtilsType} from './StyleUtils'; +import darkTheme from './themes/default'; type ThemeStylesContextType = { styles: ThemeStyles; StyleUtils: StyleUtilsType; }; -const defaultThemeStyles = new Proxy( - {}, - { - get() { - return () => undefined; - }, - }, -); +const DefaultStyleUtils = createStyleUtils(darkTheme, defaultStyles); -const ThemeStylesContext = React.createContext({styles: defaultStyles, StyleUtils: defaultThemeStyles as StyleUtilsType}); +const ThemeStylesContext = React.createContext({styles: defaultStyles, StyleUtils: DefaultStyleUtils}); export default ThemeStylesContext; export {type ThemeStylesContextType}; From fb40cf173019caa5beb7ae9327f3b775758b4a5f Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 11:32:37 +0100 Subject: [PATCH 15/39] fix: default exports --- src/styles/StyleUtils.ts | 6 +++++- src/styles/ThemeStylesContext.ts | 9 ++++----- src/styles/styles.ts | 7 +++---- src/styles/themes/Themes.ts | 3 +++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index cb3580b7d535..9037c65e7583 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -8,7 +8,8 @@ import CONST from '@src/CONST'; import {Transaction} from '@src/types/onyx'; import colors from './colors'; import fontFamily from './fontFamily'; -import {type ThemeStyles} from './styles'; +import {defaultStyles, type ThemeStyles} from './styles'; +import {defaultTheme} from './themes/Themes'; import {ThemeColors} from './themes/types'; import cursor from './utilities/cursor'; import positioning from './utilities/positioning'; @@ -1434,5 +1435,8 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ type StyleUtilsType = ReturnType; +const DefaultStyleUtils = createStyleUtils(defaultTheme, defaultStyles); + export default createStyleUtils; +export {DefaultStyleUtils}; export type {StyleUtilsType, AvatarSizeName}; diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index 5e26050f6f0c..8db1e9cc3b1a 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,15 +1,14 @@ import React from 'react'; -import defaultStyles, {ThemeStyles} from './styles'; -import createStyleUtils, {StyleUtilsType} from './StyleUtils'; -import darkTheme from './themes/default'; +import {defaultStyles} from './styles'; +import type {ThemeStyles} from './styles'; +import {DefaultStyleUtils} from './StyleUtils'; +import type {StyleUtilsType} from './StyleUtils'; type ThemeStylesContextType = { styles: ThemeStyles; StyleUtils: StyleUtilsType; }; -const DefaultStyleUtils = createStyleUtils(darkTheme, defaultStyles); - const ThemeStylesContext = React.createContext({styles: defaultStyles, StyleUtils: DefaultStyleUtils}); export default ThemeStylesContext; diff --git a/src/styles/styles.ts b/src/styles/styles.ts index b88119beae74..72dc853e7080 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -20,7 +20,7 @@ import overflowXHidden from './overflowXHidden'; import pointerEventsAuto from './pointerEventsAuto'; import pointerEventsBoxNone from './pointerEventsBoxNone'; import pointerEventsNone from './pointerEventsNone'; -import defaultTheme from './themes/default'; +import {defaultTheme} from './themes/Themes'; import {type ThemeColors} from './themes/types'; import borders from './utilities/borders'; import cursor from './utilities/cursor'; @@ -3997,8 +3997,7 @@ const styles = (theme: ThemeColors) => type ThemeStyles = ReturnType; -const stylesGenerator = styles; const defaultStyles = styles(defaultTheme); -export default defaultStyles; -export {stylesGenerator, type Styles, type ThemeStyles, type StatusBarStyle, type ColorScheme}; +export default styles; +export {defaultStyles, type Styles, type ThemeStyles, type StatusBarStyle, type ColorScheme}; diff --git a/src/styles/themes/Themes.ts b/src/styles/themes/Themes.ts index 5de65c7316b4..9fe7c02e6b4c 100644 --- a/src/styles/themes/Themes.ts +++ b/src/styles/themes/Themes.ts @@ -8,4 +8,7 @@ const Themes = { [CONST.THEME.DARK]: darkTheme, } satisfies Record; +const defaultTheme = Themes[CONST.THEME.DEFAULT]; + export default Themes; +export {defaultTheme}; From 838bda13da9203315805aba1031be227c9125766 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 11:33:34 +0100 Subject: [PATCH 16/39] fix: default theme --- src/styles/themes/ThemeContext.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/themes/ThemeContext.ts b/src/styles/themes/ThemeContext.ts index 3c969c7393c5..d0c553322b35 100644 --- a/src/styles/themes/ThemeContext.ts +++ b/src/styles/themes/ThemeContext.ts @@ -1,7 +1,7 @@ import React from 'react'; -import darkTheme from './default'; +import {defaultTheme} from './Themes'; import {type ThemeColors} from './types'; -const ThemeContext = React.createContext(darkTheme); +const ThemeContext = React.createContext(defaultTheme); export default ThemeContext; From 266730f6b3bdc88fb04126a222af42ce6c371e13 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 11:48:31 +0100 Subject: [PATCH 17/39] simplify style utils --- src/styles/ThemeStylesContext.ts | 4 +- src/styles/ThemeStylesProvider.tsx | 2 +- src/styles/getModalStyles.ts | 271 ---------------- src/styles/getTooltipStyles.ts | 301 ----------------- src/styles/utils/ModalStyleUtils.ts | 273 ++++++++++++++++ .../PopoverWithMeasuredContentStyleUtils.ts} | 4 +- .../ReportActionContextMenuStyleUtils.ts} | 32 +- src/styles/utils/TooltipStyleUtils.ts | 303 ++++++++++++++++++ src/styles/{StyleUtils.ts => utils/index.ts} | 24 +- 9 files changed, 613 insertions(+), 601 deletions(-) delete mode 100644 src/styles/getModalStyles.ts delete mode 100644 src/styles/getTooltipStyles.ts create mode 100644 src/styles/utils/ModalStyleUtils.ts rename src/styles/{getPopoverWithMeasuredContentStyles.ts => utils/PopoverWithMeasuredContentStyleUtils.ts} (94%) rename src/styles/{getReportActionContextMenuStyles.ts => utils/ReportActionContextMenuStyleUtils.ts} (55%) create mode 100644 src/styles/utils/TooltipStyleUtils.ts rename src/styles/{StyleUtils.ts => utils/index.ts} (98%) diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index 8db1e9cc3b1a..73f044f2dcbd 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,8 +1,8 @@ import React from 'react'; import {defaultStyles} from './styles'; import type {ThemeStyles} from './styles'; -import {DefaultStyleUtils} from './StyleUtils'; -import type {StyleUtilsType} from './StyleUtils'; +import {DefaultStyleUtils} from './utils'; +import type {StyleUtilsType} from './utils'; type ThemeStylesContextType = { styles: ThemeStyles; diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index a326b705b4c6..c2d44c266ec3 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -1,8 +1,8 @@ import React, {useMemo} from 'react'; import {stylesGenerator} from './styles'; -import createStyleUtils from './StyleUtils'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; +import createStyleUtils from './utils'; type ThemeStylesProviderProps = React.PropsWithChildren; diff --git a/src/styles/getModalStyles.ts b/src/styles/getModalStyles.ts deleted file mode 100644 index b11b350e4e9d..000000000000 --- a/src/styles/getModalStyles.ts +++ /dev/null @@ -1,271 +0,0 @@ -import {ViewStyle} from 'react-native'; -import {ModalProps} from 'react-native-modal'; -import {ValueOf} from 'type-fest'; -import CONST from '@src/CONST'; -import {type ThemeStyles} from './styles'; -import {type ThemeColors} from './themes/types'; -import variables from './variables'; - -function getCenteredModalStyles(styles: ThemeStyles, windowWidth: number, isSmallScreenWidth: boolean, isFullScreenWhenSmall = false): ViewStyle { - const modalStyles = styles.centeredModalStyles(isSmallScreenWidth, isFullScreenWhenSmall); - - return { - borderWidth: modalStyles.borderWidth, - width: isSmallScreenWidth ? '100%' : windowWidth - modalStyles.marginHorizontal * 2, - }; -} - -type ModalType = ValueOf; - -type WindowDimensions = { - windowWidth: number; - windowHeight: number; - isSmallScreenWidth: boolean; -}; - -type GetModalStyles = { - modalStyle: ViewStyle; - modalContainerStyle: ViewStyle; - swipeDirection: ModalProps['swipeDirection']; - animationIn: ModalProps['animationIn']; - animationOut: ModalProps['animationOut']; - hideBackdrop: boolean; - shouldAddTopSafeAreaMargin: boolean; - shouldAddBottomSafeAreaMargin: boolean; - shouldAddBottomSafeAreaPadding: boolean; - shouldAddTopSafeAreaPadding: boolean; -}; - -export default function getModalStyles( - theme: ThemeColors, - styles: ThemeStyles, - type: ModalType | undefined, - windowDimensions: WindowDimensions, - popoverAnchorPosition: ViewStyle = {}, - innerContainerStyle: ViewStyle = {}, - outerStyle: ViewStyle = {}, -): GetModalStyles { - const {isSmallScreenWidth, windowWidth} = windowDimensions; - - let modalStyle: GetModalStyles['modalStyle'] = { - margin: 0, - ...outerStyle, - }; - - let modalContainerStyle: GetModalStyles['modalContainerStyle']; - let swipeDirection: GetModalStyles['swipeDirection']; - let animationIn: GetModalStyles['animationIn']; - let animationOut: GetModalStyles['animationOut']; - let hideBackdrop = false; - let shouldAddBottomSafeAreaMargin = false; - let shouldAddTopSafeAreaMargin = false; - let shouldAddBottomSafeAreaPadding = false; - let shouldAddTopSafeAreaPadding = false; - - switch (type) { - case CONST.MODAL.MODAL_TYPE.CONFIRM: - // A confirm modal is one that has a visible backdrop - // and can be dismissed by clicking outside of the modal. - modalStyle = { - ...modalStyle, - ...{ - alignItems: 'center', - }, - }; - modalContainerStyle = { - boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)', - borderRadius: 12, - overflow: 'hidden', - width: variables.sideBarWidth, - }; - - // setting this to undefined we effectively disable the - // ability to swipe our modal - swipeDirection = undefined; - animationIn = 'fadeIn'; - animationOut = 'fadeOut'; - break; - case CONST.MODAL.MODAL_TYPE.CENTERED: - // A centered modal is one that has a visible backdrop - // and can be dismissed by clicking outside of the modal. - // This modal should take up the entire visible area when - // viewed on a smaller device (e.g. mobile or mobile web). - modalStyle = { - ...modalStyle, - ...{ - alignItems: 'center', - }, - }; - modalContainerStyle = { - boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)', - flex: 1, - marginTop: isSmallScreenWidth ? 0 : 20, - marginBottom: isSmallScreenWidth ? 0 : 20, - borderRadius: isSmallScreenWidth ? 0 : 12, - overflow: 'hidden', - ...getCenteredModalStyles(styles, windowWidth, isSmallScreenWidth), - }; - - // Allow this modal to be dismissed with a swipe down or swipe right - swipeDirection = ['down', 'right']; - animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; - animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - shouldAddTopSafeAreaMargin = !isSmallScreenWidth; - shouldAddBottomSafeAreaMargin = !isSmallScreenWidth; - shouldAddTopSafeAreaPadding = isSmallScreenWidth; - shouldAddBottomSafeAreaPadding = false; - break; - case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: - // A centered modal that cannot be dismissed with a swipe. - modalStyle = { - ...modalStyle, - ...{ - alignItems: 'center', - }, - }; - modalContainerStyle = { - boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)', - flex: 1, - marginTop: isSmallScreenWidth ? 0 : 20, - marginBottom: isSmallScreenWidth ? 0 : 20, - borderRadius: isSmallScreenWidth ? 0 : 12, - overflow: 'hidden', - ...getCenteredModalStyles(styles, windowWidth, isSmallScreenWidth, true), - }; - swipeDirection = undefined; - animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; - animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; - shouldAddTopSafeAreaMargin = !isSmallScreenWidth; - shouldAddBottomSafeAreaMargin = !isSmallScreenWidth; - shouldAddTopSafeAreaPadding = isSmallScreenWidth; - shouldAddBottomSafeAreaPadding = false; - break; - case CONST.MODAL.MODAL_TYPE.CENTERED_SMALL: - // A centered modal that takes up the minimum possible screen space on all devices - modalStyle = { - ...modalStyle, - ...{ - alignItems: 'center', - }, - }; - modalContainerStyle = { - boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)', - borderRadius: 12, - borderWidth: 0, - }; - - // Allow this modal to be dismissed with a swipe down or swipe right - swipeDirection = ['down', 'right']; - animationIn = 'fadeIn'; - animationOut = 'fadeOut'; - shouldAddTopSafeAreaMargin = false; - shouldAddBottomSafeAreaMargin = false; - shouldAddTopSafeAreaPadding = false; - shouldAddBottomSafeAreaPadding = false; - break; - case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED: - modalStyle = { - ...modalStyle, - ...{ - alignItems: 'center', - justifyContent: 'flex-end', - }, - }; - modalContainerStyle = { - width: '100%', - borderTopLeftRadius: 20, - borderTopRightRadius: 20, - paddingTop: 12, - justifyContent: 'center', - overflow: 'hidden', - }; - - shouldAddBottomSafeAreaPadding = true; - swipeDirection = undefined; - animationIn = 'slideInUp'; - animationOut = 'slideOutDown'; - break; - case CONST.MODAL.MODAL_TYPE.POPOVER: - modalStyle = { - ...modalStyle, - ...popoverAnchorPosition, - ...{ - position: 'absolute', - alignItems: 'center', - justifyContent: 'flex-end', - }, - }; - modalContainerStyle = { - borderRadius: 12, - borderWidth: 1, - borderColor: theme.border, - justifyContent: 'center', - overflow: 'hidden', - boxShadow: variables.popoverMenuShadow, - }; - - hideBackdrop = true; - swipeDirection = undefined; - animationIn = 'fadeIn'; - animationOut = 'fadeOut'; - break; - case CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED: - modalStyle = { - ...modalStyle, - ...{ - marginLeft: isSmallScreenWidth ? 0 : windowWidth - variables.sideBarWidth, - width: isSmallScreenWidth ? '100%' : variables.sideBarWidth, - flexDirection: 'row', - justifyContent: 'flex-end', - }, - }; - modalContainerStyle = { - width: isSmallScreenWidth ? '100%' : variables.sideBarWidth, - height: '100%', - overflow: 'hidden', - }; - - animationIn = { - from: { - translateX: isSmallScreenWidth ? windowWidth : variables.sideBarWidth, - }, - to: { - translateX: 0, - }, - }; - animationOut = { - from: { - translateX: 0, - }, - to: { - translateX: isSmallScreenWidth ? windowWidth : variables.sideBarWidth, - }, - }; - hideBackdrop = true; - swipeDirection = undefined; - shouldAddBottomSafeAreaPadding = true; - shouldAddTopSafeAreaPadding = true; - break; - default: - modalStyle = {}; - modalContainerStyle = {}; - swipeDirection = 'down'; - animationIn = 'slideInUp'; - animationOut = 'slideOutDown'; - } - - modalContainerStyle = {...modalContainerStyle, ...innerContainerStyle}; - - return { - modalStyle, - modalContainerStyle, - swipeDirection, - animationIn, - animationOut, - hideBackdrop, - shouldAddTopSafeAreaMargin, - shouldAddBottomSafeAreaMargin, - shouldAddBottomSafeAreaPadding, - shouldAddTopSafeAreaPadding, - }; -} diff --git a/src/styles/getTooltipStyles.ts b/src/styles/getTooltipStyles.ts deleted file mode 100644 index 1adfa1969ab9..000000000000 --- a/src/styles/getTooltipStyles.ts +++ /dev/null @@ -1,301 +0,0 @@ -import {TextStyle, View, ViewStyle} from 'react-native'; -import fontFamily from './fontFamily'; -import roundToNearestMultipleOfFour from './roundToNearestMultipleOfFour'; -import {type ThemeStyles} from './styles'; -import {type ThemeColors} from './themes/types'; -import positioning from './utilities/positioning'; -import spacing from './utilities/spacing'; -import variables from './variables'; - -/** This defines the proximity with the edge of the window in which tooltips should not be displayed. - * If a tooltip is too close to the edge of the screen, we'll shift it towards the center. */ -const GUTTER_WIDTH = variables.gutterWidth; - -/** The height of a tooltip pointer */ -const POINTER_HEIGHT = 4; - -/** The width of a tooltip pointer */ -const POINTER_WIDTH = 12; - -/** - * Compute the amount the tooltip needs to be horizontally shifted in order to keep it from displaying in the gutters. - * - * @param windowWidth - The width of the window. - * @param xOffset - The distance between the left edge of the window - * and the left edge of the wrapped component. - * @param componentWidth - The width of the wrapped component. - * @param tooltipWidth - The width of the tooltip itself. - * @param [manualShiftHorizontal] - Any additional amount to manually shift the tooltip to the left or right. - * A positive value shifts it to the right, - * and a negative value shifts it to the left. - */ -function computeHorizontalShift(windowWidth: number, xOffset: number, componentWidth: number, tooltipWidth: number, manualShiftHorizontal: number): number { - // First find the left and right edges of the tooltip (by default, it is centered on the component). - const componentCenter = xOffset + componentWidth / 2 + manualShiftHorizontal; - const tooltipLeftEdge = componentCenter - tooltipWidth / 2; - const tooltipRightEdge = componentCenter + tooltipWidth / 2; - - if (tooltipLeftEdge < GUTTER_WIDTH) { - // Tooltip is in left gutter, shift right by a multiple of four. - return roundToNearestMultipleOfFour(GUTTER_WIDTH - tooltipLeftEdge); - } - - if (tooltipRightEdge > windowWidth - GUTTER_WIDTH) { - // Tooltip is in right gutter, shift left by a multiple of four. - return roundToNearestMultipleOfFour(windowWidth - GUTTER_WIDTH - tooltipRightEdge); - } - - // Tooltip is not in the gutter, so no need to shift it horizontally - return 0; -} - -/** - * Determines if there is an overlapping element at the top of a given coordinate. - * (targetCenterX, y) - * | - * v - * _ _ _ _ _ - * | | - * | | - * | | - * | | - * |_ _ _ _ _| - * - * @param tooltip - The reference to the tooltip's root element - * @param xOffset - The distance between the left edge of the window - * and the left edge of the wrapped component. - * @param yOffset - The distance between the top edge of the window - * and the top edge of the wrapped component. - * @param tooltipTargetWidth - The width of the tooltip's target - * @param tooltipTargetHeight - The height of the tooltip's target - */ -function isOverlappingAtTop(tooltip: View | HTMLDivElement, xOffset: number, yOffset: number, tooltipTargetWidth: number, tooltipTargetHeight: number) { - if (typeof document.elementFromPoint !== 'function') { - return false; - } - - // Use the x center position of the target to prevent wrong element returned by elementFromPoint - // in case the target has a border radius or is a multiline text. - const targetCenterX = xOffset + tooltipTargetWidth / 2; - const elementAtTargetCenterX = document.elementFromPoint(targetCenterX, yOffset); - - // Ensure it's not the already rendered element of this very tooltip, so the tooltip doesn't try to "avoid" itself - if (!elementAtTargetCenterX || ('contains' in tooltip && tooltip.contains(elementAtTargetCenterX))) { - return false; - } - - const rectAtTargetCenterX = elementAtTargetCenterX.getBoundingClientRect(); - - // Ensure it's not overlapping with another element by checking if the yOffset is greater than the top of the element - // and less than the bottom of the element. Also ensure the tooltip target is not completely inside the elementAtTargetCenterX by vertical direction - const isOverlappingAtTargetCenterX = yOffset > rectAtTargetCenterX.top && yOffset < rectAtTargetCenterX.bottom && yOffset + tooltipTargetHeight > rectAtTargetCenterX.bottom; - - return isOverlappingAtTargetCenterX; -} - -type TooltipStyles = { - animationStyle: ViewStyle; - rootWrapperStyle: ViewStyle; - textStyle: TextStyle; - pointerWrapperStyle: ViewStyle; - pointerStyle: ViewStyle; -}; - -type TooltipParams = { - tooltip: View | HTMLDivElement; - currentSize: number; - windowWidth: number; - xOffset: number; - yOffset: number; - tooltipTargetWidth: number; - tooltipTargetHeight: number; - maxWidth: number; - tooltipContentWidth: number; - tooltipWrapperHeight: number; - theme: ThemeColors; - styles: ThemeStyles; - manualShiftHorizontal?: number; - manualShiftVertical?: number; -}; - -/** - * Generate styles for the tooltip component. - * - * @param tooltip - The reference to the tooltip's root element - * @param currentSize - The current size of the tooltip used in the scaling animation. - * @param windowWidth - The width of the window. - * @param xOffset - The distance between the left edge of the window - * and the left edge of the wrapped component. - * @param yOffset - The distance between the top edge of the window - * and the top edge of the wrapped component. - * @param tooltipTargetWidth - The width of the tooltip's target - * @param tooltipTargetHeight - The height of the tooltip's target - * @param maxWidth - The tooltip's max width. - * @param tooltipContentWidth - The tooltip's inner content measured width. - * @param tooltipWrapperHeight - The tooltip's wrapper measured height. - * @param [manualShiftHorizontal] - Any additional amount to manually shift the tooltip to the left or right. - * A positive value shifts it to the right, - * and a negative value shifts it to the left. - * @param [manualShiftVertical] - Any additional amount to manually shift the tooltip up or down. - * A positive value shifts it down, and a negative value shifts it up. - */ -export default function getTooltipStyles({ - tooltip, - currentSize, - windowWidth, - xOffset, - yOffset, - tooltipTargetWidth, - tooltipTargetHeight, - maxWidth, - tooltipContentWidth, - tooltipWrapperHeight, - theme, - styles, - manualShiftHorizontal = 0, - manualShiftVertical = 0, -}: TooltipParams): TooltipStyles { - const tooltipVerticalPadding = spacing.pv1; - - // We calculate tooltip width based on the tooltip's content width - // so the tooltip wrapper is just big enough to fit content and prevent white space. - // NOTE: Add 1 to the tooltipWidth to prevent truncated text in Safari - const tooltipWidth = tooltipContentWidth && tooltipContentWidth + spacing.ph2.paddingHorizontal * 2 + 1; - const tooltipHeight = tooltipWrapperHeight; - - const isTooltipSizeReady = tooltipWidth !== undefined && tooltipHeight !== undefined; - - // Set the scale to 1 to be able to measure the tooltip size correctly when it's not ready yet. - let scale = 1; - let shouldShowBelow = false; - let horizontalShift = 0; - let horizontalShiftPointer = 0; - let rootWrapperTop = 0; - let rootWrapperLeft = 0; - let pointerWrapperTop = 0; - let pointerWrapperLeft = 0; - let pointerAdditionalStyle = {}; - - if (isTooltipSizeReady) { - // Determine if the tooltip should display below the wrapped component. - // If either a tooltip will try to render within GUTTER_WIDTH logical pixels of the top of the screen, - // Or the wrapped component is overlapping at top-center with another element - // we'll display it beneath its wrapped component rather than above it as usual. - shouldShowBelow = yOffset - tooltipHeight < GUTTER_WIDTH || isOverlappingAtTop(tooltip, xOffset, yOffset, tooltipTargetWidth, tooltipTargetHeight); - - // When the tooltip size is ready, we can start animating the scale. - scale = currentSize; - - // Determine if we need to shift the tooltip horizontally to prevent it - // from displaying too near to the edge of the screen. - horizontalShift = computeHorizontalShift(windowWidth, xOffset, tooltipTargetWidth, tooltipWidth, manualShiftHorizontal); - - // Determine if we need to shift the pointer horizontally to prevent it from being too near to the edge of the tooltip - // We shift it to the right a bit if the tooltip is positioned on the extreme left - // and shift it to left a bit if the tooltip is positioned on the extreme right. - horizontalShiftPointer = - horizontalShift > 0 - ? Math.max(-horizontalShift, -(tooltipWidth / 2) + POINTER_WIDTH / 2 + variables.componentBorderRadiusSmall) - : Math.min(-horizontalShift, tooltipWidth / 2 - POINTER_WIDTH / 2 - variables.componentBorderRadiusSmall); - - // Because it uses fixed positioning, the top-left corner of the tooltip is aligned - // with the top-left corner of the window by default. - // we will use yOffset to position the tooltip relative to the Wrapped Component - // So we need to shift the tooltip vertically and horizontally to position it correctly. - // - // First, we'll position it vertically. - // To shift the tooltip down, we'll give `top` a positive value. - // To shift the tooltip up, we'll give `top` a negative value. - rootWrapperTop = shouldShowBelow - ? // We need to shift the tooltip down below the component. So shift the tooltip down (+) by... - yOffset + tooltipTargetHeight + POINTER_HEIGHT + manualShiftVertical - : // We need to shift the tooltip up above the component. So shift the tooltip up (-) by... - yOffset - (tooltipHeight + POINTER_HEIGHT) + manualShiftVertical; - - // Next, we'll position it horizontally. - // we will use xOffset to position the tooltip relative to the Wrapped Component - // To shift the tooltip right, we'll give `left` a positive value. - // To shift the tooltip left, we'll give `left` a negative value. - // - // So we'll: - // 1) Shift the tooltip right (+) to the center of the component, - // so the left edge lines up with the component center. - // 2) Shift it left (-) to by half the tooltip's width, - // so the tooltip's center lines up with the center of the wrapped component. - // 3) Add the horizontal shift (left or right) computed above to keep it out of the gutters. - // 4) Lastly, add the manual horizontal shift passed in as a parameter. - rootWrapperLeft = xOffset + (tooltipTargetWidth / 2 - tooltipWidth / 2) + horizontalShift + manualShiftHorizontal; - - // By default, the pointer's top-left will align with the top-left of the tooltip wrapper. - // - // To align it vertically, we'll: - // If the pointer should be below the tooltip wrapper, shift the pointer down (+) by the tooltip height, - // so that the top of the pointer lines up with the bottom of the tooltip - // - // OR if the pointer should be above the tooltip wrapper, then the pointer up (-) by the pointer's height - // so that the bottom of the pointer lines up with the top of the tooltip - pointerWrapperTop = shouldShowBelow ? -POINTER_HEIGHT : tooltipHeight; - - // To align it horizontally, we'll: - // 1) Shift the pointer to the right (+) by the half the tooltipWidth's width, - // so the left edge of the pointer lines up with the tooltipWidth's center. - // 2) To the left (-) by half the pointer's width, - // so the pointer's center lines up with the tooltipWidth's center. - // 3) Remove the wrapper's horizontalShift to maintain the pointer - // at the center of the hovered component. - pointerWrapperLeft = horizontalShiftPointer + (tooltipWidth / 2 - POINTER_WIDTH / 2); - - pointerAdditionalStyle = shouldShowBelow ? styles.flipUpsideDown : {}; - } - - return { - animationStyle: { - // remember Transform causes a new Local cordinate system - // https://drafts.csswg.org/css-transforms-1/#transform-rendering - // so Position fixed children will be relative to this new Local cordinate system - transform: [{scale}], - }, - rootWrapperStyle: { - ...positioning.pFixed, - backgroundColor: theme.heading, - borderRadius: variables.componentBorderRadiusSmall, - ...tooltipVerticalPadding, - ...spacing.ph2, - zIndex: variables.tooltipzIndex, - width: tooltipWidth, - maxWidth, - top: rootWrapperTop, - left: rootWrapperLeft, - - // We are adding this to prevent the tooltip text from being selected and copied on CTRL + A. - ...styles.userSelectNone, - ...styles.pointerEventsNone, - }, - textStyle: { - color: theme.textReversed, - fontFamily: fontFamily.EXP_NEUE, - fontSize: variables.fontSizeSmall, - overflow: 'hidden', - lineHeight: variables.lineHeightSmall, - textAlign: 'center', - }, - pointerWrapperStyle: { - ...positioning.pFixed, - top: pointerWrapperTop, - left: pointerWrapperLeft, - }, - pointerStyle: { - width: 0, - height: 0, - backgroundColor: theme.transparent, - borderStyle: 'solid', - borderLeftWidth: POINTER_WIDTH / 2, - borderRightWidth: POINTER_WIDTH / 2, - borderTopWidth: POINTER_HEIGHT, - borderLeftColor: theme.transparent, - borderRightColor: theme.transparent, - borderTopColor: theme.heading, - ...pointerAdditionalStyle, - }, - }; -} diff --git a/src/styles/utils/ModalStyleUtils.ts b/src/styles/utils/ModalStyleUtils.ts new file mode 100644 index 000000000000..cf312a4e76f7 --- /dev/null +++ b/src/styles/utils/ModalStyleUtils.ts @@ -0,0 +1,273 @@ +import {ViewStyle} from 'react-native'; +import {ModalProps} from 'react-native-modal'; +import {ValueOf} from 'type-fest'; +import {type ThemeStyles} from '@styles/styles'; +import {type ThemeColors} from '@styles/themes/types'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; + +function getCenteredModalStyles(styles: ThemeStyles, windowWidth: number, isSmallScreenWidth: boolean, isFullScreenWhenSmall = false): ViewStyle { + const modalStyles = styles.centeredModalStyles(isSmallScreenWidth, isFullScreenWhenSmall); + + return { + borderWidth: modalStyles.borderWidth, + width: isSmallScreenWidth ? '100%' : windowWidth - modalStyles.marginHorizontal * 2, + }; +} + +type ModalType = ValueOf; + +type WindowDimensions = { + windowWidth: number; + windowHeight: number; + isSmallScreenWidth: boolean; +}; + +type GetModalStyles = { + modalStyle: ViewStyle; + modalContainerStyle: ViewStyle; + swipeDirection: ModalProps['swipeDirection']; + animationIn: ModalProps['animationIn']; + animationOut: ModalProps['animationOut']; + hideBackdrop: boolean; + shouldAddTopSafeAreaMargin: boolean; + shouldAddBottomSafeAreaMargin: boolean; + shouldAddBottomSafeAreaPadding: boolean; + shouldAddTopSafeAreaPadding: boolean; +}; + +const createModalStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ + getModalStyles: ( + type: ModalType | undefined, + windowDimensions: WindowDimensions, + popoverAnchorPosition: ViewStyle = {}, + innerContainerStyle: ViewStyle = {}, + outerStyle: ViewStyle = {}, + ): GetModalStyles => { + const {isSmallScreenWidth, windowWidth} = windowDimensions; + + let modalStyle: GetModalStyles['modalStyle'] = { + margin: 0, + ...outerStyle, + }; + + let modalContainerStyle: GetModalStyles['modalContainerStyle']; + let swipeDirection: GetModalStyles['swipeDirection']; + let animationIn: GetModalStyles['animationIn']; + let animationOut: GetModalStyles['animationOut']; + let hideBackdrop = false; + let shouldAddBottomSafeAreaMargin = false; + let shouldAddTopSafeAreaMargin = false; + let shouldAddBottomSafeAreaPadding = false; + let shouldAddTopSafeAreaPadding = false; + + switch (type) { + case CONST.MODAL.MODAL_TYPE.CONFIRM: + // A confirm modal is one that has a visible backdrop + // and can be dismissed by clicking outside of the modal. + modalStyle = { + ...modalStyle, + ...{ + alignItems: 'center', + }, + }; + modalContainerStyle = { + boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)', + borderRadius: 12, + overflow: 'hidden', + width: variables.sideBarWidth, + }; + + // setting this to undefined we effectively disable the + // ability to swipe our modal + swipeDirection = undefined; + animationIn = 'fadeIn'; + animationOut = 'fadeOut'; + break; + case CONST.MODAL.MODAL_TYPE.CENTERED: + // A centered modal is one that has a visible backdrop + // and can be dismissed by clicking outside of the modal. + // This modal should take up the entire visible area when + // viewed on a smaller device (e.g. mobile or mobile web). + modalStyle = { + ...modalStyle, + ...{ + alignItems: 'center', + }, + }; + modalContainerStyle = { + boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)', + flex: 1, + marginTop: isSmallScreenWidth ? 0 : 20, + marginBottom: isSmallScreenWidth ? 0 : 20, + borderRadius: isSmallScreenWidth ? 0 : 12, + overflow: 'hidden', + ...getCenteredModalStyles(styles, windowWidth, isSmallScreenWidth), + }; + + // Allow this modal to be dismissed with a swipe down or swipe right + swipeDirection = ['down', 'right']; + animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; + animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; + shouldAddTopSafeAreaMargin = !isSmallScreenWidth; + shouldAddBottomSafeAreaMargin = !isSmallScreenWidth; + shouldAddTopSafeAreaPadding = isSmallScreenWidth; + shouldAddBottomSafeAreaPadding = false; + break; + case CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE: + // A centered modal that cannot be dismissed with a swipe. + modalStyle = { + ...modalStyle, + ...{ + alignItems: 'center', + }, + }; + modalContainerStyle = { + boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)', + flex: 1, + marginTop: isSmallScreenWidth ? 0 : 20, + marginBottom: isSmallScreenWidth ? 0 : 20, + borderRadius: isSmallScreenWidth ? 0 : 12, + overflow: 'hidden', + ...getCenteredModalStyles(styles, windowWidth, isSmallScreenWidth, true), + }; + swipeDirection = undefined; + animationIn = isSmallScreenWidth ? 'slideInRight' : 'fadeIn'; + animationOut = isSmallScreenWidth ? 'slideOutRight' : 'fadeOut'; + shouldAddTopSafeAreaMargin = !isSmallScreenWidth; + shouldAddBottomSafeAreaMargin = !isSmallScreenWidth; + shouldAddTopSafeAreaPadding = isSmallScreenWidth; + shouldAddBottomSafeAreaPadding = false; + break; + case CONST.MODAL.MODAL_TYPE.CENTERED_SMALL: + // A centered modal that takes up the minimum possible screen space on all devices + modalStyle = { + ...modalStyle, + ...{ + alignItems: 'center', + }, + }; + modalContainerStyle = { + boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)', + borderRadius: 12, + borderWidth: 0, + }; + + // Allow this modal to be dismissed with a swipe down or swipe right + swipeDirection = ['down', 'right']; + animationIn = 'fadeIn'; + animationOut = 'fadeOut'; + shouldAddTopSafeAreaMargin = false; + shouldAddBottomSafeAreaMargin = false; + shouldAddTopSafeAreaPadding = false; + shouldAddBottomSafeAreaPadding = false; + break; + case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED: + modalStyle = { + ...modalStyle, + ...{ + alignItems: 'center', + justifyContent: 'flex-end', + }, + }; + modalContainerStyle = { + width: '100%', + borderTopLeftRadius: 20, + borderTopRightRadius: 20, + paddingTop: 12, + justifyContent: 'center', + overflow: 'hidden', + }; + + shouldAddBottomSafeAreaPadding = true; + swipeDirection = undefined; + animationIn = 'slideInUp'; + animationOut = 'slideOutDown'; + break; + case CONST.MODAL.MODAL_TYPE.POPOVER: + modalStyle = { + ...modalStyle, + ...popoverAnchorPosition, + ...{ + position: 'absolute', + alignItems: 'center', + justifyContent: 'flex-end', + }, + }; + modalContainerStyle = { + borderRadius: 12, + borderWidth: 1, + borderColor: theme.border, + justifyContent: 'center', + overflow: 'hidden', + boxShadow: variables.popoverMenuShadow, + }; + + hideBackdrop = true; + swipeDirection = undefined; + animationIn = 'fadeIn'; + animationOut = 'fadeOut'; + break; + case CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED: + modalStyle = { + ...modalStyle, + ...{ + marginLeft: isSmallScreenWidth ? 0 : windowWidth - variables.sideBarWidth, + width: isSmallScreenWidth ? '100%' : variables.sideBarWidth, + flexDirection: 'row', + justifyContent: 'flex-end', + }, + }; + modalContainerStyle = { + width: isSmallScreenWidth ? '100%' : variables.sideBarWidth, + height: '100%', + overflow: 'hidden', + }; + + animationIn = { + from: { + translateX: isSmallScreenWidth ? windowWidth : variables.sideBarWidth, + }, + to: { + translateX: 0, + }, + }; + animationOut = { + from: { + translateX: 0, + }, + to: { + translateX: isSmallScreenWidth ? windowWidth : variables.sideBarWidth, + }, + }; + hideBackdrop = true; + swipeDirection = undefined; + shouldAddBottomSafeAreaPadding = true; + shouldAddTopSafeAreaPadding = true; + break; + default: + modalStyle = {}; + modalContainerStyle = {}; + swipeDirection = 'down'; + animationIn = 'slideInUp'; + animationOut = 'slideOutDown'; + } + + modalContainerStyle = {...modalContainerStyle, ...innerContainerStyle}; + + return { + modalStyle, + modalContainerStyle, + swipeDirection, + animationIn, + animationOut, + hideBackdrop, + shouldAddTopSafeAreaMargin, + shouldAddBottomSafeAreaMargin, + shouldAddBottomSafeAreaPadding, + shouldAddTopSafeAreaPadding, + }; + }, +}); + +export default createModalStyleUtils; diff --git a/src/styles/getPopoverWithMeasuredContentStyles.ts b/src/styles/utils/PopoverWithMeasuredContentStyleUtils.ts similarity index 94% rename from src/styles/getPopoverWithMeasuredContentStyles.ts rename to src/styles/utils/PopoverWithMeasuredContentStyleUtils.ts index 4d4e868f823b..41723c960b2a 100644 --- a/src/styles/getPopoverWithMeasuredContentStyles.ts +++ b/src/styles/utils/PopoverWithMeasuredContentStyleUtils.ts @@ -1,5 +1,5 @@ -import roundToNearestMultipleOfFour from './roundToNearestMultipleOfFour'; -import variables from './variables'; +import roundToNearestMultipleOfFour from '@styles/roundToNearestMultipleOfFour'; +import variables from '@styles/variables'; /** * Compute the amount that the Context menu's Anchor needs to be horizontally shifted diff --git a/src/styles/getReportActionContextMenuStyles.ts b/src/styles/utils/ReportActionContextMenuStyleUtils.ts similarity index 55% rename from src/styles/getReportActionContextMenuStyles.ts rename to src/styles/utils/ReportActionContextMenuStyleUtils.ts index 86dd14cb8446..9dd3c2a0d203 100644 --- a/src/styles/getReportActionContextMenuStyles.ts +++ b/src/styles/utils/ReportActionContextMenuStyleUtils.ts @@ -1,7 +1,7 @@ import {ViewStyle} from 'react-native'; -import {type ThemeStyles} from './styles'; -import {type ThemeColors} from './themes/types'; -import variables from './variables'; +import {type ThemeStyles} from '@styles/styles'; +import {type ThemeColors} from '@styles/themes/types'; +import variables from '@styles/variables'; const getDefaultWrapperStyle = (theme: ThemeColors): ViewStyle => ({ backgroundColor: theme.componentBG, @@ -27,18 +27,20 @@ const getMiniWrapperStyle = (theme: ThemeColors, styles: ThemeStyles): ViewStyle * @param isSmallScreenWidth * @param theme */ -function getReportActionContextMenuStyles(styles: ThemeStyles, isMini: boolean, isSmallScreenWidth: boolean, theme: ThemeColors): ViewStyle[] { - if (isMini) { - return getMiniWrapperStyle(theme, styles); - } +const createReportActionContextMenuStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ + getReportActionContextMenuStyles: (isMini: boolean, isSmallScreenWidth: boolean): ViewStyle[] => { + if (isMini) { + return getMiniWrapperStyle(theme, styles); + } - return [ - styles.flexColumn, - getDefaultWrapperStyle(theme), + return [ + styles.flexColumn, + getDefaultWrapperStyle(theme), - // Small screens use a bottom-docked modal that already has vertical padding. - isSmallScreenWidth ? {} : styles.pv3, - ]; -} + // Small screens use a bottom-docked modal that already has vertical padding. + isSmallScreenWidth ? {} : styles.pv3, + ]; + }, +}); -export default getReportActionContextMenuStyles; +export default createReportActionContextMenuStyleUtils; diff --git a/src/styles/utils/TooltipStyleUtils.ts b/src/styles/utils/TooltipStyleUtils.ts new file mode 100644 index 000000000000..07e5f7ec1141 --- /dev/null +++ b/src/styles/utils/TooltipStyleUtils.ts @@ -0,0 +1,303 @@ +import {TextStyle, View, ViewStyle} from 'react-native'; +import fontFamily from '@styles/fontFamily'; +import roundToNearestMultipleOfFour from '@styles/roundToNearestMultipleOfFour'; +import {type ThemeStyles} from '@styles/styles'; +import {type ThemeColors} from '@styles/themes/types'; +import positioning from '@styles/utilities/positioning'; +import spacing from '@styles/utilities/spacing'; +import variables from '@styles/variables'; + +/** This defines the proximity with the edge of the window in which tooltips should not be displayed. + * If a tooltip is too close to the edge of the screen, we'll shift it towards the center. */ +const GUTTER_WIDTH = variables.gutterWidth; + +/** The height of a tooltip pointer */ +const POINTER_HEIGHT = 4; + +/** The width of a tooltip pointer */ +const POINTER_WIDTH = 12; + +/** + * Compute the amount the tooltip needs to be horizontally shifted in order to keep it from displaying in the gutters. + * + * @param windowWidth - The width of the window. + * @param xOffset - The distance between the left edge of the window + * and the left edge of the wrapped component. + * @param componentWidth - The width of the wrapped component. + * @param tooltipWidth - The width of the tooltip itself. + * @param [manualShiftHorizontal] - Any additional amount to manually shift the tooltip to the left or right. + * A positive value shifts it to the right, + * and a negative value shifts it to the left. + */ +function computeHorizontalShift(windowWidth: number, xOffset: number, componentWidth: number, tooltipWidth: number, manualShiftHorizontal: number): number { + // First find the left and right edges of the tooltip (by default, it is centered on the component). + const componentCenter = xOffset + componentWidth / 2 + manualShiftHorizontal; + const tooltipLeftEdge = componentCenter - tooltipWidth / 2; + const tooltipRightEdge = componentCenter + tooltipWidth / 2; + + if (tooltipLeftEdge < GUTTER_WIDTH) { + // Tooltip is in left gutter, shift right by a multiple of four. + return roundToNearestMultipleOfFour(GUTTER_WIDTH - tooltipLeftEdge); + } + + if (tooltipRightEdge > windowWidth - GUTTER_WIDTH) { + // Tooltip is in right gutter, shift left by a multiple of four. + return roundToNearestMultipleOfFour(windowWidth - GUTTER_WIDTH - tooltipRightEdge); + } + + // Tooltip is not in the gutter, so no need to shift it horizontally + return 0; +} + +/** + * Determines if there is an overlapping element at the top of a given coordinate. + * (targetCenterX, y) + * | + * v + * _ _ _ _ _ + * | | + * | | + * | | + * | | + * |_ _ _ _ _| + * + * @param tooltip - The reference to the tooltip's root element + * @param xOffset - The distance between the left edge of the window + * and the left edge of the wrapped component. + * @param yOffset - The distance between the top edge of the window + * and the top edge of the wrapped component. + * @param tooltipTargetWidth - The width of the tooltip's target + * @param tooltipTargetHeight - The height of the tooltip's target + */ +function isOverlappingAtTop(tooltip: View | HTMLDivElement, xOffset: number, yOffset: number, tooltipTargetWidth: number, tooltipTargetHeight: number) { + if (typeof document.elementFromPoint !== 'function') { + return false; + } + + // Use the x center position of the target to prevent wrong element returned by elementFromPoint + // in case the target has a border radius or is a multiline text. + const targetCenterX = xOffset + tooltipTargetWidth / 2; + const elementAtTargetCenterX = document.elementFromPoint(targetCenterX, yOffset); + + // Ensure it's not the already rendered element of this very tooltip, so the tooltip doesn't try to "avoid" itself + if (!elementAtTargetCenterX || ('contains' in tooltip && tooltip.contains(elementAtTargetCenterX))) { + return false; + } + + const rectAtTargetCenterX = elementAtTargetCenterX.getBoundingClientRect(); + + // Ensure it's not overlapping with another element by checking if the yOffset is greater than the top of the element + // and less than the bottom of the element. Also ensure the tooltip target is not completely inside the elementAtTargetCenterX by vertical direction + const isOverlappingAtTargetCenterX = yOffset > rectAtTargetCenterX.top && yOffset < rectAtTargetCenterX.bottom && yOffset + tooltipTargetHeight > rectAtTargetCenterX.bottom; + + return isOverlappingAtTargetCenterX; +} + +type TooltipStyles = { + animationStyle: ViewStyle; + rootWrapperStyle: ViewStyle; + textStyle: TextStyle; + pointerWrapperStyle: ViewStyle; + pointerStyle: ViewStyle; +}; + +type TooltipParams = { + tooltip: View | HTMLDivElement; + currentSize: number; + windowWidth: number; + xOffset: number; + yOffset: number; + tooltipTargetWidth: number; + tooltipTargetHeight: number; + maxWidth: number; + tooltipContentWidth: number; + tooltipWrapperHeight: number; + theme: ThemeColors; + styles: ThemeStyles; + manualShiftHorizontal?: number; + manualShiftVertical?: number; +}; + +/** + * Generate styles for the tooltip component. + * + * @param tooltip - The reference to the tooltip's root element + * @param currentSize - The current size of the tooltip used in the scaling animation. + * @param windowWidth - The width of the window. + * @param xOffset - The distance between the left edge of the window + * and the left edge of the wrapped component. + * @param yOffset - The distance between the top edge of the window + * and the top edge of the wrapped component. + * @param tooltipTargetWidth - The width of the tooltip's target + * @param tooltipTargetHeight - The height of the tooltip's target + * @param maxWidth - The tooltip's max width. + * @param tooltipContentWidth - The tooltip's inner content measured width. + * @param tooltipWrapperHeight - The tooltip's wrapper measured height. + * @param [manualShiftHorizontal] - Any additional amount to manually shift the tooltip to the left or right. + * A positive value shifts it to the right, + * and a negative value shifts it to the left. + * @param [manualShiftVertical] - Any additional amount to manually shift the tooltip up or down. + * A positive value shifts it down, and a negative value shifts it up. + */ +const createTooltipStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ + getTooltipStyles: ({ + tooltip, + currentSize, + windowWidth, + xOffset, + yOffset, + tooltipTargetWidth, + tooltipTargetHeight, + maxWidth, + tooltipContentWidth, + tooltipWrapperHeight, + manualShiftHorizontal = 0, + manualShiftVertical = 0, + }: TooltipParams): TooltipStyles => { + const tooltipVerticalPadding = spacing.pv1; + + // We calculate tooltip width based on the tooltip's content width + // so the tooltip wrapper is just big enough to fit content and prevent white space. + // NOTE: Add 1 to the tooltipWidth to prevent truncated text in Safari + const tooltipWidth = tooltipContentWidth && tooltipContentWidth + spacing.ph2.paddingHorizontal * 2 + 1; + const tooltipHeight = tooltipWrapperHeight; + + const isTooltipSizeReady = tooltipWidth !== undefined && tooltipHeight !== undefined; + + // Set the scale to 1 to be able to measure the tooltip size correctly when it's not ready yet. + let scale = 1; + let shouldShowBelow = false; + let horizontalShift = 0; + let horizontalShiftPointer = 0; + let rootWrapperTop = 0; + let rootWrapperLeft = 0; + let pointerWrapperTop = 0; + let pointerWrapperLeft = 0; + let pointerAdditionalStyle = {}; + + if (isTooltipSizeReady) { + // Determine if the tooltip should display below the wrapped component. + // If either a tooltip will try to render within GUTTER_WIDTH logical pixels of the top of the screen, + // Or the wrapped component is overlapping at top-center with another element + // we'll display it beneath its wrapped component rather than above it as usual. + shouldShowBelow = yOffset - tooltipHeight < GUTTER_WIDTH || isOverlappingAtTop(tooltip, xOffset, yOffset, tooltipTargetWidth, tooltipTargetHeight); + + // When the tooltip size is ready, we can start animating the scale. + scale = currentSize; + + // Determine if we need to shift the tooltip horizontally to prevent it + // from displaying too near to the edge of the screen. + horizontalShift = computeHorizontalShift(windowWidth, xOffset, tooltipTargetWidth, tooltipWidth, manualShiftHorizontal); + + // Determine if we need to shift the pointer horizontally to prevent it from being too near to the edge of the tooltip + // We shift it to the right a bit if the tooltip is positioned on the extreme left + // and shift it to left a bit if the tooltip is positioned on the extreme right. + horizontalShiftPointer = + horizontalShift > 0 + ? Math.max(-horizontalShift, -(tooltipWidth / 2) + POINTER_WIDTH / 2 + variables.componentBorderRadiusSmall) + : Math.min(-horizontalShift, tooltipWidth / 2 - POINTER_WIDTH / 2 - variables.componentBorderRadiusSmall); + + // Because it uses fixed positioning, the top-left corner of the tooltip is aligned + // with the top-left corner of the window by default. + // we will use yOffset to position the tooltip relative to the Wrapped Component + // So we need to shift the tooltip vertically and horizontally to position it correctly. + // + // First, we'll position it vertically. + // To shift the tooltip down, we'll give `top` a positive value. + // To shift the tooltip up, we'll give `top` a negative value. + rootWrapperTop = shouldShowBelow + ? // We need to shift the tooltip down below the component. So shift the tooltip down (+) by... + yOffset + tooltipTargetHeight + POINTER_HEIGHT + manualShiftVertical + : // We need to shift the tooltip up above the component. So shift the tooltip up (-) by... + yOffset - (tooltipHeight + POINTER_HEIGHT) + manualShiftVertical; + + // Next, we'll position it horizontally. + // we will use xOffset to position the tooltip relative to the Wrapped Component + // To shift the tooltip right, we'll give `left` a positive value. + // To shift the tooltip left, we'll give `left` a negative value. + // + // So we'll: + // 1) Shift the tooltip right (+) to the center of the component, + // so the left edge lines up with the component center. + // 2) Shift it left (-) to by half the tooltip's width, + // so the tooltip's center lines up with the center of the wrapped component. + // 3) Add the horizontal shift (left or right) computed above to keep it out of the gutters. + // 4) Lastly, add the manual horizontal shift passed in as a parameter. + rootWrapperLeft = xOffset + (tooltipTargetWidth / 2 - tooltipWidth / 2) + horizontalShift + manualShiftHorizontal; + + // By default, the pointer's top-left will align with the top-left of the tooltip wrapper. + // + // To align it vertically, we'll: + // If the pointer should be below the tooltip wrapper, shift the pointer down (+) by the tooltip height, + // so that the top of the pointer lines up with the bottom of the tooltip + // + // OR if the pointer should be above the tooltip wrapper, then the pointer up (-) by the pointer's height + // so that the bottom of the pointer lines up with the top of the tooltip + pointerWrapperTop = shouldShowBelow ? -POINTER_HEIGHT : tooltipHeight; + + // To align it horizontally, we'll: + // 1) Shift the pointer to the right (+) by the half the tooltipWidth's width, + // so the left edge of the pointer lines up with the tooltipWidth's center. + // 2) To the left (-) by half the pointer's width, + // so the pointer's center lines up with the tooltipWidth's center. + // 3) Remove the wrapper's horizontalShift to maintain the pointer + // at the center of the hovered component. + pointerWrapperLeft = horizontalShiftPointer + (tooltipWidth / 2 - POINTER_WIDTH / 2); + + pointerAdditionalStyle = shouldShowBelow ? styles.flipUpsideDown : {}; + } + + return { + animationStyle: { + // remember Transform causes a new Local cordinate system + // https://drafts.csswg.org/css-transforms-1/#transform-rendering + // so Position fixed children will be relative to this new Local cordinate system + transform: [{scale}], + }, + rootWrapperStyle: { + ...positioning.pFixed, + backgroundColor: theme.heading, + borderRadius: variables.componentBorderRadiusSmall, + ...tooltipVerticalPadding, + ...spacing.ph2, + zIndex: variables.tooltipzIndex, + width: tooltipWidth, + maxWidth, + top: rootWrapperTop, + left: rootWrapperLeft, + + // We are adding this to prevent the tooltip text from being selected and copied on CTRL + A. + ...styles.userSelectNone, + ...styles.pointerEventsNone, + }, + textStyle: { + color: theme.textReversed, + fontFamily: fontFamily.EXP_NEUE, + fontSize: variables.fontSizeSmall, + overflow: 'hidden', + lineHeight: variables.lineHeightSmall, + textAlign: 'center', + }, + pointerWrapperStyle: { + ...positioning.pFixed, + top: pointerWrapperTop, + left: pointerWrapperLeft, + }, + pointerStyle: { + width: 0, + height: 0, + backgroundColor: theme.transparent, + borderStyle: 'solid', + borderLeftWidth: POINTER_WIDTH / 2, + borderRightWidth: POINTER_WIDTH / 2, + borderTopWidth: POINTER_HEIGHT, + borderLeftColor: theme.transparent, + borderRightColor: theme.transparent, + borderTopColor: theme.heading, + ...pointerAdditionalStyle, + }, + }; + }, +}); + +export default createTooltipStyleUtils; diff --git a/src/styles/StyleUtils.ts b/src/styles/utils/index.ts similarity index 98% rename from src/styles/StyleUtils.ts rename to src/styles/utils/index.ts index 9037c65e7583..965d5495a1f8 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/utils/index.ts @@ -4,17 +4,20 @@ import {EdgeInsets} from 'react-native-safe-area-context'; import {ValueOf} from 'type-fest'; import * as Browser from '@libs/Browser'; import * as UserUtils from '@libs/UserUtils'; +import colors from '@styles/colors'; +import fontFamily from '@styles/fontFamily'; +import {defaultStyles, type ThemeStyles} from '@styles/styles'; +import {defaultTheme} from '@styles/themes/Themes'; +import {ThemeColors} from '@styles/themes/types'; +import cursor from '@styles/utilities/cursor'; +import positioning from '@styles/utilities/positioning'; +import spacing from '@styles/utilities/spacing'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import {Transaction} from '@src/types/onyx'; -import colors from './colors'; -import fontFamily from './fontFamily'; -import {defaultStyles, type ThemeStyles} from './styles'; -import {defaultTheme} from './themes/Themes'; -import {ThemeColors} from './themes/types'; -import cursor from './utilities/cursor'; -import positioning from './utilities/positioning'; -import spacing from './utilities/spacing'; -import variables from './variables'; +import createModalStyleUtils from './ModalStyleUtils'; +import createReportActionContextMenuStyleUtils from './ReportActionContextMenuStyleUtils'; +import createTooltipStyleUtils from './TooltipStyleUtils'; type AllStyles = ViewStyle | TextStyle | ImageStyle; type ParsableStyle = StyleProp | ((state: PressableStateCallbackType) => StyleProp); @@ -1097,6 +1100,9 @@ const staticStyleUtils = { const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ ...staticStyleUtils, + ...createModalStyleUtils(theme, styles), + ...createTooltipStyleUtils(theme, styles), + ...createReportActionContextMenuStyleUtils(theme, styles), /** * Gets styles for AutoCompleteSuggestion row From 8970199d759c622097654f8450132c86cffb43db Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 11:49:30 +0100 Subject: [PATCH 18/39] re-structure styles --- src/styles/{utils => StyleUtils}/ModalStyleUtils.ts | 0 .../PopoverWithMeasuredContentStyleUtils.ts | 2 +- .../{utils => StyleUtils}/ReportActionContextMenuStyleUtils.ts | 0 src/styles/{utils => StyleUtils}/TooltipStyleUtils.ts | 2 +- src/styles/{utils => StyleUtils}/index.ts | 0 src/styles/{ => StyleUtils}/roundToNearestMultipleOfFour.ts | 0 6 files changed, 2 insertions(+), 2 deletions(-) rename src/styles/{utils => StyleUtils}/ModalStyleUtils.ts (100%) rename src/styles/{utils => StyleUtils}/PopoverWithMeasuredContentStyleUtils.ts (96%) rename src/styles/{utils => StyleUtils}/ReportActionContextMenuStyleUtils.ts (100%) rename src/styles/{utils => StyleUtils}/TooltipStyleUtils.ts (99%) rename src/styles/{utils => StyleUtils}/index.ts (100%) rename src/styles/{ => StyleUtils}/roundToNearestMultipleOfFour.ts (100%) diff --git a/src/styles/utils/ModalStyleUtils.ts b/src/styles/StyleUtils/ModalStyleUtils.ts similarity index 100% rename from src/styles/utils/ModalStyleUtils.ts rename to src/styles/StyleUtils/ModalStyleUtils.ts diff --git a/src/styles/utils/PopoverWithMeasuredContentStyleUtils.ts b/src/styles/StyleUtils/PopoverWithMeasuredContentStyleUtils.ts similarity index 96% rename from src/styles/utils/PopoverWithMeasuredContentStyleUtils.ts rename to src/styles/StyleUtils/PopoverWithMeasuredContentStyleUtils.ts index 41723c960b2a..5b485ba339a2 100644 --- a/src/styles/utils/PopoverWithMeasuredContentStyleUtils.ts +++ b/src/styles/StyleUtils/PopoverWithMeasuredContentStyleUtils.ts @@ -1,5 +1,5 @@ -import roundToNearestMultipleOfFour from '@styles/roundToNearestMultipleOfFour'; import variables from '@styles/variables'; +import roundToNearestMultipleOfFour from './roundToNearestMultipleOfFour'; /** * Compute the amount that the Context menu's Anchor needs to be horizontally shifted diff --git a/src/styles/utils/ReportActionContextMenuStyleUtils.ts b/src/styles/StyleUtils/ReportActionContextMenuStyleUtils.ts similarity index 100% rename from src/styles/utils/ReportActionContextMenuStyleUtils.ts rename to src/styles/StyleUtils/ReportActionContextMenuStyleUtils.ts diff --git a/src/styles/utils/TooltipStyleUtils.ts b/src/styles/StyleUtils/TooltipStyleUtils.ts similarity index 99% rename from src/styles/utils/TooltipStyleUtils.ts rename to src/styles/StyleUtils/TooltipStyleUtils.ts index 07e5f7ec1141..c0a07bc4c122 100644 --- a/src/styles/utils/TooltipStyleUtils.ts +++ b/src/styles/StyleUtils/TooltipStyleUtils.ts @@ -1,7 +1,7 @@ import {TextStyle, View, ViewStyle} from 'react-native'; import fontFamily from '@styles/fontFamily'; -import roundToNearestMultipleOfFour from '@styles/roundToNearestMultipleOfFour'; import {type ThemeStyles} from '@styles/styles'; +import roundToNearestMultipleOfFour from '@styles/StyleUtils/roundToNearestMultipleOfFour'; import {type ThemeColors} from '@styles/themes/types'; import positioning from '@styles/utilities/positioning'; import spacing from '@styles/utilities/spacing'; diff --git a/src/styles/utils/index.ts b/src/styles/StyleUtils/index.ts similarity index 100% rename from src/styles/utils/index.ts rename to src/styles/StyleUtils/index.ts diff --git a/src/styles/roundToNearestMultipleOfFour.ts b/src/styles/StyleUtils/roundToNearestMultipleOfFour.ts similarity index 100% rename from src/styles/roundToNearestMultipleOfFour.ts rename to src/styles/StyleUtils/roundToNearestMultipleOfFour.ts From b0616b1442347dd545343858975374306c808b7c Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 11:55:12 +0100 Subject: [PATCH 19/39] restructure themes --- .../PopoverWithMeasuredContentStyleUtils.ts | 6 ++++-- .../{StyleUtils => ThemeStyleUtils}/ModalStyleUtils.ts | 0 .../ReportActionContextMenuStyleUtils.ts | 0 .../{StyleUtils => ThemeStyleUtils}/TooltipStyleUtils.ts | 2 +- src/styles/{StyleUtils => ThemeStyleUtils}/index.ts | 0 .../roundToNearestMultipleOfFour.ts | 0 src/styles/ThemeStylesContext.ts | 4 ++-- src/styles/ThemeStylesProvider.tsx | 2 +- src/styles/useStyleUtils.ts | 2 +- 9 files changed, 9 insertions(+), 7 deletions(-) rename src/styles/{StyleUtils => }/PopoverWithMeasuredContentStyleUtils.ts (89%) rename src/styles/{StyleUtils => ThemeStyleUtils}/ModalStyleUtils.ts (100%) rename src/styles/{StyleUtils => ThemeStyleUtils}/ReportActionContextMenuStyleUtils.ts (100%) rename src/styles/{StyleUtils => ThemeStyleUtils}/TooltipStyleUtils.ts (99%) rename src/styles/{StyleUtils => ThemeStyleUtils}/index.ts (100%) rename src/styles/{StyleUtils => ThemeStyleUtils}/roundToNearestMultipleOfFour.ts (100%) diff --git a/src/styles/StyleUtils/PopoverWithMeasuredContentStyleUtils.ts b/src/styles/PopoverWithMeasuredContentStyleUtils.ts similarity index 89% rename from src/styles/StyleUtils/PopoverWithMeasuredContentStyleUtils.ts rename to src/styles/PopoverWithMeasuredContentStyleUtils.ts index 5b485ba339a2..5f8d4d6d0d4e 100644 --- a/src/styles/StyleUtils/PopoverWithMeasuredContentStyleUtils.ts +++ b/src/styles/PopoverWithMeasuredContentStyleUtils.ts @@ -1,5 +1,5 @@ import variables from '@styles/variables'; -import roundToNearestMultipleOfFour from './roundToNearestMultipleOfFour'; +import roundToNearestMultipleOfFour from './ThemeStyleUtils/roundToNearestMultipleOfFour'; /** * Compute the amount that the Context menu's Anchor needs to be horizontally shifted @@ -50,4 +50,6 @@ function computeVerticalShift(anchorTopEdge: number, menuHeight: number, windowH return 0; } -export {computeHorizontalShift, computeVerticalShift}; +const PopoverWithMeasuredContentStyleUtils = {computeHorizontalShift, computeVerticalShift}; + +export default PopoverWithMeasuredContentStyleUtils; diff --git a/src/styles/StyleUtils/ModalStyleUtils.ts b/src/styles/ThemeStyleUtils/ModalStyleUtils.ts similarity index 100% rename from src/styles/StyleUtils/ModalStyleUtils.ts rename to src/styles/ThemeStyleUtils/ModalStyleUtils.ts diff --git a/src/styles/StyleUtils/ReportActionContextMenuStyleUtils.ts b/src/styles/ThemeStyleUtils/ReportActionContextMenuStyleUtils.ts similarity index 100% rename from src/styles/StyleUtils/ReportActionContextMenuStyleUtils.ts rename to src/styles/ThemeStyleUtils/ReportActionContextMenuStyleUtils.ts diff --git a/src/styles/StyleUtils/TooltipStyleUtils.ts b/src/styles/ThemeStyleUtils/TooltipStyleUtils.ts similarity index 99% rename from src/styles/StyleUtils/TooltipStyleUtils.ts rename to src/styles/ThemeStyleUtils/TooltipStyleUtils.ts index c0a07bc4c122..405a43db65dd 100644 --- a/src/styles/StyleUtils/TooltipStyleUtils.ts +++ b/src/styles/ThemeStyleUtils/TooltipStyleUtils.ts @@ -1,8 +1,8 @@ import {TextStyle, View, ViewStyle} from 'react-native'; import fontFamily from '@styles/fontFamily'; import {type ThemeStyles} from '@styles/styles'; -import roundToNearestMultipleOfFour from '@styles/StyleUtils/roundToNearestMultipleOfFour'; import {type ThemeColors} from '@styles/themes/types'; +import roundToNearestMultipleOfFour from '@styles/ThemeStyleUtils/roundToNearestMultipleOfFour'; import positioning from '@styles/utilities/positioning'; import spacing from '@styles/utilities/spacing'; import variables from '@styles/variables'; diff --git a/src/styles/StyleUtils/index.ts b/src/styles/ThemeStyleUtils/index.ts similarity index 100% rename from src/styles/StyleUtils/index.ts rename to src/styles/ThemeStyleUtils/index.ts diff --git a/src/styles/StyleUtils/roundToNearestMultipleOfFour.ts b/src/styles/ThemeStyleUtils/roundToNearestMultipleOfFour.ts similarity index 100% rename from src/styles/StyleUtils/roundToNearestMultipleOfFour.ts rename to src/styles/ThemeStyleUtils/roundToNearestMultipleOfFour.ts diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index 73f044f2dcbd..cff708628745 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,8 +1,8 @@ import React from 'react'; import {defaultStyles} from './styles'; import type {ThemeStyles} from './styles'; -import {DefaultStyleUtils} from './utils'; -import type {StyleUtilsType} from './utils'; +import {DefaultStyleUtils} from './ThemeStyleUtils'; +import type {StyleUtilsType} from './ThemeStyleUtils'; type ThemeStylesContextType = { styles: ThemeStyles; diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index c2d44c266ec3..a73188a81890 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -2,7 +2,7 @@ import React, {useMemo} from 'react'; import {stylesGenerator} from './styles'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; -import createStyleUtils from './utils'; +import createStyleUtils from './ThemeStyleUtils'; type ThemeStylesProviderProps = React.PropsWithChildren; diff --git a/src/styles/useStyleUtils.ts b/src/styles/useStyleUtils.ts index aadb3f884220..e7d658b87d07 100644 --- a/src/styles/useStyleUtils.ts +++ b/src/styles/useStyleUtils.ts @@ -1,5 +1,5 @@ import {useContext} from 'react'; -import ThemeStylesContext from './ThemeStylesContext'; +import ThemeStylesContext from '@styles/ThemeStylesContext'; function useStyleUtils() { const themeStylesContext = useContext(ThemeStylesContext); From 76090214e6ede8dda6f0fcf078abce9df8803217 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 11:58:26 +0100 Subject: [PATCH 20/39] fix: restructures --- src/components/Avatar.tsx | 2 +- src/components/Modal/BaseModal.tsx | 2 +- src/components/PopoverWithMeasuredContent.js | 6 +++--- src/components/PopoverWithoutOverlay/index.js | 2 +- src/components/ReportActionItem/MoneyRequestView.js | 2 +- src/components/Tooltip/TooltipRenderedOnPageBody.js | 2 +- src/components/withStyleUtils.tsx | 2 +- .../report/ContextMenu/BaseReportActionContextMenu.js | 9 +++------ src/pages/signin/SignInPage.js | 2 +- 9 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 9fbc3f37fcc0..4f014a500153 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -3,8 +3,8 @@ import {StyleProp, View, ViewStyle} from 'react-native'; import useNetwork from '@hooks/useNetwork'; import * as ReportUtils from '@libs/ReportUtils'; import {AvatarSource} from '@libs/UserUtils'; -import {AvatarSizeName} from '@styles/StyleUtils'; import useTheme from '@styles/themes/useTheme'; +import type {AvatarSizeName} from '@styles/ThemeStyleUtils'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 2be3967c28e7..befd415d1b17 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -7,8 +7,8 @@ import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; import useWindowDimensions from '@hooks/useWindowDimensions'; import ComposerFocusManager from '@libs/ComposerFocusManager'; import useNativeDriver from '@libs/useNativeDriver'; -import getModalStyles from '@styles/getModalStyles'; import useTheme from '@styles/themes/useTheme'; +import getModalStyles from '@styles/ThemeStyleUtils/ModalStyleUtils'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; diff --git a/src/components/PopoverWithMeasuredContent.js b/src/components/PopoverWithMeasuredContent.js index 24a0bdb70903..b2c94c81770f 100644 --- a/src/components/PopoverWithMeasuredContent.js +++ b/src/components/PopoverWithMeasuredContent.js @@ -3,7 +3,7 @@ import React, {useMemo, useState} from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import {computeHorizontalShift, computeVerticalShift} from '@styles/getPopoverWithMeasuredContentStyles'; +import PopoverWithMeasuredContentStyleUtils from '@styles/PopoverWithMeasuredContentStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import CONST from '@src/CONST'; import Popover from './Popover'; @@ -128,8 +128,8 @@ function PopoverWithMeasuredContent(props) { }; }, [props.anchorPosition, props.anchorAlignment, popoverWidth, popoverHeight]); - const horizontalShift = computeHorizontalShift(adjustedAnchorPosition.left, popoverWidth, windowWidth); - const verticalShift = computeVerticalShift(adjustedAnchorPosition.top, popoverHeight, windowHeight); + const horizontalShift = PopoverWithMeasuredContentStyleUtils.computeHorizontalShift(adjustedAnchorPosition.left, popoverWidth, windowWidth); + const verticalShift = PopoverWithMeasuredContentStyleUtils.computeVerticalShift(adjustedAnchorPosition.top, popoverHeight, windowHeight); const shiftedAnchorPosition = { left: adjustedAnchorPosition.left + horizontalShift, bottom: windowHeight - (adjustedAnchorPosition.top + popoverHeight) - verticalShift, diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 3818dd1ac945..1aaf1fe01528 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -5,8 +5,8 @@ import {defaultProps, propTypes} from '@components/Popover/popoverPropTypes'; import {PopoverContext} from '@components/PopoverProvider'; import withWindowDimensions from '@components/withWindowDimensions'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; -import getModalStyles from '@styles/getModalStyles'; import useTheme from '@styles/themes/useTheme'; +import getModalStyles from '@styles/ThemeStyleUtils/ModalStyleUtils'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import * as Modal from '@userActions/Modal'; diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index f26350d70b3f..7fb42c0d7ea0 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -31,10 +31,10 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import iouReportPropTypes from '@pages/iouReportPropTypes'; -import reportPropTypes from '@pages/reportPropTypes'; import useTheme from '@styles/themes/useTheme'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import reportPropTypes from '@styles/utils/StyleUtilsypes'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index d92457238675..d48ab620dead 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -4,8 +4,8 @@ import ReactDOM from 'react-dom'; import {Animated, View} from 'react-native'; import Text from '@components/Text'; import Log from '@libs/Log'; -import getTooltipStyles from '@styles/getTooltipStyles'; import useTheme from '@styles/themes/useTheme'; +import getTooltipStyles from '@styles/ThemeStyleUtils/TooltipStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; const propTypes = { diff --git a/src/components/withStyleUtils.tsx b/src/components/withStyleUtils.tsx index eb31cd331c49..d4f2bd535231 100644 --- a/src/components/withStyleUtils.tsx +++ b/src/components/withStyleUtils.tsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import React, {ComponentType, ForwardedRef, forwardRef, ReactElement, RefAttributes} from 'react'; import getComponentDisplayName from '@libs/getComponentDisplayName'; -import {StyleUtilsType} from '@styles/StyleUtils'; +import {StyleUtilsType} from '@styles/ThemeStyleUtils'; import useStyleUtils from '@styles/useStyleUtils'; const withStyleUtilsPropTypes = { diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js index 051e559c34b6..33adfa4b35f9 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js @@ -12,9 +12,7 @@ import useArrowKeyFocusManager from '@hooks/useArrowKeyFocusManager'; import useKeyboardShortcut from '@hooks/useKeyboardShortcut'; import useNetwork from '@hooks/useNetwork'; import compose from '@libs/compose'; -import getReportActionContextMenuStyles from '@styles/getReportActionContextMenuStyles'; -import useTheme from '@styles/themes/useTheme'; -import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useStyleUtils'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -51,11 +49,10 @@ const defaultProps = { ...GenericReportActionContextMenuDefaultProps, }; function BaseReportActionContextMenu(props) { - const theme = useTheme(); - const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const menuItemRefs = useRef({}); const [shouldKeepOpen, setShouldKeepOpen] = useState(false); - const wrapperStyle = getReportActionContextMenuStyles(styles, props.isMini, props.isSmallScreenWidth, theme); + const wrapperStyle = StyleUtils.getReportActionContextMenuStyles(props.isMini, props.isSmallScreenWidth); const {isOffline} = useNetwork(); const reportAction = useMemo(() => { diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index dbad6324c922..72a9e3074f88 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -14,7 +14,7 @@ import * as Localize from '@libs/Localize'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import Performance from '@libs/Performance'; -import ThemeProvider from '@styles/themes/ThemeProvider'; +import ThemeProvider from '@s@styles/utils/StyleUtilsProvider'; import ThemeStylesProvider from '@styles/ThemeStylesProvider'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; From a9cdc0b9432fd78bbcf729df69e5cf81464e66c4 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 12:00:15 +0100 Subject: [PATCH 21/39] fix: old style utils --- src/components/Modal/BaseModal.tsx | 7 ++--- src/components/PopoverWithoutOverlay/index.js | 28 ++++++++----------- .../Tooltip/TooltipRenderedOnPageBody.js | 13 +++------ 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index befd415d1b17..1ea284b55280 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -8,7 +8,6 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; import ComposerFocusManager from '@libs/ComposerFocusManager'; import useNativeDriver from '@libs/useNativeDriver'; import useTheme from '@styles/themes/useTheme'; -import getModalStyles from '@styles/ThemeStyleUtils/ModalStyleUtils'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; @@ -134,9 +133,7 @@ function BaseModal( hideBackdrop, } = useMemo( () => - getModalStyles( - theme, - styles, + StyleUtils.getModalStyles( type, { windowWidth, @@ -147,7 +144,7 @@ function BaseModal( innerContainerStyle, outerStyle, ), - [innerContainerStyle, isSmallScreenWidth, outerStyle, popoverAnchorPosition, theme, type, windowHeight, windowWidth, styles], + [StyleUtils, type, windowWidth, windowHeight, isSmallScreenWidth, popoverAnchorPosition, innerContainerStyle, outerStyle], ); const { diff --git a/src/components/PopoverWithoutOverlay/index.js b/src/components/PopoverWithoutOverlay/index.js index 1aaf1fe01528..c13d9e1a0931 100644 --- a/src/components/PopoverWithoutOverlay/index.js +++ b/src/components/PopoverWithoutOverlay/index.js @@ -5,31 +5,27 @@ import {defaultProps, propTypes} from '@components/Popover/popoverPropTypes'; import {PopoverContext} from '@components/PopoverProvider'; import withWindowDimensions from '@components/withWindowDimensions'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; -import useTheme from '@styles/themes/useTheme'; -import getModalStyles from '@styles/ThemeStyleUtils/ModalStyleUtils'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import * as Modal from '@userActions/Modal'; function Popover(props) { - const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {onOpen, close} = React.useContext(PopoverContext); const insets = useSafeAreaInsets(); - const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = getModalStyles( - theme, - styles, - 'popover', - { - windowWidth: props.windowWidth, - windowHeight: props.windowHeight, - isSmallScreenWidth: false, - }, - props.anchorPosition, - props.innerContainerStyle, - props.outerStyle, - ); + const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = + StyleUtils.getModalStyles( + 'popover', + { + windowWidth: props.windowWidth, + windowHeight: props.windowHeight, + isSmallScreenWidth: false, + }, + props.anchorPosition, + props.innerContainerStyle, + props.outerStyle, + ); const { paddingTop: safeAreaPaddingTop, diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index d48ab620dead..10e82cc94c30 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -4,9 +4,7 @@ import ReactDOM from 'react-dom'; import {Animated, View} from 'react-native'; import Text from '@components/Text'; import Log from '@libs/Log'; -import useTheme from '@styles/themes/useTheme'; -import getTooltipStyles from '@styles/ThemeStyleUtils/TooltipStyleUtils'; -import useThemeStyles from '@styles/useThemeStyles'; +import useStyleUtils from '@styles/useStyleUtils'; const propTypes = { /** Window width */ @@ -84,8 +82,7 @@ function TooltipRenderedOnPageBody({ const contentRef = useRef(); const rootWrapper = useRef(); - const theme = useTheme(); - const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); useEffect(() => { if (!renderTooltipContent || !text) { @@ -103,7 +100,7 @@ function TooltipRenderedOnPageBody({ const {animationStyle, rootWrapperStyle, textStyle, pointerWrapperStyle, pointerStyle} = useMemo( () => - getTooltipStyles({ + StyleUtils.getTooltipStyles({ tooltip: rootWrapper.current, currentSize: animation, windowWidth, @@ -114,12 +111,10 @@ function TooltipRenderedOnPageBody({ maxWidth, tooltipContentWidth: contentMeasuredWidth, tooltipWrapperHeight: wrapperMeasuredHeight, - theme, - styles, shiftHorizontal, shiftVertical, }), - [animation, windowWidth, xOffset, yOffset, targetWidth, targetHeight, maxWidth, contentMeasuredWidth, wrapperMeasuredHeight, shiftHorizontal, shiftVertical, theme, styles], + [StyleUtils, animation, windowWidth, xOffset, yOffset, targetWidth, targetHeight, maxWidth, contentMeasuredWidth, wrapperMeasuredHeight, shiftHorizontal, shiftVertical], ); let content; From 524a266f85d37a309711ada94166fbc1842ebf1d Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 12:42:18 +0100 Subject: [PATCH 22/39] fix: lint and error --- src/styles/PopoverWithMeasuredContentStyleUtils.ts | 2 +- src/styles/ThemeStyleUtils/TooltipStyleUtils.ts | 2 +- src/styles/ThemeStylesProvider.tsx | 2 +- src/styles/useStyleUtils.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/styles/PopoverWithMeasuredContentStyleUtils.ts b/src/styles/PopoverWithMeasuredContentStyleUtils.ts index 5f8d4d6d0d4e..5e12e2f2d2eb 100644 --- a/src/styles/PopoverWithMeasuredContentStyleUtils.ts +++ b/src/styles/PopoverWithMeasuredContentStyleUtils.ts @@ -1,5 +1,5 @@ -import variables from '@styles/variables'; import roundToNearestMultipleOfFour from './ThemeStyleUtils/roundToNearestMultipleOfFour'; +import variables from './variables'; /** * Compute the amount that the Context menu's Anchor needs to be horizontally shifted diff --git a/src/styles/ThemeStyleUtils/TooltipStyleUtils.ts b/src/styles/ThemeStyleUtils/TooltipStyleUtils.ts index 405a43db65dd..aefd6ae54d2f 100644 --- a/src/styles/ThemeStyleUtils/TooltipStyleUtils.ts +++ b/src/styles/ThemeStyleUtils/TooltipStyleUtils.ts @@ -2,10 +2,10 @@ import {TextStyle, View, ViewStyle} from 'react-native'; import fontFamily from '@styles/fontFamily'; import {type ThemeStyles} from '@styles/styles'; import {type ThemeColors} from '@styles/themes/types'; -import roundToNearestMultipleOfFour from '@styles/ThemeStyleUtils/roundToNearestMultipleOfFour'; import positioning from '@styles/utilities/positioning'; import spacing from '@styles/utilities/spacing'; import variables from '@styles/variables'; +import roundToNearestMultipleOfFour from './roundToNearestMultipleOfFour'; /** This defines the proximity with the edge of the window in which tooltips should not be displayed. * If a tooltip is too close to the edge of the screen, we'll shift it towards the center. */ diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index a73188a81890..35722304dc39 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -1,5 +1,5 @@ import React, {useMemo} from 'react'; -import {stylesGenerator} from './styles'; +import stylesGenerator from './styles'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; import createStyleUtils from './ThemeStyleUtils'; diff --git a/src/styles/useStyleUtils.ts b/src/styles/useStyleUtils.ts index e7d658b87d07..aadb3f884220 100644 --- a/src/styles/useStyleUtils.ts +++ b/src/styles/useStyleUtils.ts @@ -1,5 +1,5 @@ import {useContext} from 'react'; -import ThemeStylesContext from '@styles/ThemeStylesContext'; +import ThemeStylesContext from './ThemeStylesContext'; function useStyleUtils() { const themeStylesContext = useContext(ThemeStylesContext); From 87f1e76462abbfb03a598fa72a9d7f11a36d14aa Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 12:43:26 +0100 Subject: [PATCH 23/39] fix: ts --- src/libs/Navigation/AppNavigator/RHPScreenOptions.ts | 4 ++-- .../Navigation/AppNavigator/getRootNavigatorScreenOptions.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/RHPScreenOptions.ts b/src/libs/Navigation/AppNavigator/RHPScreenOptions.ts index 6b56bb00cf56..6cae31a219f9 100644 --- a/src/libs/Navigation/AppNavigator/RHPScreenOptions.ts +++ b/src/libs/Navigation/AppNavigator/RHPScreenOptions.ts @@ -1,12 +1,12 @@ import {CardStyleInterpolators, StackNavigationOptions} from '@react-navigation/stack'; -import styles from '@styles/styles'; +import {ThemeStyles} from '@styles/styles'; /** * RHP stack navigator screen options generator function * @param themeStyles - The styles object * @returns The screen options object */ -const RHPScreenOptions = (themeStyles: typeof styles): StackNavigationOptions => ({ +const RHPScreenOptions = (themeStyles: ThemeStyles): StackNavigationOptions => ({ headerShown: false, animationEnabled: true, gestureDirection: 'horizontal', diff --git a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.ts b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.ts index 08f18ce3ab9d..9af92dd3e019 100644 --- a/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.ts +++ b/src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.ts @@ -1,6 +1,6 @@ import {StackCardInterpolationProps, StackNavigationOptions} from '@react-navigation/stack'; import getNavigationModalCardStyle from '@styles/getNavigationModalCardStyles'; -import styles from '@styles/styles'; +import {ThemeStyles} from '@styles/styles'; import variables from '@styles/variables'; import CONFIG from '@src/CONFIG'; import modalCardStyleInterpolator from './modalCardStyleInterpolator'; @@ -15,7 +15,7 @@ const commonScreenOptions: StackNavigationOptions = { animationTypeForReplace: 'push', }; -export default (isSmallScreenWidth: boolean, themeStyles: typeof styles): ScreenOptions => ({ +export default (isSmallScreenWidth: boolean, themeStyles: ThemeStyles): ScreenOptions => ({ rightModalNavigator: { ...commonScreenOptions, cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, false, props), From e7ccd95bd9aa188afb2835fd6dd5b5df94ea7d28 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Wed, 6 Dec 2023 13:56:47 +0100 Subject: [PATCH 24/39] rename .web files to .website files --- .../MapView/{Direction.web.tsx => Direction.website.tsx} | 0 src/components/MapView/{MapView.web.tsx => MapView.website.tsx} | 0 ...serDetailsTooltip.web.js => BaseUserDetailsTooltip.website.js} | 0 src/libs/Browser/{index.web.ts => index.website.ts} | 0 src/libs/StatusBar/{index.web.ts => index.website.ts} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename src/components/MapView/{Direction.web.tsx => Direction.website.tsx} (100%) rename src/components/MapView/{MapView.web.tsx => MapView.website.tsx} (100%) rename src/components/UserDetailsTooltip/{BaseUserDetailsTooltip.web.js => BaseUserDetailsTooltip.website.js} (100%) rename src/libs/Browser/{index.web.ts => index.website.ts} (100%) rename src/libs/StatusBar/{index.web.ts => index.website.ts} (100%) diff --git a/src/components/MapView/Direction.web.tsx b/src/components/MapView/Direction.website.tsx similarity index 100% rename from src/components/MapView/Direction.web.tsx rename to src/components/MapView/Direction.website.tsx diff --git a/src/components/MapView/MapView.web.tsx b/src/components/MapView/MapView.website.tsx similarity index 100% rename from src/components/MapView/MapView.web.tsx rename to src/components/MapView/MapView.website.tsx diff --git a/src/components/UserDetailsTooltip/BaseUserDetailsTooltip.web.js b/src/components/UserDetailsTooltip/BaseUserDetailsTooltip.website.js similarity index 100% rename from src/components/UserDetailsTooltip/BaseUserDetailsTooltip.web.js rename to src/components/UserDetailsTooltip/BaseUserDetailsTooltip.website.js diff --git a/src/libs/Browser/index.web.ts b/src/libs/Browser/index.website.ts similarity index 100% rename from src/libs/Browser/index.web.ts rename to src/libs/Browser/index.website.ts diff --git a/src/libs/StatusBar/index.web.ts b/src/libs/StatusBar/index.website.ts similarity index 100% rename from src/libs/StatusBar/index.web.ts rename to src/libs/StatusBar/index.website.ts From 8da43e07a1cf12260d148d9577644fbf055ee6e1 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Wed, 6 Dec 2023 14:07:51 +0100 Subject: [PATCH 25/39] make webpack take .website.tsx files --- config/webpack/webpack.common.js | 16 +++++++++++++++- tsconfig.json | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/config/webpack/webpack.common.js b/config/webpack/webpack.common.js index 8c74ebfd1686..008b4f45911f 100644 --- a/config/webpack/webpack.common.js +++ b/config/webpack/webpack.common.js @@ -211,7 +211,21 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ // This is also why we have to use .website.js for our own web-specific files... // Because desktop also relies on "web-specific" module implementations // This also skips packing web only dependencies to desktop and vice versa - extensions: ['.web.js', platform === 'web' ? '.website.js' : '.desktop.js', '.js', '.jsx', '.web.ts', platform === 'web' ? '.website.ts' : '.desktop.ts', '.ts', '.web.tsx', '.tsx'], + extensions: [ + '.web.js', + ...(platform === 'desktop' ? ['.desktop.js'] : []), + '.website.js', + '.js', + '.jsx', + '.web.ts', + ...(platform === 'desktop' ? ['.desktop.ts'] : []), + '.website.ts', + ...(platform === 'desktop' ? ['.desktop.tsx'] : []), + '.website.tsx', + '.ts', + '.web.tsx', + '.tsx', + ], fallback: { 'process/browser': require.resolve('process/browser'), }, diff --git a/tsconfig.json b/tsconfig.json index eafc7c375fdd..08447f306dd5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -47,5 +47,5 @@ } }, "exclude": ["**/node_modules/*", "**/dist/*", ".github/actions/**/index.js", "**/docs/*"], - "include": ["src", "desktop", "web", "docs", "assets", "config", "tests", "jest", "__mocks__", ".github/**/*", ".storybook/**/*"] + "include": ["src", "desktop", "web", "website", "docs", "assets", "config", "tests", "jest", "__mocks__", ".github/**/*", ".storybook/**/*"] } From 4066dcf27cd54ea8fd1c255021dad7225d6824a3 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 14:58:25 +0100 Subject: [PATCH 26/39] fix: test --- src/pages/signin/SignInPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index 72a9e3074f88..1fb99155af40 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -14,10 +14,10 @@ import * as Localize from '@libs/Localize'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import Performance from '@libs/Performance'; -import ThemeProvider from '@s@styles/utils/StyleUtilsProvider'; import ThemeStylesProvider from '@styles/ThemeStylesProvider'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import ThemeProvider from '@styles/utils/StyleUtilsProvider'; import * as App from '@userActions/App'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; From f0228f96a8ccf5df773bdd272e71d45205f74501 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 15:05:54 +0100 Subject: [PATCH 27/39] rename themes file --- src/styles/ThemeStyleUtils/index.ts | 2 +- src/styles/styles.ts | 2 +- src/styles/themes/ThemeContext.ts | 2 +- src/styles/themes/ThemeProvider.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/styles/ThemeStyleUtils/index.ts b/src/styles/ThemeStyleUtils/index.ts index 965d5495a1f8..13275e273053 100644 --- a/src/styles/ThemeStyleUtils/index.ts +++ b/src/styles/ThemeStyleUtils/index.ts @@ -7,7 +7,7 @@ import * as UserUtils from '@libs/UserUtils'; import colors from '@styles/colors'; import fontFamily from '@styles/fontFamily'; import {defaultStyles, type ThemeStyles} from '@styles/styles'; -import {defaultTheme} from '@styles/themes/Themes'; +import {defaultTheme} from '@styles/themes/themes'; import {ThemeColors} from '@styles/themes/types'; import cursor from '@styles/utilities/cursor'; import positioning from '@styles/utilities/positioning'; diff --git a/src/styles/styles.ts b/src/styles/styles.ts index 72dc853e7080..fa95197e9fb4 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -20,7 +20,7 @@ import overflowXHidden from './overflowXHidden'; import pointerEventsAuto from './pointerEventsAuto'; import pointerEventsBoxNone from './pointerEventsBoxNone'; import pointerEventsNone from './pointerEventsNone'; -import {defaultTheme} from './themes/Themes'; +import {defaultTheme} from './themes/themes'; import {type ThemeColors} from './themes/types'; import borders from './utilities/borders'; import cursor from './utilities/cursor'; diff --git a/src/styles/themes/ThemeContext.ts b/src/styles/themes/ThemeContext.ts index d0c553322b35..ec35675953fe 100644 --- a/src/styles/themes/ThemeContext.ts +++ b/src/styles/themes/ThemeContext.ts @@ -1,5 +1,5 @@ import React from 'react'; -import {defaultTheme} from './Themes'; +import {defaultTheme} from './themes'; import {type ThemeColors} from './types'; const ThemeContext = React.createContext(defaultTheme); diff --git a/src/styles/themes/ThemeProvider.tsx b/src/styles/themes/ThemeProvider.tsx index 20f97025c36a..2da13e2a8cc3 100644 --- a/src/styles/themes/ThemeProvider.tsx +++ b/src/styles/themes/ThemeProvider.tsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React, {useMemo} from 'react'; import ThemeContext from './ThemeContext'; -import Themes from './Themes'; +import Themes from './themes'; import {ThemePreferenceWithoutSystem} from './types'; import useThemePreferenceWithStaticOverride from './useThemePreferenceWithStaticOverride'; From d6b17dbb2ffcc8f3a6691003919acba12d309bc2 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 15:06:03 +0100 Subject: [PATCH 28/39] rename --- src/styles/themes/{Themes.ts => themess.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/styles/themes/{Themes.ts => themess.ts} (100%) diff --git a/src/styles/themes/Themes.ts b/src/styles/themes/themess.ts similarity index 100% rename from src/styles/themes/Themes.ts rename to src/styles/themes/themess.ts From 96f570da398d4c0005bcb3cc6cdda585fe346334 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 15:06:14 +0100 Subject: [PATCH 29/39] rename --- src/styles/themes/{themess.ts => themes.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/styles/themes/{themess.ts => themes.ts} (100%) diff --git a/src/styles/themes/themess.ts b/src/styles/themes/themes.ts similarity index 100% rename from src/styles/themes/themess.ts rename to src/styles/themes/themes.ts From 9d2947d559e8b25ffa9113c7a5b62302df96fa29 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 15:08:45 +0100 Subject: [PATCH 30/39] rename component casing --- src/styles/themes/ThemeProvider.tsx | 4 ++-- src/styles/themes/themes.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/styles/themes/ThemeProvider.tsx b/src/styles/themes/ThemeProvider.tsx index 2da13e2a8cc3..0d302b5ae056 100644 --- a/src/styles/themes/ThemeProvider.tsx +++ b/src/styles/themes/ThemeProvider.tsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React, {useMemo} from 'react'; import ThemeContext from './ThemeContext'; -import Themes from './themes'; +import themes from './themes'; import {ThemePreferenceWithoutSystem} from './types'; import useThemePreferenceWithStaticOverride from './useThemePreferenceWithStaticOverride'; @@ -18,7 +18,7 @@ type ThemeProviderProps = React.PropsWithChildren & { function ThemeProvider({children, theme: staticThemePreference}: ThemeProviderProps) { const themePreference = useThemePreferenceWithStaticOverride(staticThemePreference); - const theme = useMemo(() => Themes[themePreference], [themePreference]); + const theme = useMemo(() => themes[themePreference], [themePreference]); return {children}; } diff --git a/src/styles/themes/themes.ts b/src/styles/themes/themes.ts index 9fe7c02e6b4c..c0a305df294f 100644 --- a/src/styles/themes/themes.ts +++ b/src/styles/themes/themes.ts @@ -3,12 +3,12 @@ import darkTheme from './default'; import lightTheme from './light'; import {type ThemeColors, ThemePreferenceWithoutSystem} from './types'; -const Themes = { +const themes = { [CONST.THEME.LIGHT]: lightTheme, [CONST.THEME.DARK]: darkTheme, } satisfies Record; -const defaultTheme = Themes[CONST.THEME.DEFAULT]; +const defaultTheme = themes[CONST.THEME.DEFAULT]; -export default Themes; +export default themes; export {defaultTheme}; From 564f8cbc505bacfbf1aae8024a4d8b6288df9187 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 16:14:07 +0100 Subject: [PATCH 31/39] fix: import --- src/pages/signin/SignInPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index 1fb99155af40..dbad6324c922 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -14,10 +14,10 @@ import * as Localize from '@libs/Localize'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import Performance from '@libs/Performance'; +import ThemeProvider from '@styles/themes/ThemeProvider'; import ThemeStylesProvider from '@styles/ThemeStylesProvider'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import ThemeProvider from '@styles/utils/StyleUtilsProvider'; import * as App from '@userActions/App'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; From bf715127bf71a5973a6e69487aaea9bf75c0e11e Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 16:14:56 +0100 Subject: [PATCH 32/39] fix: wrong usage of StyleUtils --- src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js index 7e2d54b00ebd..3104042bf33b 100755 --- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js @@ -379,7 +379,7 @@ function BaseValidateCodeForm(props) { role={CONST.ACCESSIBILITY_ROLE.BUTTON} accessibilityLabel={props.translate('validateCodeForm.magicCodeNotReceived')} > - + {hasError ? props.translate('validateCodeForm.requestNewCodeAfterErrorOccurred') : props.translate('validateCodeForm.magicCodeNotReceived')} From 1b618ae10733a330892bc2c48d8aa21783e67de7 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 16:28:46 +0100 Subject: [PATCH 33/39] fix: remaining errors --- src/Expensify.js | 4 ++++ src/components/ContextMenuItem.js | 3 +-- src/components/LHNOptionsList/OptionRowLHN.js | 3 +-- .../LocationErrorMessage/BaseLocationErrorMessage.js | 4 ++-- src/components/RoomHeaderAvatars.js | 2 +- src/components/TextInput/BaseTextInput/index.native.js | 2 +- .../ComposerWithSuggestions/ComposerWithSuggestions.js | 5 +++-- src/pages/home/report/ReportActionItemMessageEdit.js | 5 +++-- .../Contacts/ValidateCodeForm/BaseValidateCodeForm.js | 2 +- src/styles/ThemeStyleUtils/index.ts | 9 +++++++++ 10 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/Expensify.js b/src/Expensify.js index aece93c0ff4d..b03941b28779 100644 --- a/src/Expensify.js +++ b/src/Expensify.js @@ -201,6 +201,10 @@ function Expensify(props) { // eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want this effect to run again }, []); + useEffect(() => { + Onyx.set('preferredTheme', 'light'); + }, []); + // Display a blank page until the onyx migration completes if (!isOnyxMigrated) { return null; diff --git a/src/components/ContextMenuItem.js b/src/components/ContextMenuItem.js index c089694c25b9..4b0609839a71 100644 --- a/src/components/ContextMenuItem.js +++ b/src/components/ContextMenuItem.js @@ -3,7 +3,6 @@ import React, {forwardRef, useImperativeHandle} from 'react'; import useThrottledButtonState from '@hooks/useThrottledButtonState'; import useWindowDimensions from '@hooks/useWindowDimensions'; import getButtonState from '@libs/getButtonState'; -import getContextMenuItemStyles from '@styles/getContextMenuItemStyles'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import BaseMiniContextMenuItem from './BaseMiniContextMenuItem'; @@ -99,7 +98,7 @@ function ContextMenuItem({onPress, successIcon, successText, icon, text, isMini, success={!isThrottledButtonActive} description={description} descriptionTextStyle={styles.breakAll} - style={getContextMenuItemStyles(styles, windowWidth)} + style={StyleUtils.getContextMenuItemStyles(windowWidth)} isAnonymousAction={isAnonymousAction} focused={isFocused} interactive={isThrottledButtonActive} diff --git a/src/components/LHNOptionsList/OptionRowLHN.js b/src/components/LHNOptionsList/OptionRowLHN.js index a54eb54a6bdb..d8fcc3972ed2 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.js +++ b/src/components/LHNOptionsList/OptionRowLHN.js @@ -24,7 +24,6 @@ import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManag import * as ReportUtils from '@libs/ReportUtils'; import * as ContextMenuActions from '@pages/home/report/ContextMenu/ContextMenuActions'; import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu'; -import * as optionRowStyles from '@styles/optionRowStyles'; import useTheme from '@styles/themes/useTheme'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; @@ -104,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)] : [styles.flex1]; + props.viewMode === CONST.OPTION_MODE.COMPACT ? [styles.flex1, styles.flexRow, styles.overflowHidden, StyleUtils.getCompactContentContainerStyles()] : [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/LocationErrorMessage/BaseLocationErrorMessage.js b/src/components/LocationErrorMessage/BaseLocationErrorMessage.js index 4171c04a59c6..a86cb8bd7bd9 100644 --- a/src/components/LocationErrorMessage/BaseLocationErrorMessage.js +++ b/src/components/LocationErrorMessage/BaseLocationErrorMessage.js @@ -45,14 +45,14 @@ function BaseLocationErrorMessage({onClose, onAllowLocationLinkPress, locationEr {isPermissionDenied ? ( - {`${translate('location.permissionDenied')} ${translate('location.please')}`} + {`${translate('location.permissionDenied')} ${translate('location.please')}`} {` ${translate('location.allowPermission')} `} - {translate('location.tryAgain')} + {translate('location.tryAgain')} ) : ( {translate('location.notFound')} diff --git a/src/components/RoomHeaderAvatars.js b/src/components/RoomHeaderAvatars.js index d88d65f417ea..ea05b78f98a7 100644 --- a/src/components/RoomHeaderAvatars.js +++ b/src/components/RoomHeaderAvatars.js @@ -65,7 +65,7 @@ function RoomHeaderAvatars(props) { styles.roomHeaderAvatar, // Due to border-box box-sizing, the Avatars have to be larger when bordered to visually match size with non-bordered Avatars - StyleUtils.getAvatarStyle(theme, CONST.AVATAR_SIZE.LARGE_BORDERED), + StyleUtils.getAvatarStyle(CONST.AVATAR_SIZE.LARGE_BORDERED), ]; return ( diff --git a/src/components/TextInput/BaseTextInput/index.native.js b/src/components/TextInput/BaseTextInput/index.native.js index 57e3468d1502..b9bbf567f9cb 100644 --- a/src/components/TextInput/BaseTextInput/index.native.js +++ b/src/components/TextInput/BaseTextInput/index.native.js @@ -313,7 +313,7 @@ function BaseTextInput(props) { !isMultiline && {height, lineHeight: undefined}, // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. - ...(props.autoGrowHeight ? [StyleUtils.getAutoGrowHeightInputStyle(styles, textInputHeight, maxHeight), styles.verticalAlignTop] : []), + ...(props.autoGrowHeight ? [StyleUtils.getAutoGrowHeightInputStyle(textInputHeight, maxHeight), styles.verticalAlignTop] : []), // Add disabled color theme when field is not editable. props.disabled && styles.textInputDisabled, styles.pointerEventsAuto, diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js index a3fdc7f574f6..f99bd7ab7d9d 100644 --- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js +++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js @@ -26,8 +26,8 @@ import updateMultilineInputRange from '@libs/UpdateMultilineInputRange'; import willBlurTextInputOnTapOutsideFunc from '@libs/willBlurTextInputOnTapOutside'; import SilentCommentUpdater from '@pages/home/report/ReportActionCompose/SilentCommentUpdater'; import Suggestions from '@pages/home/report/ReportActionCompose/Suggestions'; -import containerComposeStyles from '@styles/containerComposeStyles'; import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import * as EmojiPickerActions from '@userActions/EmojiPickerAction'; import * as InputFocus from '@userActions/InputFocus'; @@ -103,6 +103,7 @@ function ComposerWithSuggestions({ }) { const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {preferredLocale} = useLocalize(); const isFocused = useIsFocused(); const navigation = useNavigation(); @@ -516,7 +517,7 @@ function ComposerWithSuggestions({ return ( <> - + - + { diff --git a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js index 899409a016c4..fa1c17578126 100644 --- a/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js +++ b/src/pages/settings/Profile/Contacts/ValidateCodeForm/BaseValidateCodeForm.js @@ -210,7 +210,7 @@ function BaseValidateCodeForm(props) { role={CONST.ACCESSIBILITY_ROLE.BUTTON} accessibilityLabel={props.translate('validateCodeForm.magicCodeNotReceived')} > - {props.translate('validateCodeForm.magicCodeNotReceived')} + {props.translate('validateCodeForm.magicCodeNotReceived')} {props.hasMagicCodeBeenSent && ( ({ return containerStyles; }, + + getCompactContentContainerStyles: () => compactContentContainerStyles(styles), + + getContextMenuItemStyles: (windowWidth?: number) => getContextMenuItemStyles(styles, windowWidth), + + getContainerComposeStyles: () => containerComposeStyles(styles), }); type StyleUtilsType = ReturnType; From 3de88232d2eb00fc6d6e2757f921e0ba2e62e1d5 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 16:32:47 +0100 Subject: [PATCH 34/39] reset Expensify.js --- src/Expensify.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Expensify.js b/src/Expensify.js index b03941b28779..aece93c0ff4d 100644 --- a/src/Expensify.js +++ b/src/Expensify.js @@ -201,10 +201,6 @@ function Expensify(props) { // eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want this effect to run again }, []); - useEffect(() => { - Onyx.set('preferredTheme', 'light'); - }, []); - // Display a blank page until the onyx migration completes if (!isOnyxMigrated) { return null; From cdf4f2c75880a043c9d4c44ed6840e814b556def Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 16:38:12 +0100 Subject: [PATCH 35/39] fix --- src/components/ReportActionItem/MoneyRequestView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index 7fb42c0d7ea0..f26350d70b3f 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -31,10 +31,10 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import reportActionPropTypes from '@pages/home/report/reportActionPropTypes'; import iouReportPropTypes from '@pages/iouReportPropTypes'; +import reportPropTypes from '@pages/reportPropTypes'; import useTheme from '@styles/themes/useTheme'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; -import reportPropTypes from '@styles/utils/StyleUtilsypes'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; From fb0b93f9a00d8c480ee660d696a59e9e31b4ebc2 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 16:41:27 +0100 Subject: [PATCH 36/39] rename folder --- src/components/Avatar.tsx | 2 +- src/components/withStyleUtils.tsx | 2 +- src/styles/PopoverWithMeasuredContentStyleUtils.ts | 2 +- src/styles/ThemeStylesContext.ts | 4 ++-- src/styles/ThemeStylesProvider.tsx | 2 +- src/styles/{ThemeStyleUtils => utils}/ModalStyleUtils.ts | 0 .../ReportActionContextMenuStyleUtils.ts | 0 src/styles/{ThemeStyleUtils => utils}/TooltipStyleUtils.ts | 0 src/styles/{ThemeStyleUtils => utils}/index.ts | 0 .../roundToNearestMultipleOfFour.ts | 0 10 files changed, 6 insertions(+), 6 deletions(-) rename src/styles/{ThemeStyleUtils => utils}/ModalStyleUtils.ts (100%) rename src/styles/{ThemeStyleUtils => utils}/ReportActionContextMenuStyleUtils.ts (100%) rename src/styles/{ThemeStyleUtils => utils}/TooltipStyleUtils.ts (100%) rename src/styles/{ThemeStyleUtils => utils}/index.ts (100%) rename src/styles/{ThemeStyleUtils => utils}/roundToNearestMultipleOfFour.ts (100%) diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx index 4f014a500153..f801cb11e9df 100644 --- a/src/components/Avatar.tsx +++ b/src/components/Avatar.tsx @@ -4,9 +4,9 @@ import useNetwork from '@hooks/useNetwork'; import * as ReportUtils from '@libs/ReportUtils'; import {AvatarSource} from '@libs/UserUtils'; import useTheme from '@styles/themes/useTheme'; -import type {AvatarSizeName} from '@styles/ThemeStyleUtils'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; +import type {AvatarSizeName} from '@styles/utils'; import CONST from '@src/CONST'; import {AvatarType} from '@src/types/onyx/OnyxCommon'; import Icon from './Icon'; diff --git a/src/components/withStyleUtils.tsx b/src/components/withStyleUtils.tsx index d4f2bd535231..6ea044fce70c 100644 --- a/src/components/withStyleUtils.tsx +++ b/src/components/withStyleUtils.tsx @@ -1,8 +1,8 @@ import PropTypes from 'prop-types'; import React, {ComponentType, ForwardedRef, forwardRef, ReactElement, RefAttributes} from 'react'; import getComponentDisplayName from '@libs/getComponentDisplayName'; -import {StyleUtilsType} from '@styles/ThemeStyleUtils'; import useStyleUtils from '@styles/useStyleUtils'; +import {StyleUtilsType} from '@styles/utils'; const withStyleUtilsPropTypes = { StyleUtils: PropTypes.object.isRequired, diff --git a/src/styles/PopoverWithMeasuredContentStyleUtils.ts b/src/styles/PopoverWithMeasuredContentStyleUtils.ts index 5e12e2f2d2eb..94a0fb77d8bb 100644 --- a/src/styles/PopoverWithMeasuredContentStyleUtils.ts +++ b/src/styles/PopoverWithMeasuredContentStyleUtils.ts @@ -1,4 +1,4 @@ -import roundToNearestMultipleOfFour from './ThemeStyleUtils/roundToNearestMultipleOfFour'; +import roundToNearestMultipleOfFour from './utils/roundToNearestMultipleOfFour'; import variables from './variables'; /** diff --git a/src/styles/ThemeStylesContext.ts b/src/styles/ThemeStylesContext.ts index cff708628745..73f044f2dcbd 100644 --- a/src/styles/ThemeStylesContext.ts +++ b/src/styles/ThemeStylesContext.ts @@ -1,8 +1,8 @@ import React from 'react'; import {defaultStyles} from './styles'; import type {ThemeStyles} from './styles'; -import {DefaultStyleUtils} from './ThemeStyleUtils'; -import type {StyleUtilsType} from './ThemeStyleUtils'; +import {DefaultStyleUtils} from './utils'; +import type {StyleUtilsType} from './utils'; type ThemeStylesContextType = { styles: ThemeStyles; diff --git a/src/styles/ThemeStylesProvider.tsx b/src/styles/ThemeStylesProvider.tsx index 35722304dc39..766cb00bd09b 100644 --- a/src/styles/ThemeStylesProvider.tsx +++ b/src/styles/ThemeStylesProvider.tsx @@ -2,7 +2,7 @@ import React, {useMemo} from 'react'; import stylesGenerator from './styles'; import useTheme from './themes/useTheme'; import ThemeStylesContext from './ThemeStylesContext'; -import createStyleUtils from './ThemeStyleUtils'; +import createStyleUtils from './utils'; type ThemeStylesProviderProps = React.PropsWithChildren; diff --git a/src/styles/ThemeStyleUtils/ModalStyleUtils.ts b/src/styles/utils/ModalStyleUtils.ts similarity index 100% rename from src/styles/ThemeStyleUtils/ModalStyleUtils.ts rename to src/styles/utils/ModalStyleUtils.ts diff --git a/src/styles/ThemeStyleUtils/ReportActionContextMenuStyleUtils.ts b/src/styles/utils/ReportActionContextMenuStyleUtils.ts similarity index 100% rename from src/styles/ThemeStyleUtils/ReportActionContextMenuStyleUtils.ts rename to src/styles/utils/ReportActionContextMenuStyleUtils.ts diff --git a/src/styles/ThemeStyleUtils/TooltipStyleUtils.ts b/src/styles/utils/TooltipStyleUtils.ts similarity index 100% rename from src/styles/ThemeStyleUtils/TooltipStyleUtils.ts rename to src/styles/utils/TooltipStyleUtils.ts diff --git a/src/styles/ThemeStyleUtils/index.ts b/src/styles/utils/index.ts similarity index 100% rename from src/styles/ThemeStyleUtils/index.ts rename to src/styles/utils/index.ts diff --git a/src/styles/ThemeStyleUtils/roundToNearestMultipleOfFour.ts b/src/styles/utils/roundToNearestMultipleOfFour.ts similarity index 100% rename from src/styles/ThemeStyleUtils/roundToNearestMultipleOfFour.ts rename to src/styles/utils/roundToNearestMultipleOfFour.ts From 8dbc536405faa5ce8cfdac05624f99aa0b7170a0 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 17:41:02 +0100 Subject: [PATCH 37/39] fix: typo --- src/components/EReceiptThumbnail.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/EReceiptThumbnail.js b/src/components/EReceiptThumbnail.js index 42721bebb2af..5eb35538af80 100644 --- a/src/components/EReceiptThumbnail.js +++ b/src/components/EReceiptThumbnail.js @@ -3,6 +3,7 @@ import React, {useMemo, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import * as ReportUtils from '@libs/ReportUtils'; +import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -38,7 +39,7 @@ const backgroundImages = { function EReceiptThumbnail({transaction}) { const styles = useThemeStyles(); - const StyleUtils = useThemeStyles(); + const StyleUtils = useStyleUtils(); // Get receipt colorway, or default to Yellow. const {backgroundColor: primaryColor, color: secondaryColor} = StyleUtils.getEReceiptColorStyles(StyleUtils.getEReceiptColorCode(transaction)); From 7693508cca7aac1ff404f2a158deeb8c95b7be0b Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 17:45:18 +0100 Subject: [PATCH 38/39] update PULL_REQUEST_TEMPLATE --- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4100a13f8bee..4f7d1c71553a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -18,8 +18,8 @@ $ https://github.com/Expensify/App/issues/ Do NOT only link the issue number like this: $ # ---> -$ -PROPOSAL: +$ +PROPOSAL: ### Tests @@ -98,7 +98,7 @@ This is a checklist for PR authors. Please make sure to complete all tasks and c - [ ] The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory - [ ] If a new CSS style is added I verified that: - [ ] A similar style doesn't already exist - - [ ] The style can't be created with an existing [StyleUtils](https://github.com/Expensify/App/blob/main/src/styles/StyleUtils.js) function (i.e. `StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)`) + - [ ] The style can't be created with an existing [StyleUtils](https://github.com/Expensify/App/blob/main/src/styles/utils/index.ts) function (i.e. `StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)`) - [ ] If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic. - [ ] If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like `Avatar` is modified, I verified that `Avatar` is working as expected in all cases) - [ ] If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected. From adc06df08741169bfd98f12cacdd9133f5b28bef Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Thu, 7 Dec 2023 17:45:49 +0100 Subject: [PATCH 39/39] update REVIEWER_CHECKLIST --- contributingGuides/REVIEWER_CHECKLIST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributingGuides/REVIEWER_CHECKLIST.md b/contributingGuides/REVIEWER_CHECKLIST.md index 68088f623f8d..b7cbd87dc4b9 100644 --- a/contributingGuides/REVIEWER_CHECKLIST.md +++ b/contributingGuides/REVIEWER_CHECKLIST.md @@ -46,7 +46,7 @@ - [ ] The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory - [ ] If a new CSS style is added I verified that: - [ ] A similar style doesn't already exist - - [ ] The style can't be created with an existing [StyleUtils](https://github.com/Expensify/App/blob/main/src/styles/StyleUtils.js) function (i.e. `StyleUtils.getBackgroundAndBorderStyle(theme.componentBG`) + - [ ] The style can't be created with an existing [StyleUtils](https://github.com/Expensify/App/blob/main/src/utils/index.ts) function (i.e. `StyleUtils.getBackgroundAndBorderStyle(theme.componentBG`) - [ ] If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic. - [ ] If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like `Avatar` is modified, I verified that `Avatar` is working as expected in all cases) - [ ] If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.