diff --git a/src/components/AmountTextInput.js b/src/components/AmountTextInput.js
index 98166cabd944..cc2e1e1e872b 100644
--- a/src/components/AmountTextInput.js
+++ b/src/components/AmountTextInput.js
@@ -26,12 +26,16 @@ const propTypes = {
/** Function to call when selection in text input is changed */
onSelectionChange: PropTypes.func,
+
+ /** Function to call to handle key presses in the text input */
+ onKeyPress: PropTypes.func,
};
const defaultProps = {
forwardedRef: undefined,
selection: undefined,
onSelectionChange: () => {},
+ onKeyPress: () => {},
};
function AmountTextInput(props) {
@@ -51,6 +55,7 @@ function AmountTextInput(props) {
selection={props.selection}
onSelectionChange={props.onSelectionChange}
accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT}
+ onKeyPress={props.onKeyPress}
/>
);
}
diff --git a/src/components/TextInputWithCurrencySymbol.js b/src/components/TextInputWithCurrencySymbol.js
deleted file mode 100644
index 72ae373539f0..000000000000
--- a/src/components/TextInputWithCurrencySymbol.js
+++ /dev/null
@@ -1,119 +0,0 @@
-import React, {useState, useEffect} from 'react';
-import PropTypes from 'prop-types';
-import AmountTextInput from './AmountTextInput';
-import CurrencySymbolButton from './CurrencySymbolButton';
-import * as CurrencyUtils from '../libs/CurrencyUtils';
-import useLocalize from '../hooks/useLocalize';
-import * as MoneyRequestUtils from '../libs/MoneyRequestUtils';
-import refPropTypes from './refPropTypes';
-
-const propTypes = {
- /** A ref to forward to amount text input */
- forwardedRef: refPropTypes,
-
- /** Formatted amount in local currency */
- formattedAmount: PropTypes.string.isRequired,
-
- /** Function to call when amount in text input is changed */
- onChangeAmount: PropTypes.func,
-
- /** Function to call when currency button is pressed */
- onCurrencyButtonPress: PropTypes.func,
-
- /** Placeholder value for amount text input */
- placeholder: PropTypes.string.isRequired,
-
- /** Currency code of user's selected currency */
- selectedCurrencyCode: PropTypes.string.isRequired,
-
- /** Selection Object */
- selection: PropTypes.shape({
- start: PropTypes.number,
- end: PropTypes.number,
- }),
-
- /** Function to call when selection in text input is changed */
- onSelectionChange: PropTypes.func,
-};
-
-const defaultProps = {
- forwardedRef: undefined,
- onChangeAmount: () => {},
- onCurrencyButtonPress: () => {},
- selection: undefined,
- onSelectionChange: () => {},
-};
-
-function TextInputWithCurrencySymbol(props) {
- const {fromLocaleDigit} = useLocalize();
- const currencySymbol = CurrencyUtils.getLocalizedCurrencySymbol(props.selectedCurrencyCode);
- const isCurrencySymbolLTR = CurrencyUtils.isCurrencySymbolLTR(props.selectedCurrencyCode);
-
- const [skipNextSelectionChange, setSkipNextSelectionChange] = useState(false);
-
- useEffect(() => {
- setSkipNextSelectionChange(true);
- }, [props.formattedAmount]);
-
- const currencySymbolButton = (
-
- );
-
- /**
- * Set a new amount value properly formatted
- *
- * @param {String} text - Changed text from user input
- */
- const setFormattedAmount = (text) => {
- const newAmount = MoneyRequestUtils.addLeadingZero(MoneyRequestUtils.replaceAllDigits(text, fromLocaleDigit));
- props.onChangeAmount(newAmount);
- };
-
- const amountTextInput = (
- {
- if (skipNextSelectionChange) {
- setSkipNextSelectionChange(false);
- return;
- }
- props.onSelectionChange(e);
- }}
- />
- );
-
- if (isCurrencySymbolLTR) {
- return (
- <>
- {currencySymbolButton}
- {amountTextInput}
- >
- );
- }
-
- return (
- <>
- {amountTextInput}
- {currencySymbolButton}
- >
- );
-}
-
-TextInputWithCurrencySymbol.propTypes = propTypes;
-TextInputWithCurrencySymbol.defaultProps = defaultProps;
-TextInputWithCurrencySymbol.displayName = 'TextInputWithCurrencySymbol';
-
-export default React.forwardRef((props, ref) => (
-
-));
diff --git a/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.js b/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.js
new file mode 100644
index 000000000000..6dd1aacb0b09
--- /dev/null
+++ b/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.js
@@ -0,0 +1,72 @@
+import React from 'react';
+import AmountTextInput from '../AmountTextInput';
+import CurrencySymbolButton from '../CurrencySymbolButton';
+import * as CurrencyUtils from '../../libs/CurrencyUtils';
+import useLocalize from '../../hooks/useLocalize';
+import * as MoneyRequestUtils from '../../libs/MoneyRequestUtils';
+import * as textInputWithCurrencySymbolPropTypes from './textInputWithCurrencySymbolPropTypes';
+
+function BaseTextInputWithCurrencySymbol(props) {
+ const {fromLocaleDigit} = useLocalize();
+ const currencySymbol = CurrencyUtils.getLocalizedCurrencySymbol(props.selectedCurrencyCode);
+ const isCurrencySymbolLTR = CurrencyUtils.isCurrencySymbolLTR(props.selectedCurrencyCode);
+
+ const currencySymbolButton = (
+
+ );
+
+ /**
+ * Set a new amount value properly formatted
+ *
+ * @param {String} text - Changed text from user input
+ */
+ const setFormattedAmount = (text) => {
+ const newAmount = MoneyRequestUtils.addLeadingZero(MoneyRequestUtils.replaceAllDigits(text, fromLocaleDigit));
+ props.onChangeAmount(newAmount);
+ };
+
+ const amountTextInput = (
+ {
+ props.onSelectionChange(e);
+ }}
+ onKeyPress={props.onKeyPress}
+ />
+ );
+
+ if (isCurrencySymbolLTR) {
+ return (
+ <>
+ {currencySymbolButton}
+ {amountTextInput}
+ >
+ );
+ }
+
+ return (
+ <>
+ {amountTextInput}
+ {currencySymbolButton}
+ >
+ );
+}
+
+BaseTextInputWithCurrencySymbol.propTypes = textInputWithCurrencySymbolPropTypes.propTypes;
+BaseTextInputWithCurrencySymbol.defaultProps = textInputWithCurrencySymbolPropTypes.defaultProps;
+BaseTextInputWithCurrencySymbol.displayName = 'BaseTextInputWithCurrencySymbol';
+
+export default React.forwardRef((props, ref) => (
+
+));
diff --git a/src/components/TextInputWithCurrencySymbol/index.android.js b/src/components/TextInputWithCurrencySymbol/index.android.js
new file mode 100644
index 000000000000..7fb65257e707
--- /dev/null
+++ b/src/components/TextInputWithCurrencySymbol/index.android.js
@@ -0,0 +1,37 @@
+import React, {useState, useEffect} from 'react';
+import BaseTextInputWithCurrencySymbol from './BaseTextInputWithCurrencySymbol';
+import * as textInputWithCurrencySymbolPropTypes from './textInputWithCurrencySymbolPropTypes';
+
+function TextInputWithCurrencySymbol(props) {
+ const [skipNextSelectionChange, setSkipNextSelectionChange] = useState(false);
+
+ useEffect(() => {
+ setSkipNextSelectionChange(true);
+ }, [props.formattedAmount]);
+
+ return (
+ {
+ if (skipNextSelectionChange) {
+ setSkipNextSelectionChange(false);
+ return;
+ }
+ props.onSelectionChange(e);
+ }}
+ />
+ );
+}
+
+TextInputWithCurrencySymbol.propTypes = textInputWithCurrencySymbolPropTypes.propTypes;
+TextInputWithCurrencySymbol.defaultProps = textInputWithCurrencySymbolPropTypes.defaultProps;
+TextInputWithCurrencySymbol.displayName = 'TextInputWithCurrencySymbol';
+
+export default React.forwardRef((props, ref) => (
+
+));
diff --git a/src/components/TextInputWithCurrencySymbol/index.js b/src/components/TextInputWithCurrencySymbol/index.js
new file mode 100644
index 000000000000..bd4c881c55ba
--- /dev/null
+++ b/src/components/TextInputWithCurrencySymbol/index.js
@@ -0,0 +1,24 @@
+import React from 'react';
+import BaseTextInputWithCurrencySymbol from './BaseTextInputWithCurrencySymbol';
+import * as textInputWithCurrencySymbolPropTypes from './textInputWithCurrencySymbolPropTypes';
+
+function TextInputWithCurrencySymbol(props) {
+ return (
+
+ );
+}
+
+TextInputWithCurrencySymbol.propTypes = textInputWithCurrencySymbolPropTypes.propTypes;
+TextInputWithCurrencySymbol.defaultProps = textInputWithCurrencySymbolPropTypes.defaultProps;
+TextInputWithCurrencySymbol.displayName = 'TextInputWithCurrencySymbol';
+
+export default React.forwardRef((props, ref) => (
+
+));
diff --git a/src/components/TextInputWithCurrencySymbol/textInputWithCurrencySymbolPropTypes.js b/src/components/TextInputWithCurrencySymbol/textInputWithCurrencySymbolPropTypes.js
new file mode 100644
index 000000000000..4e891029e71d
--- /dev/null
+++ b/src/components/TextInputWithCurrencySymbol/textInputWithCurrencySymbolPropTypes.js
@@ -0,0 +1,45 @@
+import PropTypes from 'prop-types';
+import refPropTypes from '../refPropTypes';
+
+const propTypes = {
+ /** A ref to forward to amount text input */
+ forwardedRef: refPropTypes,
+
+ /** Formatted amount in local currency */
+ formattedAmount: PropTypes.string.isRequired,
+
+ /** Function to call when amount in text input is changed */
+ onChangeAmount: PropTypes.func,
+
+ /** Function to call when currency button is pressed */
+ onCurrencyButtonPress: PropTypes.func,
+
+ /** Placeholder value for amount text input */
+ placeholder: PropTypes.string.isRequired,
+
+ /** Currency code of user's selected currency */
+ selectedCurrencyCode: PropTypes.string.isRequired,
+
+ /** Selection Object */
+ selection: PropTypes.shape({
+ start: PropTypes.number,
+ end: PropTypes.number,
+ }),
+
+ /** Function to call when selection in text input is changed */
+ onSelectionChange: PropTypes.func,
+
+ /** Function to call to handle key presses in the text input */
+ onKeyPress: PropTypes.func,
+};
+
+const defaultProps = {
+ forwardedRef: undefined,
+ onChangeAmount: () => {},
+ onCurrencyButtonPress: () => {},
+ selection: undefined,
+ onSelectionChange: () => {},
+ onKeyPress: () => {},
+};
+
+export {propTypes, defaultProps};
diff --git a/src/pages/iou/steps/MoneyRequestAmountForm.js b/src/pages/iou/steps/MoneyRequestAmountForm.js
index 4c2c76452c55..1d7444397c0e 100644
--- a/src/pages/iou/steps/MoneyRequestAmountForm.js
+++ b/src/pages/iou/steps/MoneyRequestAmountForm.js
@@ -13,6 +13,8 @@ import TextInputWithCurrencySymbol from '../../../components/TextInputWithCurren
import useLocalize from '../../../hooks/useLocalize';
import CONST from '../../../CONST';
import refPropTypes from '../../../components/refPropTypes';
+import getOperatingSystem from '../../../libs/getOperatingSystem';
+import * as Browser from '../../../libs/Browser';
import useWindowDimensions from '../../../hooks/useWindowDimensions';
const propTypes = {
@@ -75,6 +77,8 @@ function MoneyRequestAmountForm({amount, currency, isEditing, forwardedRef, onCu
end: selectedAmountAsString.length,
});
+ const forwardDeletePressedRef = useRef(false);
+
/**
* Event occurs when a user presses a mouse button over an DOM element.
*
@@ -125,7 +129,8 @@ function MoneyRequestAmountForm({amount, currency, isEditing, forwardedRef, onCu
}
setCurrentAmount((prevAmount) => {
const strippedAmount = MoneyRequestUtils.stripCommaFromAmount(newAmountWithoutSpaces);
- setSelection((prevSelection) => getNewSelection(prevSelection, prevAmount.length, strippedAmount.length));
+ const isForwardDelete = prevAmount.length > strippedAmount.length && forwardDeletePressedRef.current;
+ setSelection((prevSelection) => getNewSelection(prevSelection, isForwardDelete ? strippedAmount.length : prevAmount.length, strippedAmount.length));
return strippedAmount;
});
};
@@ -175,6 +180,22 @@ function MoneyRequestAmountForm({amount, currency, isEditing, forwardedRef, onCu
onSubmitButtonPress(currentAmount);
}, [onSubmitButtonPress, currentAmount]);
+ /**
+ * Input handler to check for a forward-delete key (or keyboard shortcut) press.
+ */
+ const textInputKeyPress = ({nativeEvent}) => {
+ const key = nativeEvent.key.toLowerCase();
+ if (Browser.isMobileSafari() && key === CONST.PLATFORM_SPECIFIC_KEYS.CTRL.DEFAULT) {
+ // Optimistically anticipate forward-delete on iOS Safari (in cases where the Mac Accessiblity keyboard is being
+ // used for input). If the Control-D shortcut doesn't get sent, the ref will still be reset on the next key press.
+ forwardDeletePressedRef.current = true;
+ return;
+ }
+ // Control-D on Mac is a keyboard shortcut for forward-delete. See https://support.apple.com/en-us/HT201236 for Mac keyboard shortcuts.
+ // Also check for the keyboard shortcut on iOS in cases where a hardware keyboard may be connected to the device.
+ forwardDeletePressedRef.current = key === 'delete' || (_.contains([CONST.OS.MAC_OS, CONST.OS.IOS], getOperatingSystem()) && nativeEvent.ctrlKey && key === 'd');
+ };
+
const formattedAmount = MoneyRequestUtils.replaceAllDigits(currentAmount, toLocaleDigit);
const buttonText = isEditing ? translate('common.save') : translate('common.next');
@@ -207,6 +228,7 @@ function MoneyRequestAmountForm({amount, currency, isEditing, forwardedRef, onCu
}
setSelection(e.nativeEvent.selection);
}}
+ onKeyPress={textInputKeyPress}
/>