diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index 791b3e4d5e48..702e6c384b58 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -88,6 +88,9 @@ type MoneyRequestAmountInputProps = { * Autogrow input container length based on the entered text. */ autoGrow?: boolean; + + /** The width of inner content */ + contentWidth?: number; }; type Selection = { @@ -123,6 +126,7 @@ function MoneyRequestAmountInput( hideFocusedState = true, shouldKeepUserInput = false, autoGrow = true, + contentWidth, ...props }: MoneyRequestAmountInputProps, forwardedRef: ForwardedRef, @@ -326,6 +330,7 @@ function MoneyRequestAmountInput( hideFocusedState={hideFocusedState} onMouseDown={handleMouseDown} onMouseUp={handleMouseUp} + contentWidth={contentWidth} /> ); } diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 772b1476b84a..923d149dca10 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -1,7 +1,6 @@ import {useIsFocused} from '@react-navigation/native'; import lodashIsEqual from 'lodash/isEqual'; import React, {memo, useCallback, useEffect, useMemo, useState} from 'react'; -import type {TextStyle} from 'react-native'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; @@ -11,7 +10,6 @@ import useLocalize from '@hooks/useLocalize'; import {MouseProvider} from '@hooks/useMouseContext'; import usePermissions from '@hooks/usePermissions'; import usePrevious from '@hooks/usePrevious'; -import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import DistanceRequestUtils from '@libs/DistanceRequestUtils'; @@ -213,7 +211,6 @@ function MoneyRequestConfirmationList({ const policyCategories = policyCategoriesReal ?? policyCategoriesDraft; const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); const {translate, toLocaleDigit} = useLocalize(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const {canUseP2PDistanceRequests} = usePermissions(iouType); @@ -453,9 +450,7 @@ function MoneyRequestConfirmationList({ } const currencySymbol = currencyList?.[iouCurrencyCode ?? '']?.symbol ?? iouCurrencyCode; - const prefixPadding = StyleUtils.getCharacterPadding(currencySymbol ?? ''); const formattedTotalAmount = CurrencyUtils.convertToDisplayStringWithoutCurrency(iouAmount, iouCurrencyCode); - const amountWidth = StyleUtils.getWidthStyle(formattedTotalAmount.length * 9 + prefixPadding); return [payeeOption, ...selectedParticipants].map((participantOption: Participant) => ({ ...participantOption, @@ -473,12 +468,13 @@ function MoneyRequestConfirmationList({ hideCurrencySymbol formatAmountOnBlur prefixContainerStyle={[styles.pv0]} - inputStyle={[styles.optionRowAmountInput, amountWidth] as TextStyle[]} - containerStyle={[styles.textInputContainer, amountWidth]} + inputStyle={[styles.optionRowAmountInput]} + containerStyle={[styles.textInputContainer]} touchableInputWrapperStyle={[styles.ml3]} onFormatAmount={CurrencyUtils.convertToDisplayStringWithoutCurrency} onAmountChange={(value: string) => onSplitShareChange(participantOption.accountID ?? -1, Number(value))} maxLength={formattedTotalAmount.length} + contentWidth={formattedTotalAmount.length * 8} /> ), })); @@ -488,7 +484,6 @@ function MoneyRequestConfirmationList({ shouldShowReadOnlySplits, currencyList, iouCurrencyCode, - StyleUtils, iouAmount, selectedParticipants, styles.flexWrap, diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index 6fe5c473797e..59f205da023f 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -64,6 +64,7 @@ function BaseTextInput( shouldShowClearButton = false, prefixContainerStyle = [], prefixStyle = [], + contentWidth, ...props }: BaseTextInputProps, ref: ForwardedRef, @@ -251,12 +252,14 @@ function BaseTextInput( const newTextInputContainerStyles: StyleProp = StyleSheet.flatten([ styles.textInputContainer, textInputContainerStyles, - autoGrow && StyleUtils.getWidthStyle(textInputWidth), + (autoGrow || !!contentWidth) && StyleUtils.getWidthStyle(textInputWidth), !hideFocusedState && isFocused && styles.borderColorFocus, (!!hasError || !!errorText) && styles.borderColorDanger, autoGrowHeight && {scrollPaddingTop: typeof maxAutoGrowHeight === 'number' ? 2 * maxAutoGrowHeight : undefined}, ]); + const inputPaddingLeft = !!prefixCharacter && StyleUtils.getPaddingLeft(StyleUtils.getCharacterPadding(prefixCharacter) + styles.pl1.paddingLeft); + return ( <> @@ -341,7 +344,7 @@ function BaseTextInput( styles.w100, inputStyle, (!hasLabel || isMultiline) && styles.pv0, - !!prefixCharacter && StyleUtils.getPaddingLeft(StyleUtils.getCharacterPadding(prefixCharacter) + styles.pl1.paddingLeft), + inputPaddingLeft, inputProps.secureTextEntry && styles.secureInput, !isMultiline && {height, lineHeight: undefined}, @@ -411,6 +414,29 @@ function BaseTextInput( /> )} + {contentWidth && ( + { + if (e.nativeEvent.layout.width === 0 && e.nativeEvent.layout.height === 0) { + return; + } + setTextInputWidth(e.nativeEvent.layout.width); + setTextInputHeight(e.nativeEvent.layout.height); + }} + > + + {/* \u200B added to solve the issue of not expanding the text input enough when the value ends with '\n' (https://github.com/Expensify/App/issues/21271) */} + {value ? `${value}${value.endsWith('\n') ? '\u200B' : ''}` : placeholder} + + + )} {/* Text input component doesn't support auto grow by default. We're using a hidden text input to achieve that. diff --git a/src/components/TextInput/BaseTextInput/index.tsx b/src/components/TextInput/BaseTextInput/index.tsx index 6da87872ee96..685d54d86765 100644 --- a/src/components/TextInput/BaseTextInput/index.tsx +++ b/src/components/TextInput/BaseTextInput/index.tsx @@ -66,6 +66,7 @@ function BaseTextInput( shouldShowClearButton = false, prefixContainerStyle = [], prefixStyle = [], + contentWidth, ...inputProps }: BaseTextInputProps, ref: ForwardedRef, @@ -248,7 +249,7 @@ function BaseTextInput( const newTextInputContainerStyles: StyleProp = StyleSheet.flatten([ styles.textInputContainer, textInputContainerStyles, - autoGrow && StyleUtils.getWidthStyle(textInputWidth), + (autoGrow || !!contentWidth) && StyleUtils.getWidthStyle(textInputWidth), !hideFocusedState && isFocused && styles.borderColorFocus, (!!hasError || !!errorText) && styles.borderColorDanger, autoGrowHeight && {scrollPaddingTop: typeof maxAutoGrowHeight === 'number' ? 2 * maxAutoGrowHeight : undefined}, @@ -274,6 +275,8 @@ function BaseTextInput( return undefined; }, [inputStyle]); + const inputPaddingLeft = !!prefixCharacter && StyleUtils.getPaddingLeft(StyleUtils.getCharacterPadding(prefixCharacter) + styles.pl1.paddingLeft); + return ( <> )} + {contentWidth && ( + { + if (e.nativeEvent.layout.width === 0 && e.nativeEvent.layout.height === 0) { + return; + } + setTextInputWidth(e.nativeEvent.layout.width); + setTextInputHeight(e.nativeEvent.layout.height); + }} + > + + {/* \u200B added to solve the issue of not expanding the text input enough when the value ends with '\n' (https://github.com/Expensify/App/issues/21271) */} + {value ? `${value}${value.endsWith('\n') ? '\u200B' : ''}` : placeholder} + + + )} {/* Text input component doesn't support auto grow by default. We're using a hidden text input to achieve that. diff --git a/src/components/TextInput/BaseTextInput/types.ts b/src/components/TextInput/BaseTextInput/types.ts index 7a46cca693e3..80325e0a21f3 100644 --- a/src/components/TextInput/BaseTextInput/types.ts +++ b/src/components/TextInput/BaseTextInput/types.ts @@ -120,6 +120,9 @@ type CustomBaseTextInputProps = { /** Style for the prefix container */ prefixContainerStyle?: StyleProp; + + /** The width of inner content */ + contentWidth?: number; }; type BaseTextInputRef = HTMLFormElement | AnimatedTextInputRef; diff --git a/src/components/TextInputWithCurrencySymbol/types.ts b/src/components/TextInputWithCurrencySymbol/types.ts index c83a7b9579ab..619ed0fd84e6 100644 --- a/src/components/TextInputWithCurrencySymbol/types.ts +++ b/src/components/TextInputWithCurrencySymbol/types.ts @@ -77,6 +77,6 @@ type TextInputWithCurrencySymbolProps = { /** Hide the focus styles on TextInput */ hideFocusedState?: boolean; -} & Pick; +} & Pick; export default TextInputWithCurrencySymbolProps;