Skip to content

Commit

Permalink
Merge pull request #36497 from shubham1206agra/fix-currency-ui
Browse files Browse the repository at this point in the history
Fixed currency pressable ui and padding issues

(cherry picked from commit af1026e)
  • Loading branch information
aldo-expensify authored and OSBotify committed Feb 14, 2024
1 parent 385550f commit a38d265
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 3 deletions.
11 changes: 10 additions & 1 deletion src/components/AmountForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ type AmountFormProps = {

/** Fired when back button pressed, navigates to currency selection page */
onCurrencyButtonPress?: () => void;

/** Whether the currency symbol is pressable */
isCurrencyPressable?: boolean;
};

/**
Expand All @@ -47,8 +50,13 @@ const NUM_PAD_CONTAINER_VIEW_ID = 'numPadContainerView';
const NUM_PAD_VIEW_ID = 'numPadView';

function AmountForm(
<<<<<<< HEAD
{value: amount, currency = CONST.CURRENCY.USD, extraDecimals = 0, errorText, onInputChange, onCurrencyButtonPress}: AmountFormProps,
forwardedRef: ForwardedRef<TextInput>,
=======
{value: amount, currency = CONST.CURRENCY.USD, extraDecimals = 0, errorText, onInputChange, onCurrencyButtonPress, isCurrencyPressable = true}: AmountFormProps,
forwardedRef: ForwardedRef<BaseTextInputRef>,
>>>>>>> af1026e (Merge pull request #36497 from shubham1206agra/fix-currency-ui)
) {
const styles = useThemeStyles();
const {toLocaleDigit, numberFormat} = useLocalize();
Expand Down Expand Up @@ -210,10 +218,11 @@ function AmountForm(
setSelection(e.nativeEvent.selection);
}}
onKeyPress={textInputKeyPress}
isCurrencyPressable={isCurrencyPressable}
/>
{!!errorText && (
<FormHelpMessage
style={[styles.pAbsolute, styles.b0, styles.mb0, styles.w100]}
style={[styles.pAbsolute, styles.b0, canUseTouchScreen ? styles.mb0 : styles.mb3, styles.ph5, styles.w100]}
isError
message={errorText}
/>
Expand Down
12 changes: 10 additions & 2 deletions src/components/CurrencySymbolButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
Expand All @@ -15,13 +16,16 @@ type CurrencySymbolButtonProps = {

/** Function to call when currency button is pressed */
onCurrencyButtonPress: () => void;

/** Whether the currency button is pressable or not */
isCurrencyPressable?: boolean;
};

