diff --git a/android/app/build.gradle b/android/app/build.gradle
index 6d3168382073..e135d44eb834 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -98,8 +98,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
- versionCode 1001043201
- versionName "1.4.32-1"
+ versionCode 1001043202
+ versionName "1.4.32-2"
}
flavorDimensions "default"
diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist
index 6e62db6dea30..c636ced8e7f9 100644
--- a/ios/NewExpensify/Info.plist
+++ b/ios/NewExpensify/Info.plist
@@ -40,7 +40,7 @@
CFBundleVersion
- 1.4.32.1
+ 1.4.32.2
ITSAppUsesNonExemptEncryption
LSApplicationQueriesSchemes
diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist
index 45e0b42db439..ef1ef0d998d5 100644
--- a/ios/NewExpensifyTests/Info.plist
+++ b/ios/NewExpensifyTests/Info.plist
@@ -19,6 +19,6 @@
CFBundleSignature
????
CFBundleVersion
- 1.4.32.1
+ 1.4.32.2
diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist
index 2f0ce291dfc7..16439b1d24d9 100644
--- a/ios/NotificationServiceExtension/Info.plist
+++ b/ios/NotificationServiceExtension/Info.plist
@@ -5,7 +5,7 @@
CFBundleShortVersionString
1.4.32
CFBundleVersion
- 1.4.32.1
+ 1.4.32.2
NSExtension
NSExtensionPointIdentifier
diff --git a/package-lock.json b/package-lock.json
index 5a774298babd..543a1366f8d6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "new.expensify",
- "version": "1.4.32-1",
+ "version": "1.4.32-2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "new.expensify",
- "version": "1.4.32-1",
+ "version": "1.4.32-2",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index 055958b9a375..8ceac3912660 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
- "version": "1.4.32-1",
+ "version": "1.4.32-2",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
diff --git a/src/components/StatePicker/StateSelectorModal.js b/src/components/StatePicker/StateSelectorModal.tsx
similarity index 73%
rename from src/components/StatePicker/StateSelectorModal.js
rename to src/components/StatePicker/StateSelectorModal.tsx
index 003211478529..798d3be7a698 100644
--- a/src/components/StatePicker/StateSelectorModal.js
+++ b/src/components/StatePicker/StateSelectorModal.tsx
@@ -1,7 +1,5 @@
import {CONST as COMMON_CONST} from 'expensify-common/lib/CONST';
-import PropTypes from 'prop-types';
import React, {useEffect, useMemo} from 'react';
-import _ from 'underscore';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
@@ -9,40 +7,36 @@ import SelectionList from '@components/SelectionList';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import searchCountryOptions from '@libs/searchCountryOptions';
+import type {CountryData} from '@libs/searchCountryOptions';
import StringUtils from '@libs/StringUtils';
import CONST from '@src/CONST';
-const propTypes = {
+type State = keyof typeof COMMON_CONST.STATES;
+
+type StateSelectorModalProps = {
/** Whether the modal is visible */
- isVisible: PropTypes.bool.isRequired,
+ isVisible: boolean;
/** State value selected */
- currentState: PropTypes.string,
+ currentState?: State;
/** Function to call when the user selects a State */
- onStateSelected: PropTypes.func,
+ onStateSelected?: (state: CountryData) => void;
/** Function to call when the user closes the State modal */
- onClose: PropTypes.func,
+ onClose?: () => void;
/** The search value from the selection list */
- searchValue: PropTypes.string.isRequired,
+ searchValue: string;
/** Function to call when the user types in the search input */
- setSearchValue: PropTypes.func.isRequired,
+ setSearchValue: (value: string) => void;
/** Label to display on field */
- label: PropTypes.string,
-};
-
-const defaultProps = {
- currentState: '',
- onClose: () => {},
- onStateSelected: () => {},
- label: undefined,
+ label?: string;
};
-function StateSelectorModal({currentState, isVisible, onClose, onStateSelected, searchValue, setSearchValue, label}) {
+function StateSelectorModal({currentState, isVisible, onClose = () => {}, onStateSelected = () => {}, searchValue, setSearchValue, label}: StateSelectorModalProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
@@ -53,11 +47,11 @@ function StateSelectorModal({currentState, isVisible, onClose, onStateSelected,
setSearchValue('');
}, [isVisible, setSearchValue]);
- const countryStates = useMemo(
+ const countryStates: CountryData[] = useMemo(
() =>
- _.map(_.keys(COMMON_CONST.STATES), (state) => {
- const stateName = translate(`allStates.${state}.stateName`);
- const stateISO = translate(`allStates.${state}.stateISO`);
+ Object.keys(COMMON_CONST.STATES).map((state) => {
+ const stateName = translate(`allStates.${state as State}.stateName`);
+ const stateISO = translate(`allStates.${state as State}.stateISO`);
return {
value: stateISO,
keyForList: stateISO,
@@ -88,12 +82,16 @@ function StateSelectorModal({currentState, isVisible, onClose, onStateSelected,
testID={StateSelectorModal.displayName}
>
void;
/** Label to display on field */
- label: PropTypes.string,
+ label?: string;
/** Callback to call when the picker modal is dismissed */
- onBlur: PropTypes.func,
-};
-
-const defaultProps = {
- value: undefined,
- forwardedRef: undefined,
- errorText: '',
- onInputChange: () => {},
- label: undefined,
- onBlur: () => {},
+ onBlur?: () => void;
};
-function StatePicker({value, errorText, onInputChange, forwardedRef, label, onBlur}) {
+function StatePicker({value, onInputChange, label, onBlur, errorText = ''}: StatePickerProps, ref: ForwardedRef) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const [isPickerVisible, setIsPickerVisible] = useState(false);
@@ -51,29 +39,31 @@ function StatePicker({value, errorText, onInputChange, forwardedRef, label, onBl
const hidePickerModal = (shouldBlur = true) => {
if (shouldBlur) {
- onBlur();
+ onBlur?.();
}
setIsPickerVisible(false);
};
- const updateStateInput = (state) => {
+ const updateStateInput = (state: CountryData) => {
if (state.value !== value) {
- onInputChange(state.value);
+ onInputChange?.(state.value);
}
// If the user selects any state, call the hidePickerModal function with shouldBlur = false
// to prevent the onBlur function from being called.
hidePickerModal(false);
};
- const title = value && _.keys(COMMON_CONST.STATES).includes(value) ? translate(`allStates.${value}.stateName`) : '';
+ const title = value && Object.keys(COMMON_CONST.STATES).includes(value) ? translate(`allStates.${value}.stateName`) : '';
const descStyle = title.length === 0 ? styles.textNormal : null;
return (
(
-
-));
-
-StatePickerWithRef.displayName = 'StatePickerWithRef';
-
-export default StatePickerWithRef;
+export default React.forwardRef(StatePicker);
diff --git a/src/libs/searchCountryOptions.ts b/src/libs/searchCountryOptions.ts
index 8fb1cc9c37f3..1fc5d343f556 100644
--- a/src/libs/searchCountryOptions.ts
+++ b/src/libs/searchCountryOptions.ts
@@ -37,3 +37,4 @@ function searchCountryOptions(searchValue: string, countriesData: CountryData[])
}
export default searchCountryOptions;
+export type {CountryData};