From cc7cf3827a2b4a7d5ff566639e3beee63358f75b Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 18:49:06 +0700 Subject: [PATCH 1/6] fix: 42117 --- src/components/MoneyRequestAmountInput.tsx | 2 ++ .../MoneyRequestConfirmationList.tsx | 6 ++-- .../TextInput/BaseTextInput/index.native.tsx | 35 +++++++++++++++++-- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index 1cccfdc720b3..a6c1689cb726 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -121,6 +121,7 @@ function MoneyRequestAmountInput( hideFocusedState = true, shouldKeepUserInput = false, autoGrow = true, + contentWidth = undefined, ...props }: MoneyRequestAmountInputProps, forwardedRef: ForwardedRef, @@ -315,6 +316,7 @@ function MoneyRequestAmountInput( hideFocusedState={hideFocusedState} onMouseDown={handleMouseDown} onMouseUp={handleMouseUp} + contentWidth={contentWidth} /> ); } diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 40647e33849c..bf8393f8f357 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -491,7 +491,6 @@ 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, @@ -509,12 +508,13 @@ function MoneyRequestConfirmationList({ hideCurrencySymbol formatAmountOnBlur prefixContainerStyle={[styles.pv0]} - inputStyle={[styles.optionRowAmountInput, amountWidth] as TextStyle[]} - containerStyle={[styles.textInputContainer, amountWidth]} + inputStyle={[styles.optionRowAmountInput] as TextStyle[]} + containerStyle={[styles.textInputContainer]} touchableInputWrapperStyle={[styles.ml3]} onFormatAmount={CurrencyUtils.convertToDisplayStringWithoutCurrency} onAmountChange={(value: string) => onSplitShareChange(participantOption.accountID ?? 0, Number(value))} maxLength={formattedTotalAmount.length} + contentWidth={formattedTotalAmount.length * 9} /> ), })); diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index 809544d2c5ed..b01a48b09f62 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 = undefined, ...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,34 @@ 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. From caeb8298bbb0c806136e8deab9766039de11b634 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 13 Jun 2024 18:42:05 +0700 Subject: [PATCH 2/6] fix lint --- src/components/MoneyRequestAmountInput.tsx | 3 +++ src/components/MoneyRequestConfirmationList.tsx | 4 ---- .../TextInput/BaseTextInput/index.native.tsx | 15 +++++---------- src/components/TextInput/BaseTextInput/types.ts | 3 +++ .../TextInputWithCurrencySymbol/types.ts | 2 +- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index cbe9c1beb4cc..ab0ded0d0a52 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 = { diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 637ad3db6438..1f1d8e0443be 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -13,7 +13,6 @@ import {MouseProvider} from '@hooks/useMouseContext'; import useNetwork from '@hooks/useNetwork'; import usePermissions from '@hooks/usePermissions'; import usePrevious from '@hooks/usePrevious'; -import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as CurrencyUtils from '@libs/CurrencyUtils'; @@ -227,7 +226,6 @@ function MoneyRequestConfirmationList({ const policyCategories = policyCategoriesReal ?? policyCategoriesDraft; const theme = useTheme(); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); const {translate, toLocaleDigit} = useLocalize(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const {canUseP2PDistanceRequests, canUseViolations} = usePermissions(iouType); @@ -499,7 +497,6 @@ function MoneyRequestConfirmationList({ } const currencySymbol = currencyList?.[iouCurrencyCode ?? '']?.symbol ?? iouCurrencyCode; - const prefixPadding = StyleUtils.getCharacterPadding(currencySymbol ?? ''); const formattedTotalAmount = CurrencyUtils.convertToDisplayStringWithoutCurrency(iouAmount, iouCurrencyCode); return [payeeOption, ...selectedParticipants].map((participantOption: Participant) => ({ @@ -534,7 +531,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 0efe7ed05d08..256a7c98ceac 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -252,7 +252,7 @@ function BaseTextInput( const newTextInputContainerStyles: StyleProp = StyleSheet.flatten([ styles.textInputContainer, textInputContainerStyles, - (autoGrow || contentWidth) && StyleUtils.getWidthStyle(textInputWidth), + (autoGrow || !!contentWidth) && StyleUtils.getWidthStyle(textInputWidth), !hideFocusedState && isFocused && styles.borderColorFocus, (!!hasError || !!errorText) && styles.borderColorDanger, autoGrowHeight && {scrollPaddingTop: typeof maxAutoGrowHeight === 'number' ? 2 * maxAutoGrowHeight : undefined}, @@ -414,14 +414,9 @@ function BaseTextInput( /> )} - {contentWidth && + {contentWidth && ( { if (e.nativeEvent.layout.width === 0 && e.nativeEvent.layout.height === 0) { return; @@ -434,14 +429,14 @@ function BaseTextInput( style={[ inputStyle, autoGrowHeight && styles.autoGrowHeightHiddenInput(width ?? 0, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : undefined), - {width: contentWidth} + {width: contentWidth}, ]} > {/* \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 e8e2d5ab352d..cac7b68f0d17 100644 --- a/src/components/TextInput/BaseTextInput/types.ts +++ b/src/components/TextInput/BaseTextInput/types.ts @@ -121,6 +121,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; From 46a068b5b48a97d3ed852b91cd4dec4382e1ec30 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 14 Jun 2024 17:32:05 +0700 Subject: [PATCH 3/6] apply changes for web --- .../TextInput/BaseTextInput/index.tsx | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/components/TextInput/BaseTextInput/index.tsx b/src/components/TextInput/BaseTextInput/index.tsx index 3a1032ff7a43..5759474fc659 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 = undefined, ...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. From 9a95dcde46f04b0e85d3672949428c67a975754e Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 2 Jul 2024 09:25:31 +0700 Subject: [PATCH 4/6] remove undefined default prop --- src/components/MoneyRequestAmountInput.tsx | 2 +- src/components/MoneyRequestConfirmationList.tsx | 3 +-- src/components/TextInput/BaseTextInput/index.native.tsx | 2 +- src/components/TextInput/BaseTextInput/index.tsx | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index ab0ded0d0a52..c7f7d999fc0c 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -126,7 +126,7 @@ function MoneyRequestAmountInput( hideFocusedState = true, shouldKeepUserInput = false, autoGrow = true, - contentWidth = undefined, + contentWidth, ...props }: MoneyRequestAmountInputProps, forwardedRef: ForwardedRef, diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 8ad94d3988e7..48be99793ef5 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'; @@ -456,7 +455,7 @@ function MoneyRequestConfirmationList({ hideCurrencySymbol formatAmountOnBlur prefixContainerStyle={[styles.pv0]} - inputStyle={[styles.optionRowAmountInput] as TextStyle[]} + inputStyle={[styles.optionRowAmountInput]} containerStyle={[styles.textInputContainer]} touchableInputWrapperStyle={[styles.ml3]} onFormatAmount={CurrencyUtils.convertToDisplayStringWithoutCurrency} diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index 256a7c98ceac..d8920e1492bf 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -64,7 +64,7 @@ function BaseTextInput( shouldShowClearButton = false, prefixContainerStyle = [], prefixStyle = [], - contentWidth = undefined, + contentWidth, ...props }: BaseTextInputProps, ref: ForwardedRef, diff --git a/src/components/TextInput/BaseTextInput/index.tsx b/src/components/TextInput/BaseTextInput/index.tsx index 5759474fc659..239c0435296b 100644 --- a/src/components/TextInput/BaseTextInput/index.tsx +++ b/src/components/TextInput/BaseTextInput/index.tsx @@ -66,7 +66,7 @@ function BaseTextInput( shouldShowClearButton = false, prefixContainerStyle = [], prefixStyle = [], - contentWidth = undefined, + contentWidth, ...inputProps }: BaseTextInputProps, ref: ForwardedRef, From abc73ae5b7531cbbd82f801f4f232c27f403a273 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 2 Jul 2024 15:33:42 +0700 Subject: [PATCH 5/6] compute contentWidth based on the longest amount --- src/components/MoneyRequestConfirmationList.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 48be99793ef5..b04383d5d2e8 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -438,6 +438,9 @@ function MoneyRequestConfirmationList({ const currencySymbol = currencyList?.[iouCurrencyCode ?? '']?.symbol ?? iouCurrencyCode; const formattedTotalAmount = CurrencyUtils.convertToDisplayStringWithoutCurrency(iouAmount, iouCurrencyCode); + const maxSplitAmount = Math.max( + ...[payeeOption, ...selectedParticipants].map((participantOption: Participant) => transaction?.splitShares?.[participantOption.accountID ?? -1]?.amount ?? -1), + ); return [payeeOption, ...selectedParticipants].map((participantOption: Participant) => ({ ...participantOption, @@ -461,7 +464,7 @@ function MoneyRequestConfirmationList({ onFormatAmount={CurrencyUtils.convertToDisplayStringWithoutCurrency} onAmountChange={(value: string) => onSplitShareChange(participantOption.accountID ?? -1, Number(value))} maxLength={formattedTotalAmount.length} - contentWidth={formattedTotalAmount.length * 9} + contentWidth={CurrencyUtils.convertToDisplayStringWithoutCurrency(maxSplitAmount).length * 9} /> ), })); From c6287225db7414a3761598930b3310c81046dcf5 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 10 Jul 2024 15:11:01 +0700 Subject: [PATCH 6/6] reduce fixed digit amount to 8 --- src/components/MoneyRequestConfirmationList.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index c84495ad7836..edcea98e4387 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -438,9 +438,6 @@ function MoneyRequestConfirmationList({ const currencySymbol = currencyList?.[iouCurrencyCode ?? '']?.symbol ?? iouCurrencyCode; const formattedTotalAmount = CurrencyUtils.convertToDisplayStringWithoutCurrency(iouAmount, iouCurrencyCode); - const maxSplitAmount = Math.max( - ...[payeeOption, ...selectedParticipants].map((participantOption: Participant) => transaction?.splitShares?.[participantOption.accountID ?? -1]?.amount ?? -1), - ); return [payeeOption, ...selectedParticipants].map((participantOption: Participant) => ({ ...participantOption, @@ -464,7 +461,7 @@ function MoneyRequestConfirmationList({ onFormatAmount={CurrencyUtils.convertToDisplayStringWithoutCurrency} onAmountChange={(value: string) => onSplitShareChange(participantOption.accountID ?? -1, Number(value))} maxLength={formattedTotalAmount.length} - contentWidth={CurrencyUtils.convertToDisplayStringWithoutCurrency(maxSplitAmount).length * 9} + contentWidth={formattedTotalAmount.length * 8} /> ), }));