function CurrencySymbolButton({onCurrencyButtonPress, currencySymbol}: CurrencySymbolButtonProps) {
function CurrencySymbolButton({onCurrencyButtonPress, currencySymbol, isCurrencyPressable = true}: CurrencySymbolButtonProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const theme = useTheme();
return (
return isCurrencyPressable ? (
<Tooltip text={translate('common.selectCurrency')}>
<PressableWithoutFeedback
onPress={onCurrencyButtonPress}
Expand All @@ -37,6 +41,10 @@ function CurrencySymbolButton({onCurrencyButtonPress, currencySymbol}: CurrencyS
<Text style={styles.iouAmountText}>{currencySymbol}</Text>
</PressableWithoutFeedback>
</Tooltip>
) : (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.gap1]}>
<Text style={styles.iouAmountText}>{currencySymbol}</Text>
</View>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from 'react';
import type {NativeSyntheticEvent, TextInputSelectionChangeEventData} from 'react-native';
import AmountTextInput from '@components/AmountTextInput';
import CurrencySymbolButton from '@components/CurrencySymbolButton';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as CurrencyUtils from '@libs/CurrencyUtils';
import * as MoneyRequestUtils from '@libs/MoneyRequestUtils';
import type {BaseTextInputRef} from '@src/components/TextInput/BaseTextInput/types';
import type TextInputWithCurrencySymbolProps from './types';

function BaseTextInputWithCurrencySymbol(
{
selectedCurrencyCode,
onCurrencyButtonPress = () => {},
onChangeAmount = () => {},
formattedAmount,
placeholder,
selection,
onSelectionChange = () => {},
onKeyPress = () => {},
isCurrencyPressable = true,
}: TextInputWithCurrencySymbolProps,
ref: React.ForwardedRef<BaseTextInputRef>,
) {
const {fromLocaleDigit} = useLocalize();
const currencySymbol = CurrencyUtils.getLocalizedCurrencySymbol(selectedCurrencyCode);
const isCurrencySymbolLTR = CurrencyUtils.isCurrencySymbolLTR(selectedCurrencyCode);
const styles = useThemeStyles();

const currencySymbolButton = (
<CurrencySymbolButton
currencySymbol={currencySymbol ?? ''}
onCurrencyButtonPress={onCurrencyButtonPress}
isCurrencyPressable={isCurrencyPressable}
/>
);

/**
* Set a new amount value properly formatted
*
* @param text - Changed text from user input
*/
const setFormattedAmount = (text: string) => {
const newAmount = MoneyRequestUtils.addLeadingZero(MoneyRequestUtils.replaceAllDigits(text, fromLocaleDigit));
onChangeAmount(newAmount);
};

const amountTextInput = (
<AmountTextInput
formattedAmount={formattedAmount}
onChangeAmount={setFormattedAmount}
placeholder={placeholder}
ref={ref}
selection={selection}
onSelectionChange={(event: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => {
onSelectionChange(event);
}}
onKeyPress={onKeyPress}
style={styles.pr1}
/>
);

if (isCurrencySymbolLTR) {
return (
<>
{currencySymbolButton}
{amountTextInput}
</>
);
}

return (
<>
{amountTextInput}
{currencySymbolButton}
</>
);
}

BaseTextInputWithCurrencySymbol.displayName = 'BaseTextInputWithCurrencySymbol';

export default React.forwardRef(BaseTextInputWithCurrencySymbol);
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ const propTypes = {

/** Function to call to handle key presses in the text input */
onKeyPress: PropTypes.func,

/** Whether the currency symbol is pressable */
isCurrencyPressable: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -40,6 +43,7 @@ const defaultProps = {
selection: undefined,
onSelectionChange: () => {},
onKeyPress: () => {},
isCurrencyPressable: true,
};

export {propTypes, defaultProps};
33 changes: 33 additions & 0 deletions src/components/TextInputWithCurrencySymbol/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type {NativeSyntheticEvent, TextInputSelectionChangeEventData} from 'react-native';
import type {TextSelection} from '@components/Composer/types';

type TextInputWithCurrencySymbolProps = {
/** Formatted amount in local currency */
formattedAmount: string;

/** Function to call when amount in text input is changed */
onChangeAmount?: (value: string) => void;

/** Function to call when currency button is pressed */
onCurrencyButtonPress?: () => void;

/** Placeholder value for amount text input */
placeholder: string;

/** Currency code of user's selected currency */
selectedCurrencyCode: string;

/** Selection Object */
selection?: TextSelection;

/** Function to call when selection in text input is changed */
onSelectionChange?: (event: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => void;

/** Function to call to handle key presses in the text input */
onKeyPress?: (event: NativeSyntheticEvent<KeyboardEvent>) => void;

/** Whether the currency symbol is pressable */
isCurrencyPressable: boolean;
};

export default TextInputWithCurrencySymbolProps;
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ function WorkspaceRatePage(props: WorkspaceRatePageProps) {
defaultValue={(
(typeof props.workspaceRateAndUnit?.rate === 'string' ? parseFloat(props.workspaceRateAndUnit.rate) : defaultValue) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET
).toFixed(3)}
isCurrencyPressable={false}
/>
</FormProvider>
)}
Expand Down

0 comments on commit a38d265

Please sign in to comment